xref: /petsc/src/mat/impls/aij/seq/aij.c (revision e74208457f81a69714e7689ef1b37ce32c29727b)
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 
303cd155464SBarry Smith extern int MatMPIAIJFactorInfo_SuperLu(Mat,PetscViewer);
304a072f7f7SHong Zhang extern int MatFactorInfo_Spooles(Mat,PetscViewer);
305*e7420845SHong Zhang extern int MatSeqAIJFactorInfo_UMFPACK(Mat,PetscViewer);
306cd155464SBarry Smith 
3074a2ae208SSatish Balay #undef __FUNCT__
3084a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
309b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
310416022c9SBarry Smith {
311416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
312fb9695e5SSatish Balay   int               ierr,i,j,m = A->m,shift = a->indexshift;
313fb9695e5SSatish Balay   char              *name;
314f3ef73ceSBarry Smith   PetscViewerFormat format;
31517ab2063SBarry Smith 
3163a40ed3dSBarry Smith   PetscFunctionBegin;
317435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
318b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
319fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO_LONG || format == PETSC_VIEWER_ASCII_INFO) {
3206831982aSBarry Smith     if (a->inode.size) {
321b0a32e0cSBarry 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);
3226831982aSBarry Smith     } else {
323b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3246831982aSBarry Smith     }
325fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
326d00d2cf4SBarry Smith     int nofinalvalue = 0;
327273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
328d00d2cf4SBarry Smith       nofinalvalue = 1;
329d00d2cf4SBarry Smith     }
330b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
331b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
332b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
333b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
334b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
33517ab2063SBarry Smith 
33617ab2063SBarry Smith     for (i=0; i<m; i++) {
337416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
338aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
339b0a32e0cSBarry 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);
34017ab2063SBarry Smith #else
341b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
34217ab2063SBarry Smith #endif
34317ab2063SBarry Smith       }
34417ab2063SBarry Smith     }
345d00d2cf4SBarry Smith     if (nofinalvalue) {
346b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
347d00d2cf4SBarry Smith     }
348fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
349b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
350cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
351cd155464SBarry Smith #if defined(PETSC_HAVE_SUPERLUDIST) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
352cd155464SBarry Smith      ierr = MatMPIAIJFactorInfo_SuperLu(A,viewer);CHKERRQ(ierr);
353cd155464SBarry Smith #endif
354174d842dSHong Zhang #if defined(PETSC_HAVE_SPOOLES) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
355a072f7f7SHong Zhang      ierr = MatFactorInfo_Spooles(A,viewer);CHKERRQ(ierr);
356174d842dSHong Zhang #endif
357*e7420845SHong Zhang #if defined(PETSC_HAVE_UMFPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
358*e7420845SHong Zhang      ierr = MatSeqAIJFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr);
359*e7420845SHong Zhang #endif
360cd155464SBarry Smith      PetscFunctionReturn(0);
361fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
362b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
36344cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
364b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
36544cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
366aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
36736db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
36862b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
36936db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
37062b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
37136db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
37262b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3736831982aSBarry Smith         }
37444cd7ae7SLois Curfman McInnes #else
37562b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
37644cd7ae7SLois Curfman McInnes #endif
37744cd7ae7SLois Curfman McInnes       }
378b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
37944cd7ae7SLois Curfman McInnes     }
380b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
381fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
382496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
383b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
384b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
385496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
386496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
387496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
388496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
389aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
391496be53dSLois Curfman McInnes #else
392496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
393496be53dSLois Curfman McInnes #endif
394496be53dSLois Curfman McInnes         }
395496be53dSLois Curfman McInnes       }
396496be53dSLois Curfman McInnes     }
3972e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
398b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
3992e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
400b0a32e0cSBarry 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);}
401b0a32e0cSBarry 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);}
402b0a32e0cSBarry 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);}
403b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
404b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
405b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
406496be53dSLois Curfman McInnes     }
407b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
408606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
409496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
410496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
411b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
412496be53dSLois Curfman McInnes       }
413b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
414496be53dSLois Curfman McInnes     }
415b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
416496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
417496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
418496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
419aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
42036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
421b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4226831982aSBarry Smith           }
423496be53dSLois Curfman McInnes #else
424b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
425496be53dSLois Curfman McInnes #endif
426496be53dSLois Curfman McInnes         }
427496be53dSLois Curfman McInnes       }
428b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
429496be53dSLois Curfman McInnes     }
430b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
431fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
43202594712SBarry Smith     int         cnt = 0,jcnt;
43387828ca2SBarry Smith     PetscScalar value;
43402594712SBarry Smith 
435b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
43602594712SBarry Smith     for (i=0; i<m; i++) {
43702594712SBarry Smith       jcnt = 0;
438273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
439e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44002594712SBarry Smith           value = a->a[cnt++];
441e24b481bSBarry Smith           jcnt++;
44202594712SBarry Smith         } else {
44302594712SBarry Smith           value = 0.0;
44402594712SBarry Smith         }
445aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
446b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
44702594712SBarry Smith #else
448b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
44902594712SBarry Smith #endif
45002594712SBarry Smith       }
451b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45202594712SBarry Smith     }
453b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4543a40ed3dSBarry Smith   } else {
455b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
45617ab2063SBarry Smith     for (i=0; i<m; i++) {
457b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
458416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
459aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
46162b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
46236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
46362b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4643a40ed3dSBarry Smith         } else {
46562b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
46617ab2063SBarry Smith         }
46717ab2063SBarry Smith #else
46862b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
46917ab2063SBarry Smith #endif
47017ab2063SBarry Smith       }
471b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47217ab2063SBarry Smith     }
473b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
47417ab2063SBarry Smith   }
475b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4763a40ed3dSBarry Smith   PetscFunctionReturn(0);
477416022c9SBarry Smith }
478416022c9SBarry Smith 
4794a2ae208SSatish Balay #undef __FUNCT__
4804a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
481b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
482416022c9SBarry Smith {
483480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
484416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
485273d9f13SBarry Smith   int               ierr,i,j,m = A->m,shift = a->indexshift,color;
48636db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
487b0a32e0cSBarry Smith   PetscViewer       viewer;
488f3ef73ceSBarry Smith   PetscViewerFormat format;
489cddf8d76SBarry Smith 
4903a40ed3dSBarry Smith   PetscFunctionBegin;
491480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
492b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
49319bcc07fSBarry Smith 
494b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
495416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4960513a670SBarry Smith 
497fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4980513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
499b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
500416022c9SBarry Smith     for (i=0; i<m; i++) {
501cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
502416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
503cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
50536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
506cddf8d76SBarry Smith #else
507cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
508cddf8d76SBarry Smith #endif
509b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
510cddf8d76SBarry Smith       }
511cddf8d76SBarry Smith     }
512b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
513cddf8d76SBarry Smith     for (i=0; i<m; i++) {
514cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
515cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
516cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
517cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
518b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
519cddf8d76SBarry Smith       }
520cddf8d76SBarry Smith     }
521b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
522cddf8d76SBarry Smith     for (i=0; i<m; i++) {
523cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
524cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
525cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
526aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
52736db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
528cddf8d76SBarry Smith #else
529cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
530cddf8d76SBarry Smith #endif
531b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
532416022c9SBarry Smith       }
533416022c9SBarry Smith     }
5340513a670SBarry Smith   } else {
5350513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5360513a670SBarry Smith     /* first determine max of all nonzero values */
5370513a670SBarry Smith     int    nz = a->nz,count;
538b0a32e0cSBarry Smith     PetscDraw   popup;
53936db0b34SBarry Smith     PetscReal scale;
5400513a670SBarry Smith 
5410513a670SBarry Smith     for (i=0; i<nz; i++) {
5420513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5430513a670SBarry Smith     }
544b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
545b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
546b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5470513a670SBarry Smith     count = 0;
5480513a670SBarry Smith     for (i=0; i<m; i++) {
5490513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5500513a670SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5510513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
552b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
553b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5540513a670SBarry Smith         count++;
5550513a670SBarry Smith       }
5560513a670SBarry Smith     }
5570513a670SBarry Smith   }
558480ef9eaSBarry Smith   PetscFunctionReturn(0);
559480ef9eaSBarry Smith }
560cddf8d76SBarry Smith 
5614a2ae208SSatish Balay #undef __FUNCT__
5624a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
563b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
564480ef9eaSBarry Smith {
565480ef9eaSBarry Smith   int        ierr;
566b0a32e0cSBarry Smith   PetscDraw  draw;
56736db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
568480ef9eaSBarry Smith   PetscTruth isnull;
569480ef9eaSBarry Smith 
570480ef9eaSBarry Smith   PetscFunctionBegin;
571b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
572b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
573480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
574480ef9eaSBarry Smith 
575480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
576273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
577480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
578b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
579b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
580480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5813a40ed3dSBarry Smith   PetscFunctionReturn(0);
582416022c9SBarry Smith }
583416022c9SBarry Smith 
5844a2ae208SSatish Balay #undef __FUNCT__
5854a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
586b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
587416022c9SBarry Smith {
588416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
589bcd2baecSBarry Smith   int         ierr;
5906831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
591416022c9SBarry Smith 
5923a40ed3dSBarry Smith   PetscFunctionBegin;
593b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
594b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
595fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
596fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5970f5bd95cSBarry Smith   if (issocket) {
59801820c62SBarry Smith     if (a->indexshift) {
59929bbc08cSBarry Smith       SETERRQ(1,"Can only socket send sparse matrix with 0 based indexing");
60001820c62SBarry Smith     }
601b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
6020f5bd95cSBarry Smith   } else if (isascii) {
6033a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6040f5bd95cSBarry Smith   } else if (isbinary) {
6053a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6060f5bd95cSBarry Smith   } else if (isdraw) {
6073a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6085cd90555SBarry Smith   } else {
60929bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
61017ab2063SBarry Smith   }
6113a40ed3dSBarry Smith   PetscFunctionReturn(0);
61217ab2063SBarry Smith }
61319bcc07fSBarry Smith 
6143a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth);
6159b9367d5SHong Zhang EXTERN int MatUseSuperLU_DIST_MPIAIJ(Mat);
616cfef3cccSHong Zhang EXTERN int MatUseSpooles_SeqAIJ(Mat);
617564e58d6SHong Zhang EXTERN int MatUseUMFPACK_SeqAIJ(Mat);
6184a2ae208SSatish Balay #undef __FUNCT__
6194a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
6208f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
62117ab2063SBarry Smith {
622416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
62341c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
624273d9f13SBarry Smith   int          m = A->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0;
62587828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
626564e58d6SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) || defined(PETSC_HAVE_SPOOLES) || defined(PETSC_HAVE_UMFPACK)
6279b9367d5SHong Zhang   PetscTruth   flag;
6289e070d67SMatthew Knepley #endif
62917ab2063SBarry Smith 
6303a40ed3dSBarry Smith   PetscFunctionBegin;
6313a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
63217ab2063SBarry Smith 
63343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
63417ab2063SBarry Smith   for (i=1; i<m; i++) {
635416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
63617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
63794a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
63817ab2063SBarry Smith     if (fshift) {
6390f5bd95cSBarry Smith       ip = aj + ai[i] + shift;
6400f5bd95cSBarry Smith       ap = aa + ai[i] + shift;
64117ab2063SBarry Smith       N  = ailen[i];
64217ab2063SBarry Smith       for (j=0; j<N; j++) {
64317ab2063SBarry Smith         ip[j-fshift] = ip[j];
64417ab2063SBarry Smith         ap[j-fshift] = ap[j];
64517ab2063SBarry Smith       }
64617ab2063SBarry Smith     }
64717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
64817ab2063SBarry Smith   }
64917ab2063SBarry Smith   if (m) {
65017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
65117ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
65217ab2063SBarry Smith   }
65317ab2063SBarry Smith   /* reset ilen and imax for each row */
65417ab2063SBarry Smith   for (i=0; i<m; i++) {
65517ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
65617ab2063SBarry Smith   }
657416022c9SBarry Smith   a->nz = ai[m] + shift;
65817ab2063SBarry Smith 
65917ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
660416022c9SBarry Smith   if (fshift && a->diag) {
661606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
662b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
663416022c9SBarry Smith     a->diag = 0;
66417ab2063SBarry Smith   }
665b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
666b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
667b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
668dd5f02e7SSatish Balay   a->reallocs          = 0;
6694e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
67036db0b34SBarry Smith   a->rmax              = rmax;
6714e220ebcSLois Curfman McInnes 
67276dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6733a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
674cfef3cccSHong Zhang 
6759b9367d5SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST)
6769b9367d5SHong Zhang   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_superlu_dist",&flag);CHKERRQ(ierr);
6779b9367d5SHong Zhang   if (flag) { ierr = MatUseSuperLU_DIST_MPIAIJ(A);CHKERRQ(ierr); }
6789b9367d5SHong Zhang #endif
6799b9367d5SHong Zhang 
680cfef3cccSHong Zhang #if defined(PETSC_HAVE_SPOOLES)
681cfef3cccSHong Zhang   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_spooles",&flag);CHKERRQ(ierr);
682cfef3cccSHong Zhang   if (flag) { ierr = MatUseSpooles_SeqAIJ(A);CHKERRQ(ierr); }
683cfef3cccSHong Zhang #endif
684cfef3cccSHong Zhang 
685564e58d6SHong Zhang #if defined(PETSC_HAVE_UMFPACK)
686564e58d6SHong Zhang   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_umfpack",&flag);CHKERRQ(ierr);
687564e58d6SHong Zhang   if (flag) { ierr = MatUseUMFPACK_SeqAIJ(A);CHKERRQ(ierr); }
688564e58d6SHong Zhang #endif
689564e58d6SHong Zhang 
6903a40ed3dSBarry Smith   PetscFunctionReturn(0);
69117ab2063SBarry Smith }
69217ab2063SBarry Smith 
6934a2ae208SSatish Balay #undef __FUNCT__
6944a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6958f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
69617ab2063SBarry Smith {
697416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
698549d3d68SSatish Balay   int        ierr;
6993a40ed3dSBarry Smith 
7003a40ed3dSBarry Smith   PetscFunctionBegin;
70187828ca2SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
7023a40ed3dSBarry Smith   PetscFunctionReturn(0);
70317ab2063SBarry Smith }
704416022c9SBarry Smith 
7054a2ae208SSatish Balay #undef __FUNCT__
7064a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
707e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
70817ab2063SBarry Smith {
709416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
71082bf6240SBarry Smith   int        ierr;
711d5d45c9bSBarry Smith 
7123a40ed3dSBarry Smith   PetscFunctionBegin;
713aa482453SBarry Smith #if defined(PETSC_USE_LOG)
714b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
71517ab2063SBarry Smith #endif
71636db0b34SBarry Smith   if (a->freedata) {
717606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
718606d414cSSatish Balay     if (!a->singlemalloc) {
719606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
720606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
721606d414cSSatish Balay     }
72236db0b34SBarry Smith   }
723c38d4ed2SBarry Smith   if (a->row) {
724c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
725c38d4ed2SBarry Smith   }
726c38d4ed2SBarry Smith   if (a->col) {
727c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
728c38d4ed2SBarry Smith   }
729606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
730606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
731606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
732273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
733606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
734606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
73582bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
736606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
737cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
738606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
7393a40ed3dSBarry Smith   PetscFunctionReturn(0);
74017ab2063SBarry Smith }
74117ab2063SBarry Smith 
7424a2ae208SSatish Balay #undef __FUNCT__
7434a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
7448f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
74517ab2063SBarry Smith {
7463a40ed3dSBarry Smith   PetscFunctionBegin;
7473a40ed3dSBarry Smith   PetscFunctionReturn(0);
74817ab2063SBarry Smith }
74917ab2063SBarry Smith 
7504a2ae208SSatish Balay #undef __FUNCT__
7514a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7528f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
75317ab2063SBarry Smith {
754416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7553a40ed3dSBarry Smith 
7563a40ed3dSBarry Smith   PetscFunctionBegin;
757a65d3064SKris Buschelman   switch (op) {
758a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
759a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
760a65d3064SKris Buschelman       break;
761a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
762a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
763a65d3064SKris Buschelman       break;
764a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
765a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
766a65d3064SKris Buschelman       break;
767a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
768a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
769a65d3064SKris Buschelman       break;
770a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
771a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
772a65d3064SKris Buschelman       break;
773a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
774a65d3064SKris Buschelman       a->nonew             = 1;
775a65d3064SKris Buschelman       break;
776a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
777a65d3064SKris Buschelman       a->nonew             = -1;
778a65d3064SKris Buschelman       break;
779a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
780a65d3064SKris Buschelman       a->nonew             = -2;
781a65d3064SKris Buschelman       break;
782a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
783a65d3064SKris Buschelman       a->nonew             = 0;
784a65d3064SKris Buschelman       break;
785a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
786a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
787a65d3064SKris Buschelman       break;
788a65d3064SKris Buschelman     case MAT_USE_INODES:
789a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
790a65d3064SKris Buschelman       break;
791a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
792a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
793a65d3064SKris Buschelman       break;
794a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
795a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
796a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
797a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
798a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
799d03495bdSKris Buschelman     case MAT_USE_SINGLE_PRECISION_SOLVES:
800b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
801a65d3064SKris Buschelman       break;
802a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
80329bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
804a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
805a65d3064SKris Buschelman       a->inode.limit  = 1;
806a65d3064SKris Buschelman       break;
807a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
808a65d3064SKris Buschelman       a->inode.limit  = 2;
809a65d3064SKris Buschelman       break;
810a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
811a65d3064SKris Buschelman       a->inode.limit  = 3;
812a65d3064SKris Buschelman       break;
813a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
814a65d3064SKris Buschelman       a->inode.limit  = 4;
815a65d3064SKris Buschelman       break;
816a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
817a65d3064SKris Buschelman       a->inode.limit  = 5;
818a65d3064SKris Buschelman       break;
819a65d3064SKris Buschelman     default:
820a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
821a65d3064SKris Buschelman   }
8223a40ed3dSBarry Smith   PetscFunctionReturn(0);
82317ab2063SBarry Smith }
82417ab2063SBarry Smith 
8254a2ae208SSatish Balay #undef __FUNCT__
8264a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
8278f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
82817ab2063SBarry Smith {
829416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8303a40ed3dSBarry Smith   int          i,j,n,shift = a->indexshift,ierr;
83187828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
83217ab2063SBarry Smith 
8333a40ed3dSBarry Smith   PetscFunctionBegin;
8343a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
83536db0b34SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
83636db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
837273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
838273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
839416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
840416022c9SBarry Smith       if (a->j[j]+shift == i) {
841416022c9SBarry Smith         x[i] = a->a[j];
84217ab2063SBarry Smith         break;
84317ab2063SBarry Smith       }
84417ab2063SBarry Smith     }
84517ab2063SBarry Smith   }
84636db0b34SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8473a40ed3dSBarry Smith   PetscFunctionReturn(0);
84817ab2063SBarry Smith }
84917ab2063SBarry Smith 
850d5d45c9bSBarry Smith 
8514a2ae208SSatish Balay #undef __FUNCT__
8524a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8537c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
85417ab2063SBarry Smith {
855416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8565c897100SBarry Smith   PetscScalar  *x,*y;
8575c897100SBarry Smith   int          ierr,m = A->m,shift = a->indexshift;
8585c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8595c897100SBarry Smith   PetscScalar  *v,alpha;
8605c897100SBarry Smith   int          n,i,*idx;
8615c897100SBarry Smith #endif
86217ab2063SBarry Smith 
8633a40ed3dSBarry Smith   PetscFunctionBegin;
8642e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
865e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
866e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
86717ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
8685c897100SBarry Smith 
8695c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8705c897100SBarry Smith   fortranmulttransposeaddaij_(&m,x,a->i,a->j+shift,a->a+shift,y);
8715c897100SBarry Smith #else
87217ab2063SBarry Smith   for (i=0; i<m; i++) {
873416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
874416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
875416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
87617ab2063SBarry Smith     alpha = x[i];
87717ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
87817ab2063SBarry Smith   }
8795c897100SBarry Smith #endif
880b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
881e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
882e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8833a40ed3dSBarry Smith   PetscFunctionReturn(0);
88417ab2063SBarry Smith }
88517ab2063SBarry Smith 
8864a2ae208SSatish Balay #undef __FUNCT__
8875c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8885c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8895c897100SBarry Smith {
8908d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8915c897100SBarry Smith   int          ierr;
8925c897100SBarry Smith 
8935c897100SBarry Smith   PetscFunctionBegin;
8945c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8955c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8965c897100SBarry Smith   PetscFunctionReturn(0);
8975c897100SBarry Smith }
8985c897100SBarry Smith 
8995c897100SBarry Smith 
9005c897100SBarry Smith #undef __FUNCT__
9014a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
90244cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
90317ab2063SBarry Smith {
904416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
905362ced78SSatish Balay   PetscScalar  *x,*y,*v;
906273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
907aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
908e36a17ebSSatish Balay   int          n,i,jrow,j;
909362ced78SSatish Balay   PetscScalar  sum;
910e36a17ebSSatish Balay #endif
91117ab2063SBarry Smith 
912b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
913fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
914fee21e36SBarry Smith #endif
915fee21e36SBarry Smith 
9163a40ed3dSBarry Smith   PetscFunctionBegin;
917e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
918e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
91917ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
920416022c9SBarry Smith   idx  = a->j;
921d64ed03dSBarry Smith   v    = a->a;
922416022c9SBarry Smith   ii   = a->i;
923aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
92429b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
9258d195f9aSBarry Smith #else
926d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
927d64ed03dSBarry Smith   idx  += shift;
92817ab2063SBarry Smith   for (i=0; i<m; i++) {
9299ea0dfa2SSatish Balay     jrow = ii[i];
9309ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93117ab2063SBarry Smith     sum  = 0.0;
9329ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9339ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9349ea0dfa2SSatish Balay      }
93517ab2063SBarry Smith     y[i] = sum;
93617ab2063SBarry Smith   }
9378d195f9aSBarry Smith #endif
938b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
939e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
940e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9413a40ed3dSBarry Smith   PetscFunctionReturn(0);
94217ab2063SBarry Smith }
94317ab2063SBarry Smith 
9444a2ae208SSatish Balay #undef __FUNCT__
9454a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
94644cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
94717ab2063SBarry Smith {
948416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
949362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
950273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
951aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
952e36a17ebSSatish Balay   int          n,i,jrow,j;
953362ced78SSatish Balay PetscScalar    sum;
954e36a17ebSSatish Balay #endif
9559ea0dfa2SSatish Balay 
9563a40ed3dSBarry Smith   PetscFunctionBegin;
957e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
958e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9592e8a6d31SBarry Smith   if (zz != yy) {
960e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9612e8a6d31SBarry Smith   } else {
9622e8a6d31SBarry Smith     z = y;
9632e8a6d31SBarry Smith   }
96417ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
965cddf8d76SBarry Smith   idx  = a->j;
966d64ed03dSBarry Smith   v    = a->a;
967cddf8d76SBarry Smith   ii   = a->i;
968aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
96929b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
97002ab625aSSatish Balay #else
971d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
972d64ed03dSBarry Smith   idx += shift;
97317ab2063SBarry Smith   for (i=0; i<m; i++) {
9749ea0dfa2SSatish Balay     jrow = ii[i];
9759ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
97617ab2063SBarry Smith     sum  = y[i];
9779ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9789ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9799ea0dfa2SSatish Balay      }
98017ab2063SBarry Smith     z[i] = sum;
98117ab2063SBarry Smith   }
98202ab625aSSatish Balay #endif
983b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
984e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
985e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9862e8a6d31SBarry Smith   if (zz != yy) {
987e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9882e8a6d31SBarry Smith   }
9893a40ed3dSBarry Smith   PetscFunctionReturn(0);
99017ab2063SBarry Smith }
99117ab2063SBarry Smith 
99217ab2063SBarry Smith /*
99317ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
99417ab2063SBarry Smith */
9954a2ae208SSatish Balay #undef __FUNCT__
9964a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
997f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
99817ab2063SBarry Smith {
999416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1000b0a32e0cSBarry Smith   int        i,j,*diag,m = A->m,shift = a->indexshift,ierr;
100117ab2063SBarry Smith 
10023a40ed3dSBarry Smith   PetscFunctionBegin;
1003f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
1004f1e2ffcdSBarry Smith 
1005b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
1006b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
1007273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
100835b0346bSBarry Smith     diag[i] = a->i[i+1];
1009416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
1010416022c9SBarry Smith       if (a->j[j]+shift == i) {
101117ab2063SBarry Smith         diag[i] = j - shift;
101217ab2063SBarry Smith         break;
101317ab2063SBarry Smith       }
101417ab2063SBarry Smith     }
101517ab2063SBarry Smith   }
1016416022c9SBarry Smith   a->diag = diag;
10173a40ed3dSBarry Smith   PetscFunctionReturn(0);
101817ab2063SBarry Smith }
101917ab2063SBarry Smith 
1020be5855fcSBarry Smith /*
1021be5855fcSBarry Smith      Checks for missing diagonals
1022be5855fcSBarry Smith */
10234a2ae208SSatish Balay #undef __FUNCT__
10244a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1025f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
1026be5855fcSBarry Smith {
1027be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1028f1e2ffcdSBarry Smith   int        *diag,*jj = a->j,i,shift = a->indexshift,ierr;
1029be5855fcSBarry Smith 
1030be5855fcSBarry Smith   PetscFunctionBegin;
1031f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1032f1e2ffcdSBarry Smith   diag = a->diag;
1033273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
1034be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
103529bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
1036be5855fcSBarry Smith     }
1037be5855fcSBarry Smith   }
1038be5855fcSBarry Smith   PetscFunctionReturn(0);
1039be5855fcSBarry Smith }
1040be5855fcSBarry Smith 
10414a2ae208SSatish Balay #undef __FUNCT__
10424a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
1043c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
104417ab2063SBarry Smith {
1045416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
104687828ca2SBarry Smith   PetscScalar  *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0;
1047273d9f13SBarry Smith   int          ierr,*idx,*diag,n = A->n,m = A->m,i,shift = a->indexshift;
104817ab2063SBarry Smith 
10493a40ed3dSBarry Smith   PetscFunctionBegin;
1050b965ef7fSBarry Smith   its = its*lits;
105191723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
105291723122SBarry Smith 
1053e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1054fb2e594dSBarry Smith   if (xx != bb) {
1055e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1056fb2e594dSBarry Smith   } else {
1057fb2e594dSBarry Smith     b = x;
1058fb2e594dSBarry Smith   }
1059fb2e594dSBarry Smith 
1060f1e2ffcdSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1061416022c9SBarry Smith   diag = a->diag;
1062416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
106317ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
106417ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
106517ab2063SBarry Smith     bs = b + shift;
106617ab2063SBarry Smith     for (i=0; i<m; i++) {
1067416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1068416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1069b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1070416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1071416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
107217ab2063SBarry Smith         sum  = b[i]*d/omega;
107317ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
107417ab2063SBarry Smith         x[i] = sum;
107517ab2063SBarry Smith     }
1076cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1077fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10783a40ed3dSBarry Smith     PetscFunctionReturn(0);
107917ab2063SBarry Smith   }
1080c783ea89SBarry Smith 
1081c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1082c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1083c783ea89SBarry Smith     if (!a->idiag) {
108487828ca2SBarry Smith       ierr     = PetscMalloc(2*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1085c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1086c783ea89SBarry Smith       v        = a->a;
1087c783ea89SBarry Smith       for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];}
1088c783ea89SBarry Smith     }
1089c783ea89SBarry Smith     t     = a->ssor;
1090c783ea89SBarry Smith     idiag = a->idiag;
1091c783ea89SBarry Smith   }
1092fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1093fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1094fc3d8934SBarry Smith 
1095fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1096fc3d8934SBarry Smith 
1097fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1098fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
109948af12d7SBarry Smith     is the relaxation factor.
1100fc3d8934SBarry Smith     */
1101fc3d8934SBarry Smith 
110248af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
110329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
110448af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
110548af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
110687828ca2SBarry Smith     PetscScalar *v2;
110748af12d7SBarry Smith 
1108733d66baSBarry Smith     v2    = a->a;
1109fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1110fc3d8934SBarry Smith     for (i=m-1; i>=0; i--) {
1111fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1112fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1113fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1114fc3d8934SBarry Smith       sum  = b[i];
1115fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1116b4632166SBarry Smith       x[i] = sum*idiag[i];
1117fc3d8934SBarry Smith 
1118fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1119733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1120733d66baSBarry Smith     }
1121fc3d8934SBarry Smith 
1122fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1123fc3d8934SBarry Smith     diag = a->diag;
1124fc3d8934SBarry Smith     for (i=0; i<m; i++) {
1125fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1126fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1127fc3d8934SBarry Smith       v    = a->a + a->i[i];
1128fc3d8934SBarry Smith       sum  = t[i];
1129fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1130b4632166SBarry Smith       t[i]  = sum*idiag[i];
1131fc3d8934SBarry Smith 
1132fc3d8934SBarry Smith       /*  x = x + t */
1133733d66baSBarry Smith       x[i] += t[i];
1134733d66baSBarry Smith     }
1135733d66baSBarry Smith 
1136b0a32e0cSBarry Smith     PetscLogFlops(3*m-1 + 2*a->nz);
1137fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1138fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1139fc3d8934SBarry Smith     PetscFunctionReturn(0);
11403a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
114117ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
114217ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
114317ab2063SBarry Smith 
114417ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
114517ab2063SBarry Smith 
114617ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
114717ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
114817ab2063SBarry Smith     is the relaxation factor.
114917ab2063SBarry Smith     */
115017ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
115117ab2063SBarry Smith 
115217ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
115317ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1154416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1155416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1156416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1157416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
115817ab2063SBarry Smith       sum  = b[i];
115917ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
116017ab2063SBarry Smith       x[i] = omega*(sum/d);
116117ab2063SBarry Smith     }
116217ab2063SBarry Smith 
116317ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1164416022c9SBarry Smith     v = a->a;
116517ab2063SBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
116617ab2063SBarry Smith 
116717ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1168416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1169416022c9SBarry Smith     diag = a->diag;
117017ab2063SBarry Smith     for (i=0; i<m; i++) {
1171416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1172416022c9SBarry Smith       n    = diag[i] - a->i[i];
1173416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1174416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
117517ab2063SBarry Smith       sum  = t[i];
117617ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
117717ab2063SBarry Smith       t[i] = omega*(sum/d);
1178733d66baSBarry Smith       /*  x = x + t */
1179733d66baSBarry Smith       x[i] += t[i];
118017ab2063SBarry Smith     }
118117ab2063SBarry Smith 
1182b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
1183cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1184fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11853a40ed3dSBarry Smith     PetscFunctionReturn(0);
118617ab2063SBarry Smith   }
118717ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
118817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
118977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
119077d8c4bbSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,b);
119177d8c4bbSBarry Smith #else
119217ab2063SBarry Smith       for (i=0; i<m; i++) {
1193416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1194416022c9SBarry Smith         n    = diag[i] - a->i[i];
1195b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1196416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1197416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
119817ab2063SBarry Smith         sum  = b[i];
119917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
120017ab2063SBarry Smith         x[i] = omega*(sum/d);
120117ab2063SBarry Smith       }
120277d8c4bbSBarry Smith #endif
120317ab2063SBarry Smith       xb = x;
12043a40ed3dSBarry Smith     } else xb = b;
120517ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
120617ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
120717ab2063SBarry Smith       for (i=0; i<m; i++) {
1208416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
120917ab2063SBarry Smith       }
1210b0a32e0cSBarry Smith       PetscLogFlops(m);
121117ab2063SBarry Smith     }
121217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
121377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
121477d8c4bbSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,xb);
121577d8c4bbSBarry Smith #else
121617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1217416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1218416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1219b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1220416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1221416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
122217ab2063SBarry Smith         sum  = xb[i];
122317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
122417ab2063SBarry Smith         x[i] = omega*(sum/d);
122517ab2063SBarry Smith       }
122677d8c4bbSBarry Smith #endif
122717ab2063SBarry Smith     }
122817ab2063SBarry Smith     its--;
122917ab2063SBarry Smith   }
123017ab2063SBarry Smith   while (its--) {
123117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
123277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
123377d8c4bbSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
123477d8c4bbSBarry Smith #else
123517ab2063SBarry Smith       for (i=0; i<m; i++) {
1236416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1237416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1238b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1239416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1240416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
124117ab2063SBarry Smith         sum  = b[i];
124217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12437e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
124417ab2063SBarry Smith       }
124577d8c4bbSBarry Smith #endif
124617ab2063SBarry Smith     }
124717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
124877d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
124977d8c4bbSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
125077d8c4bbSBarry Smith #else
125117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1252416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1253416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1254b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1255416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1256416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
125717ab2063SBarry Smith         sum  = b[i];
125817ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12597e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
126017ab2063SBarry Smith       }
126177d8c4bbSBarry Smith #endif
126217ab2063SBarry Smith     }
126317ab2063SBarry Smith   }
1264cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1265fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12663a40ed3dSBarry Smith   PetscFunctionReturn(0);
126717ab2063SBarry Smith }
126817ab2063SBarry Smith 
12694a2ae208SSatish Balay #undef __FUNCT__
12704a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12718f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
127217ab2063SBarry Smith {
1273416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12744e220ebcSLois Curfman McInnes 
12753a40ed3dSBarry Smith   PetscFunctionBegin;
1276273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1277273d9f13SBarry Smith   info->columns_global = (double)A->n;
1278273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1279273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12804e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12814e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12824e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12834e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12844e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12854e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12864e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12874e220ebcSLois Curfman McInnes   if (A->factor) {
12884e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12894e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12904e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12914e220ebcSLois Curfman McInnes   } else {
12924e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12934e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12944e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12954e220ebcSLois Curfman McInnes   }
12963a40ed3dSBarry Smith   PetscFunctionReturn(0);
129717ab2063SBarry Smith }
129817ab2063SBarry Smith 
1299b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1300ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1301b9b97703SBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*);
1302ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1303ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1304ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1305ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
130617ab2063SBarry Smith 
13074a2ae208SSatish Balay #undef __FUNCT__
13084a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
130987828ca2SBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,PetscScalar *diag)
131017ab2063SBarry Smith {
1311416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1312273d9f13SBarry Smith   int         i,ierr,N,*rows,m = A->m - 1,shift = a->indexshift;
131317ab2063SBarry Smith 
13143a40ed3dSBarry Smith   PetscFunctionBegin;
1315b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
131617ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1317f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1318f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
131929bbc08cSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
132087828ca2SBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1321f1e2ffcdSBarry Smith     }
1322f1e2ffcdSBarry Smith     if (diag) {
1323f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1324f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1325f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1326f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1327f1e2ffcdSBarry Smith       }
1328f1e2ffcdSBarry Smith     }
1329f1e2ffcdSBarry Smith   } else {
133017ab2063SBarry Smith     if (diag) {
133117ab2063SBarry Smith       for (i=0; i<N; i++) {
133229bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
13337ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1334416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1335416022c9SBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1336416022c9SBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
13377ae801bdSBarry Smith         } else { /* in case row was completely empty */
1338d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
133917ab2063SBarry Smith         }
134017ab2063SBarry Smith       }
13413a40ed3dSBarry Smith     } else {
134217ab2063SBarry Smith       for (i=0; i<N; i++) {
134329bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
1344416022c9SBarry Smith         a->ilen[rows[i]] = 0;
134517ab2063SBarry Smith       }
134617ab2063SBarry Smith     }
1347f1e2ffcdSBarry Smith   }
13487ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
134943a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13503a40ed3dSBarry Smith   PetscFunctionReturn(0);
135117ab2063SBarry Smith }
135217ab2063SBarry Smith 
13534a2ae208SSatish Balay #undef __FUNCT__
13544a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
135587828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
135617ab2063SBarry Smith {
1357416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1358b0a32e0cSBarry Smith   int        *itmp,i,shift = a->indexshift,ierr;
135917ab2063SBarry Smith 
13603a40ed3dSBarry Smith   PetscFunctionBegin;
1361273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
136217ab2063SBarry Smith 
1363416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1364416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
136517ab2063SBarry Smith   if (idx) {
1366416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13674e093b46SBarry Smith     if (*nz && shift) {
1368b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
136917ab2063SBarry Smith       for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;}
13704e093b46SBarry Smith     } else if (*nz) {
13714e093b46SBarry Smith       *idx = itmp;
137217ab2063SBarry Smith     }
137317ab2063SBarry Smith     else *idx = 0;
137417ab2063SBarry Smith   }
13753a40ed3dSBarry Smith   PetscFunctionReturn(0);
137617ab2063SBarry Smith }
137717ab2063SBarry Smith 
13784a2ae208SSatish Balay #undef __FUNCT__
13794a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
138087828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
138117ab2063SBarry Smith {
13824e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1383606d414cSSatish Balay   int ierr;
13843a40ed3dSBarry Smith 
13853a40ed3dSBarry Smith   PetscFunctionBegin;
1386606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13873a40ed3dSBarry Smith   PetscFunctionReturn(0);
138817ab2063SBarry Smith }
138917ab2063SBarry Smith 
13904a2ae208SSatish Balay #undef __FUNCT__
13914a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1392064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
139317ab2063SBarry Smith {
1394416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
139587828ca2SBarry Smith   PetscScalar  *v = a->a;
139636db0b34SBarry Smith   PetscReal    sum = 0.0;
1397549d3d68SSatish Balay   int          i,j,shift = a->indexshift,ierr;
139817ab2063SBarry Smith 
13993a40ed3dSBarry Smith   PetscFunctionBegin;
140017ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1401416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1402aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
140336db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
140417ab2063SBarry Smith #else
140517ab2063SBarry Smith       sum += (*v)*(*v); v++;
140617ab2063SBarry Smith #endif
140717ab2063SBarry Smith     }
1408064f8208SBarry Smith     *nrm = sqrt(sum);
14093a40ed3dSBarry Smith   } else if (type == NORM_1) {
141036db0b34SBarry Smith     PetscReal *tmp;
1411416022c9SBarry Smith     int    *jj = a->j;
1412b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1413273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1414064f8208SBarry Smith     *nrm = 0.0;
1415416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1416a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
141717ab2063SBarry Smith     }
1418273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1419064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
142017ab2063SBarry Smith     }
1421606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
14223a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1423064f8208SBarry Smith     *nrm = 0.0;
1424273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1425416022c9SBarry Smith       v = a->a + a->i[j] + shift;
142617ab2063SBarry Smith       sum = 0.0;
1427416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1428cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
142917ab2063SBarry Smith       }
1430064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
143117ab2063SBarry Smith     }
14323a40ed3dSBarry Smith   } else {
143329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
143417ab2063SBarry Smith   }
14353a40ed3dSBarry Smith   PetscFunctionReturn(0);
143617ab2063SBarry Smith }
143717ab2063SBarry Smith 
14384a2ae208SSatish Balay #undef __FUNCT__
14394a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
14408f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
144117ab2063SBarry Smith {
1442416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1443416022c9SBarry Smith   Mat          C;
1444273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
1445273d9f13SBarry Smith   int          shift = a->indexshift;
144687828ca2SBarry Smith   PetscScalar  *array = a->a;
144717ab2063SBarry Smith 
14483a40ed3dSBarry Smith   PetscFunctionBegin;
1449273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1450b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1451273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
145217ab2063SBarry Smith   if (shift) {
145317ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] -= 1;
145417ab2063SBarry Smith   }
145517ab2063SBarry Smith   for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1;
1456273d9f13SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr);
1457606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
145817ab2063SBarry Smith   for (i=0; i<m; i++) {
145917ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1460416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1461b9b97703SBarry Smith     array += len;
1462b9b97703SBarry Smith     aj    += len;
146317ab2063SBarry Smith   }
146417ab2063SBarry Smith   if (shift) {
146517ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] += 1;
146617ab2063SBarry Smith   }
146717ab2063SBarry Smith 
14686d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14696d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
147017ab2063SBarry Smith 
1471f1e2ffcdSBarry Smith   if (B) {
1472416022c9SBarry Smith     *B = C;
147317ab2063SBarry Smith   } else {
1474273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
147517ab2063SBarry Smith   }
14763a40ed3dSBarry Smith   PetscFunctionReturn(0);
147717ab2063SBarry Smith }
147817ab2063SBarry Smith 
14794a2ae208SSatish Balay #undef __FUNCT__
14804a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14818f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
148217ab2063SBarry Smith {
1483416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
148487828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1485273d9f13SBarry Smith   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj,shift = a->indexshift;
148617ab2063SBarry Smith 
14873a40ed3dSBarry Smith   PetscFunctionBegin;
148817ab2063SBarry Smith   if (ll) {
14893ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14903ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1491e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1492273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
1493e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1494416022c9SBarry Smith     v = a->a;
149517ab2063SBarry Smith     for (i=0; i<m; i++) {
149617ab2063SBarry Smith       x = l[i];
1497416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
149817ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
149917ab2063SBarry Smith     }
1500e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1501b0a32e0cSBarry Smith     PetscLogFlops(nz);
150217ab2063SBarry Smith   }
150317ab2063SBarry Smith   if (rr) {
1504e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1505273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
1506e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1507416022c9SBarry Smith     v = a->a; jj = a->j;
150817ab2063SBarry Smith     for (i=0; i<nz; i++) {
150917ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
151017ab2063SBarry Smith     }
1511e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1512b0a32e0cSBarry Smith     PetscLogFlops(nz);
151317ab2063SBarry Smith   }
15143a40ed3dSBarry Smith   PetscFunctionReturn(0);
151517ab2063SBarry Smith }
151617ab2063SBarry Smith 
15174a2ae208SSatish Balay #undef __FUNCT__
15184a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
15197b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
152017ab2063SBarry Smith {
1521db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1522273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
152336db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
152499141d43SSatish Balay   int          *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap;
152599141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
152687828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1527416022c9SBarry Smith   Mat          C;
1528fee21e36SBarry Smith   PetscTruth   stride;
152917ab2063SBarry Smith 
15303a40ed3dSBarry Smith   PetscFunctionBegin;
1531d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
153229bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1533d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
153429bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
153599141d43SSatish Balay 
153617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1537b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1538b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
153917ab2063SBarry Smith 
1540fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1541fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1542fee21e36SBarry Smith   if (stride && step == 1) {
154302834360SBarry Smith     /* special case of contiguous rows */
154431ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
154531ebf83bSSatish Balay     starts = lens + nrows;
154602834360SBarry Smith     /* loop over new rows determining lens and starting points */
154702834360SBarry Smith     for (i=0; i<nrows; i++) {
1548a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1549a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
155002834360SBarry Smith       for (k=kstart; k<kend; k++) {
1551d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
155202834360SBarry Smith           starts[i] = k;
155302834360SBarry Smith           break;
155402834360SBarry Smith 	}
155502834360SBarry Smith       }
1556a2744918SBarry Smith       sum = 0;
155702834360SBarry Smith       while (k < kend) {
1558d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1559a2744918SBarry Smith         sum++;
156002834360SBarry Smith       }
1561a2744918SBarry Smith       lens[i] = sum;
156202834360SBarry Smith     }
156302834360SBarry Smith     /* create submatrix */
1564cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
156508480c60SBarry Smith       int n_cols,n_rows;
156608480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
156729bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1568d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
156908480c60SBarry Smith       C = *B;
15703a40ed3dSBarry Smith     } else {
157102834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
157208480c60SBarry Smith     }
1573db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1574db02288aSLois Curfman McInnes 
157502834360SBarry Smith     /* loop over rows inserting into submatrix */
1576db02288aSLois Curfman McInnes     a_new    = c->a;
1577db02288aSLois Curfman McInnes     j_new    = c->j;
1578db02288aSLois Curfman McInnes     i_new    = c->i;
1579db02288aSLois Curfman McInnes     i_new[0] = -shift;
158002834360SBarry Smith     for (i=0; i<nrows; i++) {
1581a2744918SBarry Smith       ii    = starts[i];
1582a2744918SBarry Smith       lensi = lens[i];
1583a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1584a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
158502834360SBarry Smith       }
158687828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1587a2744918SBarry Smith       a_new      += lensi;
1588a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1589a2744918SBarry Smith       c->ilen[i]  = lensi;
159002834360SBarry Smith     }
1591606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15923a40ed3dSBarry Smith   } else {
159302834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1594b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
159502834360SBarry Smith     ssmap = smap + shift;
1596b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1597549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
159817ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
159902834360SBarry Smith     /* determine lens of each row */
160002834360SBarry Smith     for (i=0; i<nrows; i++) {
1601d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
160202834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
160302834360SBarry Smith       lens[i] = 0;
160402834360SBarry Smith       for (k=kstart; k<kend; k++) {
1605d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
160602834360SBarry Smith           lens[i]++;
160702834360SBarry Smith         }
160802834360SBarry Smith       }
160902834360SBarry Smith     }
161017ab2063SBarry Smith     /* Create and fill new matrix */
1611a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16120f5bd95cSBarry Smith       PetscTruth equal;
16130f5bd95cSBarry Smith 
161499141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1615273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1616273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
16170f5bd95cSBarry Smith       if (!equal) {
161829bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
161999141d43SSatish Balay       }
1620273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
162108480c60SBarry Smith       C = *B;
16223a40ed3dSBarry Smith     } else {
162302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
162408480c60SBarry Smith     }
162599141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
162617ab2063SBarry Smith     for (i=0; i<nrows; i++) {
162799141d43SSatish Balay       row    = irow[i];
162899141d43SSatish Balay       kstart = ai[row]+shift;
162999141d43SSatish Balay       kend   = kstart + a->ilen[row];
163099141d43SSatish Balay       mat_i  = c->i[i]+shift;
163199141d43SSatish Balay       mat_j  = c->j + mat_i;
163299141d43SSatish Balay       mat_a  = c->a + mat_i;
163399141d43SSatish Balay       mat_ilen = c->ilen + i;
163417ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
163599141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
163699141d43SSatish Balay           *mat_j++ = tcol - (!shift);
163799141d43SSatish Balay           *mat_a++ = a->a[k];
163899141d43SSatish Balay           (*mat_ilen)++;
163999141d43SSatish Balay 
164017ab2063SBarry Smith         }
164117ab2063SBarry Smith       }
164217ab2063SBarry Smith     }
164302834360SBarry Smith     /* Free work space */
164402834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1645606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1646606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
164702834360SBarry Smith   }
16486d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16496d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
165017ab2063SBarry Smith 
165117ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1652416022c9SBarry Smith   *B = C;
16533a40ed3dSBarry Smith   PetscFunctionReturn(0);
165417ab2063SBarry Smith }
165517ab2063SBarry Smith 
1656a871dcd8SBarry Smith /*
1657a871dcd8SBarry Smith */
16584a2ae208SSatish Balay #undef __FUNCT__
16594a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
16605ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1661a871dcd8SBarry Smith {
166263b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
166308480c60SBarry Smith   int        ierr;
166463b91edcSBarry Smith   Mat        outA;
1665b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
166663b91edcSBarry Smith 
16673a40ed3dSBarry Smith   PetscFunctionBegin;
166829bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1669b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1670b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1671b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
167229bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1673b8a78c4aSBarry Smith   }
1674a871dcd8SBarry Smith 
167563b91edcSBarry Smith   outA          = inA;
167663b91edcSBarry Smith   inA->factor   = FACTOR_LU;
167763b91edcSBarry Smith   a->row        = row;
167863b91edcSBarry Smith   a->col        = col;
1679c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1680c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
168163b91edcSBarry Smith 
168236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1683b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16844c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1685b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1686f0ec6fceSSatish Balay 
168794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
168887828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
168994a9d846SBarry Smith   }
169063b91edcSBarry Smith 
169108480c60SBarry Smith   if (!a->diag) {
1692f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
169363b91edcSBarry Smith   }
169463b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16953a40ed3dSBarry Smith   PetscFunctionReturn(0);
1696a871dcd8SBarry Smith }
1697a871dcd8SBarry Smith 
1698d9eff348SSatish Balay #include "petscblaslapack.h"
16994a2ae208SSatish Balay #undef __FUNCT__
17004a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
170187828ca2SBarry Smith int MatScale_SeqAIJ(PetscScalar *alpha,Mat inA)
1702f0b747eeSBarry Smith {
1703f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1704f0b747eeSBarry Smith   int        one = 1;
17053a40ed3dSBarry Smith 
17063a40ed3dSBarry Smith   PetscFunctionBegin;
1707f0b747eeSBarry Smith   BLscal_(&a->nz,alpha,a->a,&one);
1708b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
17093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1710f0b747eeSBarry Smith }
1711f0b747eeSBarry Smith 
17124a2ae208SSatish Balay #undef __FUNCT__
17134a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
17147b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1715cddf8d76SBarry Smith {
1716cddf8d76SBarry Smith   int ierr,i;
1717cddf8d76SBarry Smith 
17183a40ed3dSBarry Smith   PetscFunctionBegin;
1719cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1720b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1721cddf8d76SBarry Smith   }
1722cddf8d76SBarry Smith 
1723cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17246a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1725cddf8d76SBarry Smith   }
17263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1727cddf8d76SBarry Smith }
1728cddf8d76SBarry Smith 
17294a2ae208SSatish Balay #undef __FUNCT__
17304a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17318f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17325a838052SSatish Balay {
1733f830108cSBarry Smith   PetscFunctionBegin;
17345a838052SSatish Balay   *bs = 1;
17353a40ed3dSBarry Smith   PetscFunctionReturn(0);
17365a838052SSatish Balay }
17375a838052SSatish Balay 
17384a2ae208SSatish Balay #undef __FUNCT__
17394a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
17408f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov)
17414dcbc457SBarry Smith {
1742e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
174306763907SSatish Balay   int        shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17448a047759SSatish Balay   int        start,end,*ai,*aj;
1745f1af5d2fSBarry Smith   PetscBT    table;
1746bbd702dbSSatish Balay 
17473a40ed3dSBarry Smith   PetscFunctionBegin;
17488a047759SSatish Balay   shift = a->indexshift;
1749273d9f13SBarry Smith   m     = A->m;
1750e4d965acSSatish Balay   ai    = a->i;
17518a047759SSatish Balay   aj    = a->j+shift;
17528a047759SSatish Balay 
175329bbc08cSBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used");
175406763907SSatish Balay 
1755b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17566831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
175706763907SSatish Balay 
1758e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1759b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1760e4d965acSSatish Balay     isz  = 0;
17616831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1762e4d965acSSatish Balay 
1763e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17644dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1765b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1766e4d965acSSatish Balay 
1767dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1768e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1769f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17704dcbc457SBarry Smith     }
177106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
177206763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1773e4d965acSSatish Balay 
177404a348a9SBarry Smith     k = 0;
177504a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
177604a348a9SBarry Smith       n = isz;
177706763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1778e4d965acSSatish Balay         row   = nidx[k];
1779e4d965acSSatish Balay         start = ai[row];
1780e4d965acSSatish Balay         end   = ai[row+1];
178104a348a9SBarry Smith         for (l = start; l<end ; l++){
17828a047759SSatish Balay           val = aj[l] + shift;
1783f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1784e4d965acSSatish Balay         }
1785e4d965acSSatish Balay       }
1786e4d965acSSatish Balay     }
1787029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1788e4d965acSSatish Balay   }
17896831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1790606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17913a40ed3dSBarry Smith   PetscFunctionReturn(0);
17924dcbc457SBarry Smith }
179317ab2063SBarry Smith 
17940513a670SBarry Smith /* -------------------------------------------------------------- */
17954a2ae208SSatish Balay #undef __FUNCT__
17964a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17970513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17980513a670SBarry Smith {
17990513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
180087828ca2SBarry Smith   PetscScalar  *vwork;
1801273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
18020513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
180356cd22aeSBarry Smith   IS           icolp,irowp;
18040513a670SBarry Smith 
18053a40ed3dSBarry Smith   PetscFunctionBegin;
18064c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
180756cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18084c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
180956cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18100513a670SBarry Smith 
18110513a670SBarry Smith   /* determine lengths of permuted rows */
1812b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
18130513a670SBarry Smith   for (i=0; i<m; i++) {
18140513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18150513a670SBarry Smith   }
18160513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1817606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18180513a670SBarry Smith 
1819b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18200513a670SBarry Smith   for (i=0; i<m; i++) {
18210513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18220513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18230513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18240513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18250513a670SBarry Smith   }
1826606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18270513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18280513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
182956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
183056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
183156cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
183256cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18333a40ed3dSBarry Smith   PetscFunctionReturn(0);
18340513a670SBarry Smith }
18350513a670SBarry Smith 
18364a2ae208SSatish Balay #undef __FUNCT__
18374a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1838682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1839682d7d0cSBarry Smith {
1840c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1841682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1842d132466eSBarry Smith   int               ierr;
1843682d7d0cSBarry Smith 
18443a40ed3dSBarry Smith   PetscFunctionBegin;
1845c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1846d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1847d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1848d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1849d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1850d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1851aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1852d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1853682d7d0cSBarry Smith #endif
1854cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL)
1855cd5578b5SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr);
1856cd5578b5SBarry Smith #endif
185787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
1858ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1859ca44d042SBarry Smith #endif
18603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1861682d7d0cSBarry Smith }
1862ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1863ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1864ca44d042SBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*);
18654a2ae208SSatish Balay #undef __FUNCT__
18664a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1867cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1868cb5b572fSBarry Smith {
1869be6bf707SBarry Smith   int        ierr;
1870273d9f13SBarry Smith   PetscTruth flg;
1871cb5b572fSBarry Smith 
1872cb5b572fSBarry Smith   PetscFunctionBegin;
1873273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr);
1874273d9f13SBarry Smith   if (str == SAME_NONZERO_PATTERN && flg) {
1875be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1876be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1877be6bf707SBarry Smith 
1878273d9f13SBarry Smith     if (a->i[A->m]+a->indexshift != b->i[B->m]+a->indexshift) {
187929bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1880cb5b572fSBarry Smith     }
188187828ca2SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
1882cb5b572fSBarry Smith   } else {
1883cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1884cb5b572fSBarry Smith   }
1885cb5b572fSBarry Smith   PetscFunctionReturn(0);
1886cb5b572fSBarry Smith }
1887cb5b572fSBarry Smith 
18884a2ae208SSatish Balay #undef __FUNCT__
18894a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1890273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1891273d9f13SBarry Smith {
1892273d9f13SBarry Smith   int        ierr;
1893273d9f13SBarry Smith 
1894273d9f13SBarry Smith   PetscFunctionBegin;
1895273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1896273d9f13SBarry Smith   PetscFunctionReturn(0);
1897273d9f13SBarry Smith }
1898273d9f13SBarry Smith 
18994a2ae208SSatish Balay #undef __FUNCT__
19004a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
190187828ca2SBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar **array)
19026c0721eeSBarry Smith {
19036c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19046c0721eeSBarry Smith   PetscFunctionBegin;
19056c0721eeSBarry Smith   *array = a->a;
19066c0721eeSBarry Smith   PetscFunctionReturn(0);
19076c0721eeSBarry Smith }
19086c0721eeSBarry Smith 
19094a2ae208SSatish Balay #undef __FUNCT__
19104a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
191187828ca2SBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar **array)
19126c0721eeSBarry Smith {
19136c0721eeSBarry Smith   PetscFunctionBegin;
19146c0721eeSBarry Smith   PetscFunctionReturn(0);
19156c0721eeSBarry Smith }
1916273d9f13SBarry Smith 
1917ee4f033dSBarry Smith #undef __FUNCT__
1918ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1919ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1920ee4f033dSBarry Smith {
1921ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1922ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
192387828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
192487828ca2SBarry Smith   PetscScalar   *vscale_array;
1925ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1926ee4f033dSBarry Smith   Vec           w1,w2,w3;
1927ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1928ee4f033dSBarry Smith   PetscTruth    flg;
1929ee4f033dSBarry Smith 
1930ee4f033dSBarry Smith   PetscFunctionBegin;
1931ee4f033dSBarry Smith   if (!coloring->w1) {
1932ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1933ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1934ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1935ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1936ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1937ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1938ee4f033dSBarry Smith   }
1939ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1940ee4f033dSBarry Smith 
1941ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1942ee4f033dSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1943ee4f033dSBarry Smith   if (flg) {
1944ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1945ee4f033dSBarry Smith   } else {
1946ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1947ee4f033dSBarry Smith   }
1948ee4f033dSBarry Smith 
1949ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1950ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1951ee4f033dSBarry Smith 
1952ee4f033dSBarry Smith   /*
1953ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1954ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1955ee4f033dSBarry Smith   */
1956ee4f033dSBarry Smith   if (coloring->F) {
1957ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1958ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1959ee4f033dSBarry Smith     if (m1 != m2) {
1960ee4f033dSBarry Smith       coloring->F = 0;
1961ee4f033dSBarry Smith     }
1962ee4f033dSBarry Smith   }
1963ee4f033dSBarry Smith 
1964ee4f033dSBarry Smith   if (coloring->F) {
1965ee4f033dSBarry Smith     w1          = coloring->F;
1966ee4f033dSBarry Smith     coloring->F = 0;
1967ee4f033dSBarry Smith   } else {
1968ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
1969ee4f033dSBarry Smith   }
1970ee4f033dSBarry Smith 
1971ee4f033dSBarry Smith   /*
1972ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1973ee4f033dSBarry Smith   */
1974ee4f033dSBarry Smith   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
1975ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1976ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1977ee4f033dSBarry Smith     /*
1978ee4f033dSBarry Smith        Loop over each column associated with color adding the
1979ee4f033dSBarry Smith        perturbation to the vector w3.
1980ee4f033dSBarry Smith     */
1981ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1982ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1983ee4f033dSBarry Smith       dx  = xx[col];
1984ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1985ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1986ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1987ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1988ee4f033dSBarry Smith #else
1989ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1990ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1991ee4f033dSBarry Smith #endif
1992ee4f033dSBarry Smith       dx                *= epsilon;
1993ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1994ee4f033dSBarry Smith     }
1995ee4f033dSBarry Smith   }
1996ee4f033dSBarry Smith   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1997ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1998ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1999ee4f033dSBarry Smith 
2000ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2001ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2002ee4f033dSBarry Smith 
2003ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2004ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2005ee4f033dSBarry Smith 
2006ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2007ee4f033dSBarry Smith   /*
2008ee4f033dSBarry Smith       Loop over each color
2009ee4f033dSBarry Smith   */
2010ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2011ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
2012ee4f033dSBarry Smith     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2013ee4f033dSBarry Smith     /*
2014ee4f033dSBarry Smith        Loop over each column associated with color adding the
2015ee4f033dSBarry Smith        perturbation to the vector w3.
2016ee4f033dSBarry Smith     */
2017ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2018ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2019ee4f033dSBarry Smith       dx  = xx[col];
2020ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2021ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2022ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2023ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2024ee4f033dSBarry Smith #else
2025ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2026ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2027ee4f033dSBarry Smith #endif
2028ee4f033dSBarry Smith       dx            *= epsilon;
2029ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2030ee4f033dSBarry Smith       w3_array[col] += dx;
2031ee4f033dSBarry Smith     }
2032ee4f033dSBarry Smith     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2033ee4f033dSBarry Smith 
2034ee4f033dSBarry Smith     /*
2035ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2036ee4f033dSBarry Smith     */
2037ee4f033dSBarry Smith 
2038ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
2039ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2040ee4f033dSBarry Smith 
2041ee4f033dSBarry Smith     /*
2042ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2043ee4f033dSBarry Smith     */
2044ee4f033dSBarry Smith     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2045ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2046ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2047ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2048ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2049ee4f033dSBarry Smith       srow   = row + start;
2050ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2051ee4f033dSBarry Smith     }
2052ee4f033dSBarry Smith     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2053ee4f033dSBarry Smith   }
2054ee4f033dSBarry Smith   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2055ee4f033dSBarry Smith   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2056ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2057ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2058ee4f033dSBarry Smith   PetscFunctionReturn(0);
2059ee4f033dSBarry Smith }
2060ee4f033dSBarry Smith 
2061ac90fabeSBarry Smith #include "petscblaslapack.h"
2062ac90fabeSBarry Smith 
2063ac90fabeSBarry Smith #undef __FUNCT__
2064ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2065ac90fabeSBarry Smith int MatAXPY_SeqAIJ(PetscScalar *a,Mat X,Mat Y,MatStructure str)
2066ac90fabeSBarry Smith {
2067556bd4faSSatish Balay   int        ierr,one=1;
2068ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2069ac90fabeSBarry Smith 
2070ac90fabeSBarry Smith   PetscFunctionBegin;
2071ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2072ac90fabeSBarry Smith     BLaxpy_(&x->nz,a,x->a,&one,y->a,&one);
2073ac90fabeSBarry Smith   } else {
2074ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2075ac90fabeSBarry Smith   }
2076ac90fabeSBarry Smith   PetscFunctionReturn(0);
2077ac90fabeSBarry Smith }
2078ac90fabeSBarry Smith 
2079ac90fabeSBarry Smith 
2080682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20810a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2082cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2083cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2084cb5b572fSBarry Smith        MatMult_SeqAIJ,
2085cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
20867c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20877c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2088cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2089cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20907c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
20917c922b88SBarry Smith        MatSolveTransposeAdd_SeqAIJ,
2092cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2093cb5b572fSBarry Smith        0,
209417ab2063SBarry Smith        MatRelax_SeqAIJ,
209517ab2063SBarry Smith        MatTranspose_SeqAIJ,
2096cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
2097cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2098cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2099cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2100cb5b572fSBarry Smith        MatNorm_SeqAIJ,
2101cb5b572fSBarry Smith        0,
2102cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
210317ab2063SBarry Smith        MatCompress_SeqAIJ,
2104cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2105cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2106cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
2107cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2108cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2109cb5b572fSBarry Smith        0,
2110cb5b572fSBarry Smith        0,
2111273d9f13SBarry Smith        MatSetUpPreallocation_SeqAIJ,
2112cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2113cb5b572fSBarry Smith        0,
21146c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21156c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2116be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
2117cb5b572fSBarry Smith        0,
2118cb5b572fSBarry Smith        0,
2119cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2120cb5b572fSBarry Smith        0,
2121ac90fabeSBarry Smith        MatAXPY_SeqAIJ,
2122cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2123cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2124cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2125cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2126f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
2127cb5b572fSBarry Smith        MatScale_SeqAIJ,
2128cb5b572fSBarry Smith        0,
2129cb5b572fSBarry Smith        0,
21306945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
21316945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
21323b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21333b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21343b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2135a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2136a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
2137b9617806SBarry Smith        0,
21380513a670SBarry Smith        0,
2139cda55fadSBarry Smith        MatPermute_SeqAIJ,
2140cda55fadSBarry Smith        0,
2141cda55fadSBarry Smith        0,
2142b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2143b9b97703SBarry Smith        MatView_SeqAIJ,
21448a124369SBarry Smith        MatGetPetscMaps_Petsc,
2145ee4f033dSBarry Smith        0,
2146ee4f033dSBarry Smith        0,
2147ee4f033dSBarry Smith        0,
2148ee4f033dSBarry Smith        0,
2149ee4f033dSBarry Smith        0,
2150ee4f033dSBarry Smith        0,
2151ee4f033dSBarry Smith        0,
2152ee4f033dSBarry Smith        0,
2153ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2154ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2155ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
2156ee4f033dSBarry Smith        MatFDColoringApply_SeqAIJ};
215717ab2063SBarry Smith 
2158ca44d042SBarry Smith EXTERN int MatUseSuperLU_SeqAIJ(Mat);
2159ca44d042SBarry Smith EXTERN int MatUseEssl_SeqAIJ(Mat);
2160cd5578b5SBarry Smith EXTERN int MatUseLUSOL_SeqAIJ(Mat);
2161ca44d042SBarry Smith EXTERN int MatUseMatlab_SeqAIJ(Mat);
2162ca44d042SBarry Smith EXTERN int MatUseDXML_SeqAIJ(Mat);
216317ab2063SBarry Smith 
2164fb2e594dSBarry Smith EXTERN_C_BEGIN
21654a2ae208SSatish Balay #undef __FUNCT__
21664a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
216715091d37SBarry Smith 
2168bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2169bef8e0ddSBarry Smith {
2170bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2171bef8e0ddSBarry Smith   int        i,nz,n;
2172bef8e0ddSBarry Smith 
2173bef8e0ddSBarry Smith   PetscFunctionBegin;
2174bef8e0ddSBarry Smith 
2175bef8e0ddSBarry Smith   nz = aij->maxnz;
2176273d9f13SBarry Smith   n  = mat->n;
2177bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2178bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2179bef8e0ddSBarry Smith   }
2180bef8e0ddSBarry Smith   aij->nz = nz;
2181bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2182bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2183bef8e0ddSBarry Smith   }
2184bef8e0ddSBarry Smith 
2185bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2186bef8e0ddSBarry Smith }
2187fb2e594dSBarry Smith EXTERN_C_END
2188bef8e0ddSBarry Smith 
21894a2ae208SSatish Balay #undef __FUNCT__
21904a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2191bef8e0ddSBarry Smith /*@
2192bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2193bef8e0ddSBarry Smith        in the matrix.
2194bef8e0ddSBarry Smith 
2195bef8e0ddSBarry Smith   Input Parameters:
2196bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2197bef8e0ddSBarry Smith -  indices - the column indices
2198bef8e0ddSBarry Smith 
219915091d37SBarry Smith   Level: advanced
220015091d37SBarry Smith 
2201bef8e0ddSBarry Smith   Notes:
2202bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2203bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2204bef8e0ddSBarry Smith   of the MatSetValues() operation.
2205bef8e0ddSBarry Smith 
2206bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2207bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2208bef8e0ddSBarry Smith 
2209bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2210bef8e0ddSBarry Smith 
2211b9617806SBarry Smith     The indices should start with zero, not one.
2212b9617806SBarry Smith 
2213bef8e0ddSBarry Smith @*/
2214bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2215bef8e0ddSBarry Smith {
2216bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2217bef8e0ddSBarry Smith 
2218bef8e0ddSBarry Smith   PetscFunctionBegin;
2219bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2220c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2221bef8e0ddSBarry Smith   if (f) {
2222bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2223bef8e0ddSBarry Smith   } else {
222429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2225bef8e0ddSBarry Smith   }
2226bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2227bef8e0ddSBarry Smith }
2228bef8e0ddSBarry Smith 
2229be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2230be6bf707SBarry Smith 
2231fb2e594dSBarry Smith EXTERN_C_BEGIN
22324a2ae208SSatish Balay #undef __FUNCT__
22334a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2234be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2235be6bf707SBarry Smith {
2236be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2237273d9f13SBarry Smith   int        nz = aij->i[mat->m]+aij->indexshift,ierr;
2238be6bf707SBarry Smith 
2239be6bf707SBarry Smith   PetscFunctionBegin;
2240be6bf707SBarry Smith   if (aij->nonew != 1) {
224129bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2242be6bf707SBarry Smith   }
2243be6bf707SBarry Smith 
2244be6bf707SBarry Smith   /* allocate space for values if not already there */
2245be6bf707SBarry Smith   if (!aij->saved_values) {
224687828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2247be6bf707SBarry Smith   }
2248be6bf707SBarry Smith 
2249be6bf707SBarry Smith   /* copy values over */
225087828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2251be6bf707SBarry Smith   PetscFunctionReturn(0);
2252be6bf707SBarry Smith }
2253fb2e594dSBarry Smith EXTERN_C_END
2254be6bf707SBarry Smith 
22554a2ae208SSatish Balay #undef __FUNCT__
2256b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2257be6bf707SBarry Smith /*@
2258be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2259be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2260be6bf707SBarry Smith        nonlinear portion.
2261be6bf707SBarry Smith 
2262be6bf707SBarry Smith    Collect on Mat
2263be6bf707SBarry Smith 
2264be6bf707SBarry Smith   Input Parameters:
2265be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2266be6bf707SBarry Smith 
226715091d37SBarry Smith   Level: advanced
226815091d37SBarry Smith 
2269be6bf707SBarry Smith   Common Usage, with SNESSolve():
2270be6bf707SBarry Smith $    Create Jacobian matrix
2271be6bf707SBarry Smith $    Set linear terms into matrix
2272be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2273be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2274be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2275be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2276be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2277be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2278be6bf707SBarry Smith $    In your Jacobian routine
2279be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2280be6bf707SBarry Smith $      Set nonlinear terms in matrix
2281be6bf707SBarry Smith 
2282be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2283be6bf707SBarry Smith $    // build linear portion of Jacobian
2284be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2285be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2286be6bf707SBarry Smith $    loop over nonlinear iterations
2287be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2288be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2289be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2290be6bf707SBarry Smith $       Solve linear system with Jacobian
2291be6bf707SBarry Smith $    endloop
2292be6bf707SBarry Smith 
2293be6bf707SBarry Smith   Notes:
2294be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2295be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2296be6bf707SBarry Smith     calling this routine.
2297be6bf707SBarry Smith 
2298be6bf707SBarry Smith .seealso: MatRetrieveValues()
2299be6bf707SBarry Smith 
2300be6bf707SBarry Smith @*/
2301be6bf707SBarry Smith int MatStoreValues(Mat mat)
2302be6bf707SBarry Smith {
2303be6bf707SBarry Smith   int ierr,(*f)(Mat);
2304be6bf707SBarry Smith 
2305be6bf707SBarry Smith   PetscFunctionBegin;
2306be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
230729bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
230829bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309be6bf707SBarry Smith 
2310c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2311be6bf707SBarry Smith   if (f) {
2312be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2313be6bf707SBarry Smith   } else {
231429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2315be6bf707SBarry Smith   }
2316be6bf707SBarry Smith   PetscFunctionReturn(0);
2317be6bf707SBarry Smith }
2318be6bf707SBarry Smith 
2319fb2e594dSBarry Smith EXTERN_C_BEGIN
23204a2ae208SSatish Balay #undef __FUNCT__
23214a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2322be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2323be6bf707SBarry Smith {
2324be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2325273d9f13SBarry Smith   int        nz = aij->i[mat->m]+aij->indexshift,ierr;
2326be6bf707SBarry Smith 
2327be6bf707SBarry Smith   PetscFunctionBegin;
2328be6bf707SBarry Smith   if (aij->nonew != 1) {
232929bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2330be6bf707SBarry Smith   }
2331be6bf707SBarry Smith   if (!aij->saved_values) {
233229bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2333be6bf707SBarry Smith   }
2334be6bf707SBarry Smith 
2335be6bf707SBarry Smith   /* copy values over */
233687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2337be6bf707SBarry Smith   PetscFunctionReturn(0);
2338be6bf707SBarry Smith }
2339fb2e594dSBarry Smith EXTERN_C_END
2340be6bf707SBarry Smith 
23414a2ae208SSatish Balay #undef __FUNCT__
23424a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2343be6bf707SBarry Smith /*@
2344be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2345be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2346be6bf707SBarry Smith        nonlinear portion.
2347be6bf707SBarry Smith 
2348be6bf707SBarry Smith    Collect on Mat
2349be6bf707SBarry Smith 
2350be6bf707SBarry Smith   Input Parameters:
2351be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2352be6bf707SBarry Smith 
235315091d37SBarry Smith   Level: advanced
235415091d37SBarry Smith 
2355be6bf707SBarry Smith .seealso: MatStoreValues()
2356be6bf707SBarry Smith 
2357be6bf707SBarry Smith @*/
2358be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2359be6bf707SBarry Smith {
2360be6bf707SBarry Smith   int ierr,(*f)(Mat);
2361be6bf707SBarry Smith 
2362be6bf707SBarry Smith   PetscFunctionBegin;
2363be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
236429bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
236529bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2366be6bf707SBarry Smith 
2367c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2368be6bf707SBarry Smith   if (f) {
2369be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2370be6bf707SBarry Smith   } else {
237129bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2372be6bf707SBarry Smith   }
2373be6bf707SBarry Smith   PetscFunctionReturn(0);
2374be6bf707SBarry Smith }
2375be6bf707SBarry Smith 
2376f83d6046SBarry Smith /*
2377f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2378f83d6046SBarry Smith */
237987828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2380f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2381f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2382f83d6046SBarry Smith EXTERN_C_BEGIN
23834a2ae208SSatish Balay #undef __FUNCT__
23844a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ"
2385f83d6046SBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine)
2386f83d6046SBarry Smith {
238766826eb6SBarry Smith   int         ierr,i,*ai,*aj;
2388f83d6046SBarry Smith   Mat         B = (Mat)obj;
238987828ca2SBarry Smith   PetscScalar *array;
2390f83d6046SBarry Smith   mxArray     *mat;
2391d79a51d8SBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
2392d79a51d8SBarry Smith 
2393f83d6046SBarry Smith   PetscFunctionBegin;
239401820c62SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
239587828ca2SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
2396d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
239766826eb6SBarry Smith   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
239866826eb6SBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2399f83d6046SBarry Smith 
240001820c62SBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
240101820c62SBarry Smith   if (aij->indexshift) {
240201820c62SBarry Smith     for (i=0; i<B->m+1; i++) {
240301820c62SBarry Smith       ai[i]--;
2404d79a51d8SBarry Smith     }
2405d79a51d8SBarry Smith     for (i=0; i<aij->nz; i++) {
240601820c62SBarry Smith       aj[i]--;
2407d79a51d8SBarry Smith     }
2408d79a51d8SBarry Smith   }
2409ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2410f83d6046SBarry Smith   mxSetName(mat,obj->name);
2411f83d6046SBarry Smith   engPutArray((Engine *)engine,mat);
2412f83d6046SBarry Smith   PetscFunctionReturn(0);
2413f83d6046SBarry Smith }
2414f83d6046SBarry Smith EXTERN_C_END
241566826eb6SBarry Smith 
241666826eb6SBarry Smith EXTERN_C_BEGIN
24174a2ae208SSatish Balay #undef __FUNCT__
24184a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ"
241966826eb6SBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *engine)
242066826eb6SBarry Smith {
242166826eb6SBarry Smith   int        ierr,ii;
242266826eb6SBarry Smith   Mat        mat = (Mat)obj;
242366826eb6SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
242466826eb6SBarry Smith   mxArray    *mmat;
242566826eb6SBarry Smith 
24266c0721eeSBarry Smith   PetscFunctionBegin;
242766826eb6SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
242866826eb6SBarry Smith   aij->indexshift = 0;
242966826eb6SBarry Smith 
243066826eb6SBarry Smith   mmat = engGetArray((Engine *)engine,obj->name);
243166826eb6SBarry Smith 
2432a65776f3SBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->m];
243387828ca2SBarry Smith   ierr              = PetscMalloc(aij->nz*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
243466826eb6SBarry Smith   aij->j            = (int*)(aij->a + aij->nz);
243566826eb6SBarry Smith   aij->i            = aij->j + aij->nz;
243666826eb6SBarry Smith   aij->singlemalloc = PETSC_TRUE;
243766826eb6SBarry Smith   aij->freedata     = PETSC_TRUE;
243866826eb6SBarry Smith 
243987828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
244066826eb6SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
244166826eb6SBarry Smith   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
244266826eb6SBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
244366826eb6SBarry Smith 
244466826eb6SBarry Smith   for (ii=0; ii<mat->m; ii++) {
244566826eb6SBarry Smith     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
244666826eb6SBarry Smith   }
244766826eb6SBarry Smith 
244866826eb6SBarry Smith   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244966826eb6SBarry Smith   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
245066826eb6SBarry Smith 
245166826eb6SBarry Smith   PetscFunctionReturn(0);
245266826eb6SBarry Smith }
245366826eb6SBarry Smith EXTERN_C_END
2454f83d6046SBarry Smith #endif
2455f83d6046SBarry Smith 
2456be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
24574a2ae208SSatish Balay #undef __FUNCT__
24584a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
245917ab2063SBarry Smith /*@C
2460682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
24610d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
24626e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
246351c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
24642bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
246517ab2063SBarry Smith 
2466db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2467db81eaa0SLois Curfman McInnes 
246817ab2063SBarry Smith    Input Parameters:
2469db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
247017ab2063SBarry Smith .  m - number of rows
247117ab2063SBarry Smith .  n - number of columns
247217ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
247351c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
24742bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
247517ab2063SBarry Smith 
247617ab2063SBarry Smith    Output Parameter:
2477416022c9SBarry Smith .  A - the matrix
247817ab2063SBarry Smith 
2479b259b22eSLois Curfman McInnes    Notes:
248017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
248117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24820002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
248344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
248417ab2063SBarry Smith 
248517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2486a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24873d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24886da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
248917ab2063SBarry Smith 
2490682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24914fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2492682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24936c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24946c7ebb05SLois Curfman McInnes 
24956c7ebb05SLois Curfman McInnes    Options Database Keys:
2496db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2497db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2498db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2499db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2500db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
250117ab2063SBarry Smith 
2502027ccd11SLois Curfman McInnes    Level: intermediate
2503027ccd11SLois Curfman McInnes 
250436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
250536db0b34SBarry Smith 
250617ab2063SBarry Smith @*/
2507416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A)
250817ab2063SBarry Smith {
2509273d9f13SBarry Smith   int ierr;
25106945ee14SBarry Smith 
25113a40ed3dSBarry Smith   PetscFunctionBegin;
2512273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2513273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2514273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2515273d9f13SBarry Smith   PetscFunctionReturn(0);
2516273d9f13SBarry Smith }
2517273d9f13SBarry Smith 
25185da197adSKris Buschelman #define SKIP_ALLOCATION -4
25195da197adSKris Buschelman 
25204a2ae208SSatish Balay #undef __FUNCT__
25214a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2522273d9f13SBarry Smith /*@C
2523273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2524273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2525273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2526273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2527273d9f13SBarry Smith 
2528273d9f13SBarry Smith    Collective on MPI_Comm
2529273d9f13SBarry Smith 
2530273d9f13SBarry Smith    Input Parameters:
2531273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2532273d9f13SBarry Smith .  m - number of rows
2533273d9f13SBarry Smith .  n - number of columns
2534273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2535273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2536273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2537273d9f13SBarry Smith 
2538273d9f13SBarry Smith    Output Parameter:
2539273d9f13SBarry Smith .  A - the matrix
2540273d9f13SBarry Smith 
2541273d9f13SBarry Smith    Notes:
2542273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2543273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2544273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2545273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2546273d9f13SBarry Smith 
2547273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2548273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2549273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2550273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2551273d9f13SBarry Smith 
2552273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2553273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2554273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2555273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2556273d9f13SBarry Smith 
2557273d9f13SBarry Smith    Options Database Keys:
2558273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2559273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2560273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2561273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2562273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2563273d9f13SBarry Smith 
2564273d9f13SBarry Smith    Level: intermediate
2565273d9f13SBarry Smith 
2566273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2567273d9f13SBarry Smith 
2568273d9f13SBarry Smith @*/
2569273d9f13SBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,int *nnz)
2570273d9f13SBarry Smith {
2571273d9f13SBarry Smith   Mat_SeqAIJ *b;
2572d827b245SHong Zhang   int        i,len=0,ierr;
2573c461c341SBarry Smith   PetscTruth flg2,skipallocation = PETSC_FALSE;
2574273d9f13SBarry Smith 
2575273d9f13SBarry Smith   PetscFunctionBegin;
2576273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg2);CHKERRQ(ierr);
2577273d9f13SBarry Smith   if (!flg2) PetscFunctionReturn(0);
2578d5d45c9bSBarry Smith 
2579c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2580c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2581c461c341SBarry Smith     nz             = 0;
2582c461c341SBarry Smith   }
2583c461c341SBarry Smith 
2584435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2585435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2586b73539f3SBarry Smith   if (nnz) {
2587273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
258829bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25893a7fca6bSBarry Smith       if (nnz[i] > B->n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->n);
2590b73539f3SBarry Smith     }
2591b73539f3SBarry Smith   }
2592b73539f3SBarry Smith 
2593273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2594273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2595273d9f13SBarry Smith 
2596b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2597273d9f13SBarry Smith   if (!nnz) {
2598435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2599273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2600273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2601273d9f13SBarry Smith     nz = nz*B->m;
2602273d9f13SBarry Smith   } else {
2603273d9f13SBarry Smith     nz = 0;
2604273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2605273d9f13SBarry Smith   }
2606273d9f13SBarry Smith 
2607c461c341SBarry Smith   if (!skipallocation) {
2608273d9f13SBarry Smith     /* allocate the matrix space */
260987828ca2SBarry Smith     len             = nz*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2610b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2611273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2612273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2613273d9f13SBarry Smith     b->i            = b->j + nz;
26145da197adSKris Buschelman     b->i[0] = -b->indexshift;
26155da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26165da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26175da197adSKris Buschelman     }
2618273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2619273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2620c461c341SBarry Smith   } else {
2621c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2622c461c341SBarry Smith   }
2623273d9f13SBarry Smith 
2624273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2625b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2626b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2627273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2628273d9f13SBarry Smith 
2629273d9f13SBarry Smith   b->nz                = 0;
2630273d9f13SBarry Smith   b->maxnz             = nz;
2631273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2632273d9f13SBarry Smith   PetscFunctionReturn(0);
2633273d9f13SBarry Smith }
2634273d9f13SBarry Smith 
2635eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat);
2636eb9c0419SKris Buschelman 
2637273d9f13SBarry Smith EXTERN_C_BEGIN
26384a2ae208SSatish Balay #undef __FUNCT__
26394a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2640273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2641273d9f13SBarry Smith {
2642273d9f13SBarry Smith   Mat_SeqAIJ *b;
2643273d9f13SBarry Smith   int        ierr,size;
2644273d9f13SBarry Smith   PetscTruth flg;
2645273d9f13SBarry Smith 
2646273d9f13SBarry Smith   PetscFunctionBegin;
2647273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2648273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2649273d9f13SBarry Smith 
2650273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2651273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2652273d9f13SBarry Smith 
2653b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2654b0a32e0cSBarry Smith   B->data             = (void*)b;
2655549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2656549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2657416022c9SBarry Smith   B->factor           = 0;
2658416022c9SBarry Smith   B->lupivotthreshold = 1.0;
265990f02eecSBarry Smith   B->mapping          = 0;
266087828ca2SBarry Smith   ierr = PetscOptionsGetReal(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2661b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2662416022c9SBarry Smith   b->row              = 0;
2663416022c9SBarry Smith   b->col              = 0;
266482bf6240SBarry Smith   b->icol             = 0;
2665416022c9SBarry Smith   b->indexshift       = 0;
2666b810aeb4SBarry Smith   b->reallocs         = 0;
2667b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr);
266869957df2SSatish Balay   if (flg) b->indexshift = -1;
266917ab2063SBarry Smith 
26708a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26718a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2672a5ae1ecdSBarry Smith 
2673f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
267436db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2675f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2676416022c9SBarry Smith   b->nonew             = 0;
2677416022c9SBarry Smith   b->diag              = 0;
2678416022c9SBarry Smith   b->solve_work        = 0;
26792a1b7f2aSHong Zhang   B->spptr             = 0;
2680b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2681754ec7b1SSatish Balay   b->inode.node_count  = 0;
2682754ec7b1SSatish Balay   b->inode.size        = 0;
26836c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26846c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2685be6bf707SBarry Smith   b->saved_values      = 0;
2686d7f994e1SBarry Smith   b->idiag             = 0;
2687d7f994e1SBarry Smith   b->ssor              = 0;
2688f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
268917ab2063SBarry Smith 
269035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
269135d8aa7fSBarry Smith 
2692aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
2693b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr);
269469957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
26954b14c69eSBarry Smith #endif
2696564e58d6SHong Zhang 
2697b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr);
269869957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
2699b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_lusol",&flg);CHKERRQ(ierr);
2700cd5578b5SBarry Smith   if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); }
2701b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2702ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2703b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr);
270469957df2SSatish Balay   if (flg) {
270529bbc08cSBarry Smith     if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,"need -mat_aij_oneindex with -mat_aij_dxml");
2706416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
270717ab2063SBarry Smith   }
2708f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2709bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2710bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2711f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2712be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2713bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2714f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2715be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2716bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
271787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2718f83d6046SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
271966826eb6SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
2720f83d6046SBarry Smith #endif
2721eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
27223a40ed3dSBarry Smith   PetscFunctionReturn(0);
272317ab2063SBarry Smith }
2724273d9f13SBarry Smith EXTERN_C_END
272517ab2063SBarry Smith 
27264a2ae208SSatish Balay #undef __FUNCT__
27274a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2728be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
272917ab2063SBarry Smith {
2730416022c9SBarry Smith   Mat        C;
2731416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2732273d9f13SBarry Smith   int        i,len,m = A->m,shift = a->indexshift,ierr;
273317ab2063SBarry Smith 
27343a40ed3dSBarry Smith   PetscFunctionBegin;
27354043dd9cSLois Curfman McInnes   *B = 0;
2736273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2737273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr);
2738273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2739273d9f13SBarry Smith 
2740416022c9SBarry Smith   C->factor         = A->factor;
2741416022c9SBarry Smith   c->row            = 0;
2742416022c9SBarry Smith   c->col            = 0;
274382bf6240SBarry Smith   c->icol           = 0;
2744416022c9SBarry Smith   c->indexshift     = shift;
2745f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2746c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
274717ab2063SBarry Smith 
2748273d9f13SBarry Smith   C->M          = A->m;
2749273d9f13SBarry Smith   C->N          = A->n;
275017ab2063SBarry Smith 
2751b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2752b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
275317ab2063SBarry Smith   for (i=0; i<m; i++) {
2754416022c9SBarry Smith     c->imax[i] = a->imax[i];
2755416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
275617ab2063SBarry Smith   }
275717ab2063SBarry Smith 
275817ab2063SBarry Smith   /* allocate the matrix space */
2759f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
276087828ca2SBarry Smith   len   = (m+1)*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2761b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2762416022c9SBarry Smith   c->j  = (int*)(c->a + a->i[m] + shift);
2763416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2764549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
276517ab2063SBarry Smith   if (m > 0) {
2766549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2767be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
276887828ca2SBarry Smith       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
2769be6bf707SBarry Smith     } else {
277087828ca2SBarry Smith       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
277117ab2063SBarry Smith     }
277208480c60SBarry Smith   }
277317ab2063SBarry Smith 
2774b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2775416022c9SBarry Smith   c->sorted      = a->sorted;
2776416022c9SBarry Smith   c->roworiented = a->roworiented;
2777416022c9SBarry Smith   c->nonew       = a->nonew;
27787a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2779be6bf707SBarry Smith   c->saved_values = 0;
2780d7f994e1SBarry Smith   c->idiag        = 0;
2781d7f994e1SBarry Smith   c->ssor         = 0;
278236db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
278336db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
278417ab2063SBarry Smith 
2785416022c9SBarry Smith   if (a->diag) {
2786b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2787b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
278817ab2063SBarry Smith     for (i=0; i<m; i++) {
2789416022c9SBarry Smith       c->diag[i] = a->diag[i];
279017ab2063SBarry Smith     }
27913a40ed3dSBarry Smith   } else c->diag        = 0;
2792b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27936c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
27946c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2795754ec7b1SSatish Balay   if (a->inode.size){
2796b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2797754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2798549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2799754ec7b1SSatish Balay   } else {
2800754ec7b1SSatish Balay     c->inode.size       = 0;
2801754ec7b1SSatish Balay     c->inode.node_count = 0;
2802754ec7b1SSatish Balay   }
2803416022c9SBarry Smith   c->nz                 = a->nz;
2804416022c9SBarry Smith   c->maxnz              = a->maxnz;
2805416022c9SBarry Smith   c->solve_work         = 0;
28062a1b7f2aSHong Zhang   C->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2807273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2808754ec7b1SSatish Balay 
2809416022c9SBarry Smith   *B = C;
2810b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
28113a40ed3dSBarry Smith   PetscFunctionReturn(0);
281217ab2063SBarry Smith }
281317ab2063SBarry Smith 
2814273d9f13SBarry Smith EXTERN_C_BEGIN
28154a2ae208SSatish Balay #undef __FUNCT__
28164a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2817b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A)
281817ab2063SBarry Smith {
2819416022c9SBarry Smith   Mat_SeqAIJ   *a;
2820416022c9SBarry Smith   Mat          B;
282117699dbbSLois Curfman McInnes   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift;
2822bcd2baecSBarry Smith   MPI_Comm     comm;
282317ab2063SBarry Smith 
28243a40ed3dSBarry Smith   PetscFunctionBegin;
2825e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2826d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
282729bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2828b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
28290752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2830552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
283117ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
283217ab2063SBarry Smith 
2833d64ed03dSBarry Smith   if (nz < 0) {
283429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2835d64ed03dSBarry Smith   }
2836d64ed03dSBarry Smith 
283717ab2063SBarry Smith   /* read in row lengths */
2838b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
28390752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
284017ab2063SBarry Smith 
284117ab2063SBarry Smith   /* create our matrix */
2842416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2843416022c9SBarry Smith   B = *A;
2844416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
2845416022c9SBarry Smith   shift = a->indexshift;
284617ab2063SBarry Smith 
284717ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
28480752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
284917ab2063SBarry Smith   if (shift) {
285017ab2063SBarry Smith     for (i=0; i<nz; i++) {
2851416022c9SBarry Smith       a->j[i] += 1;
285217ab2063SBarry Smith     }
285317ab2063SBarry Smith   }
285417ab2063SBarry Smith 
285517ab2063SBarry Smith   /* read in nonzero values */
28560752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
285717ab2063SBarry Smith 
285817ab2063SBarry Smith   /* set matrix "i" values */
2859416022c9SBarry Smith   a->i[0] = -shift;
286017ab2063SBarry Smith   for (i=1; i<= M; i++) {
2861416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2862416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
286317ab2063SBarry Smith   }
2864606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
286517ab2063SBarry Smith 
28666d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28676d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28683a40ed3dSBarry Smith   PetscFunctionReturn(0);
286917ab2063SBarry Smith }
2870273d9f13SBarry Smith EXTERN_C_END
287117ab2063SBarry Smith 
28724a2ae208SSatish Balay #undef __FUNCT__
2873b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28748f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28757264ac53SSatish Balay {
28767264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28770f5bd95cSBarry Smith   int        ierr;
2878273d9f13SBarry Smith   PetscTruth flag;
28797264ac53SSatish Balay 
28803a40ed3dSBarry Smith   PetscFunctionBegin;
2881273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flag);CHKERRQ(ierr);
2882273d9f13SBarry Smith   if (!flag) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices must be same type");
28837264ac53SSatish Balay 
28847264ac53SSatish Balay   /* If the  matrix dimensions are not equal,or no of nonzeros or shift */
2885273d9f13SBarry Smith   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) {
2886ca44d042SBarry Smith     *flg = PETSC_FALSE;
2887ca44d042SBarry Smith     PetscFunctionReturn(0);
2888bcd2baecSBarry Smith   }
28897264ac53SSatish Balay 
28907264ac53SSatish Balay   /* if the a->i are the same */
2891273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28920f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28937264ac53SSatish Balay 
28947264ac53SSatish Balay   /* if a->j are the same */
28950f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28960f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2897bcd2baecSBarry Smith 
2898bcd2baecSBarry Smith   /* if a->a are the same */
289987828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
29000f5bd95cSBarry Smith 
29013a40ed3dSBarry Smith   PetscFunctionReturn(0);
29027264ac53SSatish Balay 
29037264ac53SSatish Balay }
290436db0b34SBarry Smith 
29054a2ae208SSatish Balay #undef __FUNCT__
29064a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
290736db0b34SBarry Smith /*@C
290836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
290936db0b34SBarry Smith               provided by the user.
291036db0b34SBarry Smith 
291136db0b34SBarry Smith       Coolective on MPI_Comm
291236db0b34SBarry Smith 
291336db0b34SBarry Smith    Input Parameters:
291436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
291536db0b34SBarry Smith .   m - number of rows
291636db0b34SBarry Smith .   n - number of columns
291736db0b34SBarry Smith .   i - row indices
291836db0b34SBarry Smith .   j - column indices
291936db0b34SBarry Smith -   a - matrix values
292036db0b34SBarry Smith 
292136db0b34SBarry Smith    Output Parameter:
292236db0b34SBarry Smith .   mat - the matrix
292336db0b34SBarry Smith 
292436db0b34SBarry Smith    Level: intermediate
292536db0b34SBarry Smith 
292636db0b34SBarry Smith    Notes:
29270551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
292836db0b34SBarry Smith     once the matrix is destroyed
292936db0b34SBarry Smith 
293036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
293136db0b34SBarry Smith 
293236db0b34SBarry Smith        The i and j indices can be either 0- or 1 based
293336db0b34SBarry Smith 
293436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
293536db0b34SBarry Smith 
293636db0b34SBarry Smith @*/
293787828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
293836db0b34SBarry Smith {
293936db0b34SBarry Smith   int        ierr,ii;
294036db0b34SBarry Smith   Mat_SeqAIJ *aij;
294136db0b34SBarry Smith 
294236db0b34SBarry Smith   PetscFunctionBegin;
2943c461c341SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr);
294436db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
294536db0b34SBarry Smith 
294636db0b34SBarry Smith   if (i[0] == 1) {
294736db0b34SBarry Smith     aij->indexshift = -1;
294836db0b34SBarry Smith   } else if (i[0]) {
294929bbc08cSBarry Smith     SETERRQ(1,"i (row indices) do not start with 0 or 1");
295036db0b34SBarry Smith   }
295136db0b34SBarry Smith   aij->i = i;
295236db0b34SBarry Smith   aij->j = j;
295336db0b34SBarry Smith   aij->a = a;
295436db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
295536db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
295636db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
295736db0b34SBarry Smith 
295836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
295936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
29609860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296129bbc08cSBarry 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]);
296236db0b34SBarry Smith #endif
296336db0b34SBarry Smith   }
29649860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296536db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
296629bbc08cSBarry Smith     if (j[ii] < -aij->indexshift) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
296729bbc08cSBarry Smith     if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
296836db0b34SBarry Smith   }
296936db0b34SBarry Smith #endif
297036db0b34SBarry Smith 
2971b65db4caSBarry Smith   /* changes indices to start at 0 */
2972b65db4caSBarry Smith   if (i[0]) {
2973b65db4caSBarry Smith     aij->indexshift = 0;
2974b65db4caSBarry Smith     for (ii=0; ii<m; ii++) {
2975b65db4caSBarry Smith       i[ii]--;
2976b65db4caSBarry Smith     }
2977b65db4caSBarry Smith     for (ii=0; ii<i[m]; ii++) {
2978b65db4caSBarry Smith       j[ii]--;
2979b65db4caSBarry Smith     }
2980b65db4caSBarry Smith   }
2981b65db4caSBarry Smith 
2982b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2983b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
298436db0b34SBarry Smith   PetscFunctionReturn(0);
298536db0b34SBarry Smith }
298636db0b34SBarry Smith 
2987cc8ba8e1SBarry Smith #undef __FUNCT__
2988ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2989ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2990cc8ba8e1SBarry Smith {
2991cc8ba8e1SBarry Smith   int        ierr;
2992cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
299336db0b34SBarry Smith 
2994cc8ba8e1SBarry Smith   PetscFunctionBegin;
299512c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2996cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2997cc8ba8e1SBarry Smith     a->coloring = coloring;
299812c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
299912c595b3SBarry Smith     int        *colors,i,*larray;
300012c595b3SBarry Smith     ISColoring ocoloring;
300112c595b3SBarry Smith 
300212c595b3SBarry Smith     /* set coloring for diagonal portion */
300312c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
300412c595b3SBarry Smith     for (i=0; i<A->n; i++) {
300512c595b3SBarry Smith       larray[i] = i;
300612c595b3SBarry Smith     }
300712c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
300812c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&colors);CHKERRQ(ierr);
300912c595b3SBarry Smith     for (i=0; i<A->n; i++) {
301012c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
301112c595b3SBarry Smith     }
301212c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
301312c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
301412c595b3SBarry Smith     a->coloring = ocoloring;
301512c595b3SBarry Smith   }
3016cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3017cc8ba8e1SBarry Smith }
3018cc8ba8e1SBarry Smith 
301987828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
3020ee4f033dSBarry Smith EXTERN_C_BEGIN
302129c1e371SBarry Smith #include "adic/ad_utils.h"
3022ee4f033dSBarry Smith EXTERN_C_END
3023cc8ba8e1SBarry Smith 
3024cc8ba8e1SBarry Smith #undef __FUNCT__
3025ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3026ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3027cc8ba8e1SBarry Smith {
3028cc8ba8e1SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
3029ee4f033dSBarry Smith   int         m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j,nlen;
303087828ca2SBarry Smith   PetscScalar *v = a->a,*values;
3031ee4f033dSBarry Smith   char        *cadvalues = (char *)advalues;
3032cc8ba8e1SBarry Smith 
3033cc8ba8e1SBarry Smith   PetscFunctionBegin;
3034cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
303529c1e371SBarry Smith   nlen  = PetscADGetDerivTypeSize();
3036cc8ba8e1SBarry Smith   color = a->coloring->colors;
3037cc8ba8e1SBarry Smith   /* loop over rows */
3038cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3039cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3040cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
304129c1e371SBarry Smith     values = PetscADGetGradArray(cadvalues);
3042cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3043cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3044cc8ba8e1SBarry Smith     }
3045ee4f033dSBarry Smith     cadvalues += nlen; /* jump to next row of derivatives */
3046ee4f033dSBarry Smith   }
3047ee4f033dSBarry Smith   PetscFunctionReturn(0);
3048ee4f033dSBarry Smith }
3049ee4f033dSBarry Smith 
3050ee4f033dSBarry Smith #else
3051ee4f033dSBarry Smith 
3052ee4f033dSBarry Smith #undef __FUNCT__
3053ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3054ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3055ee4f033dSBarry Smith {
3056ee4f033dSBarry Smith   PetscFunctionBegin;
3057ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
3058ee4f033dSBarry Smith }
3059ee4f033dSBarry Smith 
3060ee4f033dSBarry Smith #endif
3061ee4f033dSBarry Smith 
3062ee4f033dSBarry Smith #undef __FUNCT__
3063ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
3064ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
3065ee4f033dSBarry Smith {
3066ee4f033dSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
3067ee4f033dSBarry Smith   int          m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j;
306887828ca2SBarry Smith   PetscScalar  *v = a->a,*values = (PetscScalar *)advalues;
3069ee4f033dSBarry Smith 
3070ee4f033dSBarry Smith   PetscFunctionBegin;
3071ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3072ee4f033dSBarry Smith   color = a->coloring->colors;
3073ee4f033dSBarry Smith   /* loop over rows */
3074ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3075ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3076ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3077ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3078ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3079ee4f033dSBarry Smith     }
3080ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3081cc8ba8e1SBarry Smith   }
3082cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3083cc8ba8e1SBarry Smith }
308436db0b34SBarry Smith 
3085