xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 456192e25527e6dfd94efe19f31bdabe85ed0893)
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 */
176273d9f13SBarry Smith         int         new_nz = ai[A->m] + CHUNKSIZE,len,*new_i,*new_j;
17787828ca2SBarry Smith         PetscScalar *new_a;
17817ab2063SBarry Smith 
17929bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
18096854ed6SLois Curfman McInnes 
18117ab2063SBarry Smith         /* malloc new storage space */
18287828ca2SBarry Smith         len     = new_nz*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
183b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
18417ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
18517ab2063SBarry Smith         new_i   = new_j + new_nz;
18617ab2063SBarry Smith 
18717ab2063SBarry Smith         /* copy over old data into new slots */
18817ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
189273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
190549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr);
191416022c9SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow - shift);
192549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr);
19387828ca2SBarry Smith         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
19487828ca2SBarry Smith         ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
19517ab2063SBarry Smith         /* free up old matrix storage */
196606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
197606d414cSSatish Balay         if (!a->singlemalloc) {
198606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
199606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
200606d414cSSatish Balay         }
201416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
202f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
20317ab2063SBarry Smith 
20417ab2063SBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
205416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
20687828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
207416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
208b810aeb4SBarry Smith         a->reallocs++;
20917ab2063SBarry Smith       }
210416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
211416022c9SBarry Smith       /* shift up all the later entries in this row */
212416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
21317ab2063SBarry Smith         rp[ii+1] = rp[ii];
21417ab2063SBarry Smith         ap[ii+1] = ap[ii];
21517ab2063SBarry Smith       }
21617ab2063SBarry Smith       rp[i] = col;
21717ab2063SBarry Smith       ap[i] = value;
21817ab2063SBarry Smith       noinsert:;
219416022c9SBarry Smith       low = i + 1;
22017ab2063SBarry Smith     }
22117ab2063SBarry Smith     ailen[row] = nrow;
22217ab2063SBarry Smith   }
2233a40ed3dSBarry Smith   PetscFunctionReturn(0);
22417ab2063SBarry Smith }
22517ab2063SBarry Smith 
2264a2ae208SSatish Balay #undef __FUNCT__
2274a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
22887828ca2SBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v)
2297eb43aa7SLois Curfman McInnes {
2307eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
231b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
2327eb43aa7SLois Curfman McInnes   int          *ai = a->i,*ailen = a->ilen,shift = a->indexshift;
23387828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2347eb43aa7SLois Curfman McInnes 
2353a40ed3dSBarry Smith   PetscFunctionBegin;
2367eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2377eb43aa7SLois Curfman McInnes     row  = im[k];
23829bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
239273d9f13SBarry Smith     if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: %d",row);
2407eb43aa7SLois Curfman McInnes     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
2417eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2427eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
24329bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
244273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: %d",in[l]);
2457eb43aa7SLois Curfman McInnes       col = in[l] - shift;
2467eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2477eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2487eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2497eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2507eb43aa7SLois Curfman McInnes         else             low  = t;
2517eb43aa7SLois Curfman McInnes       }
2527eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2537eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2547eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
255b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2567eb43aa7SLois Curfman McInnes           goto finished;
2577eb43aa7SLois Curfman McInnes         }
2587eb43aa7SLois Curfman McInnes       }
259b49de8d1SLois Curfman McInnes       *v++ = zero;
2607eb43aa7SLois Curfman McInnes       finished:;
2617eb43aa7SLois Curfman McInnes     }
2627eb43aa7SLois Curfman McInnes   }
2633a40ed3dSBarry Smith   PetscFunctionReturn(0);
2647eb43aa7SLois Curfman McInnes }
2657eb43aa7SLois Curfman McInnes 
26617ab2063SBarry Smith 
2674a2ae208SSatish Balay #undef __FUNCT__
2684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
269b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
27017ab2063SBarry Smith {
271416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
272416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
27317ab2063SBarry Smith 
2743a40ed3dSBarry Smith   PetscFunctionBegin;
275b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
276b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
277552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
278273d9f13SBarry Smith   col_lens[1] = A->m;
279273d9f13SBarry Smith   col_lens[2] = A->n;
280416022c9SBarry Smith   col_lens[3] = a->nz;
281416022c9SBarry Smith 
282416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
283273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
284416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
28517ab2063SBarry Smith   }
286273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
287606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
288416022c9SBarry Smith 
289416022c9SBarry Smith   /* store column indices (zero start index) */
290416022c9SBarry Smith   if (a->indexshift) {
291416022c9SBarry Smith     for (i=0; i<a->nz; i++) a->j[i]--;
29217ab2063SBarry Smith   }
2930752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
294416022c9SBarry Smith   if (a->indexshift) {
295416022c9SBarry Smith     for (i=0; i<a->nz; i++) a->j[i]++;
29617ab2063SBarry Smith   }
297416022c9SBarry Smith 
298416022c9SBarry Smith   /* store nonzero values */
2990752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
3003a40ed3dSBarry Smith   PetscFunctionReturn(0);
30117ab2063SBarry Smith }
302416022c9SBarry Smith 
3037f43a090SHong Zhang extern int MatSeqAIJFactorInfo_SuperLU(Mat,PetscViewer);
304cd155464SBarry Smith extern int MatMPIAIJFactorInfo_SuperLu(Mat,PetscViewer);
305a072f7f7SHong Zhang extern int MatFactorInfo_Spooles(Mat,PetscViewer);
306e7420845SHong Zhang extern int MatSeqAIJFactorInfo_UMFPACK(Mat,PetscViewer);
307cd155464SBarry Smith 
3084a2ae208SSatish Balay #undef __FUNCT__
3094a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
310b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
311416022c9SBarry Smith {
312416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
313fb9695e5SSatish Balay   int               ierr,i,j,m = A->m,shift = a->indexshift;
314fb9695e5SSatish Balay   char              *name;
315f3ef73ceSBarry Smith   PetscViewerFormat format;
31617ab2063SBarry Smith 
3173a40ed3dSBarry Smith   PetscFunctionBegin;
318435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
319b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
320*456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3216831982aSBarry Smith     if (a->inode.size) {
322b0a32e0cSBarry 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);
3236831982aSBarry Smith     } else {
324b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3256831982aSBarry Smith     }
326fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
327d00d2cf4SBarry Smith     int nofinalvalue = 0;
328273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
329d00d2cf4SBarry Smith       nofinalvalue = 1;
330d00d2cf4SBarry Smith     }
331b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
332b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
333b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
334b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
335b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
33617ab2063SBarry Smith 
33717ab2063SBarry Smith     for (i=0; i<m; i++) {
338416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
339aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
340b0a32e0cSBarry 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);
34117ab2063SBarry Smith #else
342b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
34317ab2063SBarry Smith #endif
34417ab2063SBarry Smith       }
34517ab2063SBarry Smith     }
346d00d2cf4SBarry Smith     if (nofinalvalue) {
347b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
348d00d2cf4SBarry Smith     }
349fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
350b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
351cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
3527f43a090SHong Zhang #if defined(PETSC_HAVE_SUPERLU) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
3537f43a090SHong Zhang      ierr = MatSeqAIJFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr);
3547f43a090SHong Zhang #endif
355cd155464SBarry Smith #if defined(PETSC_HAVE_SUPERLUDIST) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
356cd155464SBarry Smith      ierr = MatMPIAIJFactorInfo_SuperLu(A,viewer);CHKERRQ(ierr);
357cd155464SBarry Smith #endif
358174d842dSHong Zhang #if defined(PETSC_HAVE_SPOOLES) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
359a072f7f7SHong Zhang      ierr = MatFactorInfo_Spooles(A,viewer);CHKERRQ(ierr);
360174d842dSHong Zhang #endif
361e7420845SHong Zhang #if defined(PETSC_HAVE_UMFPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
362e7420845SHong Zhang      ierr = MatSeqAIJFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr);
363e7420845SHong Zhang #endif
364cd155464SBarry Smith      PetscFunctionReturn(0);
365fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
366b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
36744cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
368b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
36944cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
370aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
37136db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
37262b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
37336db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
37462b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
37536db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
37662b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3776831982aSBarry Smith         }
37844cd7ae7SLois Curfman McInnes #else
37962b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
38044cd7ae7SLois Curfman McInnes #endif
38144cd7ae7SLois Curfman McInnes       }
382b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
38344cd7ae7SLois Curfman McInnes     }
384b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
385fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
386496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
387b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
388b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
389496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
390496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
391496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
392496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
393aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
395496be53dSLois Curfman McInnes #else
396496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
397496be53dSLois Curfman McInnes #endif
398496be53dSLois Curfman McInnes         }
399496be53dSLois Curfman McInnes       }
400496be53dSLois Curfman McInnes     }
4012e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
402b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
4032e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
404b0a32e0cSBarry 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);}
405b0a32e0cSBarry 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);}
406b0a32e0cSBarry 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);}
407b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
408b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
409b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
410496be53dSLois Curfman McInnes     }
411b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
412606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
413496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
414496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
415b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
416496be53dSLois Curfman McInnes       }
417b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
418496be53dSLois Curfman McInnes     }
419b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
420496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
421496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
422496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
423aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
42436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
425b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4266831982aSBarry Smith           }
427496be53dSLois Curfman McInnes #else
428b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
429496be53dSLois Curfman McInnes #endif
430496be53dSLois Curfman McInnes         }
431496be53dSLois Curfman McInnes       }
432b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
433496be53dSLois Curfman McInnes     }
434b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
435fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
43602594712SBarry Smith     int         cnt = 0,jcnt;
43787828ca2SBarry Smith     PetscScalar value;
43802594712SBarry Smith 
439b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44002594712SBarry Smith     for (i=0; i<m; i++) {
44102594712SBarry Smith       jcnt = 0;
442273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
443e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44402594712SBarry Smith           value = a->a[cnt++];
445e24b481bSBarry Smith           jcnt++;
44602594712SBarry Smith         } else {
44702594712SBarry Smith           value = 0.0;
44802594712SBarry Smith         }
449aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
450b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
45102594712SBarry Smith #else
452b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
45302594712SBarry Smith #endif
45402594712SBarry Smith       }
455b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45602594712SBarry Smith     }
457b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4583a40ed3dSBarry Smith   } else {
459b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
46017ab2063SBarry Smith     for (i=0; i<m; i++) {
461b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
462416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
463aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46436db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
46562b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
46636db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
46762b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4683a40ed3dSBarry Smith         } else {
46962b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
47017ab2063SBarry Smith         }
47117ab2063SBarry Smith #else
47262b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
47317ab2063SBarry Smith #endif
47417ab2063SBarry Smith       }
475b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47617ab2063SBarry Smith     }
477b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
47817ab2063SBarry Smith   }
479b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4803a40ed3dSBarry Smith   PetscFunctionReturn(0);
481416022c9SBarry Smith }
482416022c9SBarry Smith 
4834a2ae208SSatish Balay #undef __FUNCT__
4844a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
485b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
486416022c9SBarry Smith {
487480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
488416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
489273d9f13SBarry Smith   int               ierr,i,j,m = A->m,shift = a->indexshift,color;
49036db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
491b0a32e0cSBarry Smith   PetscViewer       viewer;
492f3ef73ceSBarry Smith   PetscViewerFormat format;
493cddf8d76SBarry Smith 
4943a40ed3dSBarry Smith   PetscFunctionBegin;
495480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
496b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
49719bcc07fSBarry Smith 
498b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
499416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5000513a670SBarry Smith 
501fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
5020513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
503b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
504416022c9SBarry Smith     for (i=0; i<m; i++) {
505cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
506416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
507cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
508aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
50936db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
510cddf8d76SBarry Smith #else
511cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
512cddf8d76SBarry Smith #endif
513b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
514cddf8d76SBarry Smith       }
515cddf8d76SBarry Smith     }
516b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
517cddf8d76SBarry Smith     for (i=0; i<m; i++) {
518cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
519cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
520cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
521cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
522b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
523cddf8d76SBarry Smith       }
524cddf8d76SBarry Smith     }
525b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
526cddf8d76SBarry Smith     for (i=0; i<m; i++) {
527cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
528cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
529cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
530aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
53136db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
532cddf8d76SBarry Smith #else
533cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
534cddf8d76SBarry Smith #endif
535b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
536416022c9SBarry Smith       }
537416022c9SBarry Smith     }
5380513a670SBarry Smith   } else {
5390513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5400513a670SBarry Smith     /* first determine max of all nonzero values */
5410513a670SBarry Smith     int    nz = a->nz,count;
542b0a32e0cSBarry Smith     PetscDraw   popup;
54336db0b34SBarry Smith     PetscReal scale;
5440513a670SBarry Smith 
5450513a670SBarry Smith     for (i=0; i<nz; i++) {
5460513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5470513a670SBarry Smith     }
548b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
549b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
550b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5510513a670SBarry Smith     count = 0;
5520513a670SBarry Smith     for (i=0; i<m; i++) {
5530513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5540513a670SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5550513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
556b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
557b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5580513a670SBarry Smith         count++;
5590513a670SBarry Smith       }
5600513a670SBarry Smith     }
5610513a670SBarry Smith   }
562480ef9eaSBarry Smith   PetscFunctionReturn(0);
563480ef9eaSBarry Smith }
564cddf8d76SBarry Smith 
5654a2ae208SSatish Balay #undef __FUNCT__
5664a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
567b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
568480ef9eaSBarry Smith {
569480ef9eaSBarry Smith   int        ierr;
570b0a32e0cSBarry Smith   PetscDraw  draw;
57136db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
572480ef9eaSBarry Smith   PetscTruth isnull;
573480ef9eaSBarry Smith 
574480ef9eaSBarry Smith   PetscFunctionBegin;
575b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
576b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
577480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
578480ef9eaSBarry Smith 
579480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
580273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
581480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
582b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
583b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
584480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5853a40ed3dSBarry Smith   PetscFunctionReturn(0);
586416022c9SBarry Smith }
587416022c9SBarry Smith 
5884a2ae208SSatish Balay #undef __FUNCT__
5894a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
590b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
591416022c9SBarry Smith {
592416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
593bcd2baecSBarry Smith   int         ierr;
5946831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
595416022c9SBarry Smith 
5963a40ed3dSBarry Smith   PetscFunctionBegin;
597b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
598b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
599fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
600fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
6010f5bd95cSBarry Smith   if (issocket) {
60201820c62SBarry Smith     if (a->indexshift) {
60329bbc08cSBarry Smith       SETERRQ(1,"Can only socket send sparse matrix with 0 based indexing");
60401820c62SBarry Smith     }
605b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
6060f5bd95cSBarry Smith   } else if (isascii) {
6073a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6080f5bd95cSBarry Smith   } else if (isbinary) {
6093a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6100f5bd95cSBarry Smith   } else if (isdraw) {
6113a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6125cd90555SBarry Smith   } else {
61329bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
61417ab2063SBarry Smith   }
6153a40ed3dSBarry Smith   PetscFunctionReturn(0);
61617ab2063SBarry Smith }
61719bcc07fSBarry Smith 
6183a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth);
6194a2ae208SSatish Balay #undef __FUNCT__
6204a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
6218f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
62217ab2063SBarry Smith {
623416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
62441c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
625273d9f13SBarry Smith   int          m = A->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0;
62687828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
627564e58d6SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) || defined(PETSC_HAVE_SPOOLES) || defined(PETSC_HAVE_UMFPACK)
6289b9367d5SHong Zhang   PetscTruth   flag;
6299e070d67SMatthew Knepley #endif
63017ab2063SBarry Smith 
6313a40ed3dSBarry Smith   PetscFunctionBegin;
6323a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
63317ab2063SBarry Smith 
63443ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
63517ab2063SBarry Smith   for (i=1; i<m; i++) {
636416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
63717ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
63894a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
63917ab2063SBarry Smith     if (fshift) {
6400f5bd95cSBarry Smith       ip = aj + ai[i] + shift;
6410f5bd95cSBarry Smith       ap = aa + ai[i] + shift;
64217ab2063SBarry Smith       N  = ailen[i];
64317ab2063SBarry Smith       for (j=0; j<N; j++) {
64417ab2063SBarry Smith         ip[j-fshift] = ip[j];
64517ab2063SBarry Smith         ap[j-fshift] = ap[j];
64617ab2063SBarry Smith       }
64717ab2063SBarry Smith     }
64817ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
64917ab2063SBarry Smith   }
65017ab2063SBarry Smith   if (m) {
65117ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
65217ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
65317ab2063SBarry Smith   }
65417ab2063SBarry Smith   /* reset ilen and imax for each row */
65517ab2063SBarry Smith   for (i=0; i<m; i++) {
65617ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
65717ab2063SBarry Smith   }
658416022c9SBarry Smith   a->nz = ai[m] + shift;
65917ab2063SBarry Smith 
66017ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
661416022c9SBarry Smith   if (fshift && a->diag) {
662606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
663b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
664416022c9SBarry Smith     a->diag = 0;
66517ab2063SBarry Smith   }
666b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
667b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
668b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
669dd5f02e7SSatish Balay   a->reallocs          = 0;
6704e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
67136db0b34SBarry Smith   a->rmax              = rmax;
6724e220ebcSLois Curfman McInnes 
67376dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6743a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
675cfef3cccSHong Zhang 
6769b9367d5SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST)
677e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_superlu_dist",&flag);CHKERRQ(ierr);
6789b9367d5SHong Zhang   if (flag) { ierr = MatUseSuperLU_DIST_MPIAIJ(A);CHKERRQ(ierr); }
6799b9367d5SHong Zhang #endif
6809b9367d5SHong Zhang 
681cfef3cccSHong Zhang #if defined(PETSC_HAVE_SPOOLES)
682e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_spooles",&flag);CHKERRQ(ierr);
683cfef3cccSHong Zhang   if (flag) { ierr = MatUseSpooles_SeqAIJ(A);CHKERRQ(ierr); }
684cfef3cccSHong Zhang #endif
685cfef3cccSHong Zhang 
686564e58d6SHong Zhang #if defined(PETSC_HAVE_UMFPACK)
687e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_umfpack",&flag);CHKERRQ(ierr);
688564e58d6SHong Zhang   if (flag) { ierr = MatUseUMFPACK_SeqAIJ(A);CHKERRQ(ierr); }
689564e58d6SHong Zhang #endif
690564e58d6SHong Zhang 
6913a40ed3dSBarry Smith   PetscFunctionReturn(0);
69217ab2063SBarry Smith }
69317ab2063SBarry Smith 
6944a2ae208SSatish Balay #undef __FUNCT__
6954a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6968f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
69717ab2063SBarry Smith {
698416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
699549d3d68SSatish Balay   int        ierr;
7003a40ed3dSBarry Smith 
7013a40ed3dSBarry Smith   PetscFunctionBegin;
70287828ca2SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
7033a40ed3dSBarry Smith   PetscFunctionReturn(0);
70417ab2063SBarry Smith }
705416022c9SBarry Smith 
7064a2ae208SSatish Balay #undef __FUNCT__
7074a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
708e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
70917ab2063SBarry Smith {
710416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
71182bf6240SBarry Smith   int        ierr;
712d5d45c9bSBarry Smith 
7133a40ed3dSBarry Smith   PetscFunctionBegin;
714aa482453SBarry Smith #if defined(PETSC_USE_LOG)
715b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
71617ab2063SBarry Smith #endif
71736db0b34SBarry Smith   if (a->freedata) {
718606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
719606d414cSSatish Balay     if (!a->singlemalloc) {
720606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
721606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
722606d414cSSatish Balay     }
72336db0b34SBarry Smith   }
724c38d4ed2SBarry Smith   if (a->row) {
725c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
726c38d4ed2SBarry Smith   }
727c38d4ed2SBarry Smith   if (a->col) {
728c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
729c38d4ed2SBarry Smith   }
730606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
731606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
732606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
733273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
734606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
735606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
73682bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
737606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
738cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
739606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
7403a40ed3dSBarry Smith   PetscFunctionReturn(0);
74117ab2063SBarry Smith }
74217ab2063SBarry Smith 
7434a2ae208SSatish Balay #undef __FUNCT__
7444a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
7458f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
74617ab2063SBarry Smith {
7473a40ed3dSBarry Smith   PetscFunctionBegin;
7483a40ed3dSBarry Smith   PetscFunctionReturn(0);
74917ab2063SBarry Smith }
75017ab2063SBarry Smith 
7514a2ae208SSatish Balay #undef __FUNCT__
7524a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7538f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
75417ab2063SBarry Smith {
755416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7563a40ed3dSBarry Smith 
7573a40ed3dSBarry Smith   PetscFunctionBegin;
758a65d3064SKris Buschelman   switch (op) {
759a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
760a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
761a65d3064SKris Buschelman       break;
762a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
763a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
764a65d3064SKris Buschelman       break;
765a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
766a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
767a65d3064SKris Buschelman       break;
768a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
769a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
770a65d3064SKris Buschelman       break;
771a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
772a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
773a65d3064SKris Buschelman       break;
774a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
775a65d3064SKris Buschelman       a->nonew             = 1;
776a65d3064SKris Buschelman       break;
777a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
778a65d3064SKris Buschelman       a->nonew             = -1;
779a65d3064SKris Buschelman       break;
780a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
781a65d3064SKris Buschelman       a->nonew             = -2;
782a65d3064SKris Buschelman       break;
783a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
784a65d3064SKris Buschelman       a->nonew             = 0;
785a65d3064SKris Buschelman       break;
786a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
787a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
788a65d3064SKris Buschelman       break;
789a65d3064SKris Buschelman     case MAT_USE_INODES:
790a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
791a65d3064SKris Buschelman       break;
792a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
793a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
794a65d3064SKris Buschelman       break;
795a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
796a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
797a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
798a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
799a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
800d03495bdSKris Buschelman     case MAT_USE_SINGLE_PRECISION_SOLVES:
801b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
802a65d3064SKris Buschelman       break;
803a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
80429bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
805a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
806a65d3064SKris Buschelman       a->inode.limit  = 1;
807a65d3064SKris Buschelman       break;
808a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
809a65d3064SKris Buschelman       a->inode.limit  = 2;
810a65d3064SKris Buschelman       break;
811a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
812a65d3064SKris Buschelman       a->inode.limit  = 3;
813a65d3064SKris Buschelman       break;
814a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
815a65d3064SKris Buschelman       a->inode.limit  = 4;
816a65d3064SKris Buschelman       break;
817a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
818a65d3064SKris Buschelman       a->inode.limit  = 5;
819a65d3064SKris Buschelman       break;
820a65d3064SKris Buschelman     default:
821a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
822a65d3064SKris Buschelman   }
8233a40ed3dSBarry Smith   PetscFunctionReturn(0);
82417ab2063SBarry Smith }
82517ab2063SBarry Smith 
8264a2ae208SSatish Balay #undef __FUNCT__
8274a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
8288f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
82917ab2063SBarry Smith {
830416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8313a40ed3dSBarry Smith   int          i,j,n,shift = a->indexshift,ierr;
83287828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
83317ab2063SBarry Smith 
8343a40ed3dSBarry Smith   PetscFunctionBegin;
8353a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
83636db0b34SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
83736db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
838273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
839273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
840416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
841416022c9SBarry Smith       if (a->j[j]+shift == i) {
842416022c9SBarry Smith         x[i] = a->a[j];
84317ab2063SBarry Smith         break;
84417ab2063SBarry Smith       }
84517ab2063SBarry Smith     }
84617ab2063SBarry Smith   }
84736db0b34SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8483a40ed3dSBarry Smith   PetscFunctionReturn(0);
84917ab2063SBarry Smith }
85017ab2063SBarry Smith 
851d5d45c9bSBarry Smith 
8524a2ae208SSatish Balay #undef __FUNCT__
8534a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8547c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
85517ab2063SBarry Smith {
856416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8575c897100SBarry Smith   PetscScalar  *x,*y;
8585c897100SBarry Smith   int          ierr,m = A->m,shift = a->indexshift;
8595c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8605c897100SBarry Smith   PetscScalar  *v,alpha;
8615c897100SBarry Smith   int          n,i,*idx;
8625c897100SBarry Smith #endif
86317ab2063SBarry Smith 
8643a40ed3dSBarry Smith   PetscFunctionBegin;
8652e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
866e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
867e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
86817ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
8695c897100SBarry Smith 
8705c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8715c897100SBarry Smith   fortranmulttransposeaddaij_(&m,x,a->i,a->j+shift,a->a+shift,y);
8725c897100SBarry Smith #else
87317ab2063SBarry Smith   for (i=0; i<m; i++) {
874416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
875416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
876416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
87717ab2063SBarry Smith     alpha = x[i];
87817ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
87917ab2063SBarry Smith   }
8805c897100SBarry Smith #endif
881b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
882e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
883e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8843a40ed3dSBarry Smith   PetscFunctionReturn(0);
88517ab2063SBarry Smith }
88617ab2063SBarry Smith 
8874a2ae208SSatish Balay #undef __FUNCT__
8885c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8895c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8905c897100SBarry Smith {
8918d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8925c897100SBarry Smith   int          ierr;
8935c897100SBarry Smith 
8945c897100SBarry Smith   PetscFunctionBegin;
8955c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8965c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8975c897100SBarry Smith   PetscFunctionReturn(0);
8985c897100SBarry Smith }
8995c897100SBarry Smith 
9005c897100SBarry Smith 
9015c897100SBarry Smith #undef __FUNCT__
9024a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
90344cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
90417ab2063SBarry Smith {
905416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
906362ced78SSatish Balay   PetscScalar  *x,*y,*v;
907273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
908aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
909e36a17ebSSatish Balay   int          n,i,jrow,j;
910362ced78SSatish Balay   PetscScalar  sum;
911e36a17ebSSatish Balay #endif
91217ab2063SBarry Smith 
913b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
914fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
915fee21e36SBarry Smith #endif
916fee21e36SBarry Smith 
9173a40ed3dSBarry Smith   PetscFunctionBegin;
918e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
919e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
92017ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
921416022c9SBarry Smith   idx  = a->j;
922d64ed03dSBarry Smith   v    = a->a;
923416022c9SBarry Smith   ii   = a->i;
924aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
92529b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
9268d195f9aSBarry Smith #else
927d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
928d64ed03dSBarry Smith   idx  += shift;
92917ab2063SBarry Smith   for (i=0; i<m; i++) {
9309ea0dfa2SSatish Balay     jrow = ii[i];
9319ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93217ab2063SBarry Smith     sum  = 0.0;
9339ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9349ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9359ea0dfa2SSatish Balay      }
93617ab2063SBarry Smith     y[i] = sum;
93717ab2063SBarry Smith   }
9388d195f9aSBarry Smith #endif
939b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
940e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
941e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9423a40ed3dSBarry Smith   PetscFunctionReturn(0);
94317ab2063SBarry Smith }
94417ab2063SBarry Smith 
9454a2ae208SSatish Balay #undef __FUNCT__
9464a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
94744cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
94817ab2063SBarry Smith {
949416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
950362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
951273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
952aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
953e36a17ebSSatish Balay   int          n,i,jrow,j;
954362ced78SSatish Balay PetscScalar    sum;
955e36a17ebSSatish Balay #endif
9569ea0dfa2SSatish Balay 
9573a40ed3dSBarry Smith   PetscFunctionBegin;
958e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
959e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9602e8a6d31SBarry Smith   if (zz != yy) {
961e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9622e8a6d31SBarry Smith   } else {
9632e8a6d31SBarry Smith     z = y;
9642e8a6d31SBarry Smith   }
96517ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
966cddf8d76SBarry Smith   idx  = a->j;
967d64ed03dSBarry Smith   v    = a->a;
968cddf8d76SBarry Smith   ii   = a->i;
969aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
97029b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
97102ab625aSSatish Balay #else
972d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
973d64ed03dSBarry Smith   idx += shift;
97417ab2063SBarry Smith   for (i=0; i<m; i++) {
9759ea0dfa2SSatish Balay     jrow = ii[i];
9769ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
97717ab2063SBarry Smith     sum  = y[i];
9789ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9799ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9809ea0dfa2SSatish Balay      }
98117ab2063SBarry Smith     z[i] = sum;
98217ab2063SBarry Smith   }
98302ab625aSSatish Balay #endif
984b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
985e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
986e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9872e8a6d31SBarry Smith   if (zz != yy) {
988e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9892e8a6d31SBarry Smith   }
9903a40ed3dSBarry Smith   PetscFunctionReturn(0);
99117ab2063SBarry Smith }
99217ab2063SBarry Smith 
99317ab2063SBarry Smith /*
99417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
99517ab2063SBarry Smith */
9964a2ae208SSatish Balay #undef __FUNCT__
9974a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
998f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
99917ab2063SBarry Smith {
1000416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1001b0a32e0cSBarry Smith   int        i,j,*diag,m = A->m,shift = a->indexshift,ierr;
100217ab2063SBarry Smith 
10033a40ed3dSBarry Smith   PetscFunctionBegin;
1004f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
1005f1e2ffcdSBarry Smith 
1006b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
1007b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
1008273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
100935b0346bSBarry Smith     diag[i] = a->i[i+1];
1010416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
1011416022c9SBarry Smith       if (a->j[j]+shift == i) {
101217ab2063SBarry Smith         diag[i] = j - shift;
101317ab2063SBarry Smith         break;
101417ab2063SBarry Smith       }
101517ab2063SBarry Smith     }
101617ab2063SBarry Smith   }
1017416022c9SBarry Smith   a->diag = diag;
10183a40ed3dSBarry Smith   PetscFunctionReturn(0);
101917ab2063SBarry Smith }
102017ab2063SBarry Smith 
1021be5855fcSBarry Smith /*
1022be5855fcSBarry Smith      Checks for missing diagonals
1023be5855fcSBarry Smith */
10244a2ae208SSatish Balay #undef __FUNCT__
10254a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1026f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
1027be5855fcSBarry Smith {
1028be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1029f1e2ffcdSBarry Smith   int        *diag,*jj = a->j,i,shift = a->indexshift,ierr;
1030be5855fcSBarry Smith 
1031be5855fcSBarry Smith   PetscFunctionBegin;
1032f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1033f1e2ffcdSBarry Smith   diag = a->diag;
1034273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
1035be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
103629bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
1037be5855fcSBarry Smith     }
1038be5855fcSBarry Smith   }
1039be5855fcSBarry Smith   PetscFunctionReturn(0);
1040be5855fcSBarry Smith }
1041be5855fcSBarry Smith 
10424a2ae208SSatish Balay #undef __FUNCT__
10434a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
1044c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
104517ab2063SBarry Smith {
1046416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
104787828ca2SBarry Smith   PetscScalar  *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0;
1048273d9f13SBarry Smith   int          ierr,*idx,*diag,n = A->n,m = A->m,i,shift = a->indexshift;
104917ab2063SBarry Smith 
10503a40ed3dSBarry Smith   PetscFunctionBegin;
1051b965ef7fSBarry Smith   its = its*lits;
105291723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
105391723122SBarry Smith 
1054e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1055fb2e594dSBarry Smith   if (xx != bb) {
1056e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1057fb2e594dSBarry Smith   } else {
1058fb2e594dSBarry Smith     b = x;
1059fb2e594dSBarry Smith   }
1060fb2e594dSBarry Smith 
1061f1e2ffcdSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1062416022c9SBarry Smith   diag = a->diag;
1063416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
106417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
106517ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
106617ab2063SBarry Smith     bs = b + shift;
106717ab2063SBarry Smith     for (i=0; i<m; i++) {
1068416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1069416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1070b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1071416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1072416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
107317ab2063SBarry Smith         sum  = b[i]*d/omega;
107417ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
107517ab2063SBarry Smith         x[i] = sum;
107617ab2063SBarry Smith     }
1077cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1078fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10793a40ed3dSBarry Smith     PetscFunctionReturn(0);
108017ab2063SBarry Smith   }
1081c783ea89SBarry Smith 
1082c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1083c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1084c783ea89SBarry Smith     if (!a->idiag) {
108587828ca2SBarry Smith       ierr     = PetscMalloc(2*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1086c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1087c783ea89SBarry Smith       v        = a->a;
1088c783ea89SBarry Smith       for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];}
1089c783ea89SBarry Smith     }
1090c783ea89SBarry Smith     t     = a->ssor;
1091c783ea89SBarry Smith     idiag = a->idiag;
1092c783ea89SBarry Smith   }
1093fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1094fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1095fc3d8934SBarry Smith 
1096fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1097fc3d8934SBarry Smith 
1098fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1099fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
110048af12d7SBarry Smith     is the relaxation factor.
1101fc3d8934SBarry Smith     */
1102fc3d8934SBarry Smith 
110348af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
110429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
110548af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
110648af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
110787828ca2SBarry Smith     PetscScalar *v2;
110848af12d7SBarry Smith 
1109733d66baSBarry Smith     v2    = a->a;
1110fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1111fc3d8934SBarry Smith     for (i=m-1; i>=0; i--) {
1112fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1113fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1114fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1115fc3d8934SBarry Smith       sum  = b[i];
1116fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1117b4632166SBarry Smith       x[i] = sum*idiag[i];
1118fc3d8934SBarry Smith 
1119fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1120733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1121733d66baSBarry Smith     }
1122fc3d8934SBarry Smith 
1123fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1124fc3d8934SBarry Smith     diag = a->diag;
1125fc3d8934SBarry Smith     for (i=0; i<m; i++) {
1126fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1127fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1128fc3d8934SBarry Smith       v    = a->a + a->i[i];
1129fc3d8934SBarry Smith       sum  = t[i];
1130fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1131b4632166SBarry Smith       t[i]  = sum*idiag[i];
1132fc3d8934SBarry Smith 
1133fc3d8934SBarry Smith       /*  x = x + t */
1134733d66baSBarry Smith       x[i] += t[i];
1135733d66baSBarry Smith     }
1136733d66baSBarry Smith 
1137b0a32e0cSBarry Smith     PetscLogFlops(3*m-1 + 2*a->nz);
1138fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1139fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1140fc3d8934SBarry Smith     PetscFunctionReturn(0);
11413a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
114217ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
114317ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
114417ab2063SBarry Smith 
114517ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
114617ab2063SBarry Smith 
114717ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
114817ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
114917ab2063SBarry Smith     is the relaxation factor.
115017ab2063SBarry Smith     */
115117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
115217ab2063SBarry Smith 
115317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
115417ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1155416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1156416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1157416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1158416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
115917ab2063SBarry Smith       sum  = b[i];
116017ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
116117ab2063SBarry Smith       x[i] = omega*(sum/d);
116217ab2063SBarry Smith     }
116317ab2063SBarry Smith 
116417ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1165416022c9SBarry Smith     v = a->a;
116617ab2063SBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
116717ab2063SBarry Smith 
116817ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1169416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1170416022c9SBarry Smith     diag = a->diag;
117117ab2063SBarry Smith     for (i=0; i<m; i++) {
1172416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1173416022c9SBarry Smith       n    = diag[i] - a->i[i];
1174416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1175416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
117617ab2063SBarry Smith       sum  = t[i];
117717ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
117817ab2063SBarry Smith       t[i] = omega*(sum/d);
1179733d66baSBarry Smith       /*  x = x + t */
1180733d66baSBarry Smith       x[i] += t[i];
118117ab2063SBarry Smith     }
118217ab2063SBarry Smith 
1183b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
1184cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1185fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11863a40ed3dSBarry Smith     PetscFunctionReturn(0);
118717ab2063SBarry Smith   }
118817ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
118917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
119077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
119177d8c4bbSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,b);
119277d8c4bbSBarry Smith #else
119317ab2063SBarry Smith       for (i=0; i<m; i++) {
1194416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1195416022c9SBarry Smith         n    = diag[i] - a->i[i];
1196b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1197416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1198416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
119917ab2063SBarry Smith         sum  = b[i];
120017ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
120117ab2063SBarry Smith         x[i] = omega*(sum/d);
120217ab2063SBarry Smith       }
120377d8c4bbSBarry Smith #endif
120417ab2063SBarry Smith       xb = x;
12053a40ed3dSBarry Smith     } else xb = b;
120617ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
120717ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
120817ab2063SBarry Smith       for (i=0; i<m; i++) {
1209416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
121017ab2063SBarry Smith       }
1211b0a32e0cSBarry Smith       PetscLogFlops(m);
121217ab2063SBarry Smith     }
121317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
121477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
121577d8c4bbSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,xb);
121677d8c4bbSBarry Smith #else
121717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1218416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1219416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1220b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1221416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1222416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
122317ab2063SBarry Smith         sum  = xb[i];
122417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
122517ab2063SBarry Smith         x[i] = omega*(sum/d);
122617ab2063SBarry Smith       }
122777d8c4bbSBarry Smith #endif
122817ab2063SBarry Smith     }
122917ab2063SBarry Smith     its--;
123017ab2063SBarry Smith   }
123117ab2063SBarry Smith   while (its--) {
123217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
123377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
123477d8c4bbSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
123577d8c4bbSBarry Smith #else
123617ab2063SBarry Smith       for (i=0; i<m; i++) {
1237416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1238416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1239b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1240416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1241416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
124217ab2063SBarry Smith         sum  = b[i];
124317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12447e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
124517ab2063SBarry Smith       }
124677d8c4bbSBarry Smith #endif
124717ab2063SBarry Smith     }
124817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
124977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
125077d8c4bbSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
125177d8c4bbSBarry Smith #else
125217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1253416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1254416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1255b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1256416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1257416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
125817ab2063SBarry Smith         sum  = b[i];
125917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12607e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
126117ab2063SBarry Smith       }
126277d8c4bbSBarry Smith #endif
126317ab2063SBarry Smith     }
126417ab2063SBarry Smith   }
1265cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1266fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12673a40ed3dSBarry Smith   PetscFunctionReturn(0);
126817ab2063SBarry Smith }
126917ab2063SBarry Smith 
12704a2ae208SSatish Balay #undef __FUNCT__
12714a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12728f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
127317ab2063SBarry Smith {
1274416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12754e220ebcSLois Curfman McInnes 
12763a40ed3dSBarry Smith   PetscFunctionBegin;
1277273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1278273d9f13SBarry Smith   info->columns_global = (double)A->n;
1279273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1280273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12814e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12824e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12834e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12844e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12854e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12864e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12874e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12884e220ebcSLois Curfman McInnes   if (A->factor) {
12894e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12904e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12914e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12924e220ebcSLois Curfman McInnes   } else {
12934e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12944e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12954e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12964e220ebcSLois Curfman McInnes   }
12973a40ed3dSBarry Smith   PetscFunctionReturn(0);
129817ab2063SBarry Smith }
129917ab2063SBarry Smith 
1300b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1301ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1302b9b97703SBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*);
1303ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1304ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1305ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1306ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
130717ab2063SBarry Smith 
13084a2ae208SSatish Balay #undef __FUNCT__
13094a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
131087828ca2SBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,PetscScalar *diag)
131117ab2063SBarry Smith {
1312416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1313273d9f13SBarry Smith   int         i,ierr,N,*rows,m = A->m - 1,shift = a->indexshift;
131417ab2063SBarry Smith 
13153a40ed3dSBarry Smith   PetscFunctionBegin;
1316b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
131717ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1318f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1319f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
132029bbc08cSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
132187828ca2SBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1322f1e2ffcdSBarry Smith     }
1323f1e2ffcdSBarry Smith     if (diag) {
1324f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1325f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1326f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1327f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1328f1e2ffcdSBarry Smith       }
1329f1e2ffcdSBarry Smith     }
1330f1e2ffcdSBarry Smith   } else {
133117ab2063SBarry Smith     if (diag) {
133217ab2063SBarry Smith       for (i=0; i<N; i++) {
133329bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
13347ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1335416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1336416022c9SBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1337416022c9SBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
13387ae801bdSBarry Smith         } else { /* in case row was completely empty */
1339d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
134017ab2063SBarry Smith         }
134117ab2063SBarry Smith       }
13423a40ed3dSBarry Smith     } else {
134317ab2063SBarry Smith       for (i=0; i<N; i++) {
134429bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
1345416022c9SBarry Smith         a->ilen[rows[i]] = 0;
134617ab2063SBarry Smith       }
134717ab2063SBarry Smith     }
1348f1e2ffcdSBarry Smith   }
13497ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
135043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13513a40ed3dSBarry Smith   PetscFunctionReturn(0);
135217ab2063SBarry Smith }
135317ab2063SBarry Smith 
13544a2ae208SSatish Balay #undef __FUNCT__
13554a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
135687828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
135717ab2063SBarry Smith {
1358416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1359b0a32e0cSBarry Smith   int        *itmp,i,shift = a->indexshift,ierr;
136017ab2063SBarry Smith 
13613a40ed3dSBarry Smith   PetscFunctionBegin;
1362273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
136317ab2063SBarry Smith 
1364416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1365416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
136617ab2063SBarry Smith   if (idx) {
1367416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13684e093b46SBarry Smith     if (*nz && shift) {
1369b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
137017ab2063SBarry Smith       for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;}
13714e093b46SBarry Smith     } else if (*nz) {
13724e093b46SBarry Smith       *idx = itmp;
137317ab2063SBarry Smith     }
137417ab2063SBarry Smith     else *idx = 0;
137517ab2063SBarry Smith   }
13763a40ed3dSBarry Smith   PetscFunctionReturn(0);
137717ab2063SBarry Smith }
137817ab2063SBarry Smith 
13794a2ae208SSatish Balay #undef __FUNCT__
13804a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
138187828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
138217ab2063SBarry Smith {
13834e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1384606d414cSSatish Balay   int ierr;
13853a40ed3dSBarry Smith 
13863a40ed3dSBarry Smith   PetscFunctionBegin;
1387606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13883a40ed3dSBarry Smith   PetscFunctionReturn(0);
138917ab2063SBarry Smith }
139017ab2063SBarry Smith 
13914a2ae208SSatish Balay #undef __FUNCT__
13924a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1393064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
139417ab2063SBarry Smith {
1395416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
139687828ca2SBarry Smith   PetscScalar  *v = a->a;
139736db0b34SBarry Smith   PetscReal    sum = 0.0;
1398549d3d68SSatish Balay   int          i,j,shift = a->indexshift,ierr;
139917ab2063SBarry Smith 
14003a40ed3dSBarry Smith   PetscFunctionBegin;
140117ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1402416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1403aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
140436db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
140517ab2063SBarry Smith #else
140617ab2063SBarry Smith       sum += (*v)*(*v); v++;
140717ab2063SBarry Smith #endif
140817ab2063SBarry Smith     }
1409064f8208SBarry Smith     *nrm = sqrt(sum);
14103a40ed3dSBarry Smith   } else if (type == NORM_1) {
141136db0b34SBarry Smith     PetscReal *tmp;
1412416022c9SBarry Smith     int    *jj = a->j;
1413b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1414273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1415064f8208SBarry Smith     *nrm = 0.0;
1416416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1417a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
141817ab2063SBarry Smith     }
1419273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1420064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
142117ab2063SBarry Smith     }
1422606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
14233a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1424064f8208SBarry Smith     *nrm = 0.0;
1425273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1426416022c9SBarry Smith       v = a->a + a->i[j] + shift;
142717ab2063SBarry Smith       sum = 0.0;
1428416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1429cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
143017ab2063SBarry Smith       }
1431064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
143217ab2063SBarry Smith     }
14333a40ed3dSBarry Smith   } else {
143429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
143517ab2063SBarry Smith   }
14363a40ed3dSBarry Smith   PetscFunctionReturn(0);
143717ab2063SBarry Smith }
143817ab2063SBarry Smith 
14394a2ae208SSatish Balay #undef __FUNCT__
14404a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
14418f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
144217ab2063SBarry Smith {
1443416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1444416022c9SBarry Smith   Mat          C;
1445273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
1446273d9f13SBarry Smith   int          shift = a->indexshift;
144787828ca2SBarry Smith   PetscScalar  *array = a->a;
144817ab2063SBarry Smith 
14493a40ed3dSBarry Smith   PetscFunctionBegin;
1450273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1451b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1452273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
145317ab2063SBarry Smith   if (shift) {
145417ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] -= 1;
145517ab2063SBarry Smith   }
145617ab2063SBarry Smith   for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1;
1457273d9f13SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr);
1458606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
145917ab2063SBarry Smith   for (i=0; i<m; i++) {
146017ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1461416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1462b9b97703SBarry Smith     array += len;
1463b9b97703SBarry Smith     aj    += len;
146417ab2063SBarry Smith   }
146517ab2063SBarry Smith   if (shift) {
146617ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] += 1;
146717ab2063SBarry Smith   }
146817ab2063SBarry Smith 
14696d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14706d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
147117ab2063SBarry Smith 
1472f1e2ffcdSBarry Smith   if (B) {
1473416022c9SBarry Smith     *B = C;
147417ab2063SBarry Smith   } else {
1475273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
147617ab2063SBarry Smith   }
14773a40ed3dSBarry Smith   PetscFunctionReturn(0);
147817ab2063SBarry Smith }
147917ab2063SBarry Smith 
14804a2ae208SSatish Balay #undef __FUNCT__
14814a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14828f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
148317ab2063SBarry Smith {
1484416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
148587828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1486273d9f13SBarry Smith   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj,shift = a->indexshift;
148717ab2063SBarry Smith 
14883a40ed3dSBarry Smith   PetscFunctionBegin;
148917ab2063SBarry Smith   if (ll) {
14903ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14913ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1492e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1493273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
1494e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1495416022c9SBarry Smith     v = a->a;
149617ab2063SBarry Smith     for (i=0; i<m; i++) {
149717ab2063SBarry Smith       x = l[i];
1498416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
149917ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
150017ab2063SBarry Smith     }
1501e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1502b0a32e0cSBarry Smith     PetscLogFlops(nz);
150317ab2063SBarry Smith   }
150417ab2063SBarry Smith   if (rr) {
1505e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1506273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
1507e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1508416022c9SBarry Smith     v = a->a; jj = a->j;
150917ab2063SBarry Smith     for (i=0; i<nz; i++) {
151017ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
151117ab2063SBarry Smith     }
1512e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1513b0a32e0cSBarry Smith     PetscLogFlops(nz);
151417ab2063SBarry Smith   }
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
151617ab2063SBarry Smith }
151717ab2063SBarry Smith 
15184a2ae208SSatish Balay #undef __FUNCT__
15194a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
15207b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
152117ab2063SBarry Smith {
1522db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1523273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
152436db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
152599141d43SSatish Balay   int          *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap;
152699141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
152787828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1528416022c9SBarry Smith   Mat          C;
1529fee21e36SBarry Smith   PetscTruth   stride;
153017ab2063SBarry Smith 
15313a40ed3dSBarry Smith   PetscFunctionBegin;
1532d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
153329bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1534d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
153529bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
153699141d43SSatish Balay 
153717ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1538b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1539b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
154017ab2063SBarry Smith 
1541fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1542fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1543fee21e36SBarry Smith   if (stride && step == 1) {
154402834360SBarry Smith     /* special case of contiguous rows */
154531ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
154631ebf83bSSatish Balay     starts = lens + nrows;
154702834360SBarry Smith     /* loop over new rows determining lens and starting points */
154802834360SBarry Smith     for (i=0; i<nrows; i++) {
1549a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1550a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
155102834360SBarry Smith       for (k=kstart; k<kend; k++) {
1552d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
155302834360SBarry Smith           starts[i] = k;
155402834360SBarry Smith           break;
155502834360SBarry Smith 	}
155602834360SBarry Smith       }
1557a2744918SBarry Smith       sum = 0;
155802834360SBarry Smith       while (k < kend) {
1559d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1560a2744918SBarry Smith         sum++;
156102834360SBarry Smith       }
1562a2744918SBarry Smith       lens[i] = sum;
156302834360SBarry Smith     }
156402834360SBarry Smith     /* create submatrix */
1565cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
156608480c60SBarry Smith       int n_cols,n_rows;
156708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
156829bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1569d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
157008480c60SBarry Smith       C = *B;
15713a40ed3dSBarry Smith     } else {
157202834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
157308480c60SBarry Smith     }
1574db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1575db02288aSLois Curfman McInnes 
157602834360SBarry Smith     /* loop over rows inserting into submatrix */
1577db02288aSLois Curfman McInnes     a_new    = c->a;
1578db02288aSLois Curfman McInnes     j_new    = c->j;
1579db02288aSLois Curfman McInnes     i_new    = c->i;
1580db02288aSLois Curfman McInnes     i_new[0] = -shift;
158102834360SBarry Smith     for (i=0; i<nrows; i++) {
1582a2744918SBarry Smith       ii    = starts[i];
1583a2744918SBarry Smith       lensi = lens[i];
1584a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1585a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
158602834360SBarry Smith       }
158787828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1588a2744918SBarry Smith       a_new      += lensi;
1589a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1590a2744918SBarry Smith       c->ilen[i]  = lensi;
159102834360SBarry Smith     }
1592606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15933a40ed3dSBarry Smith   } else {
159402834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1595b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
159602834360SBarry Smith     ssmap = smap + shift;
1597b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1598549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
159917ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
160002834360SBarry Smith     /* determine lens of each row */
160102834360SBarry Smith     for (i=0; i<nrows; i++) {
1602d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
160302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
160402834360SBarry Smith       lens[i] = 0;
160502834360SBarry Smith       for (k=kstart; k<kend; k++) {
1606d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
160702834360SBarry Smith           lens[i]++;
160802834360SBarry Smith         }
160902834360SBarry Smith       }
161002834360SBarry Smith     }
161117ab2063SBarry Smith     /* Create and fill new matrix */
1612a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16130f5bd95cSBarry Smith       PetscTruth equal;
16140f5bd95cSBarry Smith 
161599141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1616273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1617273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
16180f5bd95cSBarry Smith       if (!equal) {
161929bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
162099141d43SSatish Balay       }
1621273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
162208480c60SBarry Smith       C = *B;
16233a40ed3dSBarry Smith     } else {
162402834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
162508480c60SBarry Smith     }
162699141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
162717ab2063SBarry Smith     for (i=0; i<nrows; i++) {
162899141d43SSatish Balay       row    = irow[i];
162999141d43SSatish Balay       kstart = ai[row]+shift;
163099141d43SSatish Balay       kend   = kstart + a->ilen[row];
163199141d43SSatish Balay       mat_i  = c->i[i]+shift;
163299141d43SSatish Balay       mat_j  = c->j + mat_i;
163399141d43SSatish Balay       mat_a  = c->a + mat_i;
163499141d43SSatish Balay       mat_ilen = c->ilen + i;
163517ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
163699141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
163799141d43SSatish Balay           *mat_j++ = tcol - (!shift);
163899141d43SSatish Balay           *mat_a++ = a->a[k];
163999141d43SSatish Balay           (*mat_ilen)++;
164099141d43SSatish Balay 
164117ab2063SBarry Smith         }
164217ab2063SBarry Smith       }
164317ab2063SBarry Smith     }
164402834360SBarry Smith     /* Free work space */
164502834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1646606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1647606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
164802834360SBarry Smith   }
16496d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16506d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
165117ab2063SBarry Smith 
165217ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1653416022c9SBarry Smith   *B = C;
16543a40ed3dSBarry Smith   PetscFunctionReturn(0);
165517ab2063SBarry Smith }
165617ab2063SBarry Smith 
1657a871dcd8SBarry Smith /*
1658a871dcd8SBarry Smith */
16594a2ae208SSatish Balay #undef __FUNCT__
16604a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
16615ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1662a871dcd8SBarry Smith {
166363b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
166408480c60SBarry Smith   int        ierr;
166563b91edcSBarry Smith   Mat        outA;
1666b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
166763b91edcSBarry Smith 
16683a40ed3dSBarry Smith   PetscFunctionBegin;
166929bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1670b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1671b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1672b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
167329bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1674b8a78c4aSBarry Smith   }
1675a871dcd8SBarry Smith 
167663b91edcSBarry Smith   outA          = inA;
167763b91edcSBarry Smith   inA->factor   = FACTOR_LU;
167863b91edcSBarry Smith   a->row        = row;
167963b91edcSBarry Smith   a->col        = col;
1680c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1681c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
168263b91edcSBarry Smith 
168336db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1684b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16854c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1686b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1687f0ec6fceSSatish Balay 
168894a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
168987828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
169094a9d846SBarry Smith   }
169163b91edcSBarry Smith 
169208480c60SBarry Smith   if (!a->diag) {
1693f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
169463b91edcSBarry Smith   }
169563b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1697a871dcd8SBarry Smith }
1698a871dcd8SBarry Smith 
1699d9eff348SSatish Balay #include "petscblaslapack.h"
17004a2ae208SSatish Balay #undef __FUNCT__
17014a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
170287828ca2SBarry Smith int MatScale_SeqAIJ(PetscScalar *alpha,Mat inA)
1703f0b747eeSBarry Smith {
1704f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1705f0b747eeSBarry Smith   int        one = 1;
17063a40ed3dSBarry Smith 
17073a40ed3dSBarry Smith   PetscFunctionBegin;
1708f0b747eeSBarry Smith   BLscal_(&a->nz,alpha,a->a,&one);
1709b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
17103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1711f0b747eeSBarry Smith }
1712f0b747eeSBarry Smith 
17134a2ae208SSatish Balay #undef __FUNCT__
17144a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
17157b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1716cddf8d76SBarry Smith {
1717cddf8d76SBarry Smith   int ierr,i;
1718cddf8d76SBarry Smith 
17193a40ed3dSBarry Smith   PetscFunctionBegin;
1720cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1721b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1722cddf8d76SBarry Smith   }
1723cddf8d76SBarry Smith 
1724cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17256a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1726cddf8d76SBarry Smith   }
17273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1728cddf8d76SBarry Smith }
1729cddf8d76SBarry Smith 
17304a2ae208SSatish Balay #undef __FUNCT__
17314a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17328f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17335a838052SSatish Balay {
1734f830108cSBarry Smith   PetscFunctionBegin;
17355a838052SSatish Balay   *bs = 1;
17363a40ed3dSBarry Smith   PetscFunctionReturn(0);
17375a838052SSatish Balay }
17385a838052SSatish Balay 
17394a2ae208SSatish Balay #undef __FUNCT__
17404a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
17418f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov)
17424dcbc457SBarry Smith {
1743e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
174406763907SSatish Balay   int        shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17458a047759SSatish Balay   int        start,end,*ai,*aj;
1746f1af5d2fSBarry Smith   PetscBT    table;
1747bbd702dbSSatish Balay 
17483a40ed3dSBarry Smith   PetscFunctionBegin;
17498a047759SSatish Balay   shift = a->indexshift;
1750273d9f13SBarry Smith   m     = A->m;
1751e4d965acSSatish Balay   ai    = a->i;
17528a047759SSatish Balay   aj    = a->j+shift;
17538a047759SSatish Balay 
175429bbc08cSBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used");
175506763907SSatish Balay 
1756b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17576831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
175806763907SSatish Balay 
1759e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1760b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1761e4d965acSSatish Balay     isz  = 0;
17626831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1763e4d965acSSatish Balay 
1764e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17654dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1766b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1767e4d965acSSatish Balay 
1768dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1769e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1770f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17714dcbc457SBarry Smith     }
177206763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
177306763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1774e4d965acSSatish Balay 
177504a348a9SBarry Smith     k = 0;
177604a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
177704a348a9SBarry Smith       n = isz;
177806763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1779e4d965acSSatish Balay         row   = nidx[k];
1780e4d965acSSatish Balay         start = ai[row];
1781e4d965acSSatish Balay         end   = ai[row+1];
178204a348a9SBarry Smith         for (l = start; l<end ; l++){
17838a047759SSatish Balay           val = aj[l] + shift;
1784f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1785e4d965acSSatish Balay         }
1786e4d965acSSatish Balay       }
1787e4d965acSSatish Balay     }
1788029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1789e4d965acSSatish Balay   }
17906831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1791606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17923a40ed3dSBarry Smith   PetscFunctionReturn(0);
17934dcbc457SBarry Smith }
179417ab2063SBarry Smith 
17950513a670SBarry Smith /* -------------------------------------------------------------- */
17964a2ae208SSatish Balay #undef __FUNCT__
17974a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17980513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17990513a670SBarry Smith {
18000513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
180187828ca2SBarry Smith   PetscScalar  *vwork;
1802273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
18030513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
180456cd22aeSBarry Smith   IS           icolp,irowp;
18050513a670SBarry Smith 
18063a40ed3dSBarry Smith   PetscFunctionBegin;
18074c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
180856cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18094c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
181056cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18110513a670SBarry Smith 
18120513a670SBarry Smith   /* determine lengths of permuted rows */
1813b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
18140513a670SBarry Smith   for (i=0; i<m; i++) {
18150513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18160513a670SBarry Smith   }
18170513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1818606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18190513a670SBarry Smith 
1820b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18210513a670SBarry Smith   for (i=0; i<m; i++) {
18220513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18230513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18240513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18250513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18260513a670SBarry Smith   }
1827606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18280513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18290513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
183056cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
183156cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
183256cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
183356cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18343a40ed3dSBarry Smith   PetscFunctionReturn(0);
18350513a670SBarry Smith }
18360513a670SBarry Smith 
18374a2ae208SSatish Balay #undef __FUNCT__
18384a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1839682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1840682d7d0cSBarry Smith {
1841c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1842682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1843d132466eSBarry Smith   int               ierr;
1844682d7d0cSBarry Smith 
18453a40ed3dSBarry Smith   PetscFunctionBegin;
1846c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1847d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1848d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1849d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1850d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1851d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1852aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1853d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1854682d7d0cSBarry Smith #endif
1855cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL)
1856cd5578b5SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr);
1857cd5578b5SBarry Smith #endif
185887828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
1859ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1860ca44d042SBarry Smith #endif
18613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1862682d7d0cSBarry Smith }
1863ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1864ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1865ca44d042SBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*);
18664a2ae208SSatish Balay #undef __FUNCT__
18674a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1868cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1869cb5b572fSBarry Smith {
1870be6bf707SBarry Smith   int        ierr;
1871273d9f13SBarry Smith   PetscTruth flg;
1872cb5b572fSBarry Smith 
1873cb5b572fSBarry Smith   PetscFunctionBegin;
1874273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr);
1875273d9f13SBarry Smith   if (str == SAME_NONZERO_PATTERN && flg) {
1876be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1877be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1878be6bf707SBarry Smith 
1879273d9f13SBarry Smith     if (a->i[A->m]+a->indexshift != b->i[B->m]+a->indexshift) {
188029bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1881cb5b572fSBarry Smith     }
188287828ca2SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
1883cb5b572fSBarry Smith   } else {
1884cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1885cb5b572fSBarry Smith   }
1886cb5b572fSBarry Smith   PetscFunctionReturn(0);
1887cb5b572fSBarry Smith }
1888cb5b572fSBarry Smith 
18894a2ae208SSatish Balay #undef __FUNCT__
18904a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1891273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1892273d9f13SBarry Smith {
1893273d9f13SBarry Smith   int        ierr;
1894273d9f13SBarry Smith 
1895273d9f13SBarry Smith   PetscFunctionBegin;
1896273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1897273d9f13SBarry Smith   PetscFunctionReturn(0);
1898273d9f13SBarry Smith }
1899273d9f13SBarry Smith 
19004a2ae208SSatish Balay #undef __FUNCT__
19014a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
190287828ca2SBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar **array)
19036c0721eeSBarry Smith {
19046c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19056c0721eeSBarry Smith   PetscFunctionBegin;
19066c0721eeSBarry Smith   *array = a->a;
19076c0721eeSBarry Smith   PetscFunctionReturn(0);
19086c0721eeSBarry Smith }
19096c0721eeSBarry Smith 
19104a2ae208SSatish Balay #undef __FUNCT__
19114a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
191287828ca2SBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar **array)
19136c0721eeSBarry Smith {
19146c0721eeSBarry Smith   PetscFunctionBegin;
19156c0721eeSBarry Smith   PetscFunctionReturn(0);
19166c0721eeSBarry Smith }
1917273d9f13SBarry Smith 
1918ee4f033dSBarry Smith #undef __FUNCT__
1919ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1920ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1921ee4f033dSBarry Smith {
1922ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1923ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
192487828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
192587828ca2SBarry Smith   PetscScalar   *vscale_array;
1926ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1927ee4f033dSBarry Smith   Vec           w1,w2,w3;
1928ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1929ee4f033dSBarry Smith   PetscTruth    flg;
1930ee4f033dSBarry Smith 
1931ee4f033dSBarry Smith   PetscFunctionBegin;
1932ee4f033dSBarry Smith   if (!coloring->w1) {
1933ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1934ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1935ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1936ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1937ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1938ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1939ee4f033dSBarry Smith   }
1940ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1941ee4f033dSBarry Smith 
1942ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1943e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1944ee4f033dSBarry Smith   if (flg) {
1945ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1946ee4f033dSBarry Smith   } else {
1947ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1948ee4f033dSBarry Smith   }
1949ee4f033dSBarry Smith 
1950ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1951ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1952ee4f033dSBarry Smith 
1953ee4f033dSBarry Smith   /*
1954ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1955ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1956ee4f033dSBarry Smith   */
1957ee4f033dSBarry Smith   if (coloring->F) {
1958ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1959ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1960ee4f033dSBarry Smith     if (m1 != m2) {
1961ee4f033dSBarry Smith       coloring->F = 0;
1962ee4f033dSBarry Smith     }
1963ee4f033dSBarry Smith   }
1964ee4f033dSBarry Smith 
1965ee4f033dSBarry Smith   if (coloring->F) {
1966ee4f033dSBarry Smith     w1          = coloring->F;
1967ee4f033dSBarry Smith     coloring->F = 0;
1968ee4f033dSBarry Smith   } else {
1969ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
1970ee4f033dSBarry Smith   }
1971ee4f033dSBarry Smith 
1972ee4f033dSBarry Smith   /*
1973ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1974ee4f033dSBarry Smith   */
1975ee4f033dSBarry Smith   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
1976ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1977ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1978ee4f033dSBarry Smith     /*
1979ee4f033dSBarry Smith        Loop over each column associated with color adding the
1980ee4f033dSBarry Smith        perturbation to the vector w3.
1981ee4f033dSBarry Smith     */
1982ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1983ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1984ee4f033dSBarry Smith       dx  = xx[col];
1985ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1986ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1987ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1988ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1989ee4f033dSBarry Smith #else
1990ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1991ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1992ee4f033dSBarry Smith #endif
1993ee4f033dSBarry Smith       dx                *= epsilon;
1994ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1995ee4f033dSBarry Smith     }
1996ee4f033dSBarry Smith   }
1997ee4f033dSBarry Smith   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1998ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1999ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2000ee4f033dSBarry Smith 
2001ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2002ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2003ee4f033dSBarry Smith 
2004ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2005ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2006ee4f033dSBarry Smith 
2007ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2008ee4f033dSBarry Smith   /*
2009ee4f033dSBarry Smith       Loop over each color
2010ee4f033dSBarry Smith   */
2011ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2012ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
2013ee4f033dSBarry Smith     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2014ee4f033dSBarry Smith     /*
2015ee4f033dSBarry Smith        Loop over each column associated with color adding the
2016ee4f033dSBarry Smith        perturbation to the vector w3.
2017ee4f033dSBarry Smith     */
2018ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2019ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2020ee4f033dSBarry Smith       dx  = xx[col];
2021ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2022ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2023ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2024ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2025ee4f033dSBarry Smith #else
2026ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2027ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2028ee4f033dSBarry Smith #endif
2029ee4f033dSBarry Smith       dx            *= epsilon;
2030ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2031ee4f033dSBarry Smith       w3_array[col] += dx;
2032ee4f033dSBarry Smith     }
2033ee4f033dSBarry Smith     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2034ee4f033dSBarry Smith 
2035ee4f033dSBarry Smith     /*
2036ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2037ee4f033dSBarry Smith     */
2038ee4f033dSBarry Smith 
2039ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
2040ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2041ee4f033dSBarry Smith 
2042ee4f033dSBarry Smith     /*
2043ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2044ee4f033dSBarry Smith     */
2045ee4f033dSBarry Smith     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2046ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2047ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2048ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2049ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2050ee4f033dSBarry Smith       srow   = row + start;
2051ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2052ee4f033dSBarry Smith     }
2053ee4f033dSBarry Smith     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2054ee4f033dSBarry Smith   }
2055ee4f033dSBarry Smith   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2056ee4f033dSBarry Smith   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2057ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2058ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2059ee4f033dSBarry Smith   PetscFunctionReturn(0);
2060ee4f033dSBarry Smith }
2061ee4f033dSBarry Smith 
2062ac90fabeSBarry Smith #include "petscblaslapack.h"
2063ac90fabeSBarry Smith 
2064ac90fabeSBarry Smith #undef __FUNCT__
2065ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2066ac90fabeSBarry Smith int MatAXPY_SeqAIJ(PetscScalar *a,Mat X,Mat Y,MatStructure str)
2067ac90fabeSBarry Smith {
2068556bd4faSSatish Balay   int        ierr,one=1;
2069ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2070ac90fabeSBarry Smith 
2071ac90fabeSBarry Smith   PetscFunctionBegin;
2072ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2073ac90fabeSBarry Smith     BLaxpy_(&x->nz,a,x->a,&one,y->a,&one);
2074ac90fabeSBarry Smith   } else {
2075ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2076ac90fabeSBarry Smith   }
2077ac90fabeSBarry Smith   PetscFunctionReturn(0);
2078ac90fabeSBarry Smith }
2079ac90fabeSBarry Smith 
2080ac90fabeSBarry Smith 
2081682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20820a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2083cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2084cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2085cb5b572fSBarry Smith        MatMult_SeqAIJ,
2086cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
20877c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20887c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2089cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2090cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20917c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
20927c922b88SBarry Smith        MatSolveTransposeAdd_SeqAIJ,
2093cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2094cb5b572fSBarry Smith        0,
209517ab2063SBarry Smith        MatRelax_SeqAIJ,
209617ab2063SBarry Smith        MatTranspose_SeqAIJ,
2097cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
2098cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2099cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2100cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2101cb5b572fSBarry Smith        MatNorm_SeqAIJ,
2102cb5b572fSBarry Smith        0,
2103cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
210417ab2063SBarry Smith        MatCompress_SeqAIJ,
2105cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2106cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2107cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
2108cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2109cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2110cb5b572fSBarry Smith        0,
2111cb5b572fSBarry Smith        0,
2112273d9f13SBarry Smith        MatSetUpPreallocation_SeqAIJ,
2113cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2114cb5b572fSBarry Smith        0,
21156c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21166c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2117be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
2118cb5b572fSBarry Smith        0,
2119cb5b572fSBarry Smith        0,
2120cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2121cb5b572fSBarry Smith        0,
2122ac90fabeSBarry Smith        MatAXPY_SeqAIJ,
2123cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2124cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2125cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2126cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2127f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
2128cb5b572fSBarry Smith        MatScale_SeqAIJ,
2129cb5b572fSBarry Smith        0,
2130cb5b572fSBarry Smith        0,
21316945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
21326945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
21333b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21343b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21353b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2136a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2137a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
2138b9617806SBarry Smith        0,
21390513a670SBarry Smith        0,
2140cda55fadSBarry Smith        MatPermute_SeqAIJ,
2141cda55fadSBarry Smith        0,
2142cda55fadSBarry Smith        0,
2143b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2144b9b97703SBarry Smith        MatView_SeqAIJ,
21458a124369SBarry Smith        MatGetPetscMaps_Petsc,
2146ee4f033dSBarry Smith        0,
2147ee4f033dSBarry Smith        0,
2148ee4f033dSBarry Smith        0,
2149ee4f033dSBarry Smith        0,
2150ee4f033dSBarry Smith        0,
2151ee4f033dSBarry Smith        0,
2152ee4f033dSBarry Smith        0,
2153ee4f033dSBarry Smith        0,
2154ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2155ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2156ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
2157ee4f033dSBarry Smith        MatFDColoringApply_SeqAIJ};
215817ab2063SBarry Smith 
2159fb2e594dSBarry Smith EXTERN_C_BEGIN
21604a2ae208SSatish Balay #undef __FUNCT__
21614a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
216215091d37SBarry Smith 
2163bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2164bef8e0ddSBarry Smith {
2165bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2166bef8e0ddSBarry Smith   int        i,nz,n;
2167bef8e0ddSBarry Smith 
2168bef8e0ddSBarry Smith   PetscFunctionBegin;
2169bef8e0ddSBarry Smith 
2170bef8e0ddSBarry Smith   nz = aij->maxnz;
2171273d9f13SBarry Smith   n  = mat->n;
2172bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2173bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2174bef8e0ddSBarry Smith   }
2175bef8e0ddSBarry Smith   aij->nz = nz;
2176bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2177bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2178bef8e0ddSBarry Smith   }
2179bef8e0ddSBarry Smith 
2180bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2181bef8e0ddSBarry Smith }
2182fb2e594dSBarry Smith EXTERN_C_END
2183bef8e0ddSBarry Smith 
21844a2ae208SSatish Balay #undef __FUNCT__
21854a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2186bef8e0ddSBarry Smith /*@
2187bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2188bef8e0ddSBarry Smith        in the matrix.
2189bef8e0ddSBarry Smith 
2190bef8e0ddSBarry Smith   Input Parameters:
2191bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2192bef8e0ddSBarry Smith -  indices - the column indices
2193bef8e0ddSBarry Smith 
219415091d37SBarry Smith   Level: advanced
219515091d37SBarry Smith 
2196bef8e0ddSBarry Smith   Notes:
2197bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2198bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2199bef8e0ddSBarry Smith   of the MatSetValues() operation.
2200bef8e0ddSBarry Smith 
2201bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2202bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2203bef8e0ddSBarry Smith 
2204bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2205bef8e0ddSBarry Smith 
2206b9617806SBarry Smith     The indices should start with zero, not one.
2207b9617806SBarry Smith 
2208bef8e0ddSBarry Smith @*/
2209bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2210bef8e0ddSBarry Smith {
2211bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2212bef8e0ddSBarry Smith 
2213bef8e0ddSBarry Smith   PetscFunctionBegin;
2214bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2215c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2216bef8e0ddSBarry Smith   if (f) {
2217bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2218bef8e0ddSBarry Smith   } else {
221929bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2220bef8e0ddSBarry Smith   }
2221bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2222bef8e0ddSBarry Smith }
2223bef8e0ddSBarry Smith 
2224be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2225be6bf707SBarry Smith 
2226fb2e594dSBarry Smith EXTERN_C_BEGIN
22274a2ae208SSatish Balay #undef __FUNCT__
22284a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2229be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2230be6bf707SBarry Smith {
2231be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2232273d9f13SBarry Smith   int        nz = aij->i[mat->m]+aij->indexshift,ierr;
2233be6bf707SBarry Smith 
2234be6bf707SBarry Smith   PetscFunctionBegin;
2235be6bf707SBarry Smith   if (aij->nonew != 1) {
223629bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2237be6bf707SBarry Smith   }
2238be6bf707SBarry Smith 
2239be6bf707SBarry Smith   /* allocate space for values if not already there */
2240be6bf707SBarry Smith   if (!aij->saved_values) {
224187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2242be6bf707SBarry Smith   }
2243be6bf707SBarry Smith 
2244be6bf707SBarry Smith   /* copy values over */
224587828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2246be6bf707SBarry Smith   PetscFunctionReturn(0);
2247be6bf707SBarry Smith }
2248fb2e594dSBarry Smith EXTERN_C_END
2249be6bf707SBarry Smith 
22504a2ae208SSatish Balay #undef __FUNCT__
2251b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2252be6bf707SBarry Smith /*@
2253be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2254be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2255be6bf707SBarry Smith        nonlinear portion.
2256be6bf707SBarry Smith 
2257be6bf707SBarry Smith    Collect on Mat
2258be6bf707SBarry Smith 
2259be6bf707SBarry Smith   Input Parameters:
2260be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2261be6bf707SBarry Smith 
226215091d37SBarry Smith   Level: advanced
226315091d37SBarry Smith 
2264be6bf707SBarry Smith   Common Usage, with SNESSolve():
2265be6bf707SBarry Smith $    Create Jacobian matrix
2266be6bf707SBarry Smith $    Set linear terms into matrix
2267be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2268be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2269be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2270be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2271be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2272be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2273be6bf707SBarry Smith $    In your Jacobian routine
2274be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2275be6bf707SBarry Smith $      Set nonlinear terms in matrix
2276be6bf707SBarry Smith 
2277be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2278be6bf707SBarry Smith $    // build linear portion of Jacobian
2279be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2280be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2281be6bf707SBarry Smith $    loop over nonlinear iterations
2282be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2283be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2284be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2285be6bf707SBarry Smith $       Solve linear system with Jacobian
2286be6bf707SBarry Smith $    endloop
2287be6bf707SBarry Smith 
2288be6bf707SBarry Smith   Notes:
2289be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2290be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2291be6bf707SBarry Smith     calling this routine.
2292be6bf707SBarry Smith 
2293be6bf707SBarry Smith .seealso: MatRetrieveValues()
2294be6bf707SBarry Smith 
2295be6bf707SBarry Smith @*/
2296be6bf707SBarry Smith int MatStoreValues(Mat mat)
2297be6bf707SBarry Smith {
2298be6bf707SBarry Smith   int ierr,(*f)(Mat);
2299be6bf707SBarry Smith 
2300be6bf707SBarry Smith   PetscFunctionBegin;
2301be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
230229bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
230329bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2304be6bf707SBarry Smith 
2305c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2306be6bf707SBarry Smith   if (f) {
2307be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2308be6bf707SBarry Smith   } else {
230929bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2310be6bf707SBarry Smith   }
2311be6bf707SBarry Smith   PetscFunctionReturn(0);
2312be6bf707SBarry Smith }
2313be6bf707SBarry Smith 
2314fb2e594dSBarry Smith EXTERN_C_BEGIN
23154a2ae208SSatish Balay #undef __FUNCT__
23164a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2317be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2318be6bf707SBarry Smith {
2319be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2320273d9f13SBarry Smith   int        nz = aij->i[mat->m]+aij->indexshift,ierr;
2321be6bf707SBarry Smith 
2322be6bf707SBarry Smith   PetscFunctionBegin;
2323be6bf707SBarry Smith   if (aij->nonew != 1) {
232429bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2325be6bf707SBarry Smith   }
2326be6bf707SBarry Smith   if (!aij->saved_values) {
232729bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2328be6bf707SBarry Smith   }
2329be6bf707SBarry Smith 
2330be6bf707SBarry Smith   /* copy values over */
233187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2332be6bf707SBarry Smith   PetscFunctionReturn(0);
2333be6bf707SBarry Smith }
2334fb2e594dSBarry Smith EXTERN_C_END
2335be6bf707SBarry Smith 
23364a2ae208SSatish Balay #undef __FUNCT__
23374a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2338be6bf707SBarry Smith /*@
2339be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2340be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2341be6bf707SBarry Smith        nonlinear portion.
2342be6bf707SBarry Smith 
2343be6bf707SBarry Smith    Collect on Mat
2344be6bf707SBarry Smith 
2345be6bf707SBarry Smith   Input Parameters:
2346be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2347be6bf707SBarry Smith 
234815091d37SBarry Smith   Level: advanced
234915091d37SBarry Smith 
2350be6bf707SBarry Smith .seealso: MatStoreValues()
2351be6bf707SBarry Smith 
2352be6bf707SBarry Smith @*/
2353be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2354be6bf707SBarry Smith {
2355be6bf707SBarry Smith   int ierr,(*f)(Mat);
2356be6bf707SBarry Smith 
2357be6bf707SBarry Smith   PetscFunctionBegin;
2358be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
235929bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
236029bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2361be6bf707SBarry Smith 
2362c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2363be6bf707SBarry Smith   if (f) {
2364be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2365be6bf707SBarry Smith   } else {
236629bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2367be6bf707SBarry Smith   }
2368be6bf707SBarry Smith   PetscFunctionReturn(0);
2369be6bf707SBarry Smith }
2370be6bf707SBarry Smith 
2371f83d6046SBarry Smith /*
2372f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2373f83d6046SBarry Smith */
237487828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2375f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2376f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2377f83d6046SBarry Smith EXTERN_C_BEGIN
23784a2ae208SSatish Balay #undef __FUNCT__
23794a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ"
2380f83d6046SBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine)
2381f83d6046SBarry Smith {
238266826eb6SBarry Smith   int         ierr,i,*ai,*aj;
2383f83d6046SBarry Smith   Mat         B = (Mat)obj;
238487828ca2SBarry Smith   PetscScalar *array;
2385f83d6046SBarry Smith   mxArray     *mat;
2386d79a51d8SBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
2387d79a51d8SBarry Smith 
2388f83d6046SBarry Smith   PetscFunctionBegin;
238901820c62SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
239087828ca2SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
2391d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
239266826eb6SBarry Smith   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
239366826eb6SBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2394f83d6046SBarry Smith 
239501820c62SBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
239601820c62SBarry Smith   if (aij->indexshift) {
239701820c62SBarry Smith     for (i=0; i<B->m+1; i++) {
239801820c62SBarry Smith       ai[i]--;
2399d79a51d8SBarry Smith     }
2400d79a51d8SBarry Smith     for (i=0; i<aij->nz; i++) {
240101820c62SBarry Smith       aj[i]--;
2402d79a51d8SBarry Smith     }
2403d79a51d8SBarry Smith   }
2404ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2405f83d6046SBarry Smith   mxSetName(mat,obj->name);
2406f83d6046SBarry Smith   engPutArray((Engine *)engine,mat);
2407f83d6046SBarry Smith   PetscFunctionReturn(0);
2408f83d6046SBarry Smith }
2409f83d6046SBarry Smith EXTERN_C_END
241066826eb6SBarry Smith 
241166826eb6SBarry Smith EXTERN_C_BEGIN
24124a2ae208SSatish Balay #undef __FUNCT__
24134a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ"
241466826eb6SBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *engine)
241566826eb6SBarry Smith {
241666826eb6SBarry Smith   int        ierr,ii;
241766826eb6SBarry Smith   Mat        mat = (Mat)obj;
241866826eb6SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
241966826eb6SBarry Smith   mxArray    *mmat;
242066826eb6SBarry Smith 
24216c0721eeSBarry Smith   PetscFunctionBegin;
242266826eb6SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
242366826eb6SBarry Smith   aij->indexshift = 0;
242466826eb6SBarry Smith 
242566826eb6SBarry Smith   mmat = engGetArray((Engine *)engine,obj->name);
242666826eb6SBarry Smith 
2427a65776f3SBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->m];
242887828ca2SBarry Smith   ierr              = PetscMalloc(aij->nz*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
242966826eb6SBarry Smith   aij->j            = (int*)(aij->a + aij->nz);
243066826eb6SBarry Smith   aij->i            = aij->j + aij->nz;
243166826eb6SBarry Smith   aij->singlemalloc = PETSC_TRUE;
243266826eb6SBarry Smith   aij->freedata     = PETSC_TRUE;
243366826eb6SBarry Smith 
243487828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
243566826eb6SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
243666826eb6SBarry Smith   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
243766826eb6SBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
243866826eb6SBarry Smith 
243966826eb6SBarry Smith   for (ii=0; ii<mat->m; ii++) {
244066826eb6SBarry Smith     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
244166826eb6SBarry Smith   }
244266826eb6SBarry Smith 
244366826eb6SBarry Smith   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244466826eb6SBarry Smith   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244566826eb6SBarry Smith 
244666826eb6SBarry Smith   PetscFunctionReturn(0);
244766826eb6SBarry Smith }
244866826eb6SBarry Smith EXTERN_C_END
2449f83d6046SBarry Smith #endif
2450f83d6046SBarry Smith 
2451be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
24524a2ae208SSatish Balay #undef __FUNCT__
24534a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
245417ab2063SBarry Smith /*@C
2455682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
24560d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
24576e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
245851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
24592bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
246017ab2063SBarry Smith 
2461db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2462db81eaa0SLois Curfman McInnes 
246317ab2063SBarry Smith    Input Parameters:
2464db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
246517ab2063SBarry Smith .  m - number of rows
246617ab2063SBarry Smith .  n - number of columns
246717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
246851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
24692bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
247017ab2063SBarry Smith 
247117ab2063SBarry Smith    Output Parameter:
2472416022c9SBarry Smith .  A - the matrix
247317ab2063SBarry Smith 
2474b259b22eSLois Curfman McInnes    Notes:
247517ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
247617ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24770002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
247844cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
247917ab2063SBarry Smith 
248017ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2481a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24823d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24836da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
248417ab2063SBarry Smith 
2485682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24864fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2487682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24886c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24896c7ebb05SLois Curfman McInnes 
24906c7ebb05SLois Curfman McInnes    Options Database Keys:
2491db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2492db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2493db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2494db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2495db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
249617ab2063SBarry Smith 
2497027ccd11SLois Curfman McInnes    Level: intermediate
2498027ccd11SLois Curfman McInnes 
249936db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
250036db0b34SBarry Smith 
250117ab2063SBarry Smith @*/
2502416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A)
250317ab2063SBarry Smith {
2504273d9f13SBarry Smith   int ierr;
25056945ee14SBarry Smith 
25063a40ed3dSBarry Smith   PetscFunctionBegin;
2507273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2508273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2509273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2510273d9f13SBarry Smith   PetscFunctionReturn(0);
2511273d9f13SBarry Smith }
2512273d9f13SBarry Smith 
25135da197adSKris Buschelman #define SKIP_ALLOCATION -4
25145da197adSKris Buschelman 
25154a2ae208SSatish Balay #undef __FUNCT__
25164a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2517273d9f13SBarry Smith /*@C
2518273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2519273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2520273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2521273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2522273d9f13SBarry Smith 
2523273d9f13SBarry Smith    Collective on MPI_Comm
2524273d9f13SBarry Smith 
2525273d9f13SBarry Smith    Input Parameters:
2526273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2527273d9f13SBarry Smith .  m - number of rows
2528273d9f13SBarry Smith .  n - number of columns
2529273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2530273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2531273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2532273d9f13SBarry Smith 
2533273d9f13SBarry Smith    Output Parameter:
2534273d9f13SBarry Smith .  A - the matrix
2535273d9f13SBarry Smith 
2536273d9f13SBarry Smith    Notes:
2537273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2538273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2539273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2540273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2541273d9f13SBarry Smith 
2542273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2543273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2544273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2545273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2546273d9f13SBarry Smith 
2547273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2548273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2549273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2550273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2551273d9f13SBarry Smith 
2552273d9f13SBarry Smith    Options Database Keys:
2553273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2554273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2555273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2556273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2557273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2558273d9f13SBarry Smith 
2559273d9f13SBarry Smith    Level: intermediate
2560273d9f13SBarry Smith 
2561273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2562273d9f13SBarry Smith 
2563273d9f13SBarry Smith @*/
2564273d9f13SBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,int *nnz)
2565273d9f13SBarry Smith {
2566273d9f13SBarry Smith   Mat_SeqAIJ *b;
2567d827b245SHong Zhang   int        i,len=0,ierr;
2568c461c341SBarry Smith   PetscTruth flg2,skipallocation = PETSC_FALSE;
2569273d9f13SBarry Smith 
2570273d9f13SBarry Smith   PetscFunctionBegin;
2571273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg2);CHKERRQ(ierr);
2572273d9f13SBarry Smith   if (!flg2) PetscFunctionReturn(0);
2573d5d45c9bSBarry Smith 
2574c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2575c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2576c461c341SBarry Smith     nz             = 0;
2577c461c341SBarry Smith   }
2578c461c341SBarry Smith 
2579435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2580435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2581b73539f3SBarry Smith   if (nnz) {
2582273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
258329bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25843a7fca6bSBarry 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);
2585b73539f3SBarry Smith     }
2586b73539f3SBarry Smith   }
2587b73539f3SBarry Smith 
2588273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2589273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2590273d9f13SBarry Smith 
2591b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2592273d9f13SBarry Smith   if (!nnz) {
2593435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2594273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2595273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2596273d9f13SBarry Smith     nz = nz*B->m;
2597273d9f13SBarry Smith   } else {
2598273d9f13SBarry Smith     nz = 0;
2599273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2600273d9f13SBarry Smith   }
2601273d9f13SBarry Smith 
2602c461c341SBarry Smith   if (!skipallocation) {
2603273d9f13SBarry Smith     /* allocate the matrix space */
260487828ca2SBarry Smith     len             = nz*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2605b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2606273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2607273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2608273d9f13SBarry Smith     b->i            = b->j + nz;
26095da197adSKris Buschelman     b->i[0] = -b->indexshift;
26105da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26115da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26125da197adSKris Buschelman     }
2613273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2614273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2615c461c341SBarry Smith   } else {
2616c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2617c461c341SBarry Smith   }
2618273d9f13SBarry Smith 
2619273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2620b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2621b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2622273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2623273d9f13SBarry Smith 
2624273d9f13SBarry Smith   b->nz                = 0;
2625273d9f13SBarry Smith   b->maxnz             = nz;
2626273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2627273d9f13SBarry Smith   PetscFunctionReturn(0);
2628273d9f13SBarry Smith }
2629273d9f13SBarry Smith 
2630eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat);
2631eb9c0419SKris Buschelman 
2632273d9f13SBarry Smith EXTERN_C_BEGIN
26334a2ae208SSatish Balay #undef __FUNCT__
26344a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2635273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2636273d9f13SBarry Smith {
2637273d9f13SBarry Smith   Mat_SeqAIJ *b;
2638273d9f13SBarry Smith   int        ierr,size;
2639273d9f13SBarry Smith   PetscTruth flg;
2640273d9f13SBarry Smith 
2641273d9f13SBarry Smith   PetscFunctionBegin;
2642273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2643273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2644273d9f13SBarry Smith 
2645273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2646273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2647273d9f13SBarry Smith 
2648b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2649b0a32e0cSBarry Smith   B->data             = (void*)b;
2650549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2651549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2652416022c9SBarry Smith   B->factor           = 0;
2653416022c9SBarry Smith   B->lupivotthreshold = 1.0;
265490f02eecSBarry Smith   B->mapping          = 0;
2655e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2656e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2657416022c9SBarry Smith   b->row              = 0;
2658416022c9SBarry Smith   b->col              = 0;
265982bf6240SBarry Smith   b->icol             = 0;
2660416022c9SBarry Smith   b->indexshift       = 0;
2661b810aeb4SBarry Smith   b->reallocs         = 0;
2662e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_oneindex",&flg);CHKERRQ(ierr);
266369957df2SSatish Balay   if (flg) b->indexshift = -1;
266417ab2063SBarry Smith 
26658a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26668a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2667a5ae1ecdSBarry Smith 
2668f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
266936db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2670f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2671416022c9SBarry Smith   b->nonew             = 0;
2672416022c9SBarry Smith   b->diag              = 0;
2673416022c9SBarry Smith   b->solve_work        = 0;
26742a1b7f2aSHong Zhang   B->spptr             = 0;
2675b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2676754ec7b1SSatish Balay   b->inode.node_count  = 0;
2677754ec7b1SSatish Balay   b->inode.size        = 0;
26786c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26796c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2680be6bf707SBarry Smith   b->saved_values      = 0;
2681d7f994e1SBarry Smith   b->idiag             = 0;
2682d7f994e1SBarry Smith   b->ssor              = 0;
2683f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
268417ab2063SBarry Smith 
268535d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
268635d8aa7fSBarry Smith 
2687aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
2688e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_superlu",&flg);CHKERRQ(ierr);
268969957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
26904b14c69eSBarry Smith #endif
2691564e58d6SHong Zhang 
2692e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_essl",&flg);CHKERRQ(ierr);
269369957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
2694e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_lusol",&flg);CHKERRQ(ierr);
2695cd5578b5SBarry Smith   if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); }
2696e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2697ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2698e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_dxml",&flg);CHKERRQ(ierr);
269969957df2SSatish Balay   if (flg) {
270029bbc08cSBarry Smith     if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,"need -mat_aij_oneindex with -mat_aij_dxml");
2701416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
270217ab2063SBarry Smith   }
2703f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2704bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2705bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2706f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2707be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2708bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2709f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2710be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2711bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
271287828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2713f83d6046SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
271466826eb6SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
2715f83d6046SBarry Smith #endif
2716eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
27173a40ed3dSBarry Smith   PetscFunctionReturn(0);
271817ab2063SBarry Smith }
2719273d9f13SBarry Smith EXTERN_C_END
272017ab2063SBarry Smith 
27214a2ae208SSatish Balay #undef __FUNCT__
27224a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2723be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
272417ab2063SBarry Smith {
2725416022c9SBarry Smith   Mat        C;
2726416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2727273d9f13SBarry Smith   int        i,len,m = A->m,shift = a->indexshift,ierr;
272817ab2063SBarry Smith 
27293a40ed3dSBarry Smith   PetscFunctionBegin;
27304043dd9cSLois Curfman McInnes   *B = 0;
2731273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2732273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr);
2733273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2734273d9f13SBarry Smith 
2735416022c9SBarry Smith   C->factor         = A->factor;
2736416022c9SBarry Smith   c->row            = 0;
2737416022c9SBarry Smith   c->col            = 0;
273882bf6240SBarry Smith   c->icol           = 0;
2739416022c9SBarry Smith   c->indexshift     = shift;
2740f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2741c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
274217ab2063SBarry Smith 
2743273d9f13SBarry Smith   C->M          = A->m;
2744273d9f13SBarry Smith   C->N          = A->n;
274517ab2063SBarry Smith 
2746b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2747b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
274817ab2063SBarry Smith   for (i=0; i<m; i++) {
2749416022c9SBarry Smith     c->imax[i] = a->imax[i];
2750416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
275117ab2063SBarry Smith   }
275217ab2063SBarry Smith 
275317ab2063SBarry Smith   /* allocate the matrix space */
2754f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
275587828ca2SBarry Smith   len   = (m+1)*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2756b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2757416022c9SBarry Smith   c->j  = (int*)(c->a + a->i[m] + shift);
2758416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2759549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
276017ab2063SBarry Smith   if (m > 0) {
2761549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2762be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
276387828ca2SBarry Smith       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
2764be6bf707SBarry Smith     } else {
276587828ca2SBarry Smith       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
276617ab2063SBarry Smith     }
276708480c60SBarry Smith   }
276817ab2063SBarry Smith 
2769b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2770416022c9SBarry Smith   c->sorted      = a->sorted;
2771416022c9SBarry Smith   c->roworiented = a->roworiented;
2772416022c9SBarry Smith   c->nonew       = a->nonew;
27737a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2774be6bf707SBarry Smith   c->saved_values = 0;
2775d7f994e1SBarry Smith   c->idiag        = 0;
2776d7f994e1SBarry Smith   c->ssor         = 0;
277736db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
277836db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
277917ab2063SBarry Smith 
2780416022c9SBarry Smith   if (a->diag) {
2781b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2782b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
278317ab2063SBarry Smith     for (i=0; i<m; i++) {
2784416022c9SBarry Smith       c->diag[i] = a->diag[i];
278517ab2063SBarry Smith     }
27863a40ed3dSBarry Smith   } else c->diag        = 0;
2787b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27886c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
27896c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2790754ec7b1SSatish Balay   if (a->inode.size){
2791b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2792754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2793549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2794754ec7b1SSatish Balay   } else {
2795754ec7b1SSatish Balay     c->inode.size       = 0;
2796754ec7b1SSatish Balay     c->inode.node_count = 0;
2797754ec7b1SSatish Balay   }
2798416022c9SBarry Smith   c->nz                 = a->nz;
2799416022c9SBarry Smith   c->maxnz              = a->maxnz;
2800416022c9SBarry Smith   c->solve_work         = 0;
28012a1b7f2aSHong Zhang   C->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2802273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2803754ec7b1SSatish Balay 
2804416022c9SBarry Smith   *B = C;
2805b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
28063a40ed3dSBarry Smith   PetscFunctionReturn(0);
280717ab2063SBarry Smith }
280817ab2063SBarry Smith 
2809273d9f13SBarry Smith EXTERN_C_BEGIN
28104a2ae208SSatish Balay #undef __FUNCT__
28114a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2812b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A)
281317ab2063SBarry Smith {
2814416022c9SBarry Smith   Mat_SeqAIJ   *a;
2815416022c9SBarry Smith   Mat          B;
281617699dbbSLois Curfman McInnes   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift;
2817bcd2baecSBarry Smith   MPI_Comm     comm;
281817ab2063SBarry Smith 
28193a40ed3dSBarry Smith   PetscFunctionBegin;
2820e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2821d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
282229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2823b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
28240752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2825552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
282617ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
282717ab2063SBarry Smith 
2828d64ed03dSBarry Smith   if (nz < 0) {
282929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2830d64ed03dSBarry Smith   }
2831d64ed03dSBarry Smith 
283217ab2063SBarry Smith   /* read in row lengths */
2833b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
28340752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
283517ab2063SBarry Smith 
283617ab2063SBarry Smith   /* create our matrix */
2837416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2838416022c9SBarry Smith   B = *A;
2839416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
2840416022c9SBarry Smith   shift = a->indexshift;
284117ab2063SBarry Smith 
284217ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
28430752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
284417ab2063SBarry Smith   if (shift) {
284517ab2063SBarry Smith     for (i=0; i<nz; i++) {
2846416022c9SBarry Smith       a->j[i] += 1;
284717ab2063SBarry Smith     }
284817ab2063SBarry Smith   }
284917ab2063SBarry Smith 
285017ab2063SBarry Smith   /* read in nonzero values */
28510752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
285217ab2063SBarry Smith 
285317ab2063SBarry Smith   /* set matrix "i" values */
2854416022c9SBarry Smith   a->i[0] = -shift;
285517ab2063SBarry Smith   for (i=1; i<= M; i++) {
2856416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2857416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
285817ab2063SBarry Smith   }
2859606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
286017ab2063SBarry Smith 
28616d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28626d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28633a40ed3dSBarry Smith   PetscFunctionReturn(0);
286417ab2063SBarry Smith }
2865273d9f13SBarry Smith EXTERN_C_END
286617ab2063SBarry Smith 
28674a2ae208SSatish Balay #undef __FUNCT__
2868b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28698f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28707264ac53SSatish Balay {
28717264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28720f5bd95cSBarry Smith   int        ierr;
2873273d9f13SBarry Smith   PetscTruth flag;
28747264ac53SSatish Balay 
28753a40ed3dSBarry Smith   PetscFunctionBegin;
2876273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flag);CHKERRQ(ierr);
2877273d9f13SBarry Smith   if (!flag) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices must be same type");
28787264ac53SSatish Balay 
28797264ac53SSatish Balay   /* If the  matrix dimensions are not equal,or no of nonzeros or shift */
2880273d9f13SBarry Smith   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) {
2881ca44d042SBarry Smith     *flg = PETSC_FALSE;
2882ca44d042SBarry Smith     PetscFunctionReturn(0);
2883bcd2baecSBarry Smith   }
28847264ac53SSatish Balay 
28857264ac53SSatish Balay   /* if the a->i are the same */
2886273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28870f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28887264ac53SSatish Balay 
28897264ac53SSatish Balay   /* if a->j are the same */
28900f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28910f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2892bcd2baecSBarry Smith 
2893bcd2baecSBarry Smith   /* if a->a are the same */
289487828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
28950f5bd95cSBarry Smith 
28963a40ed3dSBarry Smith   PetscFunctionReturn(0);
28977264ac53SSatish Balay 
28987264ac53SSatish Balay }
289936db0b34SBarry Smith 
29004a2ae208SSatish Balay #undef __FUNCT__
29014a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
290236db0b34SBarry Smith /*@C
290336db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
290436db0b34SBarry Smith               provided by the user.
290536db0b34SBarry Smith 
290636db0b34SBarry Smith       Coolective on MPI_Comm
290736db0b34SBarry Smith 
290836db0b34SBarry Smith    Input Parameters:
290936db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
291036db0b34SBarry Smith .   m - number of rows
291136db0b34SBarry Smith .   n - number of columns
291236db0b34SBarry Smith .   i - row indices
291336db0b34SBarry Smith .   j - column indices
291436db0b34SBarry Smith -   a - matrix values
291536db0b34SBarry Smith 
291636db0b34SBarry Smith    Output Parameter:
291736db0b34SBarry Smith .   mat - the matrix
291836db0b34SBarry Smith 
291936db0b34SBarry Smith    Level: intermediate
292036db0b34SBarry Smith 
292136db0b34SBarry Smith    Notes:
29220551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
292336db0b34SBarry Smith     once the matrix is destroyed
292436db0b34SBarry Smith 
292536db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
292636db0b34SBarry Smith 
292736db0b34SBarry Smith        The i and j indices can be either 0- or 1 based
292836db0b34SBarry Smith 
292936db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
293036db0b34SBarry Smith 
293136db0b34SBarry Smith @*/
293287828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
293336db0b34SBarry Smith {
293436db0b34SBarry Smith   int        ierr,ii;
293536db0b34SBarry Smith   Mat_SeqAIJ *aij;
293636db0b34SBarry Smith 
293736db0b34SBarry Smith   PetscFunctionBegin;
2938c461c341SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr);
293936db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
294036db0b34SBarry Smith 
294136db0b34SBarry Smith   if (i[0] == 1) {
294236db0b34SBarry Smith     aij->indexshift = -1;
294336db0b34SBarry Smith   } else if (i[0]) {
294429bbc08cSBarry Smith     SETERRQ(1,"i (row indices) do not start with 0 or 1");
294536db0b34SBarry Smith   }
294636db0b34SBarry Smith   aij->i = i;
294736db0b34SBarry Smith   aij->j = j;
294836db0b34SBarry Smith   aij->a = a;
294936db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
295036db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
295136db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
295236db0b34SBarry Smith 
295336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
295436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
29559860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
295629bbc08cSBarry 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]);
295736db0b34SBarry Smith #endif
295836db0b34SBarry Smith   }
29599860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296036db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
296129bbc08cSBarry Smith     if (j[ii] < -aij->indexshift) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
296229bbc08cSBarry Smith     if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
296336db0b34SBarry Smith   }
296436db0b34SBarry Smith #endif
296536db0b34SBarry Smith 
2966b65db4caSBarry Smith   /* changes indices to start at 0 */
2967b65db4caSBarry Smith   if (i[0]) {
2968b65db4caSBarry Smith     aij->indexshift = 0;
2969b65db4caSBarry Smith     for (ii=0; ii<m; ii++) {
2970b65db4caSBarry Smith       i[ii]--;
2971b65db4caSBarry Smith     }
2972b65db4caSBarry Smith     for (ii=0; ii<i[m]; ii++) {
2973b65db4caSBarry Smith       j[ii]--;
2974b65db4caSBarry Smith     }
2975b65db4caSBarry Smith   }
2976b65db4caSBarry Smith 
2977b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2978b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
297936db0b34SBarry Smith   PetscFunctionReturn(0);
298036db0b34SBarry Smith }
298136db0b34SBarry Smith 
2982cc8ba8e1SBarry Smith #undef __FUNCT__
2983ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2984ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2985cc8ba8e1SBarry Smith {
2986cc8ba8e1SBarry Smith   int        ierr;
2987cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
298836db0b34SBarry Smith 
2989cc8ba8e1SBarry Smith   PetscFunctionBegin;
299012c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2991cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2992cc8ba8e1SBarry Smith     a->coloring = coloring;
299312c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
299412c595b3SBarry Smith     int        *colors,i,*larray;
299512c595b3SBarry Smith     ISColoring ocoloring;
299612c595b3SBarry Smith 
299712c595b3SBarry Smith     /* set coloring for diagonal portion */
299812c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
299912c595b3SBarry Smith     for (i=0; i<A->n; i++) {
300012c595b3SBarry Smith       larray[i] = i;
300112c595b3SBarry Smith     }
300212c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
300312c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&colors);CHKERRQ(ierr);
300412c595b3SBarry Smith     for (i=0; i<A->n; i++) {
300512c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
300612c595b3SBarry Smith     }
300712c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
300812c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
300912c595b3SBarry Smith     a->coloring = ocoloring;
301012c595b3SBarry Smith   }
3011cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3012cc8ba8e1SBarry Smith }
3013cc8ba8e1SBarry Smith 
301487828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
3015ee4f033dSBarry Smith EXTERN_C_BEGIN
301629c1e371SBarry Smith #include "adic/ad_utils.h"
3017ee4f033dSBarry Smith EXTERN_C_END
3018cc8ba8e1SBarry Smith 
3019cc8ba8e1SBarry Smith #undef __FUNCT__
3020ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3021ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3022cc8ba8e1SBarry Smith {
3023cc8ba8e1SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
3024ee4f033dSBarry Smith   int         m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j,nlen;
302587828ca2SBarry Smith   PetscScalar *v = a->a,*values;
3026ee4f033dSBarry Smith   char        *cadvalues = (char *)advalues;
3027cc8ba8e1SBarry Smith 
3028cc8ba8e1SBarry Smith   PetscFunctionBegin;
3029cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
303029c1e371SBarry Smith   nlen  = PetscADGetDerivTypeSize();
3031cc8ba8e1SBarry Smith   color = a->coloring->colors;
3032cc8ba8e1SBarry Smith   /* loop over rows */
3033cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3034cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3035cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
303629c1e371SBarry Smith     values = PetscADGetGradArray(cadvalues);
3037cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3038cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3039cc8ba8e1SBarry Smith     }
3040ee4f033dSBarry Smith     cadvalues += nlen; /* jump to next row of derivatives */
3041ee4f033dSBarry Smith   }
3042ee4f033dSBarry Smith   PetscFunctionReturn(0);
3043ee4f033dSBarry Smith }
3044ee4f033dSBarry Smith 
3045ee4f033dSBarry Smith #else
3046ee4f033dSBarry Smith 
3047ee4f033dSBarry Smith #undef __FUNCT__
3048ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3049ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3050ee4f033dSBarry Smith {
3051ee4f033dSBarry Smith   PetscFunctionBegin;
3052ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
3053ee4f033dSBarry Smith }
3054ee4f033dSBarry Smith 
3055ee4f033dSBarry Smith #endif
3056ee4f033dSBarry Smith 
3057ee4f033dSBarry Smith #undef __FUNCT__
3058ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
3059ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
3060ee4f033dSBarry Smith {
3061ee4f033dSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
3062ee4f033dSBarry Smith   int          m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j;
306387828ca2SBarry Smith   PetscScalar  *v = a->a,*values = (PetscScalar *)advalues;
3064ee4f033dSBarry Smith 
3065ee4f033dSBarry Smith   PetscFunctionBegin;
3066ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3067ee4f033dSBarry Smith   color = a->coloring->colors;
3068ee4f033dSBarry Smith   /* loop over rows */
3069ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3070ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3071ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3072ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3073ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3074ee4f033dSBarry Smith     }
3075ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3076cc8ba8e1SBarry Smith   }
3077cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3078cc8ba8e1SBarry Smith }
307936db0b34SBarry Smith 
3080