xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 9a4540c566747109ecba68f8e2c4d5a47c914826)
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 
134a2ae208SSatish Balay #undef __FUNCT__
144a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
154e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done)
1617ab2063SBarry Smith {
17416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
186945ee14SBarry Smith   int        ierr,i,ishift;
1917ab2063SBarry Smith 
203a40ed3dSBarry Smith   PetscFunctionBegin;
2131625ec5SSatish Balay   *m     = A->m;
223a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
23bfeeae90SHong Zhang   ishift = 0;
2453e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
25273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
26bfeeae90SHong Zhang   } else if (oshift == 1) {
27435da068SBarry Smith     int nz = a->i[A->m];
283b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
291bc30dd5SBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
30b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
313b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
32273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
336945ee14SBarry Smith   } else {
346945ee14SBarry Smith     *ia = a->i; *ja = a->j;
35a2ce50c7SBarry Smith   }
363a40ed3dSBarry Smith   PetscFunctionReturn(0);
37a2744918SBarry Smith }
38a2744918SBarry Smith 
394a2ae208SSatish Balay #undef __FUNCT__
404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
414e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
426945ee14SBarry Smith {
43bfeeae90SHong Zhang   int ierr;
446945ee14SBarry Smith 
453a40ed3dSBarry Smith   PetscFunctionBegin;
463a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
47bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
48606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
49606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
50bcd2baecSBarry Smith   }
513a40ed3dSBarry Smith   PetscFunctionReturn(0);
5217ab2063SBarry Smith }
5317ab2063SBarry Smith 
544a2ae208SSatish Balay #undef __FUNCT__
554a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
564e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
573b2fbd54SBarry Smith {
583b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
59bfeeae90SHong Zhang   int        ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m;
60bfeeae90SHong Zhang   int        nz = a->i[m],row,*jj,mr,col;
613b2fbd54SBarry Smith 
623a40ed3dSBarry Smith   PetscFunctionBegin;
633b2fbd54SBarry Smith   *nn     = A->n;
643a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
653b2fbd54SBarry Smith   if (symmetric) {
66bfeeae90SHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
673b2fbd54SBarry Smith   } else {
68b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr);
69549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
70b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr);
71b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr);
723b2fbd54SBarry Smith     jj = a->j;
733b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
74bfeeae90SHong Zhang       collengths[jj[i]]++;
753b2fbd54SBarry Smith     }
763b2fbd54SBarry Smith     cia[0] = oshift;
773b2fbd54SBarry Smith     for (i=0; i<n; i++) {
783b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
793b2fbd54SBarry Smith     }
80549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
813b2fbd54SBarry Smith     jj   = a->j;
82a93ec695SBarry Smith     for (row=0; row<m; row++) {
83a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
84a93ec695SBarry Smith       for (i=0; i<mr; i++) {
85bfeeae90SHong Zhang         col = *jj++;
863b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
873b2fbd54SBarry Smith       }
883b2fbd54SBarry Smith     }
89606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
903b2fbd54SBarry Smith     *ia = cia; *ja = cja;
913b2fbd54SBarry Smith   }
923a40ed3dSBarry Smith   PetscFunctionReturn(0);
933b2fbd54SBarry Smith }
943b2fbd54SBarry Smith 
954a2ae208SSatish Balay #undef __FUNCT__
964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
974e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
983b2fbd54SBarry Smith {
99606d414cSSatish Balay   int ierr;
100606d414cSSatish Balay 
1013a40ed3dSBarry Smith   PetscFunctionBegin;
1023a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1033b2fbd54SBarry Smith 
104606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
105606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1063b2fbd54SBarry Smith 
1073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1083b2fbd54SBarry Smith }
1093b2fbd54SBarry Smith 
110227d817aSBarry Smith #define CHUNKSIZE   15
11117ab2063SBarry Smith 
1124a2ae208SSatish Balay #undef __FUNCT__
1134a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
114f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11517ab2063SBarry Smith {
116416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
117416022c9SBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
118273d9f13SBarry Smith   int         *imax = a->imax,*ai = a->i,*ailen = a->ilen;
119bfeeae90SHong Zhang   int         *aj = a->j,nonew = a->nonew,ierr;
12087828ca2SBarry Smith   PetscScalar *ap,value,*aa = a->a;
12136db0b34SBarry Smith   PetscTruth  ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
122273d9f13SBarry Smith   PetscTruth  roworiented = a->roworiented;
12317ab2063SBarry Smith 
1243a40ed3dSBarry Smith   PetscFunctionBegin;
12517ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
126416022c9SBarry Smith     row  = im[k];
1275ef9f2a5SBarry Smith     if (row < 0) continue;
128aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
129590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
1303b2fbd54SBarry Smith #endif
131bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
13217ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
133416022c9SBarry Smith     low = 0;
13417ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1355ef9f2a5SBarry Smith       if (in[l] < 0) continue;
136aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
137590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
1383b2fbd54SBarry Smith #endif
139bfeeae90SHong Zhang       col = in[l];
1404b0e389bSBarry Smith       if (roworiented) {
1415ef9f2a5SBarry Smith         value = v[l + k*n];
142bef8e0ddSBarry Smith       } else {
1434b0e389bSBarry Smith         value = v[k + l*m];
1444b0e389bSBarry Smith       }
14536db0b34SBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
14636db0b34SBarry Smith 
147416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
148416022c9SBarry Smith       while (high-low > 5) {
149416022c9SBarry Smith         t = (low+high)/2;
150416022c9SBarry Smith         if (rp[t] > col) high = t;
151416022c9SBarry Smith         else             low  = t;
15217ab2063SBarry Smith       }
153416022c9SBarry Smith       for (i=low; i<high; i++) {
15417ab2063SBarry Smith         if (rp[i] > col) break;
15517ab2063SBarry Smith         if (rp[i] == col) {
156416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
15717ab2063SBarry Smith           else                  ap[i] = value;
15817ab2063SBarry Smith           goto noinsert;
15917ab2063SBarry Smith         }
16017ab2063SBarry Smith       }
161c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
16229bbc08cSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
16317ab2063SBarry Smith       if (nrow >= rmax) {
16417ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
165a7ed9263SMatthew Knepley         int         new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j;
166a7ed9263SMatthew Knepley         size_t      len;
16787828ca2SBarry Smith         PetscScalar *new_a;
16817ab2063SBarry Smith 
16929bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
17096854ed6SLois Curfman McInnes 
17117ab2063SBarry Smith         /* malloc new storage space */
172a7ed9263SMatthew Knepley         len     = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
173b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
17417ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
17517ab2063SBarry Smith         new_i   = new_j + new_nz;
17617ab2063SBarry Smith 
17717ab2063SBarry Smith         /* copy over old data into new slots */
17817ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
179273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
180bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
181bfeeae90SHong Zhang         len  = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow );
182bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
183bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr);
184bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
18517ab2063SBarry Smith         /* free up old matrix storage */
186606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
187606d414cSSatish Balay         if (!a->singlemalloc) {
188606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
189606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
190606d414cSSatish Balay         }
191416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
192f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
19317ab2063SBarry Smith 
194bfeeae90SHong Zhang         rp   = aj + ai[row]; ap = aa + ai[row] ;
195416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
19687828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
197416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
198b810aeb4SBarry Smith         a->reallocs++;
19917ab2063SBarry Smith       }
200416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
201416022c9SBarry Smith       /* shift up all the later entries in this row */
202416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
20317ab2063SBarry Smith         rp[ii+1] = rp[ii];
20417ab2063SBarry Smith         ap[ii+1] = ap[ii];
20517ab2063SBarry Smith       }
20617ab2063SBarry Smith       rp[i] = col;
20717ab2063SBarry Smith       ap[i] = value;
20817ab2063SBarry Smith       noinsert:;
209416022c9SBarry Smith       low = i + 1;
21017ab2063SBarry Smith     }
21117ab2063SBarry Smith     ailen[row] = nrow;
21217ab2063SBarry Smith   }
2133a40ed3dSBarry Smith   PetscFunctionReturn(0);
21417ab2063SBarry Smith }
21517ab2063SBarry Smith 
2164a2ae208SSatish Balay #undef __FUNCT__
2174a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
218f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
2197eb43aa7SLois Curfman McInnes {
2207eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
221b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
222bfeeae90SHong Zhang   int          *ai = a->i,*ailen = a->ilen;
22387828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2247eb43aa7SLois Curfman McInnes 
2253a40ed3dSBarry Smith   PetscFunctionBegin;
2267eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2277eb43aa7SLois Curfman McInnes     row  = im[k];
22829bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
229590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
230bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2317eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2327eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
23329bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
234590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
235bfeeae90SHong Zhang       col = in[l] ;
2367eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2377eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2387eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2397eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2407eb43aa7SLois Curfman McInnes         else             low  = t;
2417eb43aa7SLois Curfman McInnes       }
2427eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2437eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2447eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
245b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2467eb43aa7SLois Curfman McInnes           goto finished;
2477eb43aa7SLois Curfman McInnes         }
2487eb43aa7SLois Curfman McInnes       }
249b49de8d1SLois Curfman McInnes       *v++ = zero;
2507eb43aa7SLois Curfman McInnes       finished:;
2517eb43aa7SLois Curfman McInnes     }
2527eb43aa7SLois Curfman McInnes   }
2533a40ed3dSBarry Smith   PetscFunctionReturn(0);
2547eb43aa7SLois Curfman McInnes }
2557eb43aa7SLois Curfman McInnes 
25617ab2063SBarry Smith 
2574a2ae208SSatish Balay #undef __FUNCT__
2584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
259b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
26017ab2063SBarry Smith {
261416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
262416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
26317ab2063SBarry Smith 
2643a40ed3dSBarry Smith   PetscFunctionBegin;
265b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
266b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
267552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
268273d9f13SBarry Smith   col_lens[1] = A->m;
269273d9f13SBarry Smith   col_lens[2] = A->n;
270416022c9SBarry Smith   col_lens[3] = a->nz;
271416022c9SBarry Smith 
272416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
273273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
274416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
27517ab2063SBarry Smith   }
276273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
277606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
278416022c9SBarry Smith 
279416022c9SBarry Smith   /* store column indices (zero start index) */
2800752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
281416022c9SBarry Smith 
282416022c9SBarry Smith   /* store nonzero values */
2830752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
2843a40ed3dSBarry Smith   PetscFunctionReturn(0);
28517ab2063SBarry Smith }
286416022c9SBarry Smith 
2874ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
288cd155464SBarry Smith 
2894a2ae208SSatish Balay #undef __FUNCT__
2904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
291b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
292416022c9SBarry Smith {
293416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
294bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,shift=0;
295fb9695e5SSatish Balay   char              *name;
296f3ef73ceSBarry Smith   PetscViewerFormat format;
29717ab2063SBarry Smith 
2983a40ed3dSBarry Smith   PetscFunctionBegin;
299435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
300b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
301456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3026831982aSBarry Smith     if (a->inode.size) {
303b0a32e0cSBarry 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);
3046831982aSBarry Smith     } else {
305b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3066831982aSBarry Smith     }
307fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
308d00d2cf4SBarry Smith     int nofinalvalue = 0;
309273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
310d00d2cf4SBarry Smith       nofinalvalue = 1;
311d00d2cf4SBarry Smith     }
312b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
313b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
314b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
315b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
316b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
31717ab2063SBarry Smith 
31817ab2063SBarry Smith     for (i=0; i<m; i++) {
319416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
320aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
321b0a32e0cSBarry 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);
32217ab2063SBarry Smith #else
323b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
32417ab2063SBarry Smith #endif
32517ab2063SBarry Smith       }
32617ab2063SBarry Smith     }
327d00d2cf4SBarry Smith     if (nofinalvalue) {
328b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
329d00d2cf4SBarry Smith     }
330fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
331b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
332cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
33316ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
3344ffef66eSHong Zhang      ierr = MatSeqAIJFactorInfo_Matlab(A,viewer);CHKERRQ(ierr);
3354ffef66eSHong Zhang #endif
336cd155464SBarry Smith      PetscFunctionReturn(0);
337fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
338b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
33944cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
340b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
34144cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
342aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
34336db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
34462b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34536db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
34662b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34736db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
34862b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3496831982aSBarry Smith         }
35044cd7ae7SLois Curfman McInnes #else
35162b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
35244cd7ae7SLois Curfman McInnes #endif
35344cd7ae7SLois Curfman McInnes       }
354b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
35544cd7ae7SLois Curfman McInnes     }
356b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
357fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
358496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
359b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
360b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
361496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
362496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
363496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
364496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
365aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
36636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
367496be53dSLois Curfman McInnes #else
368496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
369496be53dSLois Curfman McInnes #endif
370496be53dSLois Curfman McInnes         }
371496be53dSLois Curfman McInnes       }
372496be53dSLois Curfman McInnes     }
3732e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
374b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
3752e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
376b0a32e0cSBarry 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);}
377b0a32e0cSBarry 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);}
378b0a32e0cSBarry 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);}
379b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
380b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
381b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
382496be53dSLois Curfman McInnes     }
383b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
384606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
385496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
386496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
387b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
388496be53dSLois Curfman McInnes       }
389b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
390496be53dSLois Curfman McInnes     }
391b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
392496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
393496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
394496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
395aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
397b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
3986831982aSBarry Smith           }
399496be53dSLois Curfman McInnes #else
400b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
401496be53dSLois Curfman McInnes #endif
402496be53dSLois Curfman McInnes         }
403496be53dSLois Curfman McInnes       }
404b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
405496be53dSLois Curfman McInnes     }
406b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
407fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
40802594712SBarry Smith     int         cnt = 0,jcnt;
40987828ca2SBarry Smith     PetscScalar value;
41002594712SBarry Smith 
411b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
41202594712SBarry Smith     for (i=0; i<m; i++) {
41302594712SBarry Smith       jcnt = 0;
414273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
415e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
41602594712SBarry Smith           value = a->a[cnt++];
417e24b481bSBarry Smith           jcnt++;
41802594712SBarry Smith         } else {
41902594712SBarry Smith           value = 0.0;
42002594712SBarry Smith         }
421aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
422b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
42302594712SBarry Smith #else
424b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
42502594712SBarry Smith #endif
42602594712SBarry Smith       }
427b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42802594712SBarry Smith     }
429b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4303a40ed3dSBarry Smith   } else {
431b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
43217ab2063SBarry Smith     for (i=0; i<m; i++) {
433b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
434416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
435aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
43636db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
43762b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
43836db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
43962b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4403a40ed3dSBarry Smith         } else {
44162b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
44217ab2063SBarry Smith         }
44317ab2063SBarry Smith #else
44462b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
44517ab2063SBarry Smith #endif
44617ab2063SBarry Smith       }
447b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44817ab2063SBarry Smith     }
449b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
45017ab2063SBarry Smith   }
451b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4523a40ed3dSBarry Smith   PetscFunctionReturn(0);
453416022c9SBarry Smith }
454416022c9SBarry Smith 
4554a2ae208SSatish Balay #undef __FUNCT__
4564a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
457b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
458416022c9SBarry Smith {
459480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
460416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
461bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,color;
46236db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
463b0a32e0cSBarry Smith   PetscViewer       viewer;
464f3ef73ceSBarry Smith   PetscViewerFormat format;
465cddf8d76SBarry Smith 
4663a40ed3dSBarry Smith   PetscFunctionBegin;
467480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
468b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
46919bcc07fSBarry Smith 
470b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
471416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4720513a670SBarry Smith 
473fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4740513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
475b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
476416022c9SBarry Smith     for (i=0; i<m; i++) {
477cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
478bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
479bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
480aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
48136db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
482cddf8d76SBarry Smith #else
483cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
484cddf8d76SBarry Smith #endif
485b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
486cddf8d76SBarry Smith       }
487cddf8d76SBarry Smith     }
488b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
489cddf8d76SBarry Smith     for (i=0; i<m; i++) {
490cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
491bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
492bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
493cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
494b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
495cddf8d76SBarry Smith       }
496cddf8d76SBarry Smith     }
497b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
498cddf8d76SBarry Smith     for (i=0; i<m; i++) {
499cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
500bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
501bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
502aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
50336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
504cddf8d76SBarry Smith #else
505cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
506cddf8d76SBarry Smith #endif
507b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
508416022c9SBarry Smith       }
509416022c9SBarry Smith     }
5100513a670SBarry Smith   } else {
5110513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5120513a670SBarry Smith     /* first determine max of all nonzero values */
5130513a670SBarry Smith     int    nz = a->nz,count;
514b0a32e0cSBarry Smith     PetscDraw   popup;
51536db0b34SBarry Smith     PetscReal scale;
5160513a670SBarry Smith 
5170513a670SBarry Smith     for (i=0; i<nz; i++) {
5180513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5190513a670SBarry Smith     }
520b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
521b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
522b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5230513a670SBarry Smith     count = 0;
5240513a670SBarry Smith     for (i=0; i<m; i++) {
5250513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
526bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
527bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
528b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
529b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5300513a670SBarry Smith         count++;
5310513a670SBarry Smith       }
5320513a670SBarry Smith     }
5330513a670SBarry Smith   }
534480ef9eaSBarry Smith   PetscFunctionReturn(0);
535480ef9eaSBarry Smith }
536cddf8d76SBarry Smith 
5374a2ae208SSatish Balay #undef __FUNCT__
5384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
539b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
540480ef9eaSBarry Smith {
541480ef9eaSBarry Smith   int        ierr;
542b0a32e0cSBarry Smith   PetscDraw  draw;
54336db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
544480ef9eaSBarry Smith   PetscTruth isnull;
545480ef9eaSBarry Smith 
546480ef9eaSBarry Smith   PetscFunctionBegin;
547b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
548b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
549480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
550480ef9eaSBarry Smith 
551480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
552273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
553480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
554b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
555b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
556480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5573a40ed3dSBarry Smith   PetscFunctionReturn(0);
558416022c9SBarry Smith }
559416022c9SBarry Smith 
5604a2ae208SSatish Balay #undef __FUNCT__
5614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
562b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
563416022c9SBarry Smith {
564416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
565bcd2baecSBarry Smith   int         ierr;
5666831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
567416022c9SBarry Smith 
5683a40ed3dSBarry Smith   PetscFunctionBegin;
569b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
570b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
571fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
572fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5730f5bd95cSBarry Smith   if (issocket) {
574b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
5750f5bd95cSBarry Smith   } else if (isascii) {
5763a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5770f5bd95cSBarry Smith   } else if (isbinary) {
5783a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
5790f5bd95cSBarry Smith   } else if (isdraw) {
5803a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
5815cd90555SBarry Smith   } else {
58229bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
58317ab2063SBarry Smith   }
5843a40ed3dSBarry Smith   PetscFunctionReturn(0);
58517ab2063SBarry Smith }
58619bcc07fSBarry Smith 
5874a2ae208SSatish Balay #undef __FUNCT__
5884a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
5898f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
59017ab2063SBarry Smith {
591416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
59241c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
593bfeeae90SHong Zhang   int          m = A->m,*ip,N,*ailen = a->ilen,rmax = 0;
59487828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
59517ab2063SBarry Smith 
5963a40ed3dSBarry Smith   PetscFunctionBegin;
5973a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
59817ab2063SBarry Smith 
59943ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
60017ab2063SBarry Smith   for (i=1; i<m; i++) {
601416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
60217ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
60394a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
60417ab2063SBarry Smith     if (fshift) {
605bfeeae90SHong Zhang       ip = aj + ai[i] ;
606bfeeae90SHong Zhang       ap = aa + ai[i] ;
60717ab2063SBarry Smith       N  = ailen[i];
60817ab2063SBarry Smith       for (j=0; j<N; j++) {
60917ab2063SBarry Smith         ip[j-fshift] = ip[j];
61017ab2063SBarry Smith         ap[j-fshift] = ap[j];
61117ab2063SBarry Smith       }
61217ab2063SBarry Smith     }
61317ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
61417ab2063SBarry Smith   }
61517ab2063SBarry Smith   if (m) {
61617ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
61717ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
61817ab2063SBarry Smith   }
61917ab2063SBarry Smith   /* reset ilen and imax for each row */
62017ab2063SBarry Smith   for (i=0; i<m; i++) {
62117ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
62217ab2063SBarry Smith   }
623bfeeae90SHong Zhang   a->nz = ai[m];
62417ab2063SBarry Smith 
62517ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
626416022c9SBarry Smith   if (fshift && a->diag) {
627606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
628b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
629416022c9SBarry Smith     a->diag = 0;
63017ab2063SBarry Smith   }
631b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
632b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
633b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
634dd5f02e7SSatish Balay   a->reallocs          = 0;
6354e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
63636db0b34SBarry Smith   a->rmax              = rmax;
6374e220ebcSLois Curfman McInnes 
63876dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6393a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
640cfef3cccSHong Zhang 
6413a40ed3dSBarry Smith   PetscFunctionReturn(0);
64217ab2063SBarry Smith }
64317ab2063SBarry Smith 
6444a2ae208SSatish Balay #undef __FUNCT__
6454a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6468f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
64717ab2063SBarry Smith {
648416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
649549d3d68SSatish Balay   int        ierr;
6503a40ed3dSBarry Smith 
6513a40ed3dSBarry Smith   PetscFunctionBegin;
652bfeeae90SHong Zhang   ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
6533a40ed3dSBarry Smith   PetscFunctionReturn(0);
65417ab2063SBarry Smith }
655416022c9SBarry Smith 
6564a2ae208SSatish Balay #undef __FUNCT__
6574a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
658e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
65917ab2063SBarry Smith {
660416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
66182bf6240SBarry Smith   int        ierr;
662d5d45c9bSBarry Smith 
6633a40ed3dSBarry Smith   PetscFunctionBegin;
664aa482453SBarry Smith #if defined(PETSC_USE_LOG)
665b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
66617ab2063SBarry Smith #endif
66736db0b34SBarry Smith   if (a->freedata) {
668606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
669606d414cSSatish Balay     if (!a->singlemalloc) {
670606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
671606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
672606d414cSSatish Balay     }
67336db0b34SBarry Smith   }
674c38d4ed2SBarry Smith   if (a->row) {
675c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
676c38d4ed2SBarry Smith   }
677c38d4ed2SBarry Smith   if (a->col) {
678c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
679c38d4ed2SBarry Smith   }
680606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
681606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
682606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
683273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
684606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
685606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
68682bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
687606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
688cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
689a30b2313SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
690a30b2313SHong Zhang 
691606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
6923a40ed3dSBarry Smith   PetscFunctionReturn(0);
69317ab2063SBarry Smith }
69417ab2063SBarry Smith 
6954a2ae208SSatish Balay #undef __FUNCT__
6964a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
6978f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
69817ab2063SBarry Smith {
6993a40ed3dSBarry Smith   PetscFunctionBegin;
7003a40ed3dSBarry Smith   PetscFunctionReturn(0);
70117ab2063SBarry Smith }
70217ab2063SBarry Smith 
7034a2ae208SSatish Balay #undef __FUNCT__
7044a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7058f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
70617ab2063SBarry Smith {
707416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7083a40ed3dSBarry Smith 
7093a40ed3dSBarry Smith   PetscFunctionBegin;
710a65d3064SKris Buschelman   switch (op) {
711a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
712a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
713a65d3064SKris Buschelman       break;
714a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
715a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
716a65d3064SKris Buschelman       break;
717a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
718a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
719a65d3064SKris Buschelman       break;
720a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
721a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
722a65d3064SKris Buschelman       break;
723a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
724a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
725a65d3064SKris Buschelman       break;
726a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
727a65d3064SKris Buschelman       a->nonew             = 1;
728a65d3064SKris Buschelman       break;
729a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
730a65d3064SKris Buschelman       a->nonew             = -1;
731a65d3064SKris Buschelman       break;
732a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
733a65d3064SKris Buschelman       a->nonew             = -2;
734a65d3064SKris Buschelman       break;
735a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
736a65d3064SKris Buschelman       a->nonew             = 0;
737a65d3064SKris Buschelman       break;
738a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
739a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
740a65d3064SKris Buschelman       break;
741a65d3064SKris Buschelman     case MAT_USE_INODES:
742a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
743a65d3064SKris Buschelman       break;
744a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
745a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
746a65d3064SKris Buschelman       break;
747a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
748a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
749a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
750a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
751a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
752b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
753a65d3064SKris Buschelman       break;
754a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
75529bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
756a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
757a65d3064SKris Buschelman       a->inode.limit  = 1;
758a65d3064SKris Buschelman       break;
759a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
760a65d3064SKris Buschelman       a->inode.limit  = 2;
761a65d3064SKris Buschelman       break;
762a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
763a65d3064SKris Buschelman       a->inode.limit  = 3;
764a65d3064SKris Buschelman       break;
765a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
766a65d3064SKris Buschelman       a->inode.limit  = 4;
767a65d3064SKris Buschelman       break;
768a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
769a65d3064SKris Buschelman       a->inode.limit  = 5;
770a65d3064SKris Buschelman       break;
77177e54ba9SKris Buschelman     case MAT_SYMMETRIC:
77277e54ba9SKris Buschelman     case MAT_STRUCTURALLY_SYMMETRIC:
773*9a4540c5SBarry Smith     case MAT_NOT_SYMMETRIC:
774*9a4540c5SBarry Smith     case MAT_NOT_STRUCTURALLY_SYMMETRIC:
775*9a4540c5SBarry Smith     case MAT_HERMITIAN:
776*9a4540c5SBarry Smith     case MAT_NOT_HERMITIAN:
777*9a4540c5SBarry Smith     case MAT_SYMMETRY_ETERNAL:
778*9a4540c5SBarry Smith     case MAT_NOT_SYMMETRY_ETERNAL:
77977e54ba9SKris Buschelman       break;
780a65d3064SKris Buschelman     default:
781a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
782a65d3064SKris Buschelman   }
7833a40ed3dSBarry Smith   PetscFunctionReturn(0);
78417ab2063SBarry Smith }
78517ab2063SBarry Smith 
7864a2ae208SSatish Balay #undef __FUNCT__
7874a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
7888f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78917ab2063SBarry Smith {
790416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
791bfeeae90SHong Zhang   int          i,j,n,ierr;
79287828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
79317ab2063SBarry Smith 
7943a40ed3dSBarry Smith   PetscFunctionBegin;
7953a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
796ed480e8bSBarry Smith   ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr);
79736db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
798273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
799273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
800bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
801bfeeae90SHong Zhang       if (a->j[j] == i) {
802416022c9SBarry Smith         x[i] = a->a[j];
80317ab2063SBarry Smith         break;
80417ab2063SBarry Smith       }
80517ab2063SBarry Smith     }
80617ab2063SBarry Smith   }
807ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr);
8083a40ed3dSBarry Smith   PetscFunctionReturn(0);
80917ab2063SBarry Smith }
81017ab2063SBarry Smith 
811d5d45c9bSBarry Smith 
8124a2ae208SSatish Balay #undef __FUNCT__
8134a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8147c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
81517ab2063SBarry Smith {
816416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8175c897100SBarry Smith   PetscScalar  *x,*y;
818bfeeae90SHong Zhang   int          ierr,m = A->m;
8195c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8205c897100SBarry Smith   PetscScalar  *v,alpha;
8215c897100SBarry Smith   int          n,i,*idx;
8225c897100SBarry Smith #endif
82317ab2063SBarry Smith 
8243a40ed3dSBarry Smith   PetscFunctionBegin;
8252e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
826ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
827ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
8285c897100SBarry Smith 
8295c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
830bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8315c897100SBarry Smith #else
83217ab2063SBarry Smith   for (i=0; i<m; i++) {
833bfeeae90SHong Zhang     idx   = a->j + a->i[i] ;
834bfeeae90SHong Zhang     v     = a->a + a->i[i] ;
835416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83617ab2063SBarry Smith     alpha = x[i];
83717ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83817ab2063SBarry Smith   }
8395c897100SBarry Smith #endif
840b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
841ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
842ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
8433a40ed3dSBarry Smith   PetscFunctionReturn(0);
84417ab2063SBarry Smith }
84517ab2063SBarry Smith 
8464a2ae208SSatish Balay #undef __FUNCT__
8475c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8485c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8495c897100SBarry Smith {
8508d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8515c897100SBarry Smith   int          ierr;
8525c897100SBarry Smith 
8535c897100SBarry Smith   PetscFunctionBegin;
8545c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8555c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8565c897100SBarry Smith   PetscFunctionReturn(0);
8575c897100SBarry Smith }
8585c897100SBarry Smith 
8595c897100SBarry Smith 
8605c897100SBarry Smith #undef __FUNCT__
8614a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
86244cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
86317ab2063SBarry Smith {
864416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
865362ced78SSatish Balay   PetscScalar  *x,*y,*v;
866bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
867aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
868e36a17ebSSatish Balay   int          n,i,jrow,j;
869362ced78SSatish Balay   PetscScalar  sum;
870e36a17ebSSatish Balay #endif
87117ab2063SBarry Smith 
872b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
873fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
874fee21e36SBarry Smith #endif
875fee21e36SBarry Smith 
8763a40ed3dSBarry Smith   PetscFunctionBegin;
877ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
878ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
879416022c9SBarry Smith   idx  = a->j;
880d64ed03dSBarry Smith   v    = a->a;
881416022c9SBarry Smith   ii   = a->i;
882aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
883bfeeae90SHong Zhang   fortranmultaij_(&m,x,ii,idx,v,y);
8848d195f9aSBarry Smith #else
88517ab2063SBarry Smith   for (i=0; i<m; i++) {
8869ea0dfa2SSatish Balay     jrow = ii[i];
8879ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
88817ab2063SBarry Smith     sum  = 0.0;
8899ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
8909ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8919ea0dfa2SSatish Balay      }
89217ab2063SBarry Smith     y[i] = sum;
89317ab2063SBarry Smith   }
8948d195f9aSBarry Smith #endif
895b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
896ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
897ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
8983a40ed3dSBarry Smith   PetscFunctionReturn(0);
89917ab2063SBarry Smith }
90017ab2063SBarry Smith 
9014a2ae208SSatish Balay #undef __FUNCT__
9024a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
90344cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
90417ab2063SBarry Smith {
905416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
906362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
907bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
908aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
909e36a17ebSSatish Balay   int          n,i,jrow,j;
910362ced78SSatish Balay PetscScalar    sum;
911e36a17ebSSatish Balay #endif
9129ea0dfa2SSatish Balay 
9133a40ed3dSBarry Smith   PetscFunctionBegin;
914ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
915ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
9162e8a6d31SBarry Smith   if (zz != yy) {
917ed480e8bSBarry Smith     ierr = VecGetArrayFast(zz,&z);CHKERRQ(ierr);
9182e8a6d31SBarry Smith   } else {
9192e8a6d31SBarry Smith     z = y;
9202e8a6d31SBarry Smith   }
921bfeeae90SHong Zhang 
922cddf8d76SBarry Smith   idx  = a->j;
923d64ed03dSBarry Smith   v    = a->a;
924cddf8d76SBarry Smith   ii   = a->i;
925aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
926bfeeae90SHong Zhang   fortranmultaddaij_(&m,x,ii,idx,v,y,z);
92702ab625aSSatish Balay #else
92817ab2063SBarry Smith   for (i=0; i<m; i++) {
9299ea0dfa2SSatish Balay     jrow = ii[i];
9309ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93117ab2063SBarry Smith     sum  = y[i];
9329ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9339ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9349ea0dfa2SSatish Balay      }
93517ab2063SBarry Smith     z[i] = sum;
93617ab2063SBarry Smith   }
93702ab625aSSatish Balay #endif
938b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
939ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
940ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
9412e8a6d31SBarry Smith   if (zz != yy) {
942ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(zz,&z);CHKERRQ(ierr);
9432e8a6d31SBarry Smith   }
9443a40ed3dSBarry Smith   PetscFunctionReturn(0);
94517ab2063SBarry Smith }
94617ab2063SBarry Smith 
94717ab2063SBarry Smith /*
94817ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
94917ab2063SBarry Smith */
9504a2ae208SSatish Balay #undef __FUNCT__
9514a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
952f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
95317ab2063SBarry Smith {
954416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
955bfeeae90SHong Zhang   int        i,j,*diag,m = A->m,ierr;
95617ab2063SBarry Smith 
9573a40ed3dSBarry Smith   PetscFunctionBegin;
958f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
959f1e2ffcdSBarry Smith 
960b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
961b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
962273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
96335b0346bSBarry Smith     diag[i] = a->i[i+1];
964bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
965bfeeae90SHong Zhang       if (a->j[j] == i) {
966bfeeae90SHong Zhang         diag[i] = j;
96717ab2063SBarry Smith         break;
96817ab2063SBarry Smith       }
96917ab2063SBarry Smith     }
97017ab2063SBarry Smith   }
971416022c9SBarry Smith   a->diag = diag;
9723a40ed3dSBarry Smith   PetscFunctionReturn(0);
97317ab2063SBarry Smith }
97417ab2063SBarry Smith 
975be5855fcSBarry Smith /*
976be5855fcSBarry Smith      Checks for missing diagonals
977be5855fcSBarry Smith */
9784a2ae208SSatish Balay #undef __FUNCT__
9794a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
980f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
981be5855fcSBarry Smith {
982be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
983bfeeae90SHong Zhang   int        *diag,*jj = a->j,i,ierr;
984be5855fcSBarry Smith 
985be5855fcSBarry Smith   PetscFunctionBegin;
986f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
987f1e2ffcdSBarry Smith   diag = a->diag;
988273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
989bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
99029bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
991be5855fcSBarry Smith     }
992be5855fcSBarry Smith   }
993be5855fcSBarry Smith   PetscFunctionReturn(0);
994be5855fcSBarry Smith }
995be5855fcSBarry Smith 
9964a2ae208SSatish Balay #undef __FUNCT__
9974a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
998c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
99917ab2063SBarry Smith {
1000416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1001beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
1002beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
1003beeb8507SBarry Smith   int                ierr,n = A->n,m = A->m,i;
1004beeb8507SBarry Smith   const int          *idx,*diag;
100517ab2063SBarry Smith 
10063a40ed3dSBarry Smith   PetscFunctionBegin;
1007b965ef7fSBarry Smith   its = its*lits;
100891723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
100991723122SBarry Smith 
1010ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1011ed480e8bSBarry Smith   diag = a->diag;
1012ed480e8bSBarry Smith   if (!a->idiag) {
1013ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1014ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1015ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1016ed480e8bSBarry Smith 
1017ed480e8bSBarry Smith     v        = a->a;
1018ed480e8bSBarry Smith 
1019ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1020ed480e8bSBarry Smith     if (omega == 1.0 && fshift == 0.0) {
1021ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1022ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1023ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1024ed480e8bSBarry Smith       }
1025beeb8507SBarry Smith       PetscLogFlops(m);
1026ed480e8bSBarry Smith     } else {
1027ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1028ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1029beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1030ed480e8bSBarry Smith       }
1031beeb8507SBarry Smith       PetscLogFlops(2*m);
1032beeb8507SBarry Smith     }
1033ed480e8bSBarry Smith   }
1034ed480e8bSBarry Smith   t     = a->ssor;
1035ed480e8bSBarry Smith   idiag = a->idiag;
1036ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1037ed480e8bSBarry Smith 
1038ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
1039fb2e594dSBarry Smith   if (xx != bb) {
1040beeb8507SBarry Smith     ierr = VecGetArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1041fb2e594dSBarry Smith   } else {
1042fb2e594dSBarry Smith     b = x;
1043fb2e594dSBarry Smith   }
1044fb2e594dSBarry Smith 
1045ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1046ed480e8bSBarry Smith   xs   = x;
104717ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
104817ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1049ed480e8bSBarry Smith     bs = b;
105017ab2063SBarry Smith     for (i=0; i<m; i++) {
1051ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1052416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1053ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1054ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
105517ab2063SBarry Smith         sum  = b[i]*d/omega;
105617ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
105717ab2063SBarry Smith         x[i] = sum;
105817ab2063SBarry Smith     }
1059ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1060beeb8507SBarry Smith     if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1061ed480e8bSBarry Smith     PetscLogFlops(a->nz);
10623a40ed3dSBarry Smith     PetscFunctionReturn(0);
106317ab2063SBarry Smith   }
1064c783ea89SBarry Smith 
1065ed480e8bSBarry Smith 
1066fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1067fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1068fc3d8934SBarry Smith 
1069fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1070fc3d8934SBarry Smith 
1071fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1072fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
107348af12d7SBarry Smith     is the relaxation factor.
1074fc3d8934SBarry Smith     */
1075fc3d8934SBarry Smith 
107648af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
107729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
10783a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
107917ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
108017ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
108117ab2063SBarry Smith 
108217ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
108317ab2063SBarry Smith 
108417ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
108517ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
108617ab2063SBarry Smith     is the relaxation factor.
108717ab2063SBarry Smith     */
108817ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
108917ab2063SBarry Smith 
109017ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
109117ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1092416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1093ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1094ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
109517ab2063SBarry Smith       sum  = b[i];
109617ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1097ed480e8bSBarry Smith       x[i] = sum*idiag[i];
109817ab2063SBarry Smith     }
109917ab2063SBarry Smith 
110017ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1101416022c9SBarry Smith     v = a->a;
1102ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
110317ab2063SBarry Smith 
110417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1105ed480e8bSBarry Smith     ts = t;
1106416022c9SBarry Smith     diag = a->diag;
110717ab2063SBarry Smith     for (i=0; i<m; i++) {
1108416022c9SBarry Smith       n    = diag[i] - a->i[i];
1109ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1110ed480e8bSBarry Smith       v    = a->a + a->i[i];
111117ab2063SBarry Smith       sum  = t[i];
111217ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1113ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1114733d66baSBarry Smith       /*  x = x + t */
1115733d66baSBarry Smith       x[i] += t[i];
111617ab2063SBarry Smith     }
111717ab2063SBarry Smith 
1118b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
1119ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1120beeb8507SBarry Smith     if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11213a40ed3dSBarry Smith     PetscFunctionReturn(0);
112217ab2063SBarry Smith   }
112317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
112417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
112577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11260c559628SSatish Balay       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b);
112777d8c4bbSBarry Smith #else
112817ab2063SBarry Smith       for (i=0; i<m; i++) {
1129416022c9SBarry Smith         n    = diag[i] - a->i[i];
1130ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1131ed480e8bSBarry Smith         v    = a->a + a->i[i];
113217ab2063SBarry Smith         sum  = b[i];
113317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1134ed480e8bSBarry Smith         x[i] = sum*idiag[i];
113517ab2063SBarry Smith       }
113677d8c4bbSBarry Smith #endif
113717ab2063SBarry Smith       xb = x;
1138ed480e8bSBarry Smith       PetscLogFlops(a->nz);
11393a40ed3dSBarry Smith     } else xb = b;
114017ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
114117ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
114217ab2063SBarry Smith       for (i=0; i<m; i++) {
1143ed480e8bSBarry Smith         x[i] *= mdiag[i];
114417ab2063SBarry Smith       }
1145b0a32e0cSBarry Smith       PetscLogFlops(m);
114617ab2063SBarry Smith     }
114717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
114877d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11490c559628SSatish Balay       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb);
115077d8c4bbSBarry Smith #else
115117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1152416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1153ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1154ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
115517ab2063SBarry Smith         sum  = xb[i];
115617ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1157ed480e8bSBarry Smith         x[i] = sum*idiag[i];
115817ab2063SBarry Smith       }
115977d8c4bbSBarry Smith #endif
1160ed480e8bSBarry Smith       PetscLogFlops(a->nz);
116117ab2063SBarry Smith     }
116217ab2063SBarry Smith     its--;
116317ab2063SBarry Smith   }
116417ab2063SBarry Smith   while (its--) {
116517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
116677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11670c559628SSatish Balay       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
116877d8c4bbSBarry Smith #else
116917ab2063SBarry Smith       for (i=0; i<m; i++) {
1170ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1171416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1172ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1173ed480e8bSBarry Smith         v    = a->a + a->i[i];
117417ab2063SBarry Smith         sum  = b[i];
117517ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1176ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
117717ab2063SBarry Smith       }
117877d8c4bbSBarry Smith #endif
1179ed480e8bSBarry Smith       PetscLogFlops(a->nz);
118017ab2063SBarry Smith     }
118117ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
118277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11830c559628SSatish Balay       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
118477d8c4bbSBarry Smith #else
118517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1186ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1187416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1188ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1189ed480e8bSBarry Smith         v    = a->a + a->i[i];
119017ab2063SBarry Smith         sum  = b[i];
119117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1192ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
119317ab2063SBarry Smith       }
119477d8c4bbSBarry Smith #endif
1195ed480e8bSBarry Smith       PetscLogFlops(a->nz);
119617ab2063SBarry Smith     }
119717ab2063SBarry Smith   }
1198ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1199beeb8507SBarry Smith   if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
120117ab2063SBarry Smith }
120217ab2063SBarry Smith 
12034a2ae208SSatish Balay #undef __FUNCT__
12044a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12058f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
120617ab2063SBarry Smith {
1207416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12084e220ebcSLois Curfman McInnes 
12093a40ed3dSBarry Smith   PetscFunctionBegin;
1210273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1211273d9f13SBarry Smith   info->columns_global = (double)A->n;
1212273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1213273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12144e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12154e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12164e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12174e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12184e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12194e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12204e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12214e220ebcSLois Curfman McInnes   if (A->factor) {
12224e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12234e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12244e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12254e220ebcSLois Curfman McInnes   } else {
12264e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12274e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12284e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12294e220ebcSLois Curfman McInnes   }
12303a40ed3dSBarry Smith   PetscFunctionReturn(0);
123117ab2063SBarry Smith }
123217ab2063SBarry Smith 
12334a2ae208SSatish Balay #undef __FUNCT__
12344a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1235268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag)
123617ab2063SBarry Smith {
1237416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1238bfeeae90SHong Zhang   int         i,ierr,N,*rows,m = A->m - 1;
123917ab2063SBarry Smith 
12403a40ed3dSBarry Smith   PetscFunctionBegin;
1241b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
124217ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1243f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1244f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1245a45adfd6SMatthew Knepley       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1246bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1247f1e2ffcdSBarry Smith     }
1248f1e2ffcdSBarry Smith     if (diag) {
1249f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1250f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1251f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1252f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1253f1e2ffcdSBarry Smith       }
1254f1e2ffcdSBarry Smith     }
1255f1e2ffcdSBarry Smith   } else {
125617ab2063SBarry Smith     if (diag) {
125717ab2063SBarry Smith       for (i=0; i<N; i++) {
1258a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
12597ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1260416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1261bfeeae90SHong Zhang           a->a[a->i[rows[i]]] = *diag;
1262bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
12637ae801bdSBarry Smith         } else { /* in case row was completely empty */
1264d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126517ab2063SBarry Smith         }
126617ab2063SBarry Smith       }
12673a40ed3dSBarry Smith     } else {
126817ab2063SBarry Smith       for (i=0; i<N; i++) {
1269a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1270416022c9SBarry Smith         a->ilen[rows[i]] = 0;
127117ab2063SBarry Smith       }
127217ab2063SBarry Smith     }
1273f1e2ffcdSBarry Smith   }
12747ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127543a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12763a40ed3dSBarry Smith   PetscFunctionReturn(0);
127717ab2063SBarry Smith }
127817ab2063SBarry Smith 
12794a2ae208SSatish Balay #undef __FUNCT__
12804a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
128187828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
128217ab2063SBarry Smith {
1283416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1284b3fb0a6cSMatthew Knepley   int        *itmp;
128517ab2063SBarry Smith 
12863a40ed3dSBarry Smith   PetscFunctionBegin;
1287273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
128817ab2063SBarry Smith 
1289416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1290bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
129117ab2063SBarry Smith   if (idx) {
1292bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1293bfeeae90SHong Zhang     if (*nz) {
12944e093b46SBarry Smith       *idx = itmp;
129517ab2063SBarry Smith     }
129617ab2063SBarry Smith     else *idx = 0;
129717ab2063SBarry Smith   }
12983a40ed3dSBarry Smith   PetscFunctionReturn(0);
129917ab2063SBarry Smith }
130017ab2063SBarry Smith 
1301bfeeae90SHong Zhang /* remove this function? */
13024a2ae208SSatish Balay #undef __FUNCT__
13034a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
130487828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
130517ab2063SBarry Smith {
1306bfeeae90SHong Zhang   /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1307bfeeae90SHong Zhang      int ierr; */
13083a40ed3dSBarry Smith 
13093a40ed3dSBarry Smith   PetscFunctionBegin;
1310bfeeae90SHong Zhang   /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */
13113a40ed3dSBarry Smith   PetscFunctionReturn(0);
131217ab2063SBarry Smith }
131317ab2063SBarry Smith 
13144a2ae208SSatish Balay #undef __FUNCT__
13154a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1316064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
131717ab2063SBarry Smith {
1318416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
131987828ca2SBarry Smith   PetscScalar  *v = a->a;
132036db0b34SBarry Smith   PetscReal    sum = 0.0;
1321bfeeae90SHong Zhang   int          i,j,ierr;
132217ab2063SBarry Smith 
13233a40ed3dSBarry Smith   PetscFunctionBegin;
132417ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1325416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1326aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
132736db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
132817ab2063SBarry Smith #else
132917ab2063SBarry Smith       sum += (*v)*(*v); v++;
133017ab2063SBarry Smith #endif
133117ab2063SBarry Smith     }
1332064f8208SBarry Smith     *nrm = sqrt(sum);
13333a40ed3dSBarry Smith   } else if (type == NORM_1) {
133436db0b34SBarry Smith     PetscReal *tmp;
1335416022c9SBarry Smith     int    *jj = a->j;
1336b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1337273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1338064f8208SBarry Smith     *nrm = 0.0;
1339416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1340bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
134117ab2063SBarry Smith     }
1342273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1343064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
134417ab2063SBarry Smith     }
1345606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13463a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1347064f8208SBarry Smith     *nrm = 0.0;
1348273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1349bfeeae90SHong Zhang       v = a->a + a->i[j];
135017ab2063SBarry Smith       sum = 0.0;
1351416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1352cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
135317ab2063SBarry Smith       }
1354064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
135517ab2063SBarry Smith     }
13563a40ed3dSBarry Smith   } else {
135729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
135817ab2063SBarry Smith   }
13593a40ed3dSBarry Smith   PetscFunctionReturn(0);
136017ab2063SBarry Smith }
136117ab2063SBarry Smith 
13624a2ae208SSatish Balay #undef __FUNCT__
13634a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
13648f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
136517ab2063SBarry Smith {
1366416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1367416022c9SBarry Smith   Mat          C;
1368273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
136987828ca2SBarry Smith   PetscScalar  *array = a->a;
137017ab2063SBarry Smith 
13713a40ed3dSBarry Smith   PetscFunctionBegin;
1372273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1373b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1374273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
1375bfeeae90SHong Zhang 
1376bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1377273d9f13SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr);
1378606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
137917ab2063SBarry Smith   for (i=0; i<m; i++) {
138017ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1381416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1382b9b97703SBarry Smith     array += len;
1383b9b97703SBarry Smith     aj    += len;
138417ab2063SBarry Smith   }
138517ab2063SBarry Smith 
13866d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13876d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
138817ab2063SBarry Smith 
1389f1e2ffcdSBarry Smith   if (B) {
1390416022c9SBarry Smith     *B = C;
139117ab2063SBarry Smith   } else {
1392273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
139317ab2063SBarry Smith   }
13943a40ed3dSBarry Smith   PetscFunctionReturn(0);
139517ab2063SBarry Smith }
139617ab2063SBarry Smith 
1397cd0d46ebSvictorle EXTERN_C_BEGIN
1398cd0d46ebSvictorle #undef __FUNCT__
13995fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
14005fbd3699SBarry Smith int MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscTruth *f)
1401cd0d46ebSvictorle {
1402cd0d46ebSvictorle   Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
1403cd0d46ebSvictorle   int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
1404cd0d46ebSvictorle   int ma,na,mb,nb, i,ierr;
1405cd0d46ebSvictorle 
1406cd0d46ebSvictorle   PetscFunctionBegin;
1407cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1408cd0d46ebSvictorle 
1409cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na); CHKERRQ(ierr);
1410cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb); CHKERRQ(ierr);
1411cd0d46ebSvictorle   if (ma!=nb || na!=mb)
1412cd0d46ebSvictorle     SETERRQ(1,"Incompatible A/B sizes for symmetry test");
1413cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1414cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1415cd0d46ebSvictorle   va = aij->a; vb = bij->a;
1416cd0d46ebSvictorle   ierr = PetscMalloc(ma*sizeof(int),&aptr); CHKERRQ(ierr);
1417cd0d46ebSvictorle   ierr = PetscMalloc(mb*sizeof(int),&bptr); CHKERRQ(ierr);
1418cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1419cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1420cd0d46ebSvictorle 
1421cd0d46ebSvictorle   *f = PETSC_TRUE;
1422cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1423cd0d46ebSvictorle     /*printf("row %d spans %d--%d; we start @ %d\n",
1424cd0d46ebSvictorle       i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/
1425cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
1426cd0d46ebSvictorle       int idc,idr; PetscScalar vc,vr;
1427cd0d46ebSvictorle       /* column/row index/value */
1428cd0d46ebSvictorle       idc = adx[aptr[i]]; idr = bdx[bptr[idc]];
1429cd0d46ebSvictorle       vc = va[aptr[i]]; vr = vb[bptr[idc]];
1430cd0d46ebSvictorle       /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n",
1431cd0d46ebSvictorle 	aptr[i],i,idc,vc,idc,idr,vr);*/
1432cd0d46ebSvictorle       if (i!=idr || vc!=vr) {
1433cd0d46ebSvictorle 	*f = PETSC_FALSE; goto done;
1434cd0d46ebSvictorle       } else {
14353aeef889SHong Zhang 	aptr[i]++; if (B || i!=idc) bptr[idc]++;
1436cd0d46ebSvictorle       }
1437cd0d46ebSvictorle     }
1438cd0d46ebSvictorle   }
1439cd0d46ebSvictorle  done:
1440cd0d46ebSvictorle   ierr = PetscFree(aptr); CHKERRQ(ierr);
14413aeef889SHong Zhang   if (B) {
14423aeef889SHong Zhang     ierr = PetscFree(bptr); CHKERRQ(ierr);
14433aeef889SHong Zhang   }
1444cd0d46ebSvictorle 
1445cd0d46ebSvictorle   PetscFunctionReturn(0);
1446cd0d46ebSvictorle }
1447cd0d46ebSvictorle EXTERN_C_END
1448cd0d46ebSvictorle 
14494a2ae208SSatish Balay #undef __FUNCT__
14504a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14518f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
145217ab2063SBarry Smith {
1453416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
145487828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1455bfeeae90SHong Zhang   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
145617ab2063SBarry Smith 
14573a40ed3dSBarry Smith   PetscFunctionBegin;
145817ab2063SBarry Smith   if (ll) {
14593ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14603ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1461e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1462273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
1463ed480e8bSBarry Smith     ierr = VecGetArrayFast(ll,&l);CHKERRQ(ierr);
1464416022c9SBarry Smith     v = a->a;
146517ab2063SBarry Smith     for (i=0; i<m; i++) {
146617ab2063SBarry Smith       x = l[i];
1467416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
146817ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
146917ab2063SBarry Smith     }
1470ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(ll,&l);CHKERRQ(ierr);
1471b0a32e0cSBarry Smith     PetscLogFlops(nz);
147217ab2063SBarry Smith   }
147317ab2063SBarry Smith   if (rr) {
1474e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1475273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
1476ed480e8bSBarry Smith     ierr = VecGetArrayFast(rr,&r);CHKERRQ(ierr);
1477416022c9SBarry Smith     v = a->a; jj = a->j;
147817ab2063SBarry Smith     for (i=0; i<nz; i++) {
1479bfeeae90SHong Zhang       (*v++) *= r[*jj++];
148017ab2063SBarry Smith     }
1481ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(rr,&r);CHKERRQ(ierr);
1482b0a32e0cSBarry Smith     PetscLogFlops(nz);
148317ab2063SBarry Smith   }
14843a40ed3dSBarry Smith   PetscFunctionReturn(0);
148517ab2063SBarry Smith }
148617ab2063SBarry Smith 
14874a2ae208SSatish Balay #undef __FUNCT__
14884a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
14897b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
149017ab2063SBarry Smith {
1491db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1492273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
149336db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
1494bfeeae90SHong Zhang   int          *irow,*icol,nrows,ncols;
149599141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
149687828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1497416022c9SBarry Smith   Mat          C;
1498fee21e36SBarry Smith   PetscTruth   stride;
149917ab2063SBarry Smith 
15003a40ed3dSBarry Smith   PetscFunctionBegin;
1501d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
150229bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1503d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
150429bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
150599141d43SSatish Balay 
150617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1507b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1508b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
150917ab2063SBarry Smith 
1510fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1511fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1512fee21e36SBarry Smith   if (stride && step == 1) {
151302834360SBarry Smith     /* special case of contiguous rows */
151431ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
151531ebf83bSSatish Balay     starts = lens + nrows;
151602834360SBarry Smith     /* loop over new rows determining lens and starting points */
151702834360SBarry Smith     for (i=0; i<nrows; i++) {
1518bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1519a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
152002834360SBarry Smith       for (k=kstart; k<kend; k++) {
1521bfeeae90SHong Zhang         if (aj[k] >= first) {
152202834360SBarry Smith           starts[i] = k;
152302834360SBarry Smith           break;
152402834360SBarry Smith 	}
152502834360SBarry Smith       }
1526a2744918SBarry Smith       sum = 0;
152702834360SBarry Smith       while (k < kend) {
1528bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1529a2744918SBarry Smith         sum++;
153002834360SBarry Smith       }
1531a2744918SBarry Smith       lens[i] = sum;
153202834360SBarry Smith     }
153302834360SBarry Smith     /* create submatrix */
1534cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
153508480c60SBarry Smith       int n_cols,n_rows;
153608480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
153729bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1538d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
153908480c60SBarry Smith       C = *B;
15403a40ed3dSBarry Smith     } else {
154102834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
154208480c60SBarry Smith     }
1543db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1544db02288aSLois Curfman McInnes 
154502834360SBarry Smith     /* loop over rows inserting into submatrix */
1546db02288aSLois Curfman McInnes     a_new    = c->a;
1547db02288aSLois Curfman McInnes     j_new    = c->j;
1548db02288aSLois Curfman McInnes     i_new    = c->i;
1549bfeeae90SHong Zhang 
155002834360SBarry Smith     for (i=0; i<nrows; i++) {
1551a2744918SBarry Smith       ii    = starts[i];
1552a2744918SBarry Smith       lensi = lens[i];
1553a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1554a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
155502834360SBarry Smith       }
155687828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1557a2744918SBarry Smith       a_new      += lensi;
1558a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1559a2744918SBarry Smith       c->ilen[i]  = lensi;
156002834360SBarry Smith     }
1561606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15623a40ed3dSBarry Smith   } else {
156302834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1564b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
1565bfeeae90SHong Zhang 
1566b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1567549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
156817ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
156902834360SBarry Smith     /* determine lens of each row */
157002834360SBarry Smith     for (i=0; i<nrows; i++) {
1571bfeeae90SHong Zhang       kstart  = ai[irow[i]];
157202834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
157302834360SBarry Smith       lens[i] = 0;
157402834360SBarry Smith       for (k=kstart; k<kend; k++) {
1575bfeeae90SHong Zhang         if (smap[aj[k]]) {
157602834360SBarry Smith           lens[i]++;
157702834360SBarry Smith         }
157802834360SBarry Smith       }
157902834360SBarry Smith     }
158017ab2063SBarry Smith     /* Create and fill new matrix */
1581a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15820f5bd95cSBarry Smith       PetscTruth equal;
15830f5bd95cSBarry Smith 
158499141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1585273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1586273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
15870f5bd95cSBarry Smith       if (!equal) {
158829bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
158999141d43SSatish Balay       }
1590273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
159108480c60SBarry Smith       C = *B;
15923a40ed3dSBarry Smith     } else {
159302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
159408480c60SBarry Smith     }
159599141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
159617ab2063SBarry Smith     for (i=0; i<nrows; i++) {
159799141d43SSatish Balay       row    = irow[i];
1598bfeeae90SHong Zhang       kstart = ai[row];
159999141d43SSatish Balay       kend   = kstart + a->ilen[row];
1600bfeeae90SHong Zhang       mat_i  = c->i[i];
160199141d43SSatish Balay       mat_j  = c->j + mat_i;
160299141d43SSatish Balay       mat_a  = c->a + mat_i;
160399141d43SSatish Balay       mat_ilen = c->ilen + i;
160417ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1605bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1606ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
160799141d43SSatish Balay           *mat_a++ = a->a[k];
160899141d43SSatish Balay           (*mat_ilen)++;
160999141d43SSatish Balay 
161017ab2063SBarry Smith         }
161117ab2063SBarry Smith       }
161217ab2063SBarry Smith     }
161302834360SBarry Smith     /* Free work space */
161402834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1615606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1616606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
161702834360SBarry Smith   }
16186d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16196d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
162017ab2063SBarry Smith 
162117ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1622416022c9SBarry Smith   *B = C;
16233a40ed3dSBarry Smith   PetscFunctionReturn(0);
162417ab2063SBarry Smith }
162517ab2063SBarry Smith 
1626a871dcd8SBarry Smith /*
1627a871dcd8SBarry Smith */
16284a2ae208SSatish Balay #undef __FUNCT__
16294a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1630b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1631a871dcd8SBarry Smith {
163263b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
163308480c60SBarry Smith   int        ierr;
163463b91edcSBarry Smith   Mat        outA;
1635b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
163663b91edcSBarry Smith 
16373a40ed3dSBarry Smith   PetscFunctionBegin;
1638d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1639b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1640b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1641b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
164229bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1643b8a78c4aSBarry Smith   }
1644a871dcd8SBarry Smith 
164563b91edcSBarry Smith   outA          = inA;
164663b91edcSBarry Smith   inA->factor   = FACTOR_LU;
164763b91edcSBarry Smith   a->row        = row;
164863b91edcSBarry Smith   a->col        = col;
1649c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1650c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
165163b91edcSBarry Smith 
165236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1653b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16544c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1655b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1656f0ec6fceSSatish Balay 
165794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
165887828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
165994a9d846SBarry Smith   }
166063b91edcSBarry Smith 
166108480c60SBarry Smith   if (!a->diag) {
1662f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
166363b91edcSBarry Smith   }
166463b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1666a871dcd8SBarry Smith }
1667a871dcd8SBarry Smith 
1668d9eff348SSatish Balay #include "petscblaslapack.h"
16694a2ae208SSatish Balay #undef __FUNCT__
16704a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1671268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA)
1672f0b747eeSBarry Smith {
1673f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1674f0b747eeSBarry Smith   int        one = 1;
16753a40ed3dSBarry Smith 
16763a40ed3dSBarry Smith   PetscFunctionBegin;
1677268466fbSBarry Smith   BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one);
1678b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
16793a40ed3dSBarry Smith   PetscFunctionReturn(0);
1680f0b747eeSBarry Smith }
1681f0b747eeSBarry Smith 
16824a2ae208SSatish Balay #undef __FUNCT__
16834a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
1684268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1685cddf8d76SBarry Smith {
1686cddf8d76SBarry Smith   int ierr,i;
1687cddf8d76SBarry Smith 
16883a40ed3dSBarry Smith   PetscFunctionBegin;
1689cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1690b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1691cddf8d76SBarry Smith   }
1692cddf8d76SBarry Smith 
1693cddf8d76SBarry Smith   for (i=0; i<n; i++) {
16946a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1695cddf8d76SBarry Smith   }
16963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1697cddf8d76SBarry Smith }
1698cddf8d76SBarry Smith 
16994a2ae208SSatish Balay #undef __FUNCT__
17004a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17018f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17025a838052SSatish Balay {
1703f830108cSBarry Smith   PetscFunctionBegin;
17045a838052SSatish Balay   *bs = 1;
17053a40ed3dSBarry Smith   PetscFunctionReturn(0);
17065a838052SSatish Balay }
17075a838052SSatish Balay 
17084a2ae208SSatish Balay #undef __FUNCT__
17094a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
1710268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov)
17114dcbc457SBarry Smith {
1712e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1713efb16452SHong Zhang   int        row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17148a047759SSatish Balay   int        start,end,*ai,*aj;
1715f1af5d2fSBarry Smith   PetscBT    table;
1716bbd702dbSSatish Balay 
17173a40ed3dSBarry Smith   PetscFunctionBegin;
1718273d9f13SBarry Smith   m     = A->m;
1719e4d965acSSatish Balay   ai    = a->i;
1720bfeeae90SHong Zhang   aj    = a->j;
17218a047759SSatish Balay 
1722a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
172306763907SSatish Balay 
1724b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17256831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
172606763907SSatish Balay 
1727e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1728b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1729e4d965acSSatish Balay     isz  = 0;
17306831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1731e4d965acSSatish Balay 
1732e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17334dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1734b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1735e4d965acSSatish Balay 
1736dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1737e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1738f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17394dcbc457SBarry Smith     }
174006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
174106763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1742e4d965acSSatish Balay 
174304a348a9SBarry Smith     k = 0;
174404a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
174504a348a9SBarry Smith       n = isz;
174606763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1747e4d965acSSatish Balay         row   = nidx[k];
1748e4d965acSSatish Balay         start = ai[row];
1749e4d965acSSatish Balay         end   = ai[row+1];
175004a348a9SBarry Smith         for (l = start; l<end ; l++){
1751efb16452SHong Zhang           val = aj[l] ;
1752f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1753e4d965acSSatish Balay         }
1754e4d965acSSatish Balay       }
1755e4d965acSSatish Balay     }
1756029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1757e4d965acSSatish Balay   }
17586831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1759606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17603a40ed3dSBarry Smith   PetscFunctionReturn(0);
17614dcbc457SBarry Smith }
176217ab2063SBarry Smith 
17630513a670SBarry Smith /* -------------------------------------------------------------- */
17644a2ae208SSatish Balay #undef __FUNCT__
17654a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17660513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17670513a670SBarry Smith {
17680513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
176987828ca2SBarry Smith   PetscScalar  *vwork;
1770273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
17710513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
177256cd22aeSBarry Smith   IS           icolp,irowp;
17730513a670SBarry Smith 
17743a40ed3dSBarry Smith   PetscFunctionBegin;
17754c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
177656cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
17774c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
177856cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17790513a670SBarry Smith 
17800513a670SBarry Smith   /* determine lengths of permuted rows */
1781b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
17820513a670SBarry Smith   for (i=0; i<m; i++) {
17830513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
17840513a670SBarry Smith   }
17850513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1786606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
17870513a670SBarry Smith 
1788b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
17890513a670SBarry Smith   for (i=0; i<m; i++) {
17900513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
17910513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
17920513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
17930513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
17940513a670SBarry Smith   }
1795606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
17960513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17970513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
179856cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
179956cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
180056cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
180156cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18023a40ed3dSBarry Smith   PetscFunctionReturn(0);
18030513a670SBarry Smith }
18040513a670SBarry Smith 
18054a2ae208SSatish Balay #undef __FUNCT__
18064a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1807682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1808682d7d0cSBarry Smith {
1809c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1810682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1811d132466eSBarry Smith   int               ierr;
1812682d7d0cSBarry Smith 
18133a40ed3dSBarry Smith   PetscFunctionBegin;
1814c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1815d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1816d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1817d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1818d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1819d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
182016ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
1821ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1822ca44d042SBarry Smith #endif
18233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1824682d7d0cSBarry Smith }
182597304618SKris Buschelman 
18264a2ae208SSatish Balay #undef __FUNCT__
18274a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1828cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1829cb5b572fSBarry Smith {
1830be6bf707SBarry Smith   int        ierr;
1831cb5b572fSBarry Smith 
1832cb5b572fSBarry Smith   PetscFunctionBegin;
183333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
183433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1835be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1836be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1837be6bf707SBarry Smith 
1838bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
183929bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1840cb5b572fSBarry Smith     }
1841bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1842cb5b572fSBarry Smith   } else {
1843cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1844cb5b572fSBarry Smith   }
1845cb5b572fSBarry Smith   PetscFunctionReturn(0);
1846cb5b572fSBarry Smith }
1847cb5b572fSBarry Smith 
18484a2ae208SSatish Balay #undef __FUNCT__
18494a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1850273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1851273d9f13SBarry Smith {
1852273d9f13SBarry Smith   int        ierr;
1853273d9f13SBarry Smith 
1854273d9f13SBarry Smith   PetscFunctionBegin;
1855273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1856273d9f13SBarry Smith   PetscFunctionReturn(0);
1857273d9f13SBarry Smith }
1858273d9f13SBarry Smith 
18594a2ae208SSatish Balay #undef __FUNCT__
18604a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
18614e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
18626c0721eeSBarry Smith {
18636c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18646c0721eeSBarry Smith   PetscFunctionBegin;
18656c0721eeSBarry Smith   *array = a->a;
18666c0721eeSBarry Smith   PetscFunctionReturn(0);
18676c0721eeSBarry Smith }
18686c0721eeSBarry Smith 
18694a2ae208SSatish Balay #undef __FUNCT__
18704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
18714e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
18726c0721eeSBarry Smith {
18736c0721eeSBarry Smith   PetscFunctionBegin;
18746c0721eeSBarry Smith   PetscFunctionReturn(0);
18756c0721eeSBarry Smith }
1876273d9f13SBarry Smith 
1877ee4f033dSBarry Smith #undef __FUNCT__
1878ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1879ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1880ee4f033dSBarry Smith {
1881ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1882ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
188387828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
188487828ca2SBarry Smith   PetscScalar   *vscale_array;
1885ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1886ee4f033dSBarry Smith   Vec           w1,w2,w3;
1887ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1888ee4f033dSBarry Smith   PetscTruth    flg;
1889ee4f033dSBarry Smith 
1890ee4f033dSBarry Smith   PetscFunctionBegin;
1891ee4f033dSBarry Smith   if (!coloring->w1) {
1892ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1893ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1894ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1895ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1896ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1897ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1898ee4f033dSBarry Smith   }
1899ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1900ee4f033dSBarry Smith 
1901ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1902e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1903ee4f033dSBarry Smith   if (flg) {
1904ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1905ee4f033dSBarry Smith   } else {
1906ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1907ee4f033dSBarry Smith   }
1908ee4f033dSBarry Smith 
1909ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1910ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1911ee4f033dSBarry Smith 
1912ee4f033dSBarry Smith   /*
1913ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1914ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1915ee4f033dSBarry Smith   */
1916ee4f033dSBarry Smith   if (coloring->F) {
1917ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1918ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1919ee4f033dSBarry Smith     if (m1 != m2) {
1920ee4f033dSBarry Smith       coloring->F = 0;
1921ee4f033dSBarry Smith     }
1922ee4f033dSBarry Smith   }
1923ee4f033dSBarry Smith 
1924ee4f033dSBarry Smith   if (coloring->F) {
1925ee4f033dSBarry Smith     w1          = coloring->F;
1926ee4f033dSBarry Smith     coloring->F = 0;
1927ee4f033dSBarry Smith   } else {
192866f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1929ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
193066f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1931ee4f033dSBarry Smith   }
1932ee4f033dSBarry Smith 
1933ee4f033dSBarry Smith   /*
1934ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1935ee4f033dSBarry Smith   */
1936ed480e8bSBarry Smith   ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start;
1937ed480e8bSBarry Smith   ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1938ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1939ee4f033dSBarry Smith     /*
1940ee4f033dSBarry Smith        Loop over each column associated with color adding the
1941ee4f033dSBarry Smith        perturbation to the vector w3.
1942ee4f033dSBarry Smith     */
1943ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1944ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1945ee4f033dSBarry Smith       dx  = xx[col];
1946ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1947ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1948ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1949ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1950ee4f033dSBarry Smith #else
1951ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1952ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1953ee4f033dSBarry Smith #endif
1954ee4f033dSBarry Smith       dx                *= epsilon;
1955ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1956ee4f033dSBarry Smith     }
1957ee4f033dSBarry Smith   }
1958ed480e8bSBarry Smith   vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1959ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1960ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1961ee4f033dSBarry Smith 
1962ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
1963ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
1964ee4f033dSBarry Smith 
1965ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
1966ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
1967ee4f033dSBarry Smith 
1968ed480e8bSBarry Smith   ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1969ee4f033dSBarry Smith   /*
1970ee4f033dSBarry Smith       Loop over each color
1971ee4f033dSBarry Smith   */
1972ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
197349b058dcSBarry Smith     coloring->currentcolor = k;
1974ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
1975ed480e8bSBarry Smith     ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
1976ee4f033dSBarry Smith     /*
1977ee4f033dSBarry Smith        Loop over each column associated with color adding the
1978ee4f033dSBarry Smith        perturbation to the vector w3.
1979ee4f033dSBarry Smith     */
1980ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1981ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1982ee4f033dSBarry Smith       dx  = xx[col];
1983ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1984ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1985ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1986ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1987ee4f033dSBarry Smith #else
1988ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1989ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1990ee4f033dSBarry Smith #endif
1991ee4f033dSBarry Smith       dx            *= epsilon;
1992ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
1993ee4f033dSBarry Smith       w3_array[col] += dx;
1994ee4f033dSBarry Smith     }
1995ed480e8bSBarry Smith     w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr);
1996ee4f033dSBarry Smith 
1997ee4f033dSBarry Smith     /*
1998ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
1999ee4f033dSBarry Smith     */
2000ee4f033dSBarry Smith 
200166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2002ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
200366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2004ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2005ee4f033dSBarry Smith 
2006ee4f033dSBarry Smith     /*
2007ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2008ee4f033dSBarry Smith     */
2009ed480e8bSBarry Smith     ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr);
2010ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2011ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2012ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2013ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2014ee4f033dSBarry Smith       srow   = row + start;
2015ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2016ee4f033dSBarry Smith     }
2017ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr);
2018ee4f033dSBarry Smith   }
201949b058dcSBarry Smith   coloring->currentcolor = k;
2020ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2021ed480e8bSBarry Smith   xx = xx + start; ierr  = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr);
2022ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2023ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2024ee4f033dSBarry Smith   PetscFunctionReturn(0);
2025ee4f033dSBarry Smith }
2026ee4f033dSBarry Smith 
2027ac90fabeSBarry Smith #include "petscblaslapack.h"
2028ac90fabeSBarry Smith #undef __FUNCT__
2029ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
20307cff1425SSatish Balay int MatAXPY_SeqAIJ(const PetscScalar a[],Mat X,Mat Y,MatStructure str)
2031ac90fabeSBarry Smith {
2032c537a176SHong Zhang   int        ierr,one=1,i;
2033ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2034ac90fabeSBarry Smith 
2035ac90fabeSBarry Smith   PetscFunctionBegin;
2036ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2037268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
2038c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2039a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2040a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2041a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2042a30b2313SHong Zhang     }
2043a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
204424f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2045a30b2313SHong Zhang       y->XtoY = X;
2046c537a176SHong Zhang     }
2047a30b2313SHong Zhang     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]);
2048e2dd4fc4Svictorle     PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);
2049ac90fabeSBarry Smith   } else {
2050ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2051ac90fabeSBarry Smith   }
2052ac90fabeSBarry Smith   PetscFunctionReturn(0);
2053ac90fabeSBarry Smith }
2054ac90fabeSBarry Smith 
2055682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20560a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2057cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2058cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2059cb5b572fSBarry Smith        MatMult_SeqAIJ,
206097304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
20617c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20627c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2063cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2064cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20657c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
206697304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2067cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2068cb5b572fSBarry Smith        0,
206917ab2063SBarry Smith        MatRelax_SeqAIJ,
207017ab2063SBarry Smith        MatTranspose_SeqAIJ,
207197304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2072cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2073cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2074cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2075cb5b572fSBarry Smith        MatNorm_SeqAIJ,
207697304618SKris Buschelman /*20*/ 0,
2077cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
207817ab2063SBarry Smith        MatCompress_SeqAIJ,
2079cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2080cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
208197304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2082cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2083cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2084f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2085a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
208697304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2087cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2088861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
20896c0721eeSBarry Smith        MatGetArray_SeqAIJ,
20906c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
209197304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2092cb5b572fSBarry Smith        0,
2093cb5b572fSBarry Smith        0,
2094cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2095cb5b572fSBarry Smith        0,
209697304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2097cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2098cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2099cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2100cb5b572fSBarry Smith        MatCopy_SeqAIJ,
210197304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ,
2102cb5b572fSBarry Smith        MatScale_SeqAIJ,
2103cb5b572fSBarry Smith        0,
2104cb5b572fSBarry Smith        0,
21056945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
210697304618SKris Buschelman /*50*/ MatGetBlockSize_SeqAIJ,
21073b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21083b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21093b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2110a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
211197304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2112b9617806SBarry Smith        0,
21130513a670SBarry Smith        0,
2114cda55fadSBarry Smith        MatPermute_SeqAIJ,
2115cda55fadSBarry Smith        0,
211697304618SKris Buschelman /*60*/ 0,
2117b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2118b9b97703SBarry Smith        MatView_SeqAIJ,
21198a124369SBarry Smith        MatGetPetscMaps_Petsc,
2120ee4f033dSBarry Smith        0,
212197304618SKris Buschelman /*65*/ 0,
2122ee4f033dSBarry Smith        0,
2123ee4f033dSBarry Smith        0,
2124ee4f033dSBarry Smith        0,
2125ee4f033dSBarry Smith        0,
212697304618SKris Buschelman /*70*/ 0,
2127ee4f033dSBarry Smith        0,
2128ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2129ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2130ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
213197304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ,
213297304618SKris Buschelman        0,
213397304618SKris Buschelman        0,
213497304618SKris Buschelman        0,
213597304618SKris Buschelman        0,
213697304618SKris Buschelman /*80*/ 0,
213797304618SKris Buschelman        0,
213897304618SKris Buschelman        0,
213997304618SKris Buschelman        0,
214097304618SKris Buschelman        0,
214197304618SKris Buschelman /*85*/ MatLoad_SeqAIJ};
214217ab2063SBarry Smith 
2143fb2e594dSBarry Smith EXTERN_C_BEGIN
21444a2ae208SSatish Balay #undef __FUNCT__
21454a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
214615091d37SBarry Smith 
2147bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2148bef8e0ddSBarry Smith {
2149bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2150bef8e0ddSBarry Smith   int        i,nz,n;
2151bef8e0ddSBarry Smith 
2152bef8e0ddSBarry Smith   PetscFunctionBegin;
2153bef8e0ddSBarry Smith 
2154bef8e0ddSBarry Smith   nz = aij->maxnz;
2155273d9f13SBarry Smith   n  = mat->n;
2156bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2157bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2158bef8e0ddSBarry Smith   }
2159bef8e0ddSBarry Smith   aij->nz = nz;
2160bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2161bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2162bef8e0ddSBarry Smith   }
2163bef8e0ddSBarry Smith 
2164bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2165bef8e0ddSBarry Smith }
2166fb2e594dSBarry Smith EXTERN_C_END
2167bef8e0ddSBarry Smith 
21684a2ae208SSatish Balay #undef __FUNCT__
21694a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2170bef8e0ddSBarry Smith /*@
2171bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2172bef8e0ddSBarry Smith        in the matrix.
2173bef8e0ddSBarry Smith 
2174bef8e0ddSBarry Smith   Input Parameters:
2175bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2176bef8e0ddSBarry Smith -  indices - the column indices
2177bef8e0ddSBarry Smith 
217815091d37SBarry Smith   Level: advanced
217915091d37SBarry Smith 
2180bef8e0ddSBarry Smith   Notes:
2181bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2182bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2183bef8e0ddSBarry Smith   of the MatSetValues() operation.
2184bef8e0ddSBarry Smith 
2185bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2186bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2187bef8e0ddSBarry Smith 
2188bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2189bef8e0ddSBarry Smith 
2190b9617806SBarry Smith     The indices should start with zero, not one.
2191b9617806SBarry Smith 
2192bef8e0ddSBarry Smith @*/
2193bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2194bef8e0ddSBarry Smith {
2195bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2196bef8e0ddSBarry Smith 
2197bef8e0ddSBarry Smith   PetscFunctionBegin;
2198bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2199c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2200bef8e0ddSBarry Smith   if (f) {
2201bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2202bef8e0ddSBarry Smith   } else {
220329bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2204bef8e0ddSBarry Smith   }
2205bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2206bef8e0ddSBarry Smith }
2207bef8e0ddSBarry Smith 
2208be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2209be6bf707SBarry Smith 
2210fb2e594dSBarry Smith EXTERN_C_BEGIN
22114a2ae208SSatish Balay #undef __FUNCT__
22124a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2213be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2214be6bf707SBarry Smith {
2215be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2216bfeeae90SHong Zhang   size_t       nz = aij->i[mat->m],ierr;
2217be6bf707SBarry Smith 
2218be6bf707SBarry Smith   PetscFunctionBegin;
2219be6bf707SBarry Smith   if (aij->nonew != 1) {
222029bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2221be6bf707SBarry Smith   }
2222be6bf707SBarry Smith 
2223be6bf707SBarry Smith   /* allocate space for values if not already there */
2224be6bf707SBarry Smith   if (!aij->saved_values) {
222587828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2226be6bf707SBarry Smith   }
2227be6bf707SBarry Smith 
2228be6bf707SBarry Smith   /* copy values over */
222987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2230be6bf707SBarry Smith   PetscFunctionReturn(0);
2231be6bf707SBarry Smith }
2232fb2e594dSBarry Smith EXTERN_C_END
2233be6bf707SBarry Smith 
22344a2ae208SSatish Balay #undef __FUNCT__
2235b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2236be6bf707SBarry Smith /*@
2237be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2238be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2239be6bf707SBarry Smith        nonlinear portion.
2240be6bf707SBarry Smith 
2241be6bf707SBarry Smith    Collect on Mat
2242be6bf707SBarry Smith 
2243be6bf707SBarry Smith   Input Parameters:
2244be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2245be6bf707SBarry Smith 
224615091d37SBarry Smith   Level: advanced
224715091d37SBarry Smith 
2248be6bf707SBarry Smith   Common Usage, with SNESSolve():
2249be6bf707SBarry Smith $    Create Jacobian matrix
2250be6bf707SBarry Smith $    Set linear terms into matrix
2251be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2252be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2253be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2254be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2255be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2256be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2257be6bf707SBarry Smith $    In your Jacobian routine
2258be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2259be6bf707SBarry Smith $      Set nonlinear terms in matrix
2260be6bf707SBarry Smith 
2261be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2262be6bf707SBarry Smith $    // build linear portion of Jacobian
2263be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2264be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2265be6bf707SBarry Smith $    loop over nonlinear iterations
2266be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2267be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2268be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2269be6bf707SBarry Smith $       Solve linear system with Jacobian
2270be6bf707SBarry Smith $    endloop
2271be6bf707SBarry Smith 
2272be6bf707SBarry Smith   Notes:
2273be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2274be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2275be6bf707SBarry Smith     calling this routine.
2276be6bf707SBarry Smith 
2277be6bf707SBarry Smith .seealso: MatRetrieveValues()
2278be6bf707SBarry Smith 
2279be6bf707SBarry Smith @*/
2280be6bf707SBarry Smith int MatStoreValues(Mat mat)
2281be6bf707SBarry Smith {
2282be6bf707SBarry Smith   int ierr,(*f)(Mat);
2283be6bf707SBarry Smith 
2284be6bf707SBarry Smith   PetscFunctionBegin;
2285be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
228629bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
228729bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2288be6bf707SBarry Smith 
2289c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2290be6bf707SBarry Smith   if (f) {
2291be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2292be6bf707SBarry Smith   } else {
229329bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2294be6bf707SBarry Smith   }
2295be6bf707SBarry Smith   PetscFunctionReturn(0);
2296be6bf707SBarry Smith }
2297be6bf707SBarry Smith 
2298fb2e594dSBarry Smith EXTERN_C_BEGIN
22994a2ae208SSatish Balay #undef __FUNCT__
23004a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2301be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2302be6bf707SBarry Smith {
2303be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2304bfeeae90SHong Zhang   int        nz = aij->i[mat->m],ierr;
2305be6bf707SBarry Smith 
2306be6bf707SBarry Smith   PetscFunctionBegin;
2307be6bf707SBarry Smith   if (aij->nonew != 1) {
230829bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2309be6bf707SBarry Smith   }
2310be6bf707SBarry Smith   if (!aij->saved_values) {
231129bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2312be6bf707SBarry Smith   }
2313be6bf707SBarry Smith 
2314be6bf707SBarry Smith   /* copy values over */
231587828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2316be6bf707SBarry Smith   PetscFunctionReturn(0);
2317be6bf707SBarry Smith }
2318fb2e594dSBarry Smith EXTERN_C_END
2319be6bf707SBarry Smith 
23204a2ae208SSatish Balay #undef __FUNCT__
23214a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2322be6bf707SBarry Smith /*@
2323be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2324be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2325be6bf707SBarry Smith        nonlinear portion.
2326be6bf707SBarry Smith 
2327be6bf707SBarry Smith    Collect on Mat
2328be6bf707SBarry Smith 
2329be6bf707SBarry Smith   Input Parameters:
2330be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2331be6bf707SBarry Smith 
233215091d37SBarry Smith   Level: advanced
233315091d37SBarry Smith 
2334be6bf707SBarry Smith .seealso: MatStoreValues()
2335be6bf707SBarry Smith 
2336be6bf707SBarry Smith @*/
2337be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2338be6bf707SBarry Smith {
2339be6bf707SBarry Smith   int ierr,(*f)(Mat);
2340be6bf707SBarry Smith 
2341be6bf707SBarry Smith   PetscFunctionBegin;
2342be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
234329bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
234429bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2345be6bf707SBarry Smith 
2346c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2347be6bf707SBarry Smith   if (f) {
2348be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2349be6bf707SBarry Smith   } else {
235029bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2351be6bf707SBarry Smith   }
2352be6bf707SBarry Smith   PetscFunctionReturn(0);
2353be6bf707SBarry Smith }
2354be6bf707SBarry Smith 
2355f83d6046SBarry Smith /*
2356f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2357f83d6046SBarry Smith */
235816ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2359f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2360f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2361f83d6046SBarry Smith EXTERN_C_BEGIN
23624a2ae208SSatish Balay #undef __FUNCT__
23634a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ"
236462aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine)
2365f83d6046SBarry Smith {
236625922d2bSSatish Balay   int         ierr;
2367f83d6046SBarry Smith   Mat         B = (Mat)obj;
2368f83d6046SBarry Smith   mxArray     *mat;
2369d79a51d8SBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
2370d79a51d8SBarry Smith 
2371f83d6046SBarry Smith   PetscFunctionBegin;
237201820c62SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
237387828ca2SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
2374d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
237566826eb6SBarry Smith   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
237666826eb6SBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2377f83d6046SBarry Smith 
237801820c62SBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
2379bfeeae90SHong Zhang 
2380ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
238116ce804cSBarry Smith   engPutVariable((Engine *)mengine,obj->name,mat);
2382f83d6046SBarry Smith   PetscFunctionReturn(0);
2383f83d6046SBarry Smith }
2384f83d6046SBarry Smith EXTERN_C_END
238566826eb6SBarry Smith 
238666826eb6SBarry Smith EXTERN_C_BEGIN
23874a2ae208SSatish Balay #undef __FUNCT__
23884a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ"
238962aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine)
239066826eb6SBarry Smith {
239166826eb6SBarry Smith   int        ierr,ii;
239266826eb6SBarry Smith   Mat        mat = (Mat)obj;
239366826eb6SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
239466826eb6SBarry Smith   mxArray    *mmat;
239566826eb6SBarry Smith 
23966c0721eeSBarry Smith   PetscFunctionBegin;
239766826eb6SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
239866826eb6SBarry Smith 
239916ce804cSBarry Smith   mmat = engGetVariable((Engine *)mengine,obj->name);
240066826eb6SBarry Smith 
2401a65776f3SBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->m];
2402a7ed9263SMatthew Knepley   ierr              = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
240366826eb6SBarry Smith   aij->j            = (int*)(aij->a + aij->nz);
240466826eb6SBarry Smith   aij->i            = aij->j + aij->nz;
240566826eb6SBarry Smith   aij->singlemalloc = PETSC_TRUE;
240666826eb6SBarry Smith   aij->freedata     = PETSC_TRUE;
240766826eb6SBarry Smith 
240887828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
240966826eb6SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
241066826eb6SBarry Smith   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
241166826eb6SBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
241266826eb6SBarry Smith 
241366826eb6SBarry Smith   for (ii=0; ii<mat->m; ii++) {
241466826eb6SBarry Smith     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
241566826eb6SBarry Smith   }
241666826eb6SBarry Smith 
241766826eb6SBarry Smith   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
241866826eb6SBarry Smith   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
241966826eb6SBarry Smith 
242066826eb6SBarry Smith   PetscFunctionReturn(0);
242166826eb6SBarry Smith }
242266826eb6SBarry Smith EXTERN_C_END
2423f83d6046SBarry Smith #endif
2424f83d6046SBarry Smith 
2425be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
24264a2ae208SSatish Balay #undef __FUNCT__
24274a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
242817ab2063SBarry Smith /*@C
2429682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
24300d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
24316e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
243251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
24332bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
243417ab2063SBarry Smith 
2435db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2436db81eaa0SLois Curfman McInnes 
243717ab2063SBarry Smith    Input Parameters:
2438db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
243917ab2063SBarry Smith .  m - number of rows
244017ab2063SBarry Smith .  n - number of columns
244117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
244251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
24432bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
244417ab2063SBarry Smith 
244517ab2063SBarry Smith    Output Parameter:
2446416022c9SBarry Smith .  A - the matrix
244717ab2063SBarry Smith 
2448b259b22eSLois Curfman McInnes    Notes:
244917ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
245017ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24510002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
245244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
245317ab2063SBarry Smith 
245417ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2455a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24563d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24576da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
245817ab2063SBarry Smith 
2459682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24604fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2461682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24626c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24636c7ebb05SLois Curfman McInnes 
24646c7ebb05SLois Curfman McInnes    Options Database Keys:
2465db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2466db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2467db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2468db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2469db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
247017ab2063SBarry Smith 
2471027ccd11SLois Curfman McInnes    Level: intermediate
2472027ccd11SLois Curfman McInnes 
247336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
247436db0b34SBarry Smith 
247517ab2063SBarry Smith @*/
2476ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A)
247717ab2063SBarry Smith {
2478273d9f13SBarry Smith   int ierr;
24796945ee14SBarry Smith 
24803a40ed3dSBarry Smith   PetscFunctionBegin;
2481273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2482273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2483273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2484273d9f13SBarry Smith   PetscFunctionReturn(0);
2485273d9f13SBarry Smith }
2486273d9f13SBarry Smith 
24875da197adSKris Buschelman #define SKIP_ALLOCATION -4
24885da197adSKris Buschelman 
24894a2ae208SSatish Balay #undef __FUNCT__
24904a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2491273d9f13SBarry Smith /*@C
2492273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2493273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2494273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2495273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2496273d9f13SBarry Smith 
2497273d9f13SBarry Smith    Collective on MPI_Comm
2498273d9f13SBarry Smith 
2499273d9f13SBarry Smith    Input Parameters:
2500273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2501273d9f13SBarry Smith .  m - number of rows
2502273d9f13SBarry Smith .  n - number of columns
2503273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2504273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2505273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2506273d9f13SBarry Smith 
2507273d9f13SBarry Smith    Output Parameter:
2508273d9f13SBarry Smith .  A - the matrix
2509273d9f13SBarry Smith 
2510273d9f13SBarry Smith    Notes:
2511273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2512273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2513273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2514273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2515273d9f13SBarry Smith 
2516273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2517273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2518273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2519273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2520273d9f13SBarry Smith 
2521273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2522273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2523273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2524273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2525273d9f13SBarry Smith 
2526273d9f13SBarry Smith    Options Database Keys:
2527273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2528273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2529273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2530273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2531273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2532273d9f13SBarry Smith 
2533273d9f13SBarry Smith    Level: intermediate
2534273d9f13SBarry Smith 
2535273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2536273d9f13SBarry Smith 
2537273d9f13SBarry Smith @*/
2538ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[])
2539273d9f13SBarry Smith {
2540ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,const int[]);
2541a23d5eceSKris Buschelman 
2542a23d5eceSKris Buschelman   PetscFunctionBegin;
2543a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2544a23d5eceSKris Buschelman   if (f) {
2545a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2546a23d5eceSKris Buschelman   }
2547a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2548a23d5eceSKris Buschelman }
2549a23d5eceSKris Buschelman 
2550a23d5eceSKris Buschelman EXTERN_C_BEGIN
2551a23d5eceSKris Buschelman #undef __FUNCT__
2552a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2553a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz)
2554a23d5eceSKris Buschelman {
2555273d9f13SBarry Smith   Mat_SeqAIJ *b;
2556a7ed9263SMatthew Knepley   size_t     len = 0;
2557a43ee2ecSKris Buschelman   PetscTruth skipallocation = PETSC_FALSE;
2558a7ed9263SMatthew Knepley   int        i,ierr;
2559273d9f13SBarry Smith 
2560273d9f13SBarry Smith   PetscFunctionBegin;
2561d5d45c9bSBarry Smith 
2562c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2563c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2564c461c341SBarry Smith     nz             = 0;
2565c461c341SBarry Smith   }
2566c461c341SBarry Smith 
2567435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2568435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2569b73539f3SBarry Smith   if (nnz) {
2570273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
257129bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25723a7fca6bSBarry 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);
2573b73539f3SBarry Smith     }
2574b73539f3SBarry Smith   }
2575b73539f3SBarry Smith 
2576273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2577273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2578273d9f13SBarry Smith 
2579b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2580273d9f13SBarry Smith   if (!nnz) {
2581435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2582273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2583273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2584273d9f13SBarry Smith     nz = nz*B->m;
2585273d9f13SBarry Smith   } else {
2586273d9f13SBarry Smith     nz = 0;
2587273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2588273d9f13SBarry Smith   }
2589273d9f13SBarry Smith 
2590c461c341SBarry Smith   if (!skipallocation) {
2591273d9f13SBarry Smith     /* allocate the matrix space */
2592a7ed9263SMatthew Knepley     len             = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2593b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2594273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2595273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2596273d9f13SBarry Smith     b->i            = b->j + nz;
2597bfeeae90SHong Zhang     b->i[0] = 0;
25985da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
25995da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26005da197adSKris Buschelman     }
2601273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2602273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2603c461c341SBarry Smith   } else {
2604c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2605c461c341SBarry Smith   }
2606273d9f13SBarry Smith 
2607273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2608b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2609b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2610273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2611273d9f13SBarry Smith 
2612273d9f13SBarry Smith   b->nz                = 0;
2613273d9f13SBarry Smith   b->maxnz             = nz;
2614273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2615273d9f13SBarry Smith   PetscFunctionReturn(0);
2616273d9f13SBarry Smith }
2617a23d5eceSKris Buschelman EXTERN_C_END
2618273d9f13SBarry Smith 
26190bad9183SKris Buschelman /*MC
2620fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
26210bad9183SKris Buschelman    based on compressed sparse row format.
26220bad9183SKris Buschelman 
26230bad9183SKris Buschelman    Options Database Keys:
26240bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
26250bad9183SKris Buschelman 
26260bad9183SKris Buschelman   Level: beginner
26270bad9183SKris Buschelman 
26280bad9183SKris Buschelman .seealso: MatCreateSeqAIJ
26290bad9183SKris Buschelman M*/
26300bad9183SKris Buschelman 
2631a6175056SHong Zhang EXTERN_C_BEGIN
26324a2ae208SSatish Balay #undef __FUNCT__
26334a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2634273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2635273d9f13SBarry Smith {
2636273d9f13SBarry Smith   Mat_SeqAIJ *b;
2637273d9f13SBarry Smith   int        ierr,size;
2638273d9f13SBarry Smith   PetscTruth flg;
2639273d9f13SBarry Smith 
2640273d9f13SBarry Smith   PetscFunctionBegin;
2641273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2642273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2643273d9f13SBarry Smith 
2644273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2645273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2646273d9f13SBarry Smith 
2647b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2648b0a32e0cSBarry Smith   B->data             = (void*)b;
2649549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2650549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2651416022c9SBarry Smith   B->factor           = 0;
2652416022c9SBarry Smith   B->lupivotthreshold = 1.0;
265390f02eecSBarry Smith   B->mapping          = 0;
2654e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2655e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2656416022c9SBarry Smith   b->row              = 0;
2657416022c9SBarry Smith   b->col              = 0;
265882bf6240SBarry Smith   b->icol             = 0;
2659b810aeb4SBarry Smith   b->reallocs         = 0;
266017ab2063SBarry Smith 
26618a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26628a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2663a5ae1ecdSBarry Smith 
2664f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
266536db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2666f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2667416022c9SBarry Smith   b->nonew             = 0;
2668416022c9SBarry Smith   b->diag              = 0;
2669416022c9SBarry Smith   b->solve_work        = 0;
26702a1b7f2aSHong Zhang   B->spptr             = 0;
2671b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2672754ec7b1SSatish Balay   b->inode.node_count  = 0;
2673754ec7b1SSatish Balay   b->inode.size        = 0;
26746c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26756c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2676be6bf707SBarry Smith   b->saved_values      = 0;
2677d7f994e1SBarry Smith   b->idiag             = 0;
2678d7f994e1SBarry Smith   b->ssor              = 0;
2679f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2680a30b2313SHong Zhang   b->xtoy              = 0;
2681a30b2313SHong Zhang   b->XtoY              = 0;
268217ab2063SBarry Smith 
268335d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
268435d8aa7fSBarry Smith 
2685e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2686ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2687f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2688bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2689bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2690f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2691be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2692bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2693f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2694be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2695bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2696a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2697a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2698a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
269985fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
270085fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
270185fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
27025fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
27035fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
27045fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
2705a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2706a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2707a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
270805b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
270905b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
271005b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
27110a99d0a2SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C",
27120a99d0a2SKris Buschelman                                      "MatAdjustForInodes_SeqAIJ",
27130a99d0a2SKris Buschelman                                       MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr);
2714d758967fSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C",
2715d758967fSKris Buschelman                                      "MatSeqAIJGetInodeSizes_SeqAIJ",
2716d758967fSKris Buschelman                                       MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr);
271716ce804cSBarry Smith #if defined(PETSC_HAVE_MATLAB) && !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;
2732bfeeae90SHong Zhang   int        i,m = A->m,ierr;
2733a7ed9263SMatthew Knepley   size_t     len;
273417ab2063SBarry Smith 
27353a40ed3dSBarry Smith   PetscFunctionBegin;
27364043dd9cSLois Curfman McInnes   *B = 0;
2737273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2738273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr);
2739273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2740273d9f13SBarry Smith 
2741416022c9SBarry Smith   C->factor         = A->factor;
2742416022c9SBarry Smith   c->row            = 0;
2743416022c9SBarry Smith   c->col            = 0;
274482bf6240SBarry Smith   c->icol           = 0;
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;
2760a7ed9263SMatthew Knepley   len   = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2761b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2762bfeeae90SHong Zhang   c->j  = (int*)(c->a + a->i[m] );
2763bfeeae90SHong Zhang   c->i  = c->j + a->i[m];
2764549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
276517ab2063SBarry Smith   if (m > 0) {
2766bfeeae90SHong Zhang     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr);
2767be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2768bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2769be6bf707SBarry Smith     } else {
2770bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*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 
28144a2ae208SSatish Balay #undef __FUNCT__
28154a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2816b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A)
281717ab2063SBarry Smith {
2818416022c9SBarry Smith   Mat_SeqAIJ   *a;
2819416022c9SBarry Smith   Mat          B;
2820efb16452SHong Zhang   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N;
2821bcd2baecSBarry Smith   MPI_Comm     comm;
282217ab2063SBarry Smith 
28233a40ed3dSBarry Smith   PetscFunctionBegin;
2824e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2825d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
282629bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2827b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
28280752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2829552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
283017ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
283117ab2063SBarry Smith 
2832d64ed03dSBarry Smith   if (nz < 0) {
283329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2834d64ed03dSBarry Smith   }
2835d64ed03dSBarry Smith 
283617ab2063SBarry Smith   /* read in row lengths */
2837b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
28380752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
283917ab2063SBarry Smith 
284017ab2063SBarry Smith   /* create our matrix */
2841b3a1e11cSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr);
2842b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
2843b3a1e11cSKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
2844416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
284517ab2063SBarry Smith 
284617ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
28470752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
284817ab2063SBarry Smith 
284917ab2063SBarry Smith   /* read in nonzero values */
28500752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
285117ab2063SBarry Smith 
285217ab2063SBarry Smith   /* set matrix "i" values */
2853efb16452SHong Zhang   a->i[0] = 0;
285417ab2063SBarry Smith   for (i=1; i<= M; i++) {
2855416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2856416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
285717ab2063SBarry Smith   }
2858606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
285917ab2063SBarry Smith 
28606d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28616d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2862b3a1e11cSKris Buschelman   *A = B;
28633a40ed3dSBarry Smith   PetscFunctionReturn(0);
286417ab2063SBarry Smith }
286517ab2063SBarry Smith 
28664a2ae208SSatish Balay #undef __FUNCT__
2867b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28688f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28697264ac53SSatish Balay {
28707264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28710f5bd95cSBarry Smith   int        ierr;
28727264ac53SSatish Balay 
28733a40ed3dSBarry Smith   PetscFunctionBegin;
2874bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
2875bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
2876ca44d042SBarry Smith     *flg = PETSC_FALSE;
2877ca44d042SBarry Smith     PetscFunctionReturn(0);
2878bcd2baecSBarry Smith   }
28797264ac53SSatish Balay 
28807264ac53SSatish Balay   /* if the a->i are the same */
2881273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28820f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28837264ac53SSatish Balay 
28847264ac53SSatish Balay   /* if a->j are the same */
28850f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28860f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2887bcd2baecSBarry Smith 
2888bcd2baecSBarry Smith   /* if a->a are the same */
288987828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
28900f5bd95cSBarry Smith 
28913a40ed3dSBarry Smith   PetscFunctionReturn(0);
28927264ac53SSatish Balay 
28937264ac53SSatish Balay }
289436db0b34SBarry Smith 
28954a2ae208SSatish Balay #undef __FUNCT__
28964a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
289736db0b34SBarry Smith /*@C
289836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
289936db0b34SBarry Smith               provided by the user.
290036db0b34SBarry Smith 
290136db0b34SBarry Smith       Coolective on MPI_Comm
290236db0b34SBarry Smith 
290336db0b34SBarry Smith    Input Parameters:
290436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
290536db0b34SBarry Smith .   m - number of rows
290636db0b34SBarry Smith .   n - number of columns
290736db0b34SBarry Smith .   i - row indices
290836db0b34SBarry Smith .   j - column indices
290936db0b34SBarry Smith -   a - matrix values
291036db0b34SBarry Smith 
291136db0b34SBarry Smith    Output Parameter:
291236db0b34SBarry Smith .   mat - the matrix
291336db0b34SBarry Smith 
291436db0b34SBarry Smith    Level: intermediate
291536db0b34SBarry Smith 
291636db0b34SBarry Smith    Notes:
29170551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
291836db0b34SBarry Smith     once the matrix is destroyed
291936db0b34SBarry Smith 
292036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
292136db0b34SBarry Smith 
2922bfeeae90SHong Zhang        The i and j indices are 0 based
292336db0b34SBarry Smith 
292436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
292536db0b34SBarry Smith 
292636db0b34SBarry Smith @*/
292787828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
292836db0b34SBarry Smith {
292936db0b34SBarry Smith   int        ierr,ii;
293036db0b34SBarry Smith   Mat_SeqAIJ *aij;
293136db0b34SBarry Smith 
293236db0b34SBarry Smith   PetscFunctionBegin;
2933c461c341SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr);
293436db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
293536db0b34SBarry Smith 
2936bfeeae90SHong Zhang   if (i[0] != 0) {
2937bfeeae90SHong Zhang     SETERRQ(1,"i (row indices) must start with 0");
293836db0b34SBarry Smith   }
293936db0b34SBarry Smith   aij->i = i;
294036db0b34SBarry Smith   aij->j = j;
294136db0b34SBarry Smith   aij->a = a;
294236db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
294336db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
294436db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
294536db0b34SBarry Smith 
294636db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
294736db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
29489860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
294929bbc08cSBarry 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]);
295036db0b34SBarry Smith #endif
295136db0b34SBarry Smith   }
29529860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
295336db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
2954bfeeae90SHong Zhang     if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
2955bfeeae90SHong Zhang     if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
295636db0b34SBarry Smith   }
295736db0b34SBarry Smith #endif
295836db0b34SBarry Smith 
2959b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2960b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
296136db0b34SBarry Smith   PetscFunctionReturn(0);
296236db0b34SBarry Smith }
296336db0b34SBarry Smith 
2964cc8ba8e1SBarry Smith #undef __FUNCT__
2965ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2966ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2967cc8ba8e1SBarry Smith {
2968cc8ba8e1SBarry Smith   int        ierr;
2969cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
297036db0b34SBarry Smith 
2971cc8ba8e1SBarry Smith   PetscFunctionBegin;
297212c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2973cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2974cc8ba8e1SBarry Smith     a->coloring = coloring;
297512c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
297608b6dcc0SBarry Smith     int             i,*larray;
297712c595b3SBarry Smith     ISColoring      ocoloring;
297808b6dcc0SBarry Smith     ISColoringValue *colors;
297912c595b3SBarry Smith 
298012c595b3SBarry Smith     /* set coloring for diagonal portion */
298112c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
298212c595b3SBarry Smith     for (i=0; i<A->n; i++) {
298312c595b3SBarry Smith       larray[i] = i;
298412c595b3SBarry Smith     }
298512c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
298608b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
298712c595b3SBarry Smith     for (i=0; i<A->n; i++) {
298812c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
298912c595b3SBarry Smith     }
299012c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
299112c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
299212c595b3SBarry Smith     a->coloring = ocoloring;
299312c595b3SBarry Smith   }
2994cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
2995cc8ba8e1SBarry Smith }
2996cc8ba8e1SBarry Smith 
299787828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2998ee4f033dSBarry Smith EXTERN_C_BEGIN
299929c1e371SBarry Smith #include "adic/ad_utils.h"
3000ee4f033dSBarry Smith EXTERN_C_END
3001cc8ba8e1SBarry Smith 
3002cc8ba8e1SBarry Smith #undef __FUNCT__
3003ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3004ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3005cc8ba8e1SBarry Smith {
3006cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
300708b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
30084440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
300908b6dcc0SBarry Smith   ISColoringValue *color;
3010cc8ba8e1SBarry Smith 
3011cc8ba8e1SBarry Smith   PetscFunctionBegin;
3012cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
30134440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3014cc8ba8e1SBarry Smith   color = a->coloring->colors;
3015cc8ba8e1SBarry Smith   /* loop over rows */
3016cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3017cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3018cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3019cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3020cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3021cc8ba8e1SBarry Smith     }
30224440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3023ee4f033dSBarry Smith   }
3024ee4f033dSBarry Smith   PetscFunctionReturn(0);
3025ee4f033dSBarry Smith }
3026ee4f033dSBarry Smith 
3027ee4f033dSBarry Smith #else
3028ee4f033dSBarry Smith 
3029ee4f033dSBarry Smith #undef __FUNCT__
3030ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3031ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3032ee4f033dSBarry Smith {
3033ee4f033dSBarry Smith   PetscFunctionBegin;
3034ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
3035ee4f033dSBarry Smith }
3036ee4f033dSBarry Smith 
3037ee4f033dSBarry Smith #endif
3038ee4f033dSBarry Smith 
3039ee4f033dSBarry Smith #undef __FUNCT__
3040ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
3041ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
3042ee4f033dSBarry Smith {
3043ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
304408b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
304587828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
304608b6dcc0SBarry Smith   ISColoringValue *color;
3047ee4f033dSBarry Smith 
3048ee4f033dSBarry Smith   PetscFunctionBegin;
3049ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3050ee4f033dSBarry Smith   color = a->coloring->colors;
3051ee4f033dSBarry Smith   /* loop over rows */
3052ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3053ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3054ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3055ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3056ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3057ee4f033dSBarry Smith     }
3058ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3059cc8ba8e1SBarry Smith   }
3060cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3061cc8ba8e1SBarry Smith }
306236db0b34SBarry Smith 
3063