xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 0c559628da5d11dea2cb3e36991fcda116094c01)
173f4d377SMatthew Knepley /*$Id: aij.c,v 1.385 2001/09/07 20:09:22 bsmith Exp $*/
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
79e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
8f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
9f5eb4b81SSatish Balay #include "src/inline/spops.h"
108d195f9aSBarry Smith #include "src/inline/dot.h"
110a835dfdSSatish Balay #include "petscbt.h"
1217ab2063SBarry Smith 
13a2ce50c7SBarry Smith 
14ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
1517ab2063SBarry Smith 
164a2ae208SSatish Balay #undef __FUNCT__
174a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
184e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done)
1917ab2063SBarry Smith {
20416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
216945ee14SBarry Smith   int        ierr,i,ishift;
2217ab2063SBarry Smith 
233a40ed3dSBarry Smith   PetscFunctionBegin;
2431625ec5SSatish Balay   *m     = A->m;
253a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
26bfeeae90SHong Zhang   ishift = 0;
2753e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
28273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
29bfeeae90SHong Zhang   } else if (oshift == 1) {
30435da068SBarry Smith     int nz = a->i[A->m];
313b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
321bc30dd5SBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
33b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
343b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
35273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
366945ee14SBarry Smith   } else {
376945ee14SBarry Smith     *ia = a->i; *ja = a->j;
38a2ce50c7SBarry Smith   }
393a40ed3dSBarry Smith   PetscFunctionReturn(0);
40a2744918SBarry Smith }
41a2744918SBarry Smith 
424a2ae208SSatish Balay #undef __FUNCT__
434a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
444e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
456945ee14SBarry Smith {
46bfeeae90SHong Zhang   int ierr;
476945ee14SBarry Smith 
483a40ed3dSBarry Smith   PetscFunctionBegin;
493a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
50bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
51606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
52606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
53bcd2baecSBarry Smith   }
543a40ed3dSBarry Smith   PetscFunctionReturn(0);
5517ab2063SBarry Smith }
5617ab2063SBarry Smith 
574a2ae208SSatish Balay #undef __FUNCT__
584a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
594e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
603b2fbd54SBarry Smith {
613b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
62bfeeae90SHong Zhang   int        ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m;
63bfeeae90SHong Zhang   int        nz = a->i[m],row,*jj,mr,col;
643b2fbd54SBarry Smith 
653a40ed3dSBarry Smith   PetscFunctionBegin;
663b2fbd54SBarry Smith   *nn     = A->n;
673a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
683b2fbd54SBarry Smith   if (symmetric) {
69bfeeae90SHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
703b2fbd54SBarry Smith   } else {
71b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr);
72549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
73b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr);
74b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr);
753b2fbd54SBarry Smith     jj = a->j;
763b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
77bfeeae90SHong Zhang       collengths[jj[i]]++;
783b2fbd54SBarry Smith     }
793b2fbd54SBarry Smith     cia[0] = oshift;
803b2fbd54SBarry Smith     for (i=0; i<n; i++) {
813b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
823b2fbd54SBarry Smith     }
83549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
843b2fbd54SBarry Smith     jj   = a->j;
85a93ec695SBarry Smith     for (row=0; row<m; row++) {
86a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
87a93ec695SBarry Smith       for (i=0; i<mr; i++) {
88bfeeae90SHong Zhang         col = *jj++;
893b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
903b2fbd54SBarry Smith       }
913b2fbd54SBarry Smith     }
92606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
933b2fbd54SBarry Smith     *ia = cia; *ja = cja;
943b2fbd54SBarry Smith   }
953a40ed3dSBarry Smith   PetscFunctionReturn(0);
963b2fbd54SBarry Smith }
973b2fbd54SBarry Smith 
984a2ae208SSatish Balay #undef __FUNCT__
994a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
1004e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
1013b2fbd54SBarry Smith {
102606d414cSSatish Balay   int ierr;
103606d414cSSatish Balay 
1043a40ed3dSBarry Smith   PetscFunctionBegin;
1053a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1063b2fbd54SBarry Smith 
107606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
108606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1093b2fbd54SBarry Smith 
1103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1113b2fbd54SBarry Smith }
1123b2fbd54SBarry Smith 
113227d817aSBarry Smith #define CHUNKSIZE   15
11417ab2063SBarry Smith 
1154a2ae208SSatish Balay #undef __FUNCT__
1164a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
117f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11817ab2063SBarry Smith {
119416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
120416022c9SBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
121273d9f13SBarry Smith   int         *imax = a->imax,*ai = a->i,*ailen = a->ilen;
122bfeeae90SHong Zhang   int         *aj = a->j,nonew = a->nonew,ierr;
12387828ca2SBarry Smith   PetscScalar *ap,value,*aa = a->a;
12436db0b34SBarry Smith   PetscTruth  ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
125273d9f13SBarry Smith   PetscTruth  roworiented = a->roworiented;
12617ab2063SBarry Smith 
1273a40ed3dSBarry Smith   PetscFunctionBegin;
12817ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
129416022c9SBarry Smith     row  = im[k];
1305ef9f2a5SBarry Smith     if (row < 0) continue;
131aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
132590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
1333b2fbd54SBarry Smith #endif
134bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
13517ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
136416022c9SBarry Smith     low = 0;
13717ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1385ef9f2a5SBarry Smith       if (in[l] < 0) continue;
139aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
140590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
1413b2fbd54SBarry Smith #endif
142bfeeae90SHong Zhang       col = in[l];
1434b0e389bSBarry Smith       if (roworiented) {
1445ef9f2a5SBarry Smith         value = v[l + k*n];
145bef8e0ddSBarry Smith       } else {
1464b0e389bSBarry Smith         value = v[k + l*m];
1474b0e389bSBarry Smith       }
14836db0b34SBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
14936db0b34SBarry Smith 
150416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
151416022c9SBarry Smith       while (high-low > 5) {
152416022c9SBarry Smith         t = (low+high)/2;
153416022c9SBarry Smith         if (rp[t] > col) high = t;
154416022c9SBarry Smith         else             low  = t;
15517ab2063SBarry Smith       }
156416022c9SBarry Smith       for (i=low; i<high; i++) {
15717ab2063SBarry Smith         if (rp[i] > col) break;
15817ab2063SBarry Smith         if (rp[i] == col) {
159416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
16017ab2063SBarry Smith           else                  ap[i] = value;
16117ab2063SBarry Smith           goto noinsert;
16217ab2063SBarry Smith         }
16317ab2063SBarry Smith       }
164c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
16529bbc08cSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
16617ab2063SBarry Smith       if (nrow >= rmax) {
16717ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
168a7ed9263SMatthew Knepley         int         new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j;
169a7ed9263SMatthew Knepley         size_t      len;
17087828ca2SBarry Smith         PetscScalar *new_a;
17117ab2063SBarry Smith 
17229bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
17396854ed6SLois Curfman McInnes 
17417ab2063SBarry Smith         /* malloc new storage space */
175a7ed9263SMatthew Knepley         len     = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
176b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
17717ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
17817ab2063SBarry Smith         new_i   = new_j + new_nz;
17917ab2063SBarry Smith 
18017ab2063SBarry Smith         /* copy over old data into new slots */
18117ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
182273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
183bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
184bfeeae90SHong Zhang         len  = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow );
185bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
186bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr);
187bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
18817ab2063SBarry Smith         /* free up old matrix storage */
189606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
190606d414cSSatish Balay         if (!a->singlemalloc) {
191606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
192606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
193606d414cSSatish Balay         }
194416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
195f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
19617ab2063SBarry Smith 
197bfeeae90SHong Zhang         rp   = aj + ai[row]; ap = aa + ai[row] ;
198416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
19987828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
200416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
201b810aeb4SBarry Smith         a->reallocs++;
20217ab2063SBarry Smith       }
203416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
204416022c9SBarry Smith       /* shift up all the later entries in this row */
205416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
20617ab2063SBarry Smith         rp[ii+1] = rp[ii];
20717ab2063SBarry Smith         ap[ii+1] = ap[ii];
20817ab2063SBarry Smith       }
20917ab2063SBarry Smith       rp[i] = col;
21017ab2063SBarry Smith       ap[i] = value;
21117ab2063SBarry Smith       noinsert:;
212416022c9SBarry Smith       low = i + 1;
21317ab2063SBarry Smith     }
21417ab2063SBarry Smith     ailen[row] = nrow;
21517ab2063SBarry Smith   }
2163a40ed3dSBarry Smith   PetscFunctionReturn(0);
21717ab2063SBarry Smith }
21817ab2063SBarry Smith 
2194a2ae208SSatish Balay #undef __FUNCT__
2204a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
221f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
2227eb43aa7SLois Curfman McInnes {
2237eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
224b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
225bfeeae90SHong Zhang   int          *ai = a->i,*ailen = a->ilen;
22687828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2277eb43aa7SLois Curfman McInnes 
2283a40ed3dSBarry Smith   PetscFunctionBegin;
2297eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2307eb43aa7SLois Curfman McInnes     row  = im[k];
23129bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
232590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
233bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2347eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2357eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
23629bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
237590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
238bfeeae90SHong Zhang       col = in[l] ;
2397eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2407eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2417eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2427eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2437eb43aa7SLois Curfman McInnes         else             low  = t;
2447eb43aa7SLois Curfman McInnes       }
2457eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2467eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2477eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
248b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2497eb43aa7SLois Curfman McInnes           goto finished;
2507eb43aa7SLois Curfman McInnes         }
2517eb43aa7SLois Curfman McInnes       }
252b49de8d1SLois Curfman McInnes       *v++ = zero;
2537eb43aa7SLois Curfman McInnes       finished:;
2547eb43aa7SLois Curfman McInnes     }
2557eb43aa7SLois Curfman McInnes   }
2563a40ed3dSBarry Smith   PetscFunctionReturn(0);
2577eb43aa7SLois Curfman McInnes }
2587eb43aa7SLois Curfman McInnes 
25917ab2063SBarry Smith 
2604a2ae208SSatish Balay #undef __FUNCT__
2614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
262b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
26317ab2063SBarry Smith {
264416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
265416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
26617ab2063SBarry Smith 
2673a40ed3dSBarry Smith   PetscFunctionBegin;
268b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
269b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
270552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
271273d9f13SBarry Smith   col_lens[1] = A->m;
272273d9f13SBarry Smith   col_lens[2] = A->n;
273416022c9SBarry Smith   col_lens[3] = a->nz;
274416022c9SBarry Smith 
275416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
276273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
277416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
27817ab2063SBarry Smith   }
279273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
280606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
281416022c9SBarry Smith 
282416022c9SBarry Smith   /* store column indices (zero start index) */
2830752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
284416022c9SBarry Smith 
285416022c9SBarry Smith   /* store nonzero values */
2860752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
2873a40ed3dSBarry Smith   PetscFunctionReturn(0);
28817ab2063SBarry Smith }
289416022c9SBarry Smith 
2904ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
2911dfdf1d9SHong Zhang extern int MatFactorInfo_MUMPS(Mat,PetscViewer);
292cd155464SBarry Smith 
2934a2ae208SSatish Balay #undef __FUNCT__
2944a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
295b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
296416022c9SBarry Smith {
297416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
298bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,shift=0;
299fb9695e5SSatish Balay   char              *name;
300f3ef73ceSBarry Smith   PetscViewerFormat format;
30117ab2063SBarry Smith 
3023a40ed3dSBarry Smith   PetscFunctionBegin;
303435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
304b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
305456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3066831982aSBarry Smith     if (a->inode.size) {
307b0a32e0cSBarry 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);
3086831982aSBarry Smith     } else {
309b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3106831982aSBarry Smith     }
311fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
312d00d2cf4SBarry Smith     int nofinalvalue = 0;
313273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
314d00d2cf4SBarry Smith       nofinalvalue = 1;
315d00d2cf4SBarry Smith     }
316b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
317b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
318b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
319b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
320b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
32117ab2063SBarry Smith 
32217ab2063SBarry Smith     for (i=0; i<m; i++) {
323416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
324aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
325b0a32e0cSBarry 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);
32617ab2063SBarry Smith #else
327b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
32817ab2063SBarry Smith #endif
32917ab2063SBarry Smith       }
33017ab2063SBarry Smith     }
331d00d2cf4SBarry Smith     if (nofinalvalue) {
332b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
333d00d2cf4SBarry Smith     }
334fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
335b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
336cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
3374ffef66eSHong Zhang #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
3384ffef66eSHong Zhang      ierr = MatSeqAIJFactorInfo_Matlab(A,viewer);CHKERRQ(ierr);
3394ffef66eSHong Zhang #endif
3401dfdf1d9SHong Zhang #if defined(PETSC_HAVE_MUMPS) && !defined(PETSC_USE_SINGLE)
3411dfdf1d9SHong Zhang      ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr);
3421dfdf1d9SHong Zhang #endif
343cd155464SBarry Smith      PetscFunctionReturn(0);
344fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
345b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
34644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
347b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
34844cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
349aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
35036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
35162b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
35236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
35362b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
35436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
35562b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3566831982aSBarry Smith         }
35744cd7ae7SLois Curfman McInnes #else
35862b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
35944cd7ae7SLois Curfman McInnes #endif
36044cd7ae7SLois Curfman McInnes       }
361b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
36244cd7ae7SLois Curfman McInnes     }
363b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
364fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
365496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
366b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
367b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
368496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
369496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
370496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
371496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
372aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
37336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
374496be53dSLois Curfman McInnes #else
375496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
376496be53dSLois Curfman McInnes #endif
377496be53dSLois Curfman McInnes         }
378496be53dSLois Curfman McInnes       }
379496be53dSLois Curfman McInnes     }
3802e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
381b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
3822e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
383b0a32e0cSBarry 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);}
384b0a32e0cSBarry 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);}
385b0a32e0cSBarry 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);}
386b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
387b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
388b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
389496be53dSLois Curfman McInnes     }
390b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
391606d414cSSatish Balay     ierr = PetscFree(sptr);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++) {
394b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
395496be53dSLois Curfman McInnes       }
396b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
397496be53dSLois Curfman McInnes     }
398b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
399496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
400496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
401496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
402aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
40336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
404b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4056831982aSBarry Smith           }
406496be53dSLois Curfman McInnes #else
407b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
408496be53dSLois Curfman McInnes #endif
409496be53dSLois Curfman McInnes         }
410496be53dSLois Curfman McInnes       }
411b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
412496be53dSLois Curfman McInnes     }
413b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
414fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
41502594712SBarry Smith     int         cnt = 0,jcnt;
41687828ca2SBarry Smith     PetscScalar value;
41702594712SBarry Smith 
418b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
41902594712SBarry Smith     for (i=0; i<m; i++) {
42002594712SBarry Smith       jcnt = 0;
421273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
422e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
42302594712SBarry Smith           value = a->a[cnt++];
424e24b481bSBarry Smith           jcnt++;
42502594712SBarry Smith         } else {
42602594712SBarry Smith           value = 0.0;
42702594712SBarry Smith         }
428aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
429b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
43002594712SBarry Smith #else
431b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
43202594712SBarry Smith #endif
43302594712SBarry Smith       }
434b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
43502594712SBarry Smith     }
436b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4373a40ed3dSBarry Smith   } else {
438b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
43917ab2063SBarry Smith     for (i=0; i<m; i++) {
440b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
441416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
442aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
44336db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
44462b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
44536db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
44662b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4473a40ed3dSBarry Smith         } else {
44862b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
44917ab2063SBarry Smith         }
45017ab2063SBarry Smith #else
45162b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
45217ab2063SBarry Smith #endif
45317ab2063SBarry Smith       }
454b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45517ab2063SBarry Smith     }
456b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
45717ab2063SBarry Smith   }
458b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4593a40ed3dSBarry Smith   PetscFunctionReturn(0);
460416022c9SBarry Smith }
461416022c9SBarry Smith 
4624a2ae208SSatish Balay #undef __FUNCT__
4634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
464b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
465416022c9SBarry Smith {
466480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
467416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
468bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,color;
46936db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
470b0a32e0cSBarry Smith   PetscViewer       viewer;
471f3ef73ceSBarry Smith   PetscViewerFormat format;
472cddf8d76SBarry Smith 
4733a40ed3dSBarry Smith   PetscFunctionBegin;
474480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
475b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
47619bcc07fSBarry Smith 
477b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
478416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4790513a670SBarry Smith 
480fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4810513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
482b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
483416022c9SBarry Smith     for (i=0; i<m; i++) {
484cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
485bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
486bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
487aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
48836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
489cddf8d76SBarry Smith #else
490cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
491cddf8d76SBarry Smith #endif
492b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
493cddf8d76SBarry Smith       }
494cddf8d76SBarry Smith     }
495b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
496cddf8d76SBarry Smith     for (i=0; i<m; i++) {
497cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
498bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
499bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
500cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
501b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
502cddf8d76SBarry Smith       }
503cddf8d76SBarry Smith     }
504b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
505cddf8d76SBarry Smith     for (i=0; i<m; i++) {
506cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
507bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
508bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
509aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
51036db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
511cddf8d76SBarry Smith #else
512cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
513cddf8d76SBarry Smith #endif
514b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
515416022c9SBarry Smith       }
516416022c9SBarry Smith     }
5170513a670SBarry Smith   } else {
5180513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5190513a670SBarry Smith     /* first determine max of all nonzero values */
5200513a670SBarry Smith     int    nz = a->nz,count;
521b0a32e0cSBarry Smith     PetscDraw   popup;
52236db0b34SBarry Smith     PetscReal scale;
5230513a670SBarry Smith 
5240513a670SBarry Smith     for (i=0; i<nz; i++) {
5250513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5260513a670SBarry Smith     }
527b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
528b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
529b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5300513a670SBarry Smith     count = 0;
5310513a670SBarry Smith     for (i=0; i<m; i++) {
5320513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
533bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
534bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
535b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
536b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5370513a670SBarry Smith         count++;
5380513a670SBarry Smith       }
5390513a670SBarry Smith     }
5400513a670SBarry Smith   }
541480ef9eaSBarry Smith   PetscFunctionReturn(0);
542480ef9eaSBarry Smith }
543cddf8d76SBarry Smith 
5444a2ae208SSatish Balay #undef __FUNCT__
5454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
546b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
547480ef9eaSBarry Smith {
548480ef9eaSBarry Smith   int        ierr;
549b0a32e0cSBarry Smith   PetscDraw  draw;
55036db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
551480ef9eaSBarry Smith   PetscTruth isnull;
552480ef9eaSBarry Smith 
553480ef9eaSBarry Smith   PetscFunctionBegin;
554b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
555b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
556480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
557480ef9eaSBarry Smith 
558480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
559273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
560480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
561b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
562b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
563480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5643a40ed3dSBarry Smith   PetscFunctionReturn(0);
565416022c9SBarry Smith }
566416022c9SBarry Smith 
5674a2ae208SSatish Balay #undef __FUNCT__
5684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
569b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
570416022c9SBarry Smith {
571416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
572bcd2baecSBarry Smith   int         ierr;
5736831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
574416022c9SBarry Smith 
5753a40ed3dSBarry Smith   PetscFunctionBegin;
576b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
577b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
578fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
579fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5800f5bd95cSBarry Smith   if (issocket) {
581b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
5820f5bd95cSBarry Smith   } else if (isascii) {
5833a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5840f5bd95cSBarry Smith   } else if (isbinary) {
5853a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
5860f5bd95cSBarry Smith   } else if (isdraw) {
5873a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
5885cd90555SBarry Smith   } else {
58929bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
59017ab2063SBarry Smith   }
5913a40ed3dSBarry Smith   PetscFunctionReturn(0);
59217ab2063SBarry Smith }
59319bcc07fSBarry Smith 
5943a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth);
5954a2ae208SSatish Balay #undef __FUNCT__
5964a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
5978f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
59817ab2063SBarry Smith {
599416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
60041c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
601bfeeae90SHong Zhang   int          m = A->m,*ip,N,*ailen = a->ilen,rmax = 0;
60287828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
6031677d0b8SKris Buschelman #if defined(PETSC_HAVE_MUMPS)
6049b9367d5SHong Zhang   PetscTruth   flag;
6059e070d67SMatthew Knepley #endif
60617ab2063SBarry Smith 
6073a40ed3dSBarry Smith   PetscFunctionBegin;
6083a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
60917ab2063SBarry Smith 
61043ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
61117ab2063SBarry Smith   for (i=1; i<m; i++) {
612416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
61317ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
61494a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
61517ab2063SBarry Smith     if (fshift) {
616bfeeae90SHong Zhang       ip = aj + ai[i] ;
617bfeeae90SHong Zhang       ap = aa + ai[i] ;
61817ab2063SBarry Smith       N  = ailen[i];
61917ab2063SBarry Smith       for (j=0; j<N; j++) {
62017ab2063SBarry Smith         ip[j-fshift] = ip[j];
62117ab2063SBarry Smith         ap[j-fshift] = ap[j];
62217ab2063SBarry Smith       }
62317ab2063SBarry Smith     }
62417ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
62517ab2063SBarry Smith   }
62617ab2063SBarry Smith   if (m) {
62717ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
62817ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
62917ab2063SBarry Smith   }
63017ab2063SBarry Smith   /* reset ilen and imax for each row */
63117ab2063SBarry Smith   for (i=0; i<m; i++) {
63217ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
63317ab2063SBarry Smith   }
634bfeeae90SHong Zhang   a->nz = ai[m];
63517ab2063SBarry Smith 
63617ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
637416022c9SBarry Smith   if (fshift && a->diag) {
638606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
639b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
640416022c9SBarry Smith     a->diag = 0;
64117ab2063SBarry Smith   }
642b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
643b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
644b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
645dd5f02e7SSatish Balay   a->reallocs          = 0;
6464e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
64736db0b34SBarry Smith   a->rmax              = rmax;
6484e220ebcSLois Curfman McInnes 
64976dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6503a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
651cfef3cccSHong Zhang 
652eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS)
653eee76cafSHong Zhang   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr);
654eee76cafSHong Zhang   if (flag) { ierr = MatUseMUMPS_MPIAIJ(A);CHKERRQ(ierr); }
655eee76cafSHong Zhang #endif
656eee76cafSHong Zhang 
6573a40ed3dSBarry Smith   PetscFunctionReturn(0);
65817ab2063SBarry Smith }
65917ab2063SBarry Smith 
6604a2ae208SSatish Balay #undef __FUNCT__
6614a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6628f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
66317ab2063SBarry Smith {
664416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
665549d3d68SSatish Balay   int        ierr;
6663a40ed3dSBarry Smith 
6673a40ed3dSBarry Smith   PetscFunctionBegin;
668bfeeae90SHong Zhang   ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
6693a40ed3dSBarry Smith   PetscFunctionReturn(0);
67017ab2063SBarry Smith }
671416022c9SBarry Smith 
6724a2ae208SSatish Balay #undef __FUNCT__
6734a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
674e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
67517ab2063SBarry Smith {
676416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
67782bf6240SBarry Smith   int        ierr;
678d5d45c9bSBarry Smith 
6793a40ed3dSBarry Smith   PetscFunctionBegin;
680aa482453SBarry Smith #if defined(PETSC_USE_LOG)
681b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
68217ab2063SBarry Smith #endif
68336db0b34SBarry Smith   if (a->freedata) {
684606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
685606d414cSSatish Balay     if (!a->singlemalloc) {
686606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
687606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
688606d414cSSatish Balay     }
68936db0b34SBarry Smith   }
690c38d4ed2SBarry Smith   if (a->row) {
691c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
692c38d4ed2SBarry Smith   }
693c38d4ed2SBarry Smith   if (a->col) {
694c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
695c38d4ed2SBarry Smith   }
696606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
697606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
698606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
699273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
700606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
701606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
70282bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
703606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
704cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
705a30b2313SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
706a30b2313SHong Zhang 
707606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
7083a40ed3dSBarry Smith   PetscFunctionReturn(0);
70917ab2063SBarry Smith }
71017ab2063SBarry Smith 
7114a2ae208SSatish Balay #undef __FUNCT__
7124a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
7138f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
71417ab2063SBarry Smith {
7153a40ed3dSBarry Smith   PetscFunctionBegin;
7163a40ed3dSBarry Smith   PetscFunctionReturn(0);
71717ab2063SBarry Smith }
71817ab2063SBarry Smith 
7194a2ae208SSatish Balay #undef __FUNCT__
7204a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7218f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
72217ab2063SBarry Smith {
723416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7243a40ed3dSBarry Smith 
7253a40ed3dSBarry Smith   PetscFunctionBegin;
726a65d3064SKris Buschelman   switch (op) {
727a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
728a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
729a65d3064SKris Buschelman       break;
730a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
731a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
732a65d3064SKris Buschelman       break;
733a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
734a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
735a65d3064SKris Buschelman       break;
736a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
737a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
738a65d3064SKris Buschelman       break;
739a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
740a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
741a65d3064SKris Buschelman       break;
742a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
743a65d3064SKris Buschelman       a->nonew             = 1;
744a65d3064SKris Buschelman       break;
745a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
746a65d3064SKris Buschelman       a->nonew             = -1;
747a65d3064SKris Buschelman       break;
748a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
749a65d3064SKris Buschelman       a->nonew             = -2;
750a65d3064SKris Buschelman       break;
751a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
752a65d3064SKris Buschelman       a->nonew             = 0;
753a65d3064SKris Buschelman       break;
754a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
755a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
756a65d3064SKris Buschelman       break;
757a65d3064SKris Buschelman     case MAT_USE_INODES:
758a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
759a65d3064SKris Buschelman       break;
760a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
761a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
762a65d3064SKris Buschelman       break;
763a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
764a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
765a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
766a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
767a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
768b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
769a65d3064SKris Buschelman       break;
770a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
77129bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
772a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
773a65d3064SKris Buschelman       a->inode.limit  = 1;
774a65d3064SKris Buschelman       break;
775a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
776a65d3064SKris Buschelman       a->inode.limit  = 2;
777a65d3064SKris Buschelman       break;
778a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
779a65d3064SKris Buschelman       a->inode.limit  = 3;
780a65d3064SKris Buschelman       break;
781a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
782a65d3064SKris Buschelman       a->inode.limit  = 4;
783a65d3064SKris Buschelman       break;
784a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
785a65d3064SKris Buschelman       a->inode.limit  = 5;
786a65d3064SKris Buschelman       break;
787a65d3064SKris Buschelman     default:
788a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
789a65d3064SKris Buschelman   }
7903a40ed3dSBarry Smith   PetscFunctionReturn(0);
79117ab2063SBarry Smith }
79217ab2063SBarry Smith 
7934a2ae208SSatish Balay #undef __FUNCT__
7944a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
7958f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
79617ab2063SBarry Smith {
797416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
798bfeeae90SHong Zhang   int          i,j,n,ierr;
79987828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
80017ab2063SBarry Smith 
8013a40ed3dSBarry Smith   PetscFunctionBegin;
8023a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
803ed480e8bSBarry Smith   ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr);
80436db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
805273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
806273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
807bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
808bfeeae90SHong Zhang       if (a->j[j] == i) {
809416022c9SBarry Smith         x[i] = a->a[j];
81017ab2063SBarry Smith         break;
81117ab2063SBarry Smith       }
81217ab2063SBarry Smith     }
81317ab2063SBarry Smith   }
814ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr);
8153a40ed3dSBarry Smith   PetscFunctionReturn(0);
81617ab2063SBarry Smith }
81717ab2063SBarry Smith 
818d5d45c9bSBarry Smith 
8194a2ae208SSatish Balay #undef __FUNCT__
8204a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8217c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
82217ab2063SBarry Smith {
823416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8245c897100SBarry Smith   PetscScalar  *x,*y;
825bfeeae90SHong Zhang   int          ierr,m = A->m;
8265c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8275c897100SBarry Smith   PetscScalar  *v,alpha;
8285c897100SBarry Smith   int          n,i,*idx;
8295c897100SBarry Smith #endif
83017ab2063SBarry Smith 
8313a40ed3dSBarry Smith   PetscFunctionBegin;
8322e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
833ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
834ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
8355c897100SBarry Smith 
8365c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
837bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8385c897100SBarry Smith #else
83917ab2063SBarry Smith   for (i=0; i<m; i++) {
840bfeeae90SHong Zhang     idx   = a->j + a->i[i] ;
841bfeeae90SHong Zhang     v     = a->a + a->i[i] ;
842416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
84317ab2063SBarry Smith     alpha = x[i];
84417ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
84517ab2063SBarry Smith   }
8465c897100SBarry Smith #endif
847b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
848ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
849ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
8503a40ed3dSBarry Smith   PetscFunctionReturn(0);
85117ab2063SBarry Smith }
85217ab2063SBarry Smith 
8534a2ae208SSatish Balay #undef __FUNCT__
8545c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8555c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8565c897100SBarry Smith {
8578d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8585c897100SBarry Smith   int          ierr;
8595c897100SBarry Smith 
8605c897100SBarry Smith   PetscFunctionBegin;
8615c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8625c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8635c897100SBarry Smith   PetscFunctionReturn(0);
8645c897100SBarry Smith }
8655c897100SBarry Smith 
8665c897100SBarry Smith 
8675c897100SBarry Smith #undef __FUNCT__
8684a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
86944cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
87017ab2063SBarry Smith {
871416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
872362ced78SSatish Balay   PetscScalar  *x,*y,*v;
873bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
874aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
875e36a17ebSSatish Balay   int          n,i,jrow,j;
876362ced78SSatish Balay   PetscScalar  sum;
877e36a17ebSSatish Balay #endif
87817ab2063SBarry Smith 
879b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
880fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
881fee21e36SBarry Smith #endif
882fee21e36SBarry Smith 
8833a40ed3dSBarry Smith   PetscFunctionBegin;
884ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
885ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
886416022c9SBarry Smith   idx  = a->j;
887d64ed03dSBarry Smith   v    = a->a;
888416022c9SBarry Smith   ii   = a->i;
889aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
890bfeeae90SHong Zhang   fortranmultaij_(&m,x,ii,idx,v,y);
8918d195f9aSBarry Smith #else
89217ab2063SBarry Smith   for (i=0; i<m; i++) {
8939ea0dfa2SSatish Balay     jrow = ii[i];
8949ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
89517ab2063SBarry Smith     sum  = 0.0;
8969ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
8979ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8989ea0dfa2SSatish Balay      }
89917ab2063SBarry Smith     y[i] = sum;
90017ab2063SBarry Smith   }
9018d195f9aSBarry Smith #endif
902b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
903ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
904ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
9053a40ed3dSBarry Smith   PetscFunctionReturn(0);
90617ab2063SBarry Smith }
90717ab2063SBarry Smith 
9084a2ae208SSatish Balay #undef __FUNCT__
9094a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
91044cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
91117ab2063SBarry Smith {
912416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
913362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
914bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
915aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
916e36a17ebSSatish Balay   int          n,i,jrow,j;
917362ced78SSatish Balay PetscScalar    sum;
918e36a17ebSSatish Balay #endif
9199ea0dfa2SSatish Balay 
9203a40ed3dSBarry Smith   PetscFunctionBegin;
921ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
922ed480e8bSBarry Smith   ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr);
9232e8a6d31SBarry Smith   if (zz != yy) {
924ed480e8bSBarry Smith     ierr = VecGetArrayFast(zz,&z);CHKERRQ(ierr);
9252e8a6d31SBarry Smith   } else {
9262e8a6d31SBarry Smith     z = y;
9272e8a6d31SBarry Smith   }
928bfeeae90SHong Zhang 
929cddf8d76SBarry Smith   idx  = a->j;
930d64ed03dSBarry Smith   v    = a->a;
931cddf8d76SBarry Smith   ii   = a->i;
932aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
933bfeeae90SHong Zhang   fortranmultaddaij_(&m,x,ii,idx,v,y,z);
93402ab625aSSatish Balay #else
93517ab2063SBarry Smith   for (i=0; i<m; i++) {
9369ea0dfa2SSatish Balay     jrow = ii[i];
9379ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93817ab2063SBarry Smith     sum  = y[i];
9399ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9409ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9419ea0dfa2SSatish Balay      }
94217ab2063SBarry Smith     z[i] = sum;
94317ab2063SBarry Smith   }
94402ab625aSSatish Balay #endif
945b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
946ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
947ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr);
9482e8a6d31SBarry Smith   if (zz != yy) {
949ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(zz,&z);CHKERRQ(ierr);
9502e8a6d31SBarry Smith   }
9513a40ed3dSBarry Smith   PetscFunctionReturn(0);
95217ab2063SBarry Smith }
95317ab2063SBarry Smith 
95417ab2063SBarry Smith /*
95517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
95617ab2063SBarry Smith */
9574a2ae208SSatish Balay #undef __FUNCT__
9584a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
959f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
96017ab2063SBarry Smith {
961416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
962bfeeae90SHong Zhang   int        i,j,*diag,m = A->m,ierr;
96317ab2063SBarry Smith 
9643a40ed3dSBarry Smith   PetscFunctionBegin;
965f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
966f1e2ffcdSBarry Smith 
967b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
968b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
969273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
97035b0346bSBarry Smith     diag[i] = a->i[i+1];
971bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
972bfeeae90SHong Zhang       if (a->j[j] == i) {
973bfeeae90SHong Zhang         diag[i] = j;
97417ab2063SBarry Smith         break;
97517ab2063SBarry Smith       }
97617ab2063SBarry Smith     }
97717ab2063SBarry Smith   }
978416022c9SBarry Smith   a->diag = diag;
9793a40ed3dSBarry Smith   PetscFunctionReturn(0);
98017ab2063SBarry Smith }
98117ab2063SBarry Smith 
982be5855fcSBarry Smith /*
983be5855fcSBarry Smith      Checks for missing diagonals
984be5855fcSBarry Smith */
9854a2ae208SSatish Balay #undef __FUNCT__
9864a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
987f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
988be5855fcSBarry Smith {
989be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
990bfeeae90SHong Zhang   int        *diag,*jj = a->j,i,ierr;
991be5855fcSBarry Smith 
992be5855fcSBarry Smith   PetscFunctionBegin;
993f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
994f1e2ffcdSBarry Smith   diag = a->diag;
995273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
996bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
99729bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
998be5855fcSBarry Smith     }
999be5855fcSBarry Smith   }
1000be5855fcSBarry Smith   PetscFunctionReturn(0);
1001be5855fcSBarry Smith }
1002be5855fcSBarry Smith 
10034a2ae208SSatish Balay #undef __FUNCT__
10044a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
1005c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
100617ab2063SBarry Smith {
1007416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1008beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
1009beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
1010beeb8507SBarry Smith   int                ierr,n = A->n,m = A->m,i;
1011beeb8507SBarry Smith   const int          *idx,*diag;
101217ab2063SBarry Smith 
10133a40ed3dSBarry Smith   PetscFunctionBegin;
1014b965ef7fSBarry Smith   its = its*lits;
101591723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
101691723122SBarry Smith 
1017ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1018ed480e8bSBarry Smith   diag = a->diag;
1019ed480e8bSBarry Smith   if (!a->idiag) {
1020ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1021ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1022ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1023ed480e8bSBarry Smith 
1024ed480e8bSBarry Smith     v        = a->a;
1025ed480e8bSBarry Smith 
1026ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1027ed480e8bSBarry Smith     if (omega == 1.0 && fshift == 0.0) {
1028ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1029ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1030ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1031ed480e8bSBarry Smith       }
1032beeb8507SBarry Smith       PetscLogFlops(m);
1033ed480e8bSBarry Smith     } else {
1034ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1035ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1036beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1037ed480e8bSBarry Smith       }
1038beeb8507SBarry Smith       PetscLogFlops(2*m);
1039beeb8507SBarry Smith     }
1040ed480e8bSBarry Smith   }
1041ed480e8bSBarry Smith   t     = a->ssor;
1042ed480e8bSBarry Smith   idiag = a->idiag;
1043ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1044ed480e8bSBarry Smith 
1045ed480e8bSBarry Smith   ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr);
1046fb2e594dSBarry Smith   if (xx != bb) {
1047beeb8507SBarry Smith     ierr = VecGetArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1048fb2e594dSBarry Smith   } else {
1049fb2e594dSBarry Smith     b = x;
1050fb2e594dSBarry Smith   }
1051fb2e594dSBarry Smith 
1052ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1053ed480e8bSBarry Smith   xs   = x;
105417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
105517ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1056ed480e8bSBarry Smith     bs = b;
105717ab2063SBarry Smith     for (i=0; i<m; i++) {
1058ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1059416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1060ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1061ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
106217ab2063SBarry Smith         sum  = b[i]*d/omega;
106317ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
106417ab2063SBarry Smith         x[i] = sum;
106517ab2063SBarry Smith     }
1066ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1067beeb8507SBarry Smith     if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1068ed480e8bSBarry Smith     PetscLogFlops(a->nz);
10693a40ed3dSBarry Smith     PetscFunctionReturn(0);
107017ab2063SBarry Smith   }
1071c783ea89SBarry Smith 
1072ed480e8bSBarry Smith 
1073fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1074fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1075fc3d8934SBarry Smith 
1076fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1077fc3d8934SBarry Smith 
1078fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1079fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
108048af12d7SBarry Smith     is the relaxation factor.
1081fc3d8934SBarry Smith     */
1082fc3d8934SBarry Smith 
108348af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
108429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
10853a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
108617ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
108717ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
108817ab2063SBarry Smith 
108917ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
109017ab2063SBarry Smith 
109117ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
109217ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
109317ab2063SBarry Smith     is the relaxation factor.
109417ab2063SBarry Smith     */
109517ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
109617ab2063SBarry Smith 
109717ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
109817ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1099416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1100ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1101ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
110217ab2063SBarry Smith       sum  = b[i];
110317ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1104ed480e8bSBarry Smith       x[i] = sum*idiag[i];
110517ab2063SBarry Smith     }
110617ab2063SBarry Smith 
110717ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1108416022c9SBarry Smith     v = a->a;
1109ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
111017ab2063SBarry Smith 
111117ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1112ed480e8bSBarry Smith     ts = t;
1113416022c9SBarry Smith     diag = a->diag;
111417ab2063SBarry Smith     for (i=0; i<m; i++) {
1115416022c9SBarry Smith       n    = diag[i] - a->i[i];
1116ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1117ed480e8bSBarry Smith       v    = a->a + a->i[i];
111817ab2063SBarry Smith       sum  = t[i];
111917ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1120ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1121733d66baSBarry Smith       /*  x = x + t */
1122733d66baSBarry Smith       x[i] += t[i];
112317ab2063SBarry Smith     }
112417ab2063SBarry Smith 
1125b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
1126ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1127beeb8507SBarry Smith     if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11283a40ed3dSBarry Smith     PetscFunctionReturn(0);
112917ab2063SBarry Smith   }
113017ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
113117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
113277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
1133*0c559628SSatish Balay       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b);
113477d8c4bbSBarry Smith #else
113517ab2063SBarry Smith       for (i=0; i<m; i++) {
1136416022c9SBarry Smith         n    = diag[i] - a->i[i];
1137ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1138ed480e8bSBarry Smith         v    = a->a + a->i[i];
113917ab2063SBarry Smith         sum  = b[i];
114017ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1141ed480e8bSBarry Smith         x[i] = sum*idiag[i];
114217ab2063SBarry Smith       }
114377d8c4bbSBarry Smith #endif
114417ab2063SBarry Smith       xb = x;
1145ed480e8bSBarry Smith       PetscLogFlops(a->nz);
11463a40ed3dSBarry Smith     } else xb = b;
114717ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
114817ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
114917ab2063SBarry Smith       for (i=0; i<m; i++) {
1150ed480e8bSBarry Smith         x[i] *= mdiag[i];
115117ab2063SBarry Smith       }
1152b0a32e0cSBarry Smith       PetscLogFlops(m);
115317ab2063SBarry Smith     }
115417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
115577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
1156*0c559628SSatish Balay       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb);
115777d8c4bbSBarry Smith #else
115817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1159416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1160ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1161ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
116217ab2063SBarry Smith         sum  = xb[i];
116317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1164ed480e8bSBarry Smith         x[i] = sum*idiag[i];
116517ab2063SBarry Smith       }
116677d8c4bbSBarry Smith #endif
1167ed480e8bSBarry Smith       PetscLogFlops(a->nz);
116817ab2063SBarry Smith     }
116917ab2063SBarry Smith     its--;
117017ab2063SBarry Smith   }
117117ab2063SBarry Smith   while (its--) {
117217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
117377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
1174*0c559628SSatish Balay       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
117577d8c4bbSBarry Smith #else
117617ab2063SBarry Smith       for (i=0; i<m; i++) {
1177ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1178416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1179ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1180ed480e8bSBarry Smith         v    = a->a + a->i[i];
118117ab2063SBarry Smith         sum  = b[i];
118217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1183ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
118417ab2063SBarry Smith       }
118577d8c4bbSBarry Smith #endif
1186ed480e8bSBarry Smith       PetscLogFlops(a->nz);
118717ab2063SBarry Smith     }
118817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
118977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
1190*0c559628SSatish Balay       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
119177d8c4bbSBarry Smith #else
119217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1193ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1194416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1195ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1196ed480e8bSBarry Smith         v    = a->a + a->i[i];
119717ab2063SBarry Smith         sum  = b[i];
119817ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1199ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
120017ab2063SBarry Smith       }
120177d8c4bbSBarry Smith #endif
1202ed480e8bSBarry Smith       PetscLogFlops(a->nz);
120317ab2063SBarry Smith     }
120417ab2063SBarry Smith   }
1205ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr);
1206beeb8507SBarry Smith   if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
12073a40ed3dSBarry Smith   PetscFunctionReturn(0);
120817ab2063SBarry Smith }
120917ab2063SBarry Smith 
12104a2ae208SSatish Balay #undef __FUNCT__
12114a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12128f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
121317ab2063SBarry Smith {
1214416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12154e220ebcSLois Curfman McInnes 
12163a40ed3dSBarry Smith   PetscFunctionBegin;
1217273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1218273d9f13SBarry Smith   info->columns_global = (double)A->n;
1219273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1220273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12214e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12224e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12234e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12244e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12254e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12264e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12274e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12284e220ebcSLois Curfman McInnes   if (A->factor) {
12294e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12304e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12314e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12324e220ebcSLois Curfman McInnes   } else {
12334e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12344e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12354e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12364e220ebcSLois Curfman McInnes   }
12373a40ed3dSBarry Smith   PetscFunctionReturn(0);
123817ab2063SBarry Smith }
123917ab2063SBarry Smith 
1240b380c88cSHong Zhang EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatFactorInfo*,Mat*);
1241ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1242b380c88cSHong Zhang EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatFactorInfo*);
1243ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1244ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1245ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1246ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124717ab2063SBarry Smith 
12484a2ae208SSatish Balay #undef __FUNCT__
12494a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1250268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag)
125117ab2063SBarry Smith {
1252416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1253bfeeae90SHong Zhang   int         i,ierr,N,*rows,m = A->m - 1;
125417ab2063SBarry Smith 
12553a40ed3dSBarry Smith   PetscFunctionBegin;
1256b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
125717ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1258f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1259f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
126029bbc08cSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
1261bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1262f1e2ffcdSBarry Smith     }
1263f1e2ffcdSBarry Smith     if (diag) {
1264f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1265f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1266f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1267f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1268f1e2ffcdSBarry Smith       }
1269f1e2ffcdSBarry Smith     }
1270f1e2ffcdSBarry Smith   } else {
127117ab2063SBarry Smith     if (diag) {
127217ab2063SBarry Smith       for (i=0; i<N; i++) {
127329bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
12747ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1275416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1276bfeeae90SHong Zhang           a->a[a->i[rows[i]]] = *diag;
1277bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
12787ae801bdSBarry Smith         } else { /* in case row was completely empty */
1279d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
128017ab2063SBarry Smith         }
128117ab2063SBarry Smith       }
12823a40ed3dSBarry Smith     } else {
128317ab2063SBarry Smith       for (i=0; i<N; i++) {
128429bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
1285416022c9SBarry Smith         a->ilen[rows[i]] = 0;
128617ab2063SBarry Smith       }
128717ab2063SBarry Smith     }
1288f1e2ffcdSBarry Smith   }
12897ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
129043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12913a40ed3dSBarry Smith   PetscFunctionReturn(0);
129217ab2063SBarry Smith }
129317ab2063SBarry Smith 
12944a2ae208SSatish Balay #undef __FUNCT__
12954a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
129687828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
129717ab2063SBarry Smith {
1298416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1299b3fb0a6cSMatthew Knepley   int        *itmp;
130017ab2063SBarry Smith 
13013a40ed3dSBarry Smith   PetscFunctionBegin;
1302273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
130317ab2063SBarry Smith 
1304416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1305bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
130617ab2063SBarry Smith   if (idx) {
1307bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1308bfeeae90SHong Zhang     if (*nz) {
13094e093b46SBarry Smith       *idx = itmp;
131017ab2063SBarry Smith     }
131117ab2063SBarry Smith     else *idx = 0;
131217ab2063SBarry Smith   }
13133a40ed3dSBarry Smith   PetscFunctionReturn(0);
131417ab2063SBarry Smith }
131517ab2063SBarry Smith 
1316bfeeae90SHong Zhang /* remove this function? */
13174a2ae208SSatish Balay #undef __FUNCT__
13184a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
131987828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
132017ab2063SBarry Smith {
1321bfeeae90SHong Zhang   /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1322bfeeae90SHong Zhang      int ierr; */
13233a40ed3dSBarry Smith 
13243a40ed3dSBarry Smith   PetscFunctionBegin;
1325bfeeae90SHong Zhang   /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */
13263a40ed3dSBarry Smith   PetscFunctionReturn(0);
132717ab2063SBarry Smith }
132817ab2063SBarry Smith 
13294a2ae208SSatish Balay #undef __FUNCT__
13304a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1331064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
133217ab2063SBarry Smith {
1333416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
133487828ca2SBarry Smith   PetscScalar  *v = a->a;
133536db0b34SBarry Smith   PetscReal    sum = 0.0;
1336bfeeae90SHong Zhang   int          i,j,ierr;
133717ab2063SBarry Smith 
13383a40ed3dSBarry Smith   PetscFunctionBegin;
133917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1340416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1341aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
134236db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
134317ab2063SBarry Smith #else
134417ab2063SBarry Smith       sum += (*v)*(*v); v++;
134517ab2063SBarry Smith #endif
134617ab2063SBarry Smith     }
1347064f8208SBarry Smith     *nrm = sqrt(sum);
13483a40ed3dSBarry Smith   } else if (type == NORM_1) {
134936db0b34SBarry Smith     PetscReal *tmp;
1350416022c9SBarry Smith     int    *jj = a->j;
1351b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1352273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1353064f8208SBarry Smith     *nrm = 0.0;
1354416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1355bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
135617ab2063SBarry Smith     }
1357273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1358064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
135917ab2063SBarry Smith     }
1360606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13613a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1362064f8208SBarry Smith     *nrm = 0.0;
1363273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1364bfeeae90SHong Zhang       v = a->a + a->i[j];
136517ab2063SBarry Smith       sum = 0.0;
1366416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1367cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
136817ab2063SBarry Smith       }
1369064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
137017ab2063SBarry Smith     }
13713a40ed3dSBarry Smith   } else {
137229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
137317ab2063SBarry Smith   }
13743a40ed3dSBarry Smith   PetscFunctionReturn(0);
137517ab2063SBarry Smith }
137617ab2063SBarry Smith 
13774a2ae208SSatish Balay #undef __FUNCT__
13784a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
13798f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
138017ab2063SBarry Smith {
1381416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1382416022c9SBarry Smith   Mat          C;
1383273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
138487828ca2SBarry Smith   PetscScalar  *array = a->a;
138517ab2063SBarry Smith 
13863a40ed3dSBarry Smith   PetscFunctionBegin;
1387273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1388b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1389273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
1390bfeeae90SHong Zhang 
1391bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1392273d9f13SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr);
1393606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
139417ab2063SBarry Smith   for (i=0; i<m; i++) {
139517ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1396416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1397b9b97703SBarry Smith     array += len;
1398b9b97703SBarry Smith     aj    += len;
139917ab2063SBarry Smith   }
140017ab2063SBarry Smith 
14016d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14026d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
140317ab2063SBarry Smith 
1404f1e2ffcdSBarry Smith   if (B) {
1405416022c9SBarry Smith     *B = C;
140617ab2063SBarry Smith   } else {
1407273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
140817ab2063SBarry Smith   }
14093a40ed3dSBarry Smith   PetscFunctionReturn(0);
141017ab2063SBarry Smith }
141117ab2063SBarry Smith 
1412cd0d46ebSvictorle EXTERN_C_BEGIN
1413cd0d46ebSvictorle #undef __FUNCT__
1414cd0d46ebSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1415cd0d46ebSvictorle int MatIsSymmetric_SeqAIJ(Mat A,Mat B,PetscTruth *f)
1416cd0d46ebSvictorle {
1417cd0d46ebSvictorle   Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
1418cd0d46ebSvictorle   int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
1419cd0d46ebSvictorle   int ma,na,mb,nb, i,ierr;
1420cd0d46ebSvictorle 
1421cd0d46ebSvictorle   PetscFunctionBegin;
1422cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1423cd0d46ebSvictorle 
1424cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na); CHKERRQ(ierr);
1425cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb); CHKERRQ(ierr);
1426cd0d46ebSvictorle   if (ma!=nb || na!=mb)
1427cd0d46ebSvictorle     SETERRQ(1,"Incompatible A/B sizes for symmetry test");
1428cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1429cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1430cd0d46ebSvictorle   va = aij->a; vb = bij->a;
1431cd0d46ebSvictorle   ierr = PetscMalloc(ma*sizeof(int),&aptr); CHKERRQ(ierr);
1432cd0d46ebSvictorle   ierr = PetscMalloc(mb*sizeof(int),&bptr); CHKERRQ(ierr);
1433cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1434cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1435cd0d46ebSvictorle 
1436cd0d46ebSvictorle   *f = PETSC_TRUE;
1437cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1438cd0d46ebSvictorle     /*printf("row %d spans %d--%d; we start @ %d\n",
1439cd0d46ebSvictorle       i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/
1440cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
1441cd0d46ebSvictorle       int idc,idr; PetscScalar vc,vr;
1442cd0d46ebSvictorle       /* column/row index/value */
1443cd0d46ebSvictorle       idc = adx[aptr[i]]; idr = bdx[bptr[idc]];
1444cd0d46ebSvictorle       vc = va[aptr[i]]; vr = vb[bptr[idc]];
1445cd0d46ebSvictorle       /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n",
1446cd0d46ebSvictorle 	aptr[i],i,idc,vc,idc,idr,vr);*/
1447cd0d46ebSvictorle       if (i!=idr || vc!=vr) {
1448cd0d46ebSvictorle 	*f = PETSC_FALSE; goto done;
1449cd0d46ebSvictorle       } else {
14503aeef889SHong Zhang 	aptr[i]++; if (B || i!=idc) bptr[idc]++;
1451cd0d46ebSvictorle       }
1452cd0d46ebSvictorle     }
1453cd0d46ebSvictorle   }
1454cd0d46ebSvictorle  done:
1455cd0d46ebSvictorle   ierr = PetscFree(aptr); CHKERRQ(ierr);
14563aeef889SHong Zhang   if (B) {
14573aeef889SHong Zhang     ierr = PetscFree(bptr); CHKERRQ(ierr);
14583aeef889SHong Zhang   }
1459cd0d46ebSvictorle 
1460cd0d46ebSvictorle   PetscFunctionReturn(0);
1461cd0d46ebSvictorle }
1462cd0d46ebSvictorle EXTERN_C_END
1463cd0d46ebSvictorle 
14644a2ae208SSatish Balay #undef __FUNCT__
14654a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14668f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
146717ab2063SBarry Smith {
1468416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
146987828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1470bfeeae90SHong Zhang   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
147117ab2063SBarry Smith 
14723a40ed3dSBarry Smith   PetscFunctionBegin;
147317ab2063SBarry Smith   if (ll) {
14743ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14753ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1476e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1477273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
1478ed480e8bSBarry Smith     ierr = VecGetArrayFast(ll,&l);CHKERRQ(ierr);
1479416022c9SBarry Smith     v = a->a;
148017ab2063SBarry Smith     for (i=0; i<m; i++) {
148117ab2063SBarry Smith       x = l[i];
1482416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
148317ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
148417ab2063SBarry Smith     }
1485ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(ll,&l);CHKERRQ(ierr);
1486b0a32e0cSBarry Smith     PetscLogFlops(nz);
148717ab2063SBarry Smith   }
148817ab2063SBarry Smith   if (rr) {
1489e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1490273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
1491ed480e8bSBarry Smith     ierr = VecGetArrayFast(rr,&r);CHKERRQ(ierr);
1492416022c9SBarry Smith     v = a->a; jj = a->j;
149317ab2063SBarry Smith     for (i=0; i<nz; i++) {
1494bfeeae90SHong Zhang       (*v++) *= r[*jj++];
149517ab2063SBarry Smith     }
1496ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(rr,&r);CHKERRQ(ierr);
1497b0a32e0cSBarry Smith     PetscLogFlops(nz);
149817ab2063SBarry Smith   }
14993a40ed3dSBarry Smith   PetscFunctionReturn(0);
150017ab2063SBarry Smith }
150117ab2063SBarry Smith 
15024a2ae208SSatish Balay #undef __FUNCT__
15034a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
15047b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
150517ab2063SBarry Smith {
1506db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1507273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
150836db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
1509bfeeae90SHong Zhang   int          *irow,*icol,nrows,ncols;
151099141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
151187828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1512416022c9SBarry Smith   Mat          C;
1513fee21e36SBarry Smith   PetscTruth   stride;
151417ab2063SBarry Smith 
15153a40ed3dSBarry Smith   PetscFunctionBegin;
1516d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
151729bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1518d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
151929bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
152099141d43SSatish Balay 
152117ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1522b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1523b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
152417ab2063SBarry Smith 
1525fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1526fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1527fee21e36SBarry Smith   if (stride && step == 1) {
152802834360SBarry Smith     /* special case of contiguous rows */
152931ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
153031ebf83bSSatish Balay     starts = lens + nrows;
153102834360SBarry Smith     /* loop over new rows determining lens and starting points */
153202834360SBarry Smith     for (i=0; i<nrows; i++) {
1533bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1534a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
153502834360SBarry Smith       for (k=kstart; k<kend; k++) {
1536bfeeae90SHong Zhang         if (aj[k] >= first) {
153702834360SBarry Smith           starts[i] = k;
153802834360SBarry Smith           break;
153902834360SBarry Smith 	}
154002834360SBarry Smith       }
1541a2744918SBarry Smith       sum = 0;
154202834360SBarry Smith       while (k < kend) {
1543bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1544a2744918SBarry Smith         sum++;
154502834360SBarry Smith       }
1546a2744918SBarry Smith       lens[i] = sum;
154702834360SBarry Smith     }
154802834360SBarry Smith     /* create submatrix */
1549cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
155008480c60SBarry Smith       int n_cols,n_rows;
155108480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
155229bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1553d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
155408480c60SBarry Smith       C = *B;
15553a40ed3dSBarry Smith     } else {
155602834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
155708480c60SBarry Smith     }
1558db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1559db02288aSLois Curfman McInnes 
156002834360SBarry Smith     /* loop over rows inserting into submatrix */
1561db02288aSLois Curfman McInnes     a_new    = c->a;
1562db02288aSLois Curfman McInnes     j_new    = c->j;
1563db02288aSLois Curfman McInnes     i_new    = c->i;
1564bfeeae90SHong Zhang 
156502834360SBarry Smith     for (i=0; i<nrows; i++) {
1566a2744918SBarry Smith       ii    = starts[i];
1567a2744918SBarry Smith       lensi = lens[i];
1568a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1569a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
157002834360SBarry Smith       }
157187828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1572a2744918SBarry Smith       a_new      += lensi;
1573a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1574a2744918SBarry Smith       c->ilen[i]  = lensi;
157502834360SBarry Smith     }
1576606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15773a40ed3dSBarry Smith   } else {
157802834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1579b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
1580bfeeae90SHong Zhang 
1581b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1582549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
158317ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
158402834360SBarry Smith     /* determine lens of each row */
158502834360SBarry Smith     for (i=0; i<nrows; i++) {
1586bfeeae90SHong Zhang       kstart  = ai[irow[i]];
158702834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
158802834360SBarry Smith       lens[i] = 0;
158902834360SBarry Smith       for (k=kstart; k<kend; k++) {
1590bfeeae90SHong Zhang         if (smap[aj[k]]) {
159102834360SBarry Smith           lens[i]++;
159202834360SBarry Smith         }
159302834360SBarry Smith       }
159402834360SBarry Smith     }
159517ab2063SBarry Smith     /* Create and fill new matrix */
1596a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15970f5bd95cSBarry Smith       PetscTruth equal;
15980f5bd95cSBarry Smith 
159999141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1600273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1601273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
16020f5bd95cSBarry Smith       if (!equal) {
160329bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
160499141d43SSatish Balay       }
1605273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
160608480c60SBarry Smith       C = *B;
16073a40ed3dSBarry Smith     } else {
160802834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
160908480c60SBarry Smith     }
161099141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
161117ab2063SBarry Smith     for (i=0; i<nrows; i++) {
161299141d43SSatish Balay       row    = irow[i];
1613bfeeae90SHong Zhang       kstart = ai[row];
161499141d43SSatish Balay       kend   = kstart + a->ilen[row];
1615bfeeae90SHong Zhang       mat_i  = c->i[i];
161699141d43SSatish Balay       mat_j  = c->j + mat_i;
161799141d43SSatish Balay       mat_a  = c->a + mat_i;
161899141d43SSatish Balay       mat_ilen = c->ilen + i;
161917ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1620bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1621ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
162299141d43SSatish Balay           *mat_a++ = a->a[k];
162399141d43SSatish Balay           (*mat_ilen)++;
162499141d43SSatish Balay 
162517ab2063SBarry Smith         }
162617ab2063SBarry Smith       }
162717ab2063SBarry Smith     }
162802834360SBarry Smith     /* Free work space */
162902834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1630606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1631606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
163202834360SBarry Smith   }
16336d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16346d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163517ab2063SBarry Smith 
163617ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1637416022c9SBarry Smith   *B = C;
16383a40ed3dSBarry Smith   PetscFunctionReturn(0);
163917ab2063SBarry Smith }
164017ab2063SBarry Smith 
1641a871dcd8SBarry Smith /*
1642a871dcd8SBarry Smith */
16434a2ae208SSatish Balay #undef __FUNCT__
16444a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1645b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1646a871dcd8SBarry Smith {
164763b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
164808480c60SBarry Smith   int        ierr;
164963b91edcSBarry Smith   Mat        outA;
1650b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
165163b91edcSBarry Smith 
16523a40ed3dSBarry Smith   PetscFunctionBegin;
1653d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1654b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1655b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1656b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
165729bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1658b8a78c4aSBarry Smith   }
1659a871dcd8SBarry Smith 
166063b91edcSBarry Smith   outA          = inA;
166163b91edcSBarry Smith   inA->factor   = FACTOR_LU;
166263b91edcSBarry Smith   a->row        = row;
166363b91edcSBarry Smith   a->col        = col;
1664c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1665c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
166663b91edcSBarry Smith 
166736db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1668b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16694c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1670b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1671f0ec6fceSSatish Balay 
167294a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
167387828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
167494a9d846SBarry Smith   }
167563b91edcSBarry Smith 
167608480c60SBarry Smith   if (!a->diag) {
1677f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
167863b91edcSBarry Smith   }
167963b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1681a871dcd8SBarry Smith }
1682a871dcd8SBarry Smith 
1683d9eff348SSatish Balay #include "petscblaslapack.h"
16844a2ae208SSatish Balay #undef __FUNCT__
16854a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1686268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA)
1687f0b747eeSBarry Smith {
1688f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1689f0b747eeSBarry Smith   int        one = 1;
16903a40ed3dSBarry Smith 
16913a40ed3dSBarry Smith   PetscFunctionBegin;
1692268466fbSBarry Smith   BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one);
1693b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
16943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1695f0b747eeSBarry Smith }
1696f0b747eeSBarry Smith 
16974a2ae208SSatish Balay #undef __FUNCT__
16984a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
1699268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1700cddf8d76SBarry Smith {
1701cddf8d76SBarry Smith   int ierr,i;
1702cddf8d76SBarry Smith 
17033a40ed3dSBarry Smith   PetscFunctionBegin;
1704cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1705b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1706cddf8d76SBarry Smith   }
1707cddf8d76SBarry Smith 
1708cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17096a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1710cddf8d76SBarry Smith   }
17113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1712cddf8d76SBarry Smith }
1713cddf8d76SBarry Smith 
17144a2ae208SSatish Balay #undef __FUNCT__
17154a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17168f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17175a838052SSatish Balay {
1718f830108cSBarry Smith   PetscFunctionBegin;
17195a838052SSatish Balay   *bs = 1;
17203a40ed3dSBarry Smith   PetscFunctionReturn(0);
17215a838052SSatish Balay }
17225a838052SSatish Balay 
17234a2ae208SSatish Balay #undef __FUNCT__
17244a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
1725268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov)
17264dcbc457SBarry Smith {
1727e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1728efb16452SHong Zhang   int        row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17298a047759SSatish Balay   int        start,end,*ai,*aj;
1730f1af5d2fSBarry Smith   PetscBT    table;
1731bbd702dbSSatish Balay 
17323a40ed3dSBarry Smith   PetscFunctionBegin;
1733273d9f13SBarry Smith   m     = A->m;
1734e4d965acSSatish Balay   ai    = a->i;
1735bfeeae90SHong Zhang   aj    = a->j;
17368a047759SSatish Balay 
173729bbc08cSBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used");
173806763907SSatish Balay 
1739b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17406831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
174106763907SSatish Balay 
1742e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1743b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1744e4d965acSSatish Balay     isz  = 0;
17456831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1746e4d965acSSatish Balay 
1747e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17484dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1749b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1750e4d965acSSatish Balay 
1751dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1752e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1753f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17544dcbc457SBarry Smith     }
175506763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
175606763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1757e4d965acSSatish Balay 
175804a348a9SBarry Smith     k = 0;
175904a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
176004a348a9SBarry Smith       n = isz;
176106763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1762e4d965acSSatish Balay         row   = nidx[k];
1763e4d965acSSatish Balay         start = ai[row];
1764e4d965acSSatish Balay         end   = ai[row+1];
176504a348a9SBarry Smith         for (l = start; l<end ; l++){
1766efb16452SHong Zhang           val = aj[l] ;
1767f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1768e4d965acSSatish Balay         }
1769e4d965acSSatish Balay       }
1770e4d965acSSatish Balay     }
1771029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1772e4d965acSSatish Balay   }
17736831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1774606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17753a40ed3dSBarry Smith   PetscFunctionReturn(0);
17764dcbc457SBarry Smith }
177717ab2063SBarry Smith 
17780513a670SBarry Smith /* -------------------------------------------------------------- */
17794a2ae208SSatish Balay #undef __FUNCT__
17804a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17810513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17820513a670SBarry Smith {
17830513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
178487828ca2SBarry Smith   PetscScalar  *vwork;
1785273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
17860513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
178756cd22aeSBarry Smith   IS           icolp,irowp;
17880513a670SBarry Smith 
17893a40ed3dSBarry Smith   PetscFunctionBegin;
17904c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
179156cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
17924c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
179356cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17940513a670SBarry Smith 
17950513a670SBarry Smith   /* determine lengths of permuted rows */
1796b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
17970513a670SBarry Smith   for (i=0; i<m; i++) {
17980513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
17990513a670SBarry Smith   }
18000513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1801606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18020513a670SBarry Smith 
1803b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18040513a670SBarry Smith   for (i=0; i<m; i++) {
18050513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18060513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18070513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18080513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18090513a670SBarry Smith   }
1810606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18110513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18120513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
181356cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
181456cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
181556cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
181656cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18173a40ed3dSBarry Smith   PetscFunctionReturn(0);
18180513a670SBarry Smith }
18190513a670SBarry Smith 
18204a2ae208SSatish Balay #undef __FUNCT__
18214a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1822682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1823682d7d0cSBarry Smith {
1824c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1825682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1826d132466eSBarry Smith   int               ierr;
1827682d7d0cSBarry Smith 
18283a40ed3dSBarry Smith   PetscFunctionBegin;
1829c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1830d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1831d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1832d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1833d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1834d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
183587828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
1836ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1837ca44d042SBarry Smith #endif
18383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1839682d7d0cSBarry Smith }
1840ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1841ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1842b380c88cSHong Zhang EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatFactorInfo*,IS,IS,Mat*);
18434a2ae208SSatish Balay #undef __FUNCT__
18444a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1845cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1846cb5b572fSBarry Smith {
1847be6bf707SBarry Smith   int        ierr;
1848cb5b572fSBarry Smith 
1849cb5b572fSBarry Smith   PetscFunctionBegin;
185033f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
185133f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1852be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1853be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1854be6bf707SBarry Smith 
1855bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
185629bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1857cb5b572fSBarry Smith     }
1858bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1859cb5b572fSBarry Smith   } else {
1860cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1861cb5b572fSBarry Smith   }
1862cb5b572fSBarry Smith   PetscFunctionReturn(0);
1863cb5b572fSBarry Smith }
1864cb5b572fSBarry Smith 
18654a2ae208SSatish Balay #undef __FUNCT__
18664a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1867273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1868273d9f13SBarry Smith {
1869273d9f13SBarry Smith   int        ierr;
1870273d9f13SBarry Smith 
1871273d9f13SBarry Smith   PetscFunctionBegin;
1872273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1873273d9f13SBarry Smith   PetscFunctionReturn(0);
1874273d9f13SBarry Smith }
1875273d9f13SBarry Smith 
18764a2ae208SSatish Balay #undef __FUNCT__
18774a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
18784e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
18796c0721eeSBarry Smith {
18806c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18816c0721eeSBarry Smith   PetscFunctionBegin;
18826c0721eeSBarry Smith   *array = a->a;
18836c0721eeSBarry Smith   PetscFunctionReturn(0);
18846c0721eeSBarry Smith }
18856c0721eeSBarry Smith 
18864a2ae208SSatish Balay #undef __FUNCT__
18874a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
18884e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
18896c0721eeSBarry Smith {
18906c0721eeSBarry Smith   PetscFunctionBegin;
18916c0721eeSBarry Smith   PetscFunctionReturn(0);
18926c0721eeSBarry Smith }
1893273d9f13SBarry Smith 
1894ee4f033dSBarry Smith #undef __FUNCT__
1895ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1896ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1897ee4f033dSBarry Smith {
1898ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1899ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
190087828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
190187828ca2SBarry Smith   PetscScalar   *vscale_array;
1902ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1903ee4f033dSBarry Smith   Vec           w1,w2,w3;
1904ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1905ee4f033dSBarry Smith   PetscTruth    flg;
1906ee4f033dSBarry Smith 
1907ee4f033dSBarry Smith   PetscFunctionBegin;
1908ee4f033dSBarry Smith   if (!coloring->w1) {
1909ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1910ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1911ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1912ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1913ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1914ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1915ee4f033dSBarry Smith   }
1916ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1917ee4f033dSBarry Smith 
1918ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1919e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1920ee4f033dSBarry Smith   if (flg) {
1921ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1922ee4f033dSBarry Smith   } else {
1923ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1924ee4f033dSBarry Smith   }
1925ee4f033dSBarry Smith 
1926ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1927ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1928ee4f033dSBarry Smith 
1929ee4f033dSBarry Smith   /*
1930ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1931ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1932ee4f033dSBarry Smith   */
1933ee4f033dSBarry Smith   if (coloring->F) {
1934ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1935ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1936ee4f033dSBarry Smith     if (m1 != m2) {
1937ee4f033dSBarry Smith       coloring->F = 0;
1938ee4f033dSBarry Smith     }
1939ee4f033dSBarry Smith   }
1940ee4f033dSBarry Smith 
1941ee4f033dSBarry Smith   if (coloring->F) {
1942ee4f033dSBarry Smith     w1          = coloring->F;
1943ee4f033dSBarry Smith     coloring->F = 0;
1944ee4f033dSBarry Smith   } else {
194566f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1946ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
194766f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1948ee4f033dSBarry Smith   }
1949ee4f033dSBarry Smith 
1950ee4f033dSBarry Smith   /*
1951ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1952ee4f033dSBarry Smith   */
1953ed480e8bSBarry Smith   ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start;
1954ed480e8bSBarry Smith   ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1955ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1956ee4f033dSBarry Smith     /*
1957ee4f033dSBarry Smith        Loop over each column associated with color adding the
1958ee4f033dSBarry Smith        perturbation to the vector w3.
1959ee4f033dSBarry Smith     */
1960ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1961ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1962ee4f033dSBarry Smith       dx  = xx[col];
1963ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1964ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1965ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1966ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1967ee4f033dSBarry Smith #else
1968ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1969ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1970ee4f033dSBarry Smith #endif
1971ee4f033dSBarry Smith       dx                *= epsilon;
1972ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1973ee4f033dSBarry Smith     }
1974ee4f033dSBarry Smith   }
1975ed480e8bSBarry Smith   vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1976ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1977ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1978ee4f033dSBarry Smith 
1979ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
1980ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
1981ee4f033dSBarry Smith 
1982ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
1983ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
1984ee4f033dSBarry Smith 
1985ed480e8bSBarry Smith   ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1986ee4f033dSBarry Smith   /*
1987ee4f033dSBarry Smith       Loop over each color
1988ee4f033dSBarry Smith   */
1989ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
199049b058dcSBarry Smith     coloring->currentcolor = k;
1991ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
1992ed480e8bSBarry Smith     ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
1993ee4f033dSBarry Smith     /*
1994ee4f033dSBarry Smith        Loop over each column associated with color adding the
1995ee4f033dSBarry Smith        perturbation to the vector w3.
1996ee4f033dSBarry Smith     */
1997ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1998ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1999ee4f033dSBarry Smith       dx  = xx[col];
2000ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2001ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2002ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2003ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2004ee4f033dSBarry Smith #else
2005ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2006ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2007ee4f033dSBarry Smith #endif
2008ee4f033dSBarry Smith       dx            *= epsilon;
2009ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2010ee4f033dSBarry Smith       w3_array[col] += dx;
2011ee4f033dSBarry Smith     }
2012ed480e8bSBarry Smith     w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr);
2013ee4f033dSBarry Smith 
2014ee4f033dSBarry Smith     /*
2015ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2016ee4f033dSBarry Smith     */
2017ee4f033dSBarry Smith 
201866f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2019ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
202066f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2021ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2022ee4f033dSBarry Smith 
2023ee4f033dSBarry Smith     /*
2024ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2025ee4f033dSBarry Smith     */
2026ed480e8bSBarry Smith     ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr);
2027ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2028ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2029ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2030ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2031ee4f033dSBarry Smith       srow   = row + start;
2032ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2033ee4f033dSBarry Smith     }
2034ed480e8bSBarry Smith     ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr);
2035ee4f033dSBarry Smith   }
203649b058dcSBarry Smith   coloring->currentcolor = k;
2037ed480e8bSBarry Smith   ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2038ed480e8bSBarry Smith   xx = xx + start; ierr  = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr);
2039ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2040ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2041ee4f033dSBarry Smith   PetscFunctionReturn(0);
2042ee4f033dSBarry Smith }
2043ee4f033dSBarry Smith 
2044ac90fabeSBarry Smith #include "petscblaslapack.h"
2045ac90fabeSBarry Smith #undef __FUNCT__
2046ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2047268466fbSBarry Smith int MatAXPY_SeqAIJ(const PetscScalar *a,Mat X,Mat Y,MatStructure str)
2048ac90fabeSBarry Smith {
2049c537a176SHong Zhang   int        ierr,one=1,i;
2050ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2051ac90fabeSBarry Smith 
2052ac90fabeSBarry Smith   PetscFunctionBegin;
2053ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2054268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
2055c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2056a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2057a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2058a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2059a30b2313SHong Zhang     }
2060a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
206124f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2062a30b2313SHong Zhang       y->XtoY = X;
2063c537a176SHong Zhang     }
2064a30b2313SHong Zhang     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]);
2065e2dd4fc4Svictorle     PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);
2066ac90fabeSBarry Smith   } else {
2067ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2068ac90fabeSBarry Smith   }
2069ac90fabeSBarry Smith   PetscFunctionReturn(0);
2070ac90fabeSBarry Smith }
2071ac90fabeSBarry Smith 
2072682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20730a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2074cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2075cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2076cb5b572fSBarry Smith        MatMult_SeqAIJ,
2077cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
20787c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20797c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2080cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2081cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20827c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
20837c922b88SBarry Smith        MatSolveTransposeAdd_SeqAIJ,
2084cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2085cb5b572fSBarry Smith        0,
208617ab2063SBarry Smith        MatRelax_SeqAIJ,
208717ab2063SBarry Smith        MatTranspose_SeqAIJ,
2088cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
2089cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2090cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2091cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2092cb5b572fSBarry Smith        MatNorm_SeqAIJ,
2093cb5b572fSBarry Smith        0,
2094cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
209517ab2063SBarry Smith        MatCompress_SeqAIJ,
2096cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2097cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2098cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
2099cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2100cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2101f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2102a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
2103273d9f13SBarry Smith        MatSetUpPreallocation_SeqAIJ,
2104cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2105861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
21066c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21076c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2108be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
2109cb5b572fSBarry Smith        0,
2110cb5b572fSBarry Smith        0,
2111cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2112cb5b572fSBarry Smith        0,
2113ac90fabeSBarry Smith        MatAXPY_SeqAIJ,
2114cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2115cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2116cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2117cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2118f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
2119cb5b572fSBarry Smith        MatScale_SeqAIJ,
2120cb5b572fSBarry Smith        0,
2121cb5b572fSBarry Smith        0,
21226945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
21236945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
21243b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21253b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21263b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2127a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2128a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
2129b9617806SBarry Smith        0,
21300513a670SBarry Smith        0,
2131cda55fadSBarry Smith        MatPermute_SeqAIJ,
2132cda55fadSBarry Smith        0,
2133cda55fadSBarry Smith        0,
2134b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2135b9b97703SBarry Smith        MatView_SeqAIJ,
21368a124369SBarry Smith        MatGetPetscMaps_Petsc,
2137ee4f033dSBarry Smith        0,
2138ee4f033dSBarry Smith        0,
2139ee4f033dSBarry Smith        0,
2140ee4f033dSBarry Smith        0,
2141ee4f033dSBarry Smith        0,
2142ee4f033dSBarry Smith        0,
2143ee4f033dSBarry Smith        0,
2144ee4f033dSBarry Smith        0,
2145ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2146ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2147ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
2148ee4f033dSBarry Smith        MatFDColoringApply_SeqAIJ};
214917ab2063SBarry Smith 
2150fb2e594dSBarry Smith EXTERN_C_BEGIN
21514a2ae208SSatish Balay #undef __FUNCT__
21524a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
215315091d37SBarry Smith 
2154bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2155bef8e0ddSBarry Smith {
2156bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2157bef8e0ddSBarry Smith   int        i,nz,n;
2158bef8e0ddSBarry Smith 
2159bef8e0ddSBarry Smith   PetscFunctionBegin;
2160bef8e0ddSBarry Smith 
2161bef8e0ddSBarry Smith   nz = aij->maxnz;
2162273d9f13SBarry Smith   n  = mat->n;
2163bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2164bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2165bef8e0ddSBarry Smith   }
2166bef8e0ddSBarry Smith   aij->nz = nz;
2167bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2168bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2169bef8e0ddSBarry Smith   }
2170bef8e0ddSBarry Smith 
2171bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2172bef8e0ddSBarry Smith }
2173fb2e594dSBarry Smith EXTERN_C_END
2174bef8e0ddSBarry Smith 
21754a2ae208SSatish Balay #undef __FUNCT__
21764a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2177bef8e0ddSBarry Smith /*@
2178bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2179bef8e0ddSBarry Smith        in the matrix.
2180bef8e0ddSBarry Smith 
2181bef8e0ddSBarry Smith   Input Parameters:
2182bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2183bef8e0ddSBarry Smith -  indices - the column indices
2184bef8e0ddSBarry Smith 
218515091d37SBarry Smith   Level: advanced
218615091d37SBarry Smith 
2187bef8e0ddSBarry Smith   Notes:
2188bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2189bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2190bef8e0ddSBarry Smith   of the MatSetValues() operation.
2191bef8e0ddSBarry Smith 
2192bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2193bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2194bef8e0ddSBarry Smith 
2195bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2196bef8e0ddSBarry Smith 
2197b9617806SBarry Smith     The indices should start with zero, not one.
2198b9617806SBarry Smith 
2199bef8e0ddSBarry Smith @*/
2200bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2201bef8e0ddSBarry Smith {
2202bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2203bef8e0ddSBarry Smith 
2204bef8e0ddSBarry Smith   PetscFunctionBegin;
2205bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2206c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2207bef8e0ddSBarry Smith   if (f) {
2208bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2209bef8e0ddSBarry Smith   } else {
221029bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2211bef8e0ddSBarry Smith   }
2212bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2213bef8e0ddSBarry Smith }
2214bef8e0ddSBarry Smith 
2215be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2216be6bf707SBarry Smith 
2217fb2e594dSBarry Smith EXTERN_C_BEGIN
22184a2ae208SSatish Balay #undef __FUNCT__
22194a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2220be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2221be6bf707SBarry Smith {
2222be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2223bfeeae90SHong Zhang   size_t       nz = aij->i[mat->m],ierr;
2224be6bf707SBarry Smith 
2225be6bf707SBarry Smith   PetscFunctionBegin;
2226be6bf707SBarry Smith   if (aij->nonew != 1) {
222729bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2228be6bf707SBarry Smith   }
2229be6bf707SBarry Smith 
2230be6bf707SBarry Smith   /* allocate space for values if not already there */
2231be6bf707SBarry Smith   if (!aij->saved_values) {
223287828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2233be6bf707SBarry Smith   }
2234be6bf707SBarry Smith 
2235be6bf707SBarry Smith   /* copy values over */
223687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2237be6bf707SBarry Smith   PetscFunctionReturn(0);
2238be6bf707SBarry Smith }
2239fb2e594dSBarry Smith EXTERN_C_END
2240be6bf707SBarry Smith 
22414a2ae208SSatish Balay #undef __FUNCT__
2242b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2243be6bf707SBarry Smith /*@
2244be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2245be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2246be6bf707SBarry Smith        nonlinear portion.
2247be6bf707SBarry Smith 
2248be6bf707SBarry Smith    Collect on Mat
2249be6bf707SBarry Smith 
2250be6bf707SBarry Smith   Input Parameters:
2251be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2252be6bf707SBarry Smith 
225315091d37SBarry Smith   Level: advanced
225415091d37SBarry Smith 
2255be6bf707SBarry Smith   Common Usage, with SNESSolve():
2256be6bf707SBarry Smith $    Create Jacobian matrix
2257be6bf707SBarry Smith $    Set linear terms into matrix
2258be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2259be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2260be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2261be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2262be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2263be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2264be6bf707SBarry Smith $    In your Jacobian routine
2265be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2266be6bf707SBarry Smith $      Set nonlinear terms in matrix
2267be6bf707SBarry Smith 
2268be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2269be6bf707SBarry Smith $    // build linear portion of Jacobian
2270be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2271be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2272be6bf707SBarry Smith $    loop over nonlinear iterations
2273be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2274be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2275be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2276be6bf707SBarry Smith $       Solve linear system with Jacobian
2277be6bf707SBarry Smith $    endloop
2278be6bf707SBarry Smith 
2279be6bf707SBarry Smith   Notes:
2280be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2281be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2282be6bf707SBarry Smith     calling this routine.
2283be6bf707SBarry Smith 
2284be6bf707SBarry Smith .seealso: MatRetrieveValues()
2285be6bf707SBarry Smith 
2286be6bf707SBarry Smith @*/
2287be6bf707SBarry Smith int MatStoreValues(Mat mat)
2288be6bf707SBarry Smith {
2289be6bf707SBarry Smith   int ierr,(*f)(Mat);
2290be6bf707SBarry Smith 
2291be6bf707SBarry Smith   PetscFunctionBegin;
2292be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
229329bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
229429bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2295be6bf707SBarry Smith 
2296c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2297be6bf707SBarry Smith   if (f) {
2298be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2299be6bf707SBarry Smith   } else {
230029bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2301be6bf707SBarry Smith   }
2302be6bf707SBarry Smith   PetscFunctionReturn(0);
2303be6bf707SBarry Smith }
2304be6bf707SBarry Smith 
2305fb2e594dSBarry Smith EXTERN_C_BEGIN
23064a2ae208SSatish Balay #undef __FUNCT__
23074a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2308be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2309be6bf707SBarry Smith {
2310be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2311bfeeae90SHong Zhang   int        nz = aij->i[mat->m],ierr;
2312be6bf707SBarry Smith 
2313be6bf707SBarry Smith   PetscFunctionBegin;
2314be6bf707SBarry Smith   if (aij->nonew != 1) {
231529bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2316be6bf707SBarry Smith   }
2317be6bf707SBarry Smith   if (!aij->saved_values) {
231829bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2319be6bf707SBarry Smith   }
2320be6bf707SBarry Smith 
2321be6bf707SBarry Smith   /* copy values over */
232287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2323be6bf707SBarry Smith   PetscFunctionReturn(0);
2324be6bf707SBarry Smith }
2325fb2e594dSBarry Smith EXTERN_C_END
2326be6bf707SBarry Smith 
23274a2ae208SSatish Balay #undef __FUNCT__
23284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2329be6bf707SBarry Smith /*@
2330be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2331be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2332be6bf707SBarry Smith        nonlinear portion.
2333be6bf707SBarry Smith 
2334be6bf707SBarry Smith    Collect on Mat
2335be6bf707SBarry Smith 
2336be6bf707SBarry Smith   Input Parameters:
2337be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2338be6bf707SBarry Smith 
233915091d37SBarry Smith   Level: advanced
234015091d37SBarry Smith 
2341be6bf707SBarry Smith .seealso: MatStoreValues()
2342be6bf707SBarry Smith 
2343be6bf707SBarry Smith @*/
2344be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2345be6bf707SBarry Smith {
2346be6bf707SBarry Smith   int ierr,(*f)(Mat);
2347be6bf707SBarry Smith 
2348be6bf707SBarry Smith   PetscFunctionBegin;
2349be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
235029bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
235129bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2352be6bf707SBarry Smith 
2353c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2354be6bf707SBarry Smith   if (f) {
2355be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2356be6bf707SBarry Smith   } else {
235729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2358be6bf707SBarry Smith   }
2359be6bf707SBarry Smith   PetscFunctionReturn(0);
2360be6bf707SBarry Smith }
2361be6bf707SBarry Smith 
2362f83d6046SBarry Smith /*
2363f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2364f83d6046SBarry Smith */
236587828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2366f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2367f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2368f83d6046SBarry Smith EXTERN_C_BEGIN
23694a2ae208SSatish Balay #undef __FUNCT__
23704a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ"
237162aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine)
2372f83d6046SBarry Smith {
23734a4478b9SSatish Balay   int         ierr,i,*ai,*aj;
2374f83d6046SBarry Smith   Mat         B = (Mat)obj;
2375f83d6046SBarry Smith   mxArray     *mat;
2376d79a51d8SBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
2377d79a51d8SBarry Smith 
2378f83d6046SBarry Smith   PetscFunctionBegin;
237901820c62SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
238087828ca2SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
2381d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
238266826eb6SBarry Smith   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
238366826eb6SBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2384f83d6046SBarry Smith 
238501820c62SBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
2386bfeeae90SHong Zhang 
2387ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2388f83d6046SBarry Smith   mxSetName(mat,obj->name);
238962aa7f4eSBarry Smith   engPutArray((Engine *)mengine,mat);
2390f83d6046SBarry Smith   PetscFunctionReturn(0);
2391f83d6046SBarry Smith }
2392f83d6046SBarry Smith EXTERN_C_END
239366826eb6SBarry Smith 
239466826eb6SBarry Smith EXTERN_C_BEGIN
23954a2ae208SSatish Balay #undef __FUNCT__
23964a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ"
239762aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine)
239866826eb6SBarry Smith {
239966826eb6SBarry Smith   int        ierr,ii;
240066826eb6SBarry Smith   Mat        mat = (Mat)obj;
240166826eb6SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
240266826eb6SBarry Smith   mxArray    *mmat;
240366826eb6SBarry Smith 
24046c0721eeSBarry Smith   PetscFunctionBegin;
240566826eb6SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
240666826eb6SBarry Smith 
240762aa7f4eSBarry Smith   mmat = engGetArray((Engine *)mengine,obj->name);
240866826eb6SBarry Smith 
2409a65776f3SBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->m];
2410a7ed9263SMatthew Knepley   ierr              = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
241166826eb6SBarry Smith   aij->j            = (int*)(aij->a + aij->nz);
241266826eb6SBarry Smith   aij->i            = aij->j + aij->nz;
241366826eb6SBarry Smith   aij->singlemalloc = PETSC_TRUE;
241466826eb6SBarry Smith   aij->freedata     = PETSC_TRUE;
241566826eb6SBarry Smith 
241687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
241766826eb6SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
241866826eb6SBarry Smith   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
241966826eb6SBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
242066826eb6SBarry Smith 
242166826eb6SBarry Smith   for (ii=0; ii<mat->m; ii++) {
242266826eb6SBarry Smith     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
242366826eb6SBarry Smith   }
242466826eb6SBarry Smith 
242566826eb6SBarry Smith   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
242666826eb6SBarry Smith   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
242766826eb6SBarry Smith 
242866826eb6SBarry Smith   PetscFunctionReturn(0);
242966826eb6SBarry Smith }
243066826eb6SBarry Smith EXTERN_C_END
2431f83d6046SBarry Smith #endif
2432f83d6046SBarry Smith 
2433be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
24344a2ae208SSatish Balay #undef __FUNCT__
24354a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
243617ab2063SBarry Smith /*@C
2437682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
24380d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
24396e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
244051c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
24412bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
244217ab2063SBarry Smith 
2443db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2444db81eaa0SLois Curfman McInnes 
244517ab2063SBarry Smith    Input Parameters:
2446db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
244717ab2063SBarry Smith .  m - number of rows
244817ab2063SBarry Smith .  n - number of columns
244917ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
245051c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
24512bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
245217ab2063SBarry Smith 
245317ab2063SBarry Smith    Output Parameter:
2454416022c9SBarry Smith .  A - the matrix
245517ab2063SBarry Smith 
2456b259b22eSLois Curfman McInnes    Notes:
245717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
245817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24590002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
246044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
246117ab2063SBarry Smith 
246217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2463a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24643d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24656da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
246617ab2063SBarry Smith 
2467682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24684fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2469682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24706c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24716c7ebb05SLois Curfman McInnes 
24726c7ebb05SLois Curfman McInnes    Options Database Keys:
2473db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2474db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2475db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2476db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2477db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
247817ab2063SBarry Smith 
2479027ccd11SLois Curfman McInnes    Level: intermediate
2480027ccd11SLois Curfman McInnes 
248136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
248236db0b34SBarry Smith 
248317ab2063SBarry Smith @*/
2484ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A)
248517ab2063SBarry Smith {
2486273d9f13SBarry Smith   int ierr;
24876945ee14SBarry Smith 
24883a40ed3dSBarry Smith   PetscFunctionBegin;
2489273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2490273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2491273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2492273d9f13SBarry Smith   PetscFunctionReturn(0);
2493273d9f13SBarry Smith }
2494273d9f13SBarry Smith 
24955da197adSKris Buschelman #define SKIP_ALLOCATION -4
24965da197adSKris Buschelman 
24974a2ae208SSatish Balay #undef __FUNCT__
24984a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2499273d9f13SBarry Smith /*@C
2500273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2501273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2502273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2503273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2504273d9f13SBarry Smith 
2505273d9f13SBarry Smith    Collective on MPI_Comm
2506273d9f13SBarry Smith 
2507273d9f13SBarry Smith    Input Parameters:
2508273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2509273d9f13SBarry Smith .  m - number of rows
2510273d9f13SBarry Smith .  n - number of columns
2511273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2512273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2513273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2514273d9f13SBarry Smith 
2515273d9f13SBarry Smith    Output Parameter:
2516273d9f13SBarry Smith .  A - the matrix
2517273d9f13SBarry Smith 
2518273d9f13SBarry Smith    Notes:
2519273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2520273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2521273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2522273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2523273d9f13SBarry Smith 
2524273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2525273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2526273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2527273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2528273d9f13SBarry Smith 
2529273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2530273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2531273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2532273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2533273d9f13SBarry Smith 
2534273d9f13SBarry Smith    Options Database Keys:
2535273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2536273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2537273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2538273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2539273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2540273d9f13SBarry Smith 
2541273d9f13SBarry Smith    Level: intermediate
2542273d9f13SBarry Smith 
2543273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2544273d9f13SBarry Smith 
2545273d9f13SBarry Smith @*/
2546ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[])
2547273d9f13SBarry Smith {
2548ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,const int[]);
2549a23d5eceSKris Buschelman 
2550a23d5eceSKris Buschelman   PetscFunctionBegin;
2551a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2552a23d5eceSKris Buschelman   if (f) {
2553a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2554a23d5eceSKris Buschelman   }
2555a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2556a23d5eceSKris Buschelman }
2557a23d5eceSKris Buschelman 
2558a23d5eceSKris Buschelman EXTERN_C_BEGIN
2559a23d5eceSKris Buschelman #undef __FUNCT__
2560a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2561a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz)
2562a23d5eceSKris Buschelman {
2563273d9f13SBarry Smith   Mat_SeqAIJ *b;
2564a7ed9263SMatthew Knepley   size_t     len = 0;
2565a43ee2ecSKris Buschelman   PetscTruth skipallocation = PETSC_FALSE;
2566a7ed9263SMatthew Knepley   int        i,ierr;
2567273d9f13SBarry Smith 
2568273d9f13SBarry Smith   PetscFunctionBegin;
2569d5d45c9bSBarry Smith 
2570c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2571c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2572c461c341SBarry Smith     nz             = 0;
2573c461c341SBarry Smith   }
2574c461c341SBarry Smith 
2575435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2576435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2577b73539f3SBarry Smith   if (nnz) {
2578273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
257929bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25803a7fca6bSBarry 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);
2581b73539f3SBarry Smith     }
2582b73539f3SBarry Smith   }
2583b73539f3SBarry Smith 
2584273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2585273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2586273d9f13SBarry Smith 
2587b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2588273d9f13SBarry Smith   if (!nnz) {
2589435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2590273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2591273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2592273d9f13SBarry Smith     nz = nz*B->m;
2593273d9f13SBarry Smith   } else {
2594273d9f13SBarry Smith     nz = 0;
2595273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2596273d9f13SBarry Smith   }
2597273d9f13SBarry Smith 
2598c461c341SBarry Smith   if (!skipallocation) {
2599273d9f13SBarry Smith     /* allocate the matrix space */
2600a7ed9263SMatthew Knepley     len             = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2601b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2602273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2603273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2604273d9f13SBarry Smith     b->i            = b->j + nz;
2605bfeeae90SHong Zhang     b->i[0] = 0;
26065da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26075da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26085da197adSKris Buschelman     }
2609273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2610273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2611c461c341SBarry Smith   } else {
2612c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2613c461c341SBarry Smith   }
2614273d9f13SBarry Smith 
2615273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2616b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2617b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2618273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2619273d9f13SBarry Smith 
2620273d9f13SBarry Smith   b->nz                = 0;
2621273d9f13SBarry Smith   b->maxnz             = nz;
2622273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2623273d9f13SBarry Smith   PetscFunctionReturn(0);
2624273d9f13SBarry Smith }
2625a23d5eceSKris Buschelman EXTERN_C_END
2626273d9f13SBarry Smith 
2627eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat);
2628eb9c0419SKris Buschelman 
2629273d9f13SBarry Smith EXTERN_C_BEGIN
263005b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqSBAIJ(Mat,MatType,Mat*);
263105b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqBAIJ(Mat,MatType,Mat*);
263205b94e36SKris Buschelman EXTERN int MatReorderForNonzeroDiagonal_SeqAIJ(Mat,PetscReal,IS,IS);
26330a99d0a2SKris Buschelman EXTERN int MatAdjustForInodes_SeqAIJ(Mat,IS*,IS*);
2634d758967fSKris Buschelman EXTERN int MatSeqAIJGetInodeSizes_SeqAIJ(Mat,int*,int*[],int*);
2635a6175056SHong Zhang EXTERN_C_END
2636a6175056SHong Zhang 
2637a6175056SHong Zhang EXTERN_C_BEGIN
26384a2ae208SSatish Balay #undef __FUNCT__
26394a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2640273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2641273d9f13SBarry Smith {
2642273d9f13SBarry Smith   Mat_SeqAIJ *b;
2643273d9f13SBarry Smith   int        ierr,size;
2644273d9f13SBarry Smith   PetscTruth flg;
2645273d9f13SBarry Smith 
2646273d9f13SBarry Smith   PetscFunctionBegin;
2647273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2648273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2649273d9f13SBarry Smith 
2650273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2651273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2652273d9f13SBarry Smith 
2653b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2654b0a32e0cSBarry Smith   B->data             = (void*)b;
2655549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2656549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2657416022c9SBarry Smith   B->factor           = 0;
2658416022c9SBarry Smith   B->lupivotthreshold = 1.0;
265990f02eecSBarry Smith   B->mapping          = 0;
2660e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2661e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2662416022c9SBarry Smith   b->row              = 0;
2663416022c9SBarry Smith   b->col              = 0;
266482bf6240SBarry Smith   b->icol             = 0;
2665b810aeb4SBarry Smith   b->reallocs         = 0;
266617ab2063SBarry Smith 
26678a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26688a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2669a5ae1ecdSBarry Smith 
2670f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
267136db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2672f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2673416022c9SBarry Smith   b->nonew             = 0;
2674416022c9SBarry Smith   b->diag              = 0;
2675416022c9SBarry Smith   b->solve_work        = 0;
26762a1b7f2aSHong Zhang   B->spptr             = 0;
2677b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2678754ec7b1SSatish Balay   b->inode.node_count  = 0;
2679754ec7b1SSatish Balay   b->inode.size        = 0;
26806c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26816c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2682be6bf707SBarry Smith   b->saved_values      = 0;
2683d7f994e1SBarry Smith   b->idiag             = 0;
2684d7f994e1SBarry Smith   b->ssor              = 0;
2685f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2686a30b2313SHong Zhang   b->xtoy              = 0;
2687a30b2313SHong Zhang   b->XtoY              = 0;
268817ab2063SBarry Smith 
268935d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
269035d8aa7fSBarry Smith 
2691e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2692ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2693f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2694bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2695bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2696f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2697be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2698bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2699f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2700be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2701bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2702a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2703a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2704a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
270585fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
270685fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
270785fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
2708cd0d46ebSvictorle   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsSymmetric_C",
2709cd0d46ebSvictorle                                      "MatIsSymmetric_SeqAIJ",
2710cd0d46ebSvictorle                                       MatIsSymmetric_SeqAIJ);CHKERRQ(ierr);
2711a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2712a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2713a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
271405b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
271505b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
271605b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
27170a99d0a2SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C",
27180a99d0a2SKris Buschelman                                      "MatAdjustForInodes_SeqAIJ",
27190a99d0a2SKris Buschelman                                       MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr);
2720d758967fSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C",
2721d758967fSKris Buschelman                                      "MatSeqAIJGetInodeSizes_SeqAIJ",
2722d758967fSKris Buschelman                                       MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr);
272387828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2724f83d6046SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
272566826eb6SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
2726f83d6046SBarry Smith #endif
2727eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
27283a40ed3dSBarry Smith   PetscFunctionReturn(0);
272917ab2063SBarry Smith }
2730273d9f13SBarry Smith EXTERN_C_END
273117ab2063SBarry Smith 
27324a2ae208SSatish Balay #undef __FUNCT__
27334a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2734be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
273517ab2063SBarry Smith {
2736416022c9SBarry Smith   Mat        C;
2737416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2738bfeeae90SHong Zhang   int        i,m = A->m,ierr;
2739a7ed9263SMatthew Knepley   size_t     len;
274017ab2063SBarry Smith 
27413a40ed3dSBarry Smith   PetscFunctionBegin;
27424043dd9cSLois Curfman McInnes   *B = 0;
2743273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2744273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr);
2745273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2746273d9f13SBarry Smith 
2747416022c9SBarry Smith   C->factor         = A->factor;
2748416022c9SBarry Smith   c->row            = 0;
2749416022c9SBarry Smith   c->col            = 0;
275082bf6240SBarry Smith   c->icol           = 0;
2751f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2752c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
275317ab2063SBarry Smith 
2754273d9f13SBarry Smith   C->M          = A->m;
2755273d9f13SBarry Smith   C->N          = A->n;
275617ab2063SBarry Smith 
2757b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2758b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
275917ab2063SBarry Smith   for (i=0; i<m; i++) {
2760416022c9SBarry Smith     c->imax[i] = a->imax[i];
2761416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
276217ab2063SBarry Smith   }
276317ab2063SBarry Smith 
276417ab2063SBarry Smith   /* allocate the matrix space */
2765f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2766a7ed9263SMatthew Knepley   len   = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2767b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2768bfeeae90SHong Zhang   c->j  = (int*)(c->a + a->i[m] );
2769bfeeae90SHong Zhang   c->i  = c->j + a->i[m];
2770549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
277117ab2063SBarry Smith   if (m > 0) {
2772bfeeae90SHong Zhang     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr);
2773be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2774bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2775be6bf707SBarry Smith     } else {
2776bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
277717ab2063SBarry Smith     }
277808480c60SBarry Smith   }
277917ab2063SBarry Smith 
2780b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2781416022c9SBarry Smith   c->sorted      = a->sorted;
2782416022c9SBarry Smith   c->roworiented = a->roworiented;
2783416022c9SBarry Smith   c->nonew       = a->nonew;
27847a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2785be6bf707SBarry Smith   c->saved_values = 0;
2786d7f994e1SBarry Smith   c->idiag        = 0;
2787d7f994e1SBarry Smith   c->ssor         = 0;
278836db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
278936db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
279017ab2063SBarry Smith 
2791416022c9SBarry Smith   if (a->diag) {
2792b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2793b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
279417ab2063SBarry Smith     for (i=0; i<m; i++) {
2795416022c9SBarry Smith       c->diag[i] = a->diag[i];
279617ab2063SBarry Smith     }
27973a40ed3dSBarry Smith   } else c->diag        = 0;
2798b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27996c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
28006c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2801754ec7b1SSatish Balay   if (a->inode.size){
2802b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2803754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2804549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2805754ec7b1SSatish Balay   } else {
2806754ec7b1SSatish Balay     c->inode.size       = 0;
2807754ec7b1SSatish Balay     c->inode.node_count = 0;
2808754ec7b1SSatish Balay   }
2809416022c9SBarry Smith   c->nz                 = a->nz;
2810416022c9SBarry Smith   c->maxnz              = a->maxnz;
2811416022c9SBarry Smith   c->solve_work         = 0;
28122a1b7f2aSHong Zhang   C->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2813273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2814754ec7b1SSatish Balay 
2815416022c9SBarry Smith   *B = C;
2816b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
28173a40ed3dSBarry Smith   PetscFunctionReturn(0);
281817ab2063SBarry Smith }
281917ab2063SBarry Smith 
2820273d9f13SBarry Smith EXTERN_C_BEGIN
28214a2ae208SSatish Balay #undef __FUNCT__
28224a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2823b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A)
282417ab2063SBarry Smith {
2825416022c9SBarry Smith   Mat_SeqAIJ   *a;
2826416022c9SBarry Smith   Mat          B;
2827efb16452SHong Zhang   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N;
2828bcd2baecSBarry Smith   MPI_Comm     comm;
28291677d0b8SKris Buschelman #if defined(PETSC_HAVE_MUMPS)
283027fa2452SHong Zhang   PetscTruth   flag;
283127fa2452SHong Zhang #endif
283217ab2063SBarry Smith 
28333a40ed3dSBarry Smith   PetscFunctionBegin;
2834e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2835d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
283629bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2837b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
28380752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2839552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
284017ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
284117ab2063SBarry Smith 
2842d64ed03dSBarry Smith   if (nz < 0) {
284329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2844d64ed03dSBarry Smith   }
2845d64ed03dSBarry Smith 
284617ab2063SBarry Smith   /* read in row lengths */
2847b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
28480752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
284917ab2063SBarry Smith 
285017ab2063SBarry Smith   /* create our matrix */
2851b3a1e11cSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr);
2852b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
2853b3a1e11cSKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
2854416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
285517ab2063SBarry Smith 
285617ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
28570752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
285817ab2063SBarry Smith 
285917ab2063SBarry Smith   /* read in nonzero values */
28600752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
286117ab2063SBarry Smith 
286217ab2063SBarry Smith   /* set matrix "i" values */
2863efb16452SHong Zhang   a->i[0] = 0;
286417ab2063SBarry Smith   for (i=1; i<= M; i++) {
2865416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2866416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
286717ab2063SBarry Smith   }
2868606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
286917ab2063SBarry Smith 
28706d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28716d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2872eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS)
2873eee76cafSHong Zhang   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr);
2874eee76cafSHong Zhang   if (flag) { ierr = MatUseMUMPS_MPIAIJ(B);CHKERRQ(ierr); }
2875eee76cafSHong Zhang #endif
2876b3a1e11cSKris Buschelman   *A = B;
28773a40ed3dSBarry Smith   PetscFunctionReturn(0);
287817ab2063SBarry Smith }
2879273d9f13SBarry Smith EXTERN_C_END
288017ab2063SBarry Smith 
28814a2ae208SSatish Balay #undef __FUNCT__
2882b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28838f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28847264ac53SSatish Balay {
28857264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28860f5bd95cSBarry Smith   int        ierr;
28877264ac53SSatish Balay 
28883a40ed3dSBarry Smith   PetscFunctionBegin;
2889bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
2890bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
2891ca44d042SBarry Smith     *flg = PETSC_FALSE;
2892ca44d042SBarry Smith     PetscFunctionReturn(0);
2893bcd2baecSBarry Smith   }
28947264ac53SSatish Balay 
28957264ac53SSatish Balay   /* if the a->i are the same */
2896273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28970f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28987264ac53SSatish Balay 
28997264ac53SSatish Balay   /* if a->j are the same */
29000f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
29010f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2902bcd2baecSBarry Smith 
2903bcd2baecSBarry Smith   /* if a->a are the same */
290487828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
29050f5bd95cSBarry Smith 
29063a40ed3dSBarry Smith   PetscFunctionReturn(0);
29077264ac53SSatish Balay 
29087264ac53SSatish Balay }
290936db0b34SBarry Smith 
29104a2ae208SSatish Balay #undef __FUNCT__
29114a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
291236db0b34SBarry Smith /*@C
291336db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
291436db0b34SBarry Smith               provided by the user.
291536db0b34SBarry Smith 
291636db0b34SBarry Smith       Coolective on MPI_Comm
291736db0b34SBarry Smith 
291836db0b34SBarry Smith    Input Parameters:
291936db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
292036db0b34SBarry Smith .   m - number of rows
292136db0b34SBarry Smith .   n - number of columns
292236db0b34SBarry Smith .   i - row indices
292336db0b34SBarry Smith .   j - column indices
292436db0b34SBarry Smith -   a - matrix values
292536db0b34SBarry Smith 
292636db0b34SBarry Smith    Output Parameter:
292736db0b34SBarry Smith .   mat - the matrix
292836db0b34SBarry Smith 
292936db0b34SBarry Smith    Level: intermediate
293036db0b34SBarry Smith 
293136db0b34SBarry Smith    Notes:
29320551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
293336db0b34SBarry Smith     once the matrix is destroyed
293436db0b34SBarry Smith 
293536db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
293636db0b34SBarry Smith 
2937bfeeae90SHong Zhang        The i and j indices are 0 based
293836db0b34SBarry Smith 
293936db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
294036db0b34SBarry Smith 
294136db0b34SBarry Smith @*/
294287828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
294336db0b34SBarry Smith {
294436db0b34SBarry Smith   int        ierr,ii;
294536db0b34SBarry Smith   Mat_SeqAIJ *aij;
294636db0b34SBarry Smith 
294736db0b34SBarry Smith   PetscFunctionBegin;
2948c461c341SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr);
294936db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
295036db0b34SBarry Smith 
2951bfeeae90SHong Zhang   if (i[0] != 0) {
2952bfeeae90SHong Zhang     SETERRQ(1,"i (row indices) must start with 0");
295336db0b34SBarry Smith   }
295436db0b34SBarry Smith   aij->i = i;
295536db0b34SBarry Smith   aij->j = j;
295636db0b34SBarry Smith   aij->a = a;
295736db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
295836db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
295936db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
296036db0b34SBarry Smith 
296136db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
296236db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
29639860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296429bbc08cSBarry 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]);
296536db0b34SBarry Smith #endif
296636db0b34SBarry Smith   }
29679860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296836db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
2969bfeeae90SHong Zhang     if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
2970bfeeae90SHong Zhang     if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
297136db0b34SBarry Smith   }
297236db0b34SBarry Smith #endif
297336db0b34SBarry Smith 
2974b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2975b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
297636db0b34SBarry Smith   PetscFunctionReturn(0);
297736db0b34SBarry Smith }
297836db0b34SBarry Smith 
2979cc8ba8e1SBarry Smith #undef __FUNCT__
2980ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2981ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2982cc8ba8e1SBarry Smith {
2983cc8ba8e1SBarry Smith   int        ierr;
2984cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
298536db0b34SBarry Smith 
2986cc8ba8e1SBarry Smith   PetscFunctionBegin;
298712c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2988cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2989cc8ba8e1SBarry Smith     a->coloring = coloring;
299012c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
299108b6dcc0SBarry Smith     int             i,*larray;
299212c595b3SBarry Smith     ISColoring      ocoloring;
299308b6dcc0SBarry Smith     ISColoringValue *colors;
299412c595b3SBarry Smith 
299512c595b3SBarry Smith     /* set coloring for diagonal portion */
299612c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
299712c595b3SBarry Smith     for (i=0; i<A->n; i++) {
299812c595b3SBarry Smith       larray[i] = i;
299912c595b3SBarry Smith     }
300012c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
300108b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
300212c595b3SBarry Smith     for (i=0; i<A->n; i++) {
300312c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
300412c595b3SBarry Smith     }
300512c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
300612c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
300712c595b3SBarry Smith     a->coloring = ocoloring;
300812c595b3SBarry Smith   }
3009cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3010cc8ba8e1SBarry Smith }
3011cc8ba8e1SBarry Smith 
301287828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
3013ee4f033dSBarry Smith EXTERN_C_BEGIN
301429c1e371SBarry Smith #include "adic/ad_utils.h"
3015ee4f033dSBarry Smith EXTERN_C_END
3016cc8ba8e1SBarry Smith 
3017cc8ba8e1SBarry Smith #undef __FUNCT__
3018ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3019ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3020cc8ba8e1SBarry Smith {
3021cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
302208b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
30234440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
302408b6dcc0SBarry Smith   ISColoringValue *color;
3025cc8ba8e1SBarry Smith 
3026cc8ba8e1SBarry Smith   PetscFunctionBegin;
3027cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
30284440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3029cc8ba8e1SBarry Smith   color = a->coloring->colors;
3030cc8ba8e1SBarry Smith   /* loop over rows */
3031cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3032cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3033cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3034cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3035cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3036cc8ba8e1SBarry Smith     }
30374440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3038ee4f033dSBarry Smith   }
3039ee4f033dSBarry Smith   PetscFunctionReturn(0);
3040ee4f033dSBarry Smith }
3041ee4f033dSBarry Smith 
3042ee4f033dSBarry Smith #else
3043ee4f033dSBarry Smith 
3044ee4f033dSBarry Smith #undef __FUNCT__
3045ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3046ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3047ee4f033dSBarry Smith {
3048ee4f033dSBarry Smith   PetscFunctionBegin;
3049ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
3050ee4f033dSBarry Smith }
3051ee4f033dSBarry Smith 
3052ee4f033dSBarry Smith #endif
3053ee4f033dSBarry Smith 
3054ee4f033dSBarry Smith #undef __FUNCT__
3055ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
3056ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
3057ee4f033dSBarry Smith {
3058ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
305908b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
306087828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
306108b6dcc0SBarry Smith   ISColoringValue *color;
3062ee4f033dSBarry Smith 
3063ee4f033dSBarry Smith   PetscFunctionBegin;
3064ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3065ee4f033dSBarry Smith   color = a->coloring->colors;
3066ee4f033dSBarry Smith   /* loop over rows */
3067ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3068ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3069ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3070ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3071ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3072ee4f033dSBarry Smith     }
3073ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3074cc8ba8e1SBarry Smith   }
3075cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3076cc8ba8e1SBarry Smith }
307736db0b34SBarry Smith 
3078