xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 5b8514eb5c47e8e3689c8fb9dc9fe3f0f65ee1ea)
1b3cc6726SBarry Smith 
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/inline/spops.h"
98d195f9aSBarry Smith #include "src/inline/dot.h"
100a835dfdSSatish Balay #include "petscbt.h"
1117ab2063SBarry Smith 
124a2ae208SSatish Balay #undef __FUNCT__
134a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
144e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done)
1517ab2063SBarry Smith {
16416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
176945ee14SBarry Smith   int        ierr,i,ishift;
1817ab2063SBarry Smith 
193a40ed3dSBarry Smith   PetscFunctionBegin;
2031625ec5SSatish Balay   *m     = A->m;
213a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
22bfeeae90SHong Zhang   ishift = 0;
2353e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
24273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
25bfeeae90SHong Zhang   } else if (oshift == 1) {
26435da068SBarry Smith     int nz = a->i[A->m];
273b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
281bc30dd5SBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
29b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
303b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
31273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
326945ee14SBarry Smith   } else {
336945ee14SBarry Smith     *ia = a->i; *ja = a->j;
34a2ce50c7SBarry Smith   }
353a40ed3dSBarry Smith   PetscFunctionReturn(0);
36a2744918SBarry Smith }
37a2744918SBarry Smith 
384a2ae208SSatish Balay #undef __FUNCT__
394a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
404e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
416945ee14SBarry Smith {
42bfeeae90SHong Zhang   int ierr;
436945ee14SBarry Smith 
443a40ed3dSBarry Smith   PetscFunctionBegin;
453a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
46bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
47606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
48606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
49bcd2baecSBarry Smith   }
503a40ed3dSBarry Smith   PetscFunctionReturn(0);
5117ab2063SBarry Smith }
5217ab2063SBarry Smith 
534a2ae208SSatish Balay #undef __FUNCT__
544a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
554e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
563b2fbd54SBarry Smith {
573b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
58bfeeae90SHong Zhang   int        ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m;
59bfeeae90SHong Zhang   int        nz = a->i[m],row,*jj,mr,col;
603b2fbd54SBarry Smith 
613a40ed3dSBarry Smith   PetscFunctionBegin;
623b2fbd54SBarry Smith   *nn     = A->n;
633a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
643b2fbd54SBarry Smith   if (symmetric) {
65bfeeae90SHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
663b2fbd54SBarry Smith   } else {
67b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr);
68549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
69b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr);
70b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr);
713b2fbd54SBarry Smith     jj = a->j;
723b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
73bfeeae90SHong Zhang       collengths[jj[i]]++;
743b2fbd54SBarry Smith     }
753b2fbd54SBarry Smith     cia[0] = oshift;
763b2fbd54SBarry Smith     for (i=0; i<n; i++) {
773b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
783b2fbd54SBarry Smith     }
79549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
803b2fbd54SBarry Smith     jj   = a->j;
81a93ec695SBarry Smith     for (row=0; row<m; row++) {
82a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
83a93ec695SBarry Smith       for (i=0; i<mr; i++) {
84bfeeae90SHong Zhang         col = *jj++;
853b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
863b2fbd54SBarry Smith       }
873b2fbd54SBarry Smith     }
88606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
893b2fbd54SBarry Smith     *ia = cia; *ja = cja;
903b2fbd54SBarry Smith   }
913a40ed3dSBarry Smith   PetscFunctionReturn(0);
923b2fbd54SBarry Smith }
933b2fbd54SBarry Smith 
944a2ae208SSatish Balay #undef __FUNCT__
954a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
964e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
973b2fbd54SBarry Smith {
98606d414cSSatish Balay   int ierr;
99606d414cSSatish Balay 
1003a40ed3dSBarry Smith   PetscFunctionBegin;
1013a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1023b2fbd54SBarry Smith 
103606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
104606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1053b2fbd54SBarry Smith 
1063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1073b2fbd54SBarry Smith }
1083b2fbd54SBarry Smith 
109227d817aSBarry Smith #define CHUNKSIZE   15
11017ab2063SBarry Smith 
1114a2ae208SSatish Balay #undef __FUNCT__
1124a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
113f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11417ab2063SBarry Smith {
115416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
116416022c9SBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
117273d9f13SBarry Smith   int         *imax = a->imax,*ai = a->i,*ailen = a->ilen;
118bfeeae90SHong Zhang   int         *aj = a->j,nonew = a->nonew,ierr;
11987828ca2SBarry Smith   PetscScalar *ap,value,*aa = a->a;
12036db0b34SBarry Smith   PetscTruth  ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
121273d9f13SBarry Smith   PetscTruth  roworiented = a->roworiented;
12217ab2063SBarry Smith 
1233a40ed3dSBarry Smith   PetscFunctionBegin;
12417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
125416022c9SBarry Smith     row  = im[k];
1265ef9f2a5SBarry Smith     if (row < 0) continue;
127aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
128590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
1293b2fbd54SBarry Smith #endif
130bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
13117ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
132416022c9SBarry Smith     low = 0;
13317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1345ef9f2a5SBarry Smith       if (in[l] < 0) continue;
135aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
136590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
1373b2fbd54SBarry Smith #endif
138bfeeae90SHong Zhang       col = in[l];
1394b0e389bSBarry Smith       if (roworiented) {
1405ef9f2a5SBarry Smith         value = v[l + k*n];
141bef8e0ddSBarry Smith       } else {
1424b0e389bSBarry Smith         value = v[k + l*m];
1434b0e389bSBarry Smith       }
144*5b8514ebSBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
14536db0b34SBarry Smith 
146416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
147416022c9SBarry Smith       while (high-low > 5) {
148416022c9SBarry Smith         t = (low+high)/2;
149416022c9SBarry Smith         if (rp[t] > col) high = t;
150416022c9SBarry Smith         else             low  = t;
15117ab2063SBarry Smith       }
152416022c9SBarry Smith       for (i=low; i<high; i++) {
15317ab2063SBarry Smith         if (rp[i] > col) break;
15417ab2063SBarry Smith         if (rp[i] == col) {
155416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
15617ab2063SBarry Smith           else                  ap[i] = value;
15717ab2063SBarry Smith           goto noinsert;
15817ab2063SBarry Smith         }
15917ab2063SBarry Smith       }
160c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
16129bbc08cSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
16217ab2063SBarry Smith       if (nrow >= rmax) {
16317ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
164a7ed9263SMatthew Knepley         int         new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j;
165a7ed9263SMatthew Knepley         size_t      len;
16687828ca2SBarry Smith         PetscScalar *new_a;
16717ab2063SBarry Smith 
16829bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
16996854ed6SLois Curfman McInnes 
17017ab2063SBarry Smith         /* malloc new storage space */
171a7ed9263SMatthew Knepley         len     = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
172b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
17317ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
17417ab2063SBarry Smith         new_i   = new_j + new_nz;
17517ab2063SBarry Smith 
17617ab2063SBarry Smith         /* copy over old data into new slots */
17717ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
178273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
179bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
180bfeeae90SHong Zhang         len  = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow );
181bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
182bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr);
183bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
18417ab2063SBarry Smith         /* free up old matrix storage */
185606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
186606d414cSSatish Balay         if (!a->singlemalloc) {
187606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
188606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
189606d414cSSatish Balay         }
190416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
191f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
19217ab2063SBarry Smith 
193bfeeae90SHong Zhang         rp   = aj + ai[row]; ap = aa + ai[row] ;
194416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
19587828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
196416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
197b810aeb4SBarry Smith         a->reallocs++;
19817ab2063SBarry Smith       }
199416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
200416022c9SBarry Smith       /* shift up all the later entries in this row */
201416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
20217ab2063SBarry Smith         rp[ii+1] = rp[ii];
20317ab2063SBarry Smith         ap[ii+1] = ap[ii];
20417ab2063SBarry Smith       }
20517ab2063SBarry Smith       rp[i] = col;
20617ab2063SBarry Smith       ap[i] = value;
20717ab2063SBarry Smith       noinsert:;
208416022c9SBarry Smith       low = i + 1;
20917ab2063SBarry Smith     }
21017ab2063SBarry Smith     ailen[row] = nrow;
21117ab2063SBarry Smith   }
2123a40ed3dSBarry Smith   PetscFunctionReturn(0);
21317ab2063SBarry Smith }
21417ab2063SBarry Smith 
2154a2ae208SSatish Balay #undef __FUNCT__
2164a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
217f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
2187eb43aa7SLois Curfman McInnes {
2197eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
220b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
221bfeeae90SHong Zhang   int          *ai = a->i,*ailen = a->ilen;
22287828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2237eb43aa7SLois Curfman McInnes 
2243a40ed3dSBarry Smith   PetscFunctionBegin;
2257eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2267eb43aa7SLois Curfman McInnes     row  = im[k];
22729bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
228590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
229bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2307eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2317eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
23229bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
233590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
234bfeeae90SHong Zhang       col = in[l] ;
2357eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2367eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2377eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2387eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2397eb43aa7SLois Curfman McInnes         else             low  = t;
2407eb43aa7SLois Curfman McInnes       }
2417eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2427eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2437eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
244b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2457eb43aa7SLois Curfman McInnes           goto finished;
2467eb43aa7SLois Curfman McInnes         }
2477eb43aa7SLois Curfman McInnes       }
248b49de8d1SLois Curfman McInnes       *v++ = zero;
2497eb43aa7SLois Curfman McInnes       finished:;
2507eb43aa7SLois Curfman McInnes     }
2517eb43aa7SLois Curfman McInnes   }
2523a40ed3dSBarry Smith   PetscFunctionReturn(0);
2537eb43aa7SLois Curfman McInnes }
2547eb43aa7SLois Curfman McInnes 
25517ab2063SBarry Smith 
2564a2ae208SSatish Balay #undef __FUNCT__
2574a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
258b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
25917ab2063SBarry Smith {
260416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
261416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
26217ab2063SBarry Smith 
2633a40ed3dSBarry Smith   PetscFunctionBegin;
264b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
265b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
266552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
267273d9f13SBarry Smith   col_lens[1] = A->m;
268273d9f13SBarry Smith   col_lens[2] = A->n;
269416022c9SBarry Smith   col_lens[3] = a->nz;
270416022c9SBarry Smith 
271416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
272273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
273416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
27417ab2063SBarry Smith   }
275273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
276606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
277416022c9SBarry Smith 
278416022c9SBarry Smith   /* store column indices (zero start index) */
2790752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
280416022c9SBarry Smith 
281416022c9SBarry Smith   /* store nonzero values */
2820752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
2833a40ed3dSBarry Smith   PetscFunctionReturn(0);
28417ab2063SBarry Smith }
285416022c9SBarry Smith 
2864ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
287cd155464SBarry Smith 
2884a2ae208SSatish Balay #undef __FUNCT__
2894a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
290b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
291416022c9SBarry Smith {
292416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
293bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,shift=0;
294fb9695e5SSatish Balay   char              *name;
295f3ef73ceSBarry Smith   PetscViewerFormat format;
29617ab2063SBarry Smith 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
298435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
299b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
300456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3016831982aSBarry Smith     if (a->inode.size) {
302b0a32e0cSBarry 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);
3036831982aSBarry Smith     } else {
304b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3056831982aSBarry Smith     }
306fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
307d00d2cf4SBarry Smith     int nofinalvalue = 0;
308273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
309d00d2cf4SBarry Smith       nofinalvalue = 1;
310d00d2cf4SBarry Smith     }
311b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
312b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
313b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
314b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
315b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
31617ab2063SBarry Smith 
31717ab2063SBarry Smith     for (i=0; i<m; i++) {
318416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
319aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
320b0a32e0cSBarry 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);
32117ab2063SBarry Smith #else
322b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
32317ab2063SBarry Smith #endif
32417ab2063SBarry Smith       }
32517ab2063SBarry Smith     }
326d00d2cf4SBarry Smith     if (nofinalvalue) {
327b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
328d00d2cf4SBarry Smith     }
329fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
330b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
331cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
332cd155464SBarry Smith      PetscFunctionReturn(0);
333fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
334b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
33544cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
336b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
33744cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
338aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
33936db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
34062b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34136db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
34262b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34336db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
34462b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3456831982aSBarry Smith         }
34644cd7ae7SLois Curfman McInnes #else
34762b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
34844cd7ae7SLois Curfman McInnes #endif
34944cd7ae7SLois Curfman McInnes       }
350b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
35144cd7ae7SLois Curfman McInnes     }
352b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
353fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
354496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
355b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
356b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
357496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
358496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
359496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
360496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
361aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
36236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
363496be53dSLois Curfman McInnes #else
364496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
365496be53dSLois Curfman McInnes #endif
366496be53dSLois Curfman McInnes         }
367496be53dSLois Curfman McInnes       }
368496be53dSLois Curfman McInnes     }
3692e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
370b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
3712e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
372b0a32e0cSBarry 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);}
373b0a32e0cSBarry 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);}
374b0a32e0cSBarry 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);}
375b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
376b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
377b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
378496be53dSLois Curfman McInnes     }
379b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
380606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
381496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
382496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
383b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
384496be53dSLois Curfman McInnes       }
385b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
386496be53dSLois Curfman McInnes     }
387b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
388496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
389496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
390496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
391aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
393b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
3946831982aSBarry Smith           }
395496be53dSLois Curfman McInnes #else
396b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
397496be53dSLois Curfman McInnes #endif
398496be53dSLois Curfman McInnes         }
399496be53dSLois Curfman McInnes       }
400b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
401496be53dSLois Curfman McInnes     }
402b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
403fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
40402594712SBarry Smith     int         cnt = 0,jcnt;
40587828ca2SBarry Smith     PetscScalar value;
40602594712SBarry Smith 
407b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
40802594712SBarry Smith     for (i=0; i<m; i++) {
40902594712SBarry Smith       jcnt = 0;
410273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
411e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
41202594712SBarry Smith           value = a->a[cnt++];
413e24b481bSBarry Smith           jcnt++;
41402594712SBarry Smith         } else {
41502594712SBarry Smith           value = 0.0;
41602594712SBarry Smith         }
417aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
418b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
41902594712SBarry Smith #else
420b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
42102594712SBarry Smith #endif
42202594712SBarry Smith       }
423b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42402594712SBarry Smith     }
425b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4263a40ed3dSBarry Smith   } else {
427b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
42817ab2063SBarry Smith     for (i=0; i<m; i++) {
429b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
430416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
431aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
43236db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
43362b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
43436db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
43562b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4363a40ed3dSBarry Smith         } else {
43762b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
43817ab2063SBarry Smith         }
43917ab2063SBarry Smith #else
44062b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
44117ab2063SBarry Smith #endif
44217ab2063SBarry Smith       }
443b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44417ab2063SBarry Smith     }
445b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
44617ab2063SBarry Smith   }
447b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4483a40ed3dSBarry Smith   PetscFunctionReturn(0);
449416022c9SBarry Smith }
450416022c9SBarry Smith 
4514a2ae208SSatish Balay #undef __FUNCT__
4524a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
453b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
454416022c9SBarry Smith {
455480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
456416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
457bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,color;
45836db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
459b0a32e0cSBarry Smith   PetscViewer       viewer;
460f3ef73ceSBarry Smith   PetscViewerFormat format;
461cddf8d76SBarry Smith 
4623a40ed3dSBarry Smith   PetscFunctionBegin;
463480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
464b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
46519bcc07fSBarry Smith 
466b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
467416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4680513a670SBarry Smith 
469fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4700513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
471b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
472416022c9SBarry Smith     for (i=0; i<m; i++) {
473cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
474bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
475bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
476aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
47736db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
478cddf8d76SBarry Smith #else
479cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
480cddf8d76SBarry Smith #endif
481b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
482cddf8d76SBarry Smith       }
483cddf8d76SBarry Smith     }
484b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
485cddf8d76SBarry Smith     for (i=0; i<m; i++) {
486cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
487bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
488bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
489cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
490b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
491cddf8d76SBarry Smith       }
492cddf8d76SBarry Smith     }
493b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
494cddf8d76SBarry Smith     for (i=0; i<m; i++) {
495cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
496bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
497bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
498aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49936db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
500cddf8d76SBarry Smith #else
501cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
502cddf8d76SBarry Smith #endif
503b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
504416022c9SBarry Smith       }
505416022c9SBarry Smith     }
5060513a670SBarry Smith   } else {
5070513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5080513a670SBarry Smith     /* first determine max of all nonzero values */
5090513a670SBarry Smith     int    nz = a->nz,count;
510b0a32e0cSBarry Smith     PetscDraw   popup;
51136db0b34SBarry Smith     PetscReal scale;
5120513a670SBarry Smith 
5130513a670SBarry Smith     for (i=0; i<nz; i++) {
5140513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5150513a670SBarry Smith     }
516b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
517b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
518b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5190513a670SBarry Smith     count = 0;
5200513a670SBarry Smith     for (i=0; i<m; i++) {
5210513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
522bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
523bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
524b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
525b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5260513a670SBarry Smith         count++;
5270513a670SBarry Smith       }
5280513a670SBarry Smith     }
5290513a670SBarry Smith   }
530480ef9eaSBarry Smith   PetscFunctionReturn(0);
531480ef9eaSBarry Smith }
532cddf8d76SBarry Smith 
5334a2ae208SSatish Balay #undef __FUNCT__
5344a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
535b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
536480ef9eaSBarry Smith {
537480ef9eaSBarry Smith   int        ierr;
538b0a32e0cSBarry Smith   PetscDraw  draw;
53936db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
540480ef9eaSBarry Smith   PetscTruth isnull;
541480ef9eaSBarry Smith 
542480ef9eaSBarry Smith   PetscFunctionBegin;
543b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
544b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
545480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
546480ef9eaSBarry Smith 
547480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
548273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
549480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
550b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
551b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
552480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5533a40ed3dSBarry Smith   PetscFunctionReturn(0);
554416022c9SBarry Smith }
555416022c9SBarry Smith 
5564a2ae208SSatish Balay #undef __FUNCT__
5574a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
558b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
559416022c9SBarry Smith {
560416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
561bcd2baecSBarry Smith   int         ierr;
56232077d6dSBarry Smith   PetscTruth  issocket,iascii,isbinary,isdraw;
563416022c9SBarry Smith 
5643a40ed3dSBarry Smith   PetscFunctionBegin;
565b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
56632077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
567fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
568fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5690f5bd95cSBarry Smith   if (issocket) {
570b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
57132077d6dSBarry Smith   } else if (iascii) {
5723a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5730f5bd95cSBarry Smith   } else if (isbinary) {
5743a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
5750f5bd95cSBarry Smith   } else if (isdraw) {
5763a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
5775cd90555SBarry Smith   } else {
578958c9bccSBarry Smith     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
57917ab2063SBarry Smith   }
5803a40ed3dSBarry Smith   PetscFunctionReturn(0);
58117ab2063SBarry Smith }
58219bcc07fSBarry Smith 
5834a2ae208SSatish Balay #undef __FUNCT__
5844a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
5858f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
58617ab2063SBarry Smith {
587416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
58841c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
589bfeeae90SHong Zhang   int          m = A->m,*ip,N,*ailen = a->ilen,rmax = 0;
59087828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
59117ab2063SBarry Smith 
5923a40ed3dSBarry Smith   PetscFunctionBegin;
5933a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
59417ab2063SBarry Smith 
59543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
59617ab2063SBarry Smith   for (i=1; i<m; i++) {
597416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
59817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
59994a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
60017ab2063SBarry Smith     if (fshift) {
601bfeeae90SHong Zhang       ip = aj + ai[i] ;
602bfeeae90SHong Zhang       ap = aa + ai[i] ;
60317ab2063SBarry Smith       N  = ailen[i];
60417ab2063SBarry Smith       for (j=0; j<N; j++) {
60517ab2063SBarry Smith         ip[j-fshift] = ip[j];
60617ab2063SBarry Smith         ap[j-fshift] = ap[j];
60717ab2063SBarry Smith       }
60817ab2063SBarry Smith     }
60917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
61017ab2063SBarry Smith   }
61117ab2063SBarry Smith   if (m) {
61217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
61317ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
61417ab2063SBarry Smith   }
61517ab2063SBarry Smith   /* reset ilen and imax for each row */
61617ab2063SBarry Smith   for (i=0; i<m; i++) {
61717ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
61817ab2063SBarry Smith   }
619bfeeae90SHong Zhang   a->nz = ai[m];
62017ab2063SBarry Smith 
62117ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
622416022c9SBarry Smith   if (fshift && a->diag) {
623606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
624b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
625416022c9SBarry Smith     a->diag = 0;
62617ab2063SBarry Smith   }
627b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
628b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
629b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
630dd5f02e7SSatish Balay   a->reallocs          = 0;
6314e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
63236db0b34SBarry Smith   a->rmax              = rmax;
6334e220ebcSLois Curfman McInnes 
63476dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6353a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
636cfef3cccSHong Zhang 
6373a40ed3dSBarry Smith   PetscFunctionReturn(0);
63817ab2063SBarry Smith }
63917ab2063SBarry Smith 
6404a2ae208SSatish Balay #undef __FUNCT__
6414a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6428f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
64317ab2063SBarry Smith {
644416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
645549d3d68SSatish Balay   int        ierr;
6463a40ed3dSBarry Smith 
6473a40ed3dSBarry Smith   PetscFunctionBegin;
648bfeeae90SHong Zhang   ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
6493a40ed3dSBarry Smith   PetscFunctionReturn(0);
65017ab2063SBarry Smith }
651416022c9SBarry Smith 
6524a2ae208SSatish Balay #undef __FUNCT__
6534a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
654e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
65517ab2063SBarry Smith {
656416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
65782bf6240SBarry Smith   int        ierr;
658d5d45c9bSBarry Smith 
6593a40ed3dSBarry Smith   PetscFunctionBegin;
660aa482453SBarry Smith #if defined(PETSC_USE_LOG)
661b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
66217ab2063SBarry Smith #endif
66336db0b34SBarry Smith   if (a->freedata) {
664606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
665606d414cSSatish Balay     if (!a->singlemalloc) {
666606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
667606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
668606d414cSSatish Balay     }
66936db0b34SBarry Smith   }
670c38d4ed2SBarry Smith   if (a->row) {
671c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
672c38d4ed2SBarry Smith   }
673c38d4ed2SBarry Smith   if (a->col) {
674c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
675c38d4ed2SBarry Smith   }
676606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
677606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
678606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
679273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
680606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
681606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
68282bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
683606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
684cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
685a30b2313SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
686a30b2313SHong Zhang 
687606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
6883a40ed3dSBarry Smith   PetscFunctionReturn(0);
68917ab2063SBarry Smith }
69017ab2063SBarry Smith 
6914a2ae208SSatish Balay #undef __FUNCT__
6924a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
6938f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
69417ab2063SBarry Smith {
6953a40ed3dSBarry Smith   PetscFunctionBegin;
6963a40ed3dSBarry Smith   PetscFunctionReturn(0);
69717ab2063SBarry Smith }
69817ab2063SBarry Smith 
6994a2ae208SSatish Balay #undef __FUNCT__
7004a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7018f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
70217ab2063SBarry Smith {
703416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7043a40ed3dSBarry Smith 
7053a40ed3dSBarry Smith   PetscFunctionBegin;
706a65d3064SKris Buschelman   switch (op) {
707a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
708a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
709a65d3064SKris Buschelman       break;
710a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
711a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
712a65d3064SKris Buschelman       break;
713a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
714a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
715a65d3064SKris Buschelman       break;
716a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
717a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
718a65d3064SKris Buschelman       break;
719a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
720a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
721a65d3064SKris Buschelman       break;
722a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
723a65d3064SKris Buschelman       a->nonew             = 1;
724a65d3064SKris Buschelman       break;
725a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
726a65d3064SKris Buschelman       a->nonew             = -1;
727a65d3064SKris Buschelman       break;
728a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
729a65d3064SKris Buschelman       a->nonew             = -2;
730a65d3064SKris Buschelman       break;
731a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
732a65d3064SKris Buschelman       a->nonew             = 0;
733a65d3064SKris Buschelman       break;
734a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
735a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
736a65d3064SKris Buschelman       break;
737a65d3064SKris Buschelman     case MAT_USE_INODES:
738a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
739a65d3064SKris Buschelman       break;
740a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
741a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
742a65d3064SKris Buschelman       break;
743a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
744a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
745a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
746a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
747a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
748b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
749a65d3064SKris Buschelman       break;
750a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
75129bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
752a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
753a65d3064SKris Buschelman       a->inode.limit  = 1;
754a65d3064SKris Buschelman       break;
755a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
756a65d3064SKris Buschelman       a->inode.limit  = 2;
757a65d3064SKris Buschelman       break;
758a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
759a65d3064SKris Buschelman       a->inode.limit  = 3;
760a65d3064SKris Buschelman       break;
761a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
762a65d3064SKris Buschelman       a->inode.limit  = 4;
763a65d3064SKris Buschelman       break;
764a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
765a65d3064SKris Buschelman       a->inode.limit  = 5;
766a65d3064SKris Buschelman       break;
76777e54ba9SKris Buschelman     case MAT_SYMMETRIC:
76877e54ba9SKris Buschelman     case MAT_STRUCTURALLY_SYMMETRIC:
7699a4540c5SBarry Smith     case MAT_NOT_SYMMETRIC:
7709a4540c5SBarry Smith     case MAT_NOT_STRUCTURALLY_SYMMETRIC:
7719a4540c5SBarry Smith     case MAT_HERMITIAN:
7729a4540c5SBarry Smith     case MAT_NOT_HERMITIAN:
7739a4540c5SBarry Smith     case MAT_SYMMETRY_ETERNAL:
7749a4540c5SBarry Smith     case MAT_NOT_SYMMETRY_ETERNAL:
77577e54ba9SKris Buschelman       break;
776a65d3064SKris Buschelman     default:
777a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
778a65d3064SKris Buschelman   }
7793a40ed3dSBarry Smith   PetscFunctionReturn(0);
78017ab2063SBarry Smith }
78117ab2063SBarry Smith 
7824a2ae208SSatish Balay #undef __FUNCT__
7834a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
7848f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78517ab2063SBarry Smith {
786416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
787bfeeae90SHong Zhang   int          i,j,n,ierr;
78887828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
78917ab2063SBarry Smith 
7903a40ed3dSBarry Smith   PetscFunctionBegin;
7913a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
7921ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
79336db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
794273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
795273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
796bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
797bfeeae90SHong Zhang       if (a->j[j] == i) {
798416022c9SBarry Smith         x[i] = a->a[j];
79917ab2063SBarry Smith         break;
80017ab2063SBarry Smith       }
80117ab2063SBarry Smith     }
80217ab2063SBarry Smith   }
8031ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8043a40ed3dSBarry Smith   PetscFunctionReturn(0);
80517ab2063SBarry Smith }
80617ab2063SBarry Smith 
807d5d45c9bSBarry Smith 
8084a2ae208SSatish Balay #undef __FUNCT__
8094a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8107c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
81117ab2063SBarry Smith {
812416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8135c897100SBarry Smith   PetscScalar  *x,*y;
814bfeeae90SHong Zhang   int          ierr,m = A->m;
8155c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8165c897100SBarry Smith   PetscScalar  *v,alpha;
8175c897100SBarry Smith   int          n,i,*idx;
8185c897100SBarry Smith #endif
81917ab2063SBarry Smith 
8203a40ed3dSBarry Smith   PetscFunctionBegin;
8212e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
8221ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8245c897100SBarry Smith 
8255c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
826bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8275c897100SBarry Smith #else
82817ab2063SBarry Smith   for (i=0; i<m; i++) {
829bfeeae90SHong Zhang     idx   = a->j + a->i[i] ;
830bfeeae90SHong Zhang     v     = a->a + a->i[i] ;
831416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83217ab2063SBarry Smith     alpha = x[i];
83317ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83417ab2063SBarry Smith   }
8355c897100SBarry Smith #endif
836b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
8371ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8381ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8393a40ed3dSBarry Smith   PetscFunctionReturn(0);
84017ab2063SBarry Smith }
84117ab2063SBarry Smith 
8424a2ae208SSatish Balay #undef __FUNCT__
8435c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8445c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8455c897100SBarry Smith {
8468d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8475c897100SBarry Smith   int          ierr;
8485c897100SBarry Smith 
8495c897100SBarry Smith   PetscFunctionBegin;
8505c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8515c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8525c897100SBarry Smith   PetscFunctionReturn(0);
8535c897100SBarry Smith }
8545c897100SBarry Smith 
8555c897100SBarry Smith 
8565c897100SBarry Smith #undef __FUNCT__
8574a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
85844cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
85917ab2063SBarry Smith {
860416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
861362ced78SSatish Balay   PetscScalar  *x,*y,*v;
862bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
863aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
864e36a17ebSSatish Balay   int          n,i,jrow,j;
865362ced78SSatish Balay   PetscScalar  sum;
866e36a17ebSSatish Balay #endif
86717ab2063SBarry Smith 
868b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
869fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
870fee21e36SBarry Smith #endif
871fee21e36SBarry Smith 
8723a40ed3dSBarry Smith   PetscFunctionBegin;
8731ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8741ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
875416022c9SBarry Smith   idx  = a->j;
876d64ed03dSBarry Smith   v    = a->a;
877416022c9SBarry Smith   ii   = a->i;
878aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
879bfeeae90SHong Zhang   fortranmultaij_(&m,x,ii,idx,v,y);
8808d195f9aSBarry Smith #else
88117ab2063SBarry Smith   for (i=0; i<m; i++) {
8829ea0dfa2SSatish Balay     jrow = ii[i];
8839ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
88417ab2063SBarry Smith     sum  = 0.0;
8859ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
8869ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8879ea0dfa2SSatish Balay      }
88817ab2063SBarry Smith     y[i] = sum;
88917ab2063SBarry Smith   }
8908d195f9aSBarry Smith #endif
891b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
8921ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8931ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
89517ab2063SBarry Smith }
89617ab2063SBarry Smith 
8974a2ae208SSatish Balay #undef __FUNCT__
8984a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
89944cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
90017ab2063SBarry Smith {
901416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
902362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
903bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
904aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
905e36a17ebSSatish Balay   int          n,i,jrow,j;
906362ced78SSatish Balay PetscScalar    sum;
907e36a17ebSSatish Balay #endif
9089ea0dfa2SSatish Balay 
9093a40ed3dSBarry Smith   PetscFunctionBegin;
9101ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9111ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9122e8a6d31SBarry Smith   if (zz != yy) {
9131ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9142e8a6d31SBarry Smith   } else {
9152e8a6d31SBarry Smith     z = y;
9162e8a6d31SBarry Smith   }
917bfeeae90SHong Zhang 
918cddf8d76SBarry Smith   idx  = a->j;
919d64ed03dSBarry Smith   v    = a->a;
920cddf8d76SBarry Smith   ii   = a->i;
921aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
922bfeeae90SHong Zhang   fortranmultaddaij_(&m,x,ii,idx,v,y,z);
92302ab625aSSatish Balay #else
92417ab2063SBarry Smith   for (i=0; i<m; i++) {
9259ea0dfa2SSatish Balay     jrow = ii[i];
9269ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
92717ab2063SBarry Smith     sum  = y[i];
9289ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9299ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9309ea0dfa2SSatish Balay      }
93117ab2063SBarry Smith     z[i] = sum;
93217ab2063SBarry Smith   }
93302ab625aSSatish Balay #endif
934b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
9351ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9361ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9372e8a6d31SBarry Smith   if (zz != yy) {
9381ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9392e8a6d31SBarry Smith   }
9403a40ed3dSBarry Smith   PetscFunctionReturn(0);
94117ab2063SBarry Smith }
94217ab2063SBarry Smith 
94317ab2063SBarry Smith /*
94417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
94517ab2063SBarry Smith */
9464a2ae208SSatish Balay #undef __FUNCT__
9474a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
948f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
94917ab2063SBarry Smith {
950416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
951bfeeae90SHong Zhang   int        i,j,*diag,m = A->m,ierr;
95217ab2063SBarry Smith 
9533a40ed3dSBarry Smith   PetscFunctionBegin;
954f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
955f1e2ffcdSBarry Smith 
956b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
957b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
958273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
95935b0346bSBarry Smith     diag[i] = a->i[i+1];
960bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
961bfeeae90SHong Zhang       if (a->j[j] == i) {
962bfeeae90SHong Zhang         diag[i] = j;
96317ab2063SBarry Smith         break;
96417ab2063SBarry Smith       }
96517ab2063SBarry Smith     }
96617ab2063SBarry Smith   }
967416022c9SBarry Smith   a->diag = diag;
9683a40ed3dSBarry Smith   PetscFunctionReturn(0);
96917ab2063SBarry Smith }
97017ab2063SBarry Smith 
971be5855fcSBarry Smith /*
972be5855fcSBarry Smith      Checks for missing diagonals
973be5855fcSBarry Smith */
9744a2ae208SSatish Balay #undef __FUNCT__
9754a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
976f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
977be5855fcSBarry Smith {
978be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
979bfeeae90SHong Zhang   int        *diag,*jj = a->j,i,ierr;
980be5855fcSBarry Smith 
981be5855fcSBarry Smith   PetscFunctionBegin;
982f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
983f1e2ffcdSBarry Smith   diag = a->diag;
984273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
985bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
986958c9bccSBarry Smith       SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %d",i);
987be5855fcSBarry Smith     }
988be5855fcSBarry Smith   }
989be5855fcSBarry Smith   PetscFunctionReturn(0);
990be5855fcSBarry Smith }
991be5855fcSBarry Smith 
9924a2ae208SSatish Balay #undef __FUNCT__
9934a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
994c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
99517ab2063SBarry Smith {
996416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
997beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
998beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
999beeb8507SBarry Smith   int                ierr,n = A->n,m = A->m,i;
1000beeb8507SBarry Smith   const int          *idx,*diag;
100117ab2063SBarry Smith 
10023a40ed3dSBarry Smith   PetscFunctionBegin;
1003b965ef7fSBarry Smith   its = its*lits;
100491723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
100591723122SBarry Smith 
1006ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1007ed480e8bSBarry Smith   diag = a->diag;
1008ed480e8bSBarry Smith   if (!a->idiag) {
1009ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1010ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1011ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1012ed480e8bSBarry Smith 
1013ed480e8bSBarry Smith     v        = a->a;
1014ed480e8bSBarry Smith 
1015ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1016958c9bccSBarry Smith     if (omega == 1.0 && !fshift) {
1017ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1018ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1019ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1020ed480e8bSBarry Smith       }
1021beeb8507SBarry Smith       PetscLogFlops(m);
1022ed480e8bSBarry Smith     } else {
1023ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1024ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1025beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1026ed480e8bSBarry Smith       }
1027beeb8507SBarry Smith       PetscLogFlops(2*m);
1028beeb8507SBarry Smith     }
1029ed480e8bSBarry Smith   }
1030ed480e8bSBarry Smith   t     = a->ssor;
1031ed480e8bSBarry Smith   idiag = a->idiag;
1032ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1033ed480e8bSBarry Smith 
10341ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1035fb2e594dSBarry Smith   if (xx != bb) {
10361ebc52fbSHong Zhang     ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1037fb2e594dSBarry Smith   } else {
1038fb2e594dSBarry Smith     b = x;
1039fb2e594dSBarry Smith   }
1040fb2e594dSBarry Smith 
1041ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1042ed480e8bSBarry Smith   xs   = x;
104317ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
104417ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1045ed480e8bSBarry Smith     bs = b;
104617ab2063SBarry Smith     for (i=0; i<m; i++) {
1047ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1048416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1049ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1050ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
105117ab2063SBarry Smith         sum  = b[i]*d/omega;
105217ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
105317ab2063SBarry Smith         x[i] = sum;
105417ab2063SBarry Smith     }
10551ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10561ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1057ed480e8bSBarry Smith     PetscLogFlops(a->nz);
10583a40ed3dSBarry Smith     PetscFunctionReturn(0);
105917ab2063SBarry Smith   }
1060c783ea89SBarry Smith 
1061ed480e8bSBarry Smith 
1062fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1063fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1064fc3d8934SBarry Smith 
1065fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1066fc3d8934SBarry Smith 
1067fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1068fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
106948af12d7SBarry Smith     is the relaxation factor.
1070fc3d8934SBarry Smith     */
1071fc3d8934SBarry Smith 
107248af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
107329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
10743a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
107517ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
107617ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
107717ab2063SBarry Smith 
107817ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
107917ab2063SBarry Smith 
108017ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
108117ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
108217ab2063SBarry Smith     is the relaxation factor.
108317ab2063SBarry Smith     */
108417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
108517ab2063SBarry Smith 
108617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
108717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1088416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1089ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1090ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
109117ab2063SBarry Smith       sum  = b[i];
109217ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1093ed480e8bSBarry Smith       x[i] = sum*idiag[i];
109417ab2063SBarry Smith     }
109517ab2063SBarry Smith 
109617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1097416022c9SBarry Smith     v = a->a;
1098ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
109917ab2063SBarry Smith 
110017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1101ed480e8bSBarry Smith     ts = t;
1102416022c9SBarry Smith     diag = a->diag;
110317ab2063SBarry Smith     for (i=0; i<m; i++) {
1104416022c9SBarry Smith       n    = diag[i] - a->i[i];
1105ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1106ed480e8bSBarry Smith       v    = a->a + a->i[i];
110717ab2063SBarry Smith       sum  = t[i];
110817ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1109ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1110733d66baSBarry Smith       /*  x = x + t */
1111733d66baSBarry Smith       x[i] += t[i];
111217ab2063SBarry Smith     }
111317ab2063SBarry Smith 
1114b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
11151ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11161ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11173a40ed3dSBarry Smith     PetscFunctionReturn(0);
111817ab2063SBarry Smith   }
111917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
112017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
112177d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11220c559628SSatish Balay       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b);
112377d8c4bbSBarry Smith #else
112417ab2063SBarry Smith       for (i=0; i<m; i++) {
1125416022c9SBarry Smith         n    = diag[i] - a->i[i];
1126ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1127ed480e8bSBarry Smith         v    = a->a + a->i[i];
112817ab2063SBarry Smith         sum  = b[i];
112917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1130ed480e8bSBarry Smith         x[i] = sum*idiag[i];
113117ab2063SBarry Smith       }
113277d8c4bbSBarry Smith #endif
113317ab2063SBarry Smith       xb = x;
1134ed480e8bSBarry Smith       PetscLogFlops(a->nz);
11353a40ed3dSBarry Smith     } else xb = b;
113617ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
113717ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
113817ab2063SBarry Smith       for (i=0; i<m; i++) {
1139ed480e8bSBarry Smith         x[i] *= mdiag[i];
114017ab2063SBarry Smith       }
1141b0a32e0cSBarry Smith       PetscLogFlops(m);
114217ab2063SBarry Smith     }
114317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
114477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11450c559628SSatish Balay       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb);
114677d8c4bbSBarry Smith #else
114717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1148416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1149ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1150ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
115117ab2063SBarry Smith         sum  = xb[i];
115217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1153ed480e8bSBarry Smith         x[i] = sum*idiag[i];
115417ab2063SBarry Smith       }
115577d8c4bbSBarry Smith #endif
1156ed480e8bSBarry Smith       PetscLogFlops(a->nz);
115717ab2063SBarry Smith     }
115817ab2063SBarry Smith     its--;
115917ab2063SBarry Smith   }
116017ab2063SBarry Smith   while (its--) {
116117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
116277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11630c559628SSatish Balay       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
116477d8c4bbSBarry Smith #else
116517ab2063SBarry Smith       for (i=0; i<m; i++) {
1166ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1167416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1168ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1169ed480e8bSBarry Smith         v    = a->a + a->i[i];
117017ab2063SBarry Smith         sum  = b[i];
117117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1172ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
117317ab2063SBarry Smith       }
117477d8c4bbSBarry Smith #endif
1175ed480e8bSBarry Smith       PetscLogFlops(a->nz);
117617ab2063SBarry Smith     }
117717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
117877d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11790c559628SSatish Balay       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
118077d8c4bbSBarry Smith #else
118117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1182ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1183416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1184ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1185ed480e8bSBarry Smith         v    = a->a + a->i[i];
118617ab2063SBarry Smith         sum  = b[i];
118717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1188ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
118917ab2063SBarry Smith       }
119077d8c4bbSBarry Smith #endif
1191ed480e8bSBarry Smith       PetscLogFlops(a->nz);
119217ab2063SBarry Smith     }
119317ab2063SBarry Smith   }
11941ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11951ebc52fbSHong Zhang   if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11963a40ed3dSBarry Smith   PetscFunctionReturn(0);
119717ab2063SBarry Smith }
119817ab2063SBarry Smith 
11994a2ae208SSatish Balay #undef __FUNCT__
12004a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12018f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
120217ab2063SBarry Smith {
1203416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12044e220ebcSLois Curfman McInnes 
12053a40ed3dSBarry Smith   PetscFunctionBegin;
1206273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1207273d9f13SBarry Smith   info->columns_global = (double)A->n;
1208273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1209273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12104e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12114e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12124e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12134e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12144e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12154e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12164e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12174e220ebcSLois Curfman McInnes   if (A->factor) {
12184e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12194e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12204e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12214e220ebcSLois Curfman McInnes   } else {
12224e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12234e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12244e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12254e220ebcSLois Curfman McInnes   }
12263a40ed3dSBarry Smith   PetscFunctionReturn(0);
122717ab2063SBarry Smith }
122817ab2063SBarry Smith 
12294a2ae208SSatish Balay #undef __FUNCT__
12304a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1231268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag)
123217ab2063SBarry Smith {
1233416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1234bfeeae90SHong Zhang   int         i,ierr,N,*rows,m = A->m - 1;
123517ab2063SBarry Smith 
12363a40ed3dSBarry Smith   PetscFunctionBegin;
1237b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
123817ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1239f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1240f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1241a45adfd6SMatthew Knepley       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1242bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1243f1e2ffcdSBarry Smith     }
1244f1e2ffcdSBarry Smith     if (diag) {
1245f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1246f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1247f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1248f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1249f1e2ffcdSBarry Smith       }
1250f1e2ffcdSBarry Smith     }
1251f1e2ffcdSBarry Smith   } else {
125217ab2063SBarry Smith     if (diag) {
125317ab2063SBarry Smith       for (i=0; i<N; i++) {
1254a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
12557ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1256416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1257bfeeae90SHong Zhang           a->a[a->i[rows[i]]] = *diag;
1258bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
12597ae801bdSBarry Smith         } else { /* in case row was completely empty */
1260d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126117ab2063SBarry Smith         }
126217ab2063SBarry Smith       }
12633a40ed3dSBarry Smith     } else {
126417ab2063SBarry Smith       for (i=0; i<N; i++) {
1265a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1266416022c9SBarry Smith         a->ilen[rows[i]] = 0;
126717ab2063SBarry Smith       }
126817ab2063SBarry Smith     }
1269f1e2ffcdSBarry Smith   }
12707ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127143a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12723a40ed3dSBarry Smith   PetscFunctionReturn(0);
127317ab2063SBarry Smith }
127417ab2063SBarry Smith 
12754a2ae208SSatish Balay #undef __FUNCT__
12764a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
127787828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
127817ab2063SBarry Smith {
1279416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1280b3fb0a6cSMatthew Knepley   int        *itmp;
128117ab2063SBarry Smith 
12823a40ed3dSBarry Smith   PetscFunctionBegin;
1283273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
128417ab2063SBarry Smith 
1285416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1286bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
128717ab2063SBarry Smith   if (idx) {
1288bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1289bfeeae90SHong Zhang     if (*nz) {
12904e093b46SBarry Smith       *idx = itmp;
129117ab2063SBarry Smith     }
129217ab2063SBarry Smith     else *idx = 0;
129317ab2063SBarry Smith   }
12943a40ed3dSBarry Smith   PetscFunctionReturn(0);
129517ab2063SBarry Smith }
129617ab2063SBarry Smith 
1297bfeeae90SHong Zhang /* remove this function? */
12984a2ae208SSatish Balay #undef __FUNCT__
12994a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
130087828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
130117ab2063SBarry Smith {
1302bfeeae90SHong Zhang   /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1303bfeeae90SHong Zhang      int ierr; */
13043a40ed3dSBarry Smith 
13053a40ed3dSBarry Smith   PetscFunctionBegin;
1306bfeeae90SHong Zhang   /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */
13073a40ed3dSBarry Smith   PetscFunctionReturn(0);
130817ab2063SBarry Smith }
130917ab2063SBarry Smith 
13104a2ae208SSatish Balay #undef __FUNCT__
13114a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1312064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
131317ab2063SBarry Smith {
1314416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
131587828ca2SBarry Smith   PetscScalar  *v = a->a;
131636db0b34SBarry Smith   PetscReal    sum = 0.0;
1317bfeeae90SHong Zhang   int          i,j,ierr;
131817ab2063SBarry Smith 
13193a40ed3dSBarry Smith   PetscFunctionBegin;
132017ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1321416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1322aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
132336db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
132417ab2063SBarry Smith #else
132517ab2063SBarry Smith       sum += (*v)*(*v); v++;
132617ab2063SBarry Smith #endif
132717ab2063SBarry Smith     }
1328064f8208SBarry Smith     *nrm = sqrt(sum);
13293a40ed3dSBarry Smith   } else if (type == NORM_1) {
133036db0b34SBarry Smith     PetscReal *tmp;
1331416022c9SBarry Smith     int    *jj = a->j;
1332b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1333273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1334064f8208SBarry Smith     *nrm = 0.0;
1335416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1336bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
133717ab2063SBarry Smith     }
1338273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1339064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
134017ab2063SBarry Smith     }
1341606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13423a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1343064f8208SBarry Smith     *nrm = 0.0;
1344273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1345bfeeae90SHong Zhang       v = a->a + a->i[j];
134617ab2063SBarry Smith       sum = 0.0;
1347416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1348cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
134917ab2063SBarry Smith       }
1350064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
135117ab2063SBarry Smith     }
13523a40ed3dSBarry Smith   } else {
135329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
135417ab2063SBarry Smith   }
13553a40ed3dSBarry Smith   PetscFunctionReturn(0);
135617ab2063SBarry Smith }
135717ab2063SBarry Smith 
13584a2ae208SSatish Balay #undef __FUNCT__
13594a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
13608f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
136117ab2063SBarry Smith {
1362416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1363416022c9SBarry Smith   Mat          C;
1364273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
136587828ca2SBarry Smith   PetscScalar  *array = a->a;
136617ab2063SBarry Smith 
13673a40ed3dSBarry Smith   PetscFunctionBegin;
1368273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1369b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1370273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
1371bfeeae90SHong Zhang 
1372bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1373f204ca49SKris Buschelman   ierr = MatCreate(A->comm,A->n,m,A->n,m,&C);CHKERRQ(ierr);
1374f204ca49SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1375f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(C,0,col);CHKERRQ(ierr);
1376606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
137717ab2063SBarry Smith   for (i=0; i<m; i++) {
137817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1379416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1380b9b97703SBarry Smith     array += len;
1381b9b97703SBarry Smith     aj    += len;
138217ab2063SBarry Smith   }
138317ab2063SBarry Smith 
13846d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13856d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
138617ab2063SBarry Smith 
1387f1e2ffcdSBarry Smith   if (B) {
1388416022c9SBarry Smith     *B = C;
138917ab2063SBarry Smith   } else {
1390273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
139117ab2063SBarry Smith   }
13923a40ed3dSBarry Smith   PetscFunctionReturn(0);
139317ab2063SBarry Smith }
139417ab2063SBarry Smith 
1395cd0d46ebSvictorle EXTERN_C_BEGIN
1396cd0d46ebSvictorle #undef __FUNCT__
13975fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
13985485867bSBarry Smith int MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f)
1399cd0d46ebSvictorle {
1400cd0d46ebSvictorle   Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
1401cd0d46ebSvictorle   int        *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
1402cd0d46ebSvictorle   int        ma,na,mb,nb, i,ierr;
1403cd0d46ebSvictorle 
1404cd0d46ebSvictorle   PetscFunctionBegin;
1405cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1406cd0d46ebSvictorle 
1407cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1408cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
14095485867bSBarry Smith   if (ma!=nb || na!=mb){
14105485867bSBarry Smith     *f = PETSC_FALSE;
14115485867bSBarry Smith     PetscFunctionReturn(0);
14125485867bSBarry Smith   }
1413cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1414cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1415cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
1416cd0d46ebSvictorle   ierr = PetscMalloc(ma*sizeof(int),&aptr);CHKERRQ(ierr);
1417cd0d46ebSvictorle   ierr = PetscMalloc(mb*sizeof(int),&bptr);CHKERRQ(ierr);
1418cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1419cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1420cd0d46ebSvictorle 
1421cd0d46ebSvictorle   *f = PETSC_TRUE;
1422cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1423cd0d46ebSvictorle     /*printf("row %d spans %d--%d; we start @ %d\n",
1424cd0d46ebSvictorle       i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/
1425cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
14265485867bSBarry Smith       int         idc,idr;
14275485867bSBarry Smith       PetscScalar vc,vr;
1428cd0d46ebSvictorle       /* column/row index/value */
14295485867bSBarry Smith       idc = adx[aptr[i]];
14305485867bSBarry Smith       idr = bdx[bptr[idc]];
14315485867bSBarry Smith       vc  = va[aptr[i]];
14325485867bSBarry Smith       vr  = vb[bptr[idc]];
1433cd0d46ebSvictorle       /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n",
1434cd0d46ebSvictorle 	aptr[i],i,idc,vc,idc,idr,vr);*/
14355485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
14365485867bSBarry Smith 	*f = PETSC_FALSE;
14375485867bSBarry Smith         goto done;
1438cd0d46ebSvictorle       } else {
14395485867bSBarry Smith 	aptr[i]++;
14405485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1441cd0d46ebSvictorle       }
1442cd0d46ebSvictorle     }
1443cd0d46ebSvictorle   }
1444cd0d46ebSvictorle  done:
1445cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
14463aeef889SHong Zhang   if (B) {
14473aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
14483aeef889SHong Zhang   }
1449cd0d46ebSvictorle   PetscFunctionReturn(0);
1450cd0d46ebSvictorle }
1451cd0d46ebSvictorle EXTERN_C_END
1452cd0d46ebSvictorle 
14539e29f15eSvictorle #undef __FUNCT__
14549e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
14555485867bSBarry Smith int MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f)
14569e29f15eSvictorle {
1457dee28dbaSBarry Smith   int ierr;
14589e29f15eSvictorle   PetscFunctionBegin;
14595485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
14609e29f15eSvictorle   PetscFunctionReturn(0);
14619e29f15eSvictorle }
14629e29f15eSvictorle 
14634a2ae208SSatish Balay #undef __FUNCT__
14644a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14658f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
146617ab2063SBarry Smith {
1467416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
146887828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1469bfeeae90SHong Zhang   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
147017ab2063SBarry Smith 
14713a40ed3dSBarry Smith   PetscFunctionBegin;
147217ab2063SBarry Smith   if (ll) {
14733ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14743ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1475e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1476273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
14771ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1478416022c9SBarry Smith     v = a->a;
147917ab2063SBarry Smith     for (i=0; i<m; i++) {
148017ab2063SBarry Smith       x = l[i];
1481416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
148217ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
148317ab2063SBarry Smith     }
14841ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1485b0a32e0cSBarry Smith     PetscLogFlops(nz);
148617ab2063SBarry Smith   }
148717ab2063SBarry Smith   if (rr) {
1488e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1489273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
14901ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1491416022c9SBarry Smith     v = a->a; jj = a->j;
149217ab2063SBarry Smith     for (i=0; i<nz; i++) {
1493bfeeae90SHong Zhang       (*v++) *= r[*jj++];
149417ab2063SBarry Smith     }
14951ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1496b0a32e0cSBarry Smith     PetscLogFlops(nz);
149717ab2063SBarry Smith   }
14983a40ed3dSBarry Smith   PetscFunctionReturn(0);
149917ab2063SBarry Smith }
150017ab2063SBarry Smith 
15014a2ae208SSatish Balay #undef __FUNCT__
15024a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
15037b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
150417ab2063SBarry Smith {
1505db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1506273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
150736db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
1508bfeeae90SHong Zhang   int          *irow,*icol,nrows,ncols;
150999141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
151087828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1511416022c9SBarry Smith   Mat          C;
1512fee21e36SBarry Smith   PetscTruth   stride;
151317ab2063SBarry Smith 
15143a40ed3dSBarry Smith   PetscFunctionBegin;
1515d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
151629bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1517d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
151829bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
151999141d43SSatish Balay 
152017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1521b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1522b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
152317ab2063SBarry Smith 
1524fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1525fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1526fee21e36SBarry Smith   if (stride && step == 1) {
152702834360SBarry Smith     /* special case of contiguous rows */
152831ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
152931ebf83bSSatish Balay     starts = lens + nrows;
153002834360SBarry Smith     /* loop over new rows determining lens and starting points */
153102834360SBarry Smith     for (i=0; i<nrows; i++) {
1532bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1533a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
153402834360SBarry Smith       for (k=kstart; k<kend; k++) {
1535bfeeae90SHong Zhang         if (aj[k] >= first) {
153602834360SBarry Smith           starts[i] = k;
153702834360SBarry Smith           break;
153802834360SBarry Smith 	}
153902834360SBarry Smith       }
1540a2744918SBarry Smith       sum = 0;
154102834360SBarry Smith       while (k < kend) {
1542bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1543a2744918SBarry Smith         sum++;
154402834360SBarry Smith       }
1545a2744918SBarry Smith       lens[i] = sum;
154602834360SBarry Smith     }
154702834360SBarry Smith     /* create submatrix */
1548cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
154908480c60SBarry Smith       int n_cols,n_rows;
155008480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
155129bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1552d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
155308480c60SBarry Smith       C = *B;
15543a40ed3dSBarry Smith     } else {
1555e2d9671bSKris Buschelman       ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr);
1556e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1557e2d9671bSKris Buschelman       ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr);
155808480c60SBarry Smith     }
1559db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1560db02288aSLois Curfman McInnes 
156102834360SBarry Smith     /* loop over rows inserting into submatrix */
1562db02288aSLois Curfman McInnes     a_new    = c->a;
1563db02288aSLois Curfman McInnes     j_new    = c->j;
1564db02288aSLois Curfman McInnes     i_new    = c->i;
1565bfeeae90SHong Zhang 
156602834360SBarry Smith     for (i=0; i<nrows; i++) {
1567a2744918SBarry Smith       ii    = starts[i];
1568a2744918SBarry Smith       lensi = lens[i];
1569a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1570a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
157102834360SBarry Smith       }
157287828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1573a2744918SBarry Smith       a_new      += lensi;
1574a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1575a2744918SBarry Smith       c->ilen[i]  = lensi;
157602834360SBarry Smith     }
1577606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15783a40ed3dSBarry Smith   } else {
157902834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1580b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
1581bfeeae90SHong Zhang 
1582b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1583549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
158417ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
158502834360SBarry Smith     /* determine lens of each row */
158602834360SBarry Smith     for (i=0; i<nrows; i++) {
1587bfeeae90SHong Zhang       kstart  = ai[irow[i]];
158802834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
158902834360SBarry Smith       lens[i] = 0;
159002834360SBarry Smith       for (k=kstart; k<kend; k++) {
1591bfeeae90SHong Zhang         if (smap[aj[k]]) {
159202834360SBarry Smith           lens[i]++;
159302834360SBarry Smith         }
159402834360SBarry Smith       }
159502834360SBarry Smith     }
159617ab2063SBarry Smith     /* Create and fill new matrix */
1597a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15980f5bd95cSBarry Smith       PetscTruth equal;
15990f5bd95cSBarry Smith 
160099141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1601273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1602273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
16030f5bd95cSBarry Smith       if (!equal) {
160429bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
160599141d43SSatish Balay       }
1606273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
160708480c60SBarry Smith       C = *B;
16083a40ed3dSBarry Smith     } else {
1609e2d9671bSKris Buschelman       ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr);
1610e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1611e2d9671bSKris Buschelman       ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr);
161208480c60SBarry Smith     }
161399141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
161417ab2063SBarry Smith     for (i=0; i<nrows; i++) {
161599141d43SSatish Balay       row    = irow[i];
1616bfeeae90SHong Zhang       kstart = ai[row];
161799141d43SSatish Balay       kend   = kstart + a->ilen[row];
1618bfeeae90SHong Zhang       mat_i  = c->i[i];
161999141d43SSatish Balay       mat_j  = c->j + mat_i;
162099141d43SSatish Balay       mat_a  = c->a + mat_i;
162199141d43SSatish Balay       mat_ilen = c->ilen + i;
162217ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1623bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1624ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
162599141d43SSatish Balay           *mat_a++ = a->a[k];
162699141d43SSatish Balay           (*mat_ilen)++;
162799141d43SSatish Balay 
162817ab2063SBarry Smith         }
162917ab2063SBarry Smith       }
163017ab2063SBarry Smith     }
163102834360SBarry Smith     /* Free work space */
163202834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1633606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1634606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
163502834360SBarry Smith   }
16366d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16376d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163817ab2063SBarry Smith 
163917ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1640416022c9SBarry Smith   *B = C;
16413a40ed3dSBarry Smith   PetscFunctionReturn(0);
164217ab2063SBarry Smith }
164317ab2063SBarry Smith 
1644a871dcd8SBarry Smith /*
1645a871dcd8SBarry Smith */
16464a2ae208SSatish Balay #undef __FUNCT__
16474a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1648b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1649a871dcd8SBarry Smith {
165063b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
165108480c60SBarry Smith   int        ierr;
165263b91edcSBarry Smith   Mat        outA;
1653b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
165463b91edcSBarry Smith 
16553a40ed3dSBarry Smith   PetscFunctionBegin;
1656d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1657b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1658b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1659b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
166029bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1661b8a78c4aSBarry Smith   }
1662a871dcd8SBarry Smith 
166363b91edcSBarry Smith   outA          = inA;
166463b91edcSBarry Smith   inA->factor   = FACTOR_LU;
166563b91edcSBarry Smith   a->row        = row;
166663b91edcSBarry Smith   a->col        = col;
1667c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1668c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
166963b91edcSBarry Smith 
167036db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1671b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16724c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1673b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1674f0ec6fceSSatish Balay 
167594a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
167687828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
167794a9d846SBarry Smith   }
167863b91edcSBarry Smith 
167908480c60SBarry Smith   if (!a->diag) {
1680f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
168163b91edcSBarry Smith   }
168263b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1684a871dcd8SBarry Smith }
1685a871dcd8SBarry Smith 
1686d9eff348SSatish Balay #include "petscblaslapack.h"
16874a2ae208SSatish Balay #undef __FUNCT__
16884a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1689268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA)
1690f0b747eeSBarry Smith {
1691f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1692f0b747eeSBarry Smith   int        one = 1;
16933a40ed3dSBarry Smith 
16943a40ed3dSBarry Smith   PetscFunctionBegin;
1695268466fbSBarry Smith   BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one);
1696b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1698f0b747eeSBarry Smith }
1699f0b747eeSBarry Smith 
17004a2ae208SSatish Balay #undef __FUNCT__
17014a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
1702268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1703cddf8d76SBarry Smith {
1704cddf8d76SBarry Smith   int        ierr,i;
1705cddf8d76SBarry Smith 
17063a40ed3dSBarry Smith   PetscFunctionBegin;
1707cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1708b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1709cddf8d76SBarry Smith   }
1710cddf8d76SBarry Smith 
1711cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17126a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1713cddf8d76SBarry Smith   }
17143a40ed3dSBarry Smith   PetscFunctionReturn(0);
1715cddf8d76SBarry Smith }
1716cddf8d76SBarry Smith 
17174a2ae208SSatish Balay #undef __FUNCT__
17184a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17198f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17205a838052SSatish Balay {
1721f830108cSBarry Smith   PetscFunctionBegin;
17225a838052SSatish Balay   *bs = 1;
17233a40ed3dSBarry Smith   PetscFunctionReturn(0);
17245a838052SSatish Balay }
17255a838052SSatish Balay 
17264a2ae208SSatish Balay #undef __FUNCT__
17274a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
1728268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov)
17294dcbc457SBarry Smith {
1730e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1731efb16452SHong Zhang   int        row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17328a047759SSatish Balay   int        start,end,*ai,*aj;
1733f1af5d2fSBarry Smith   PetscBT    table;
1734bbd702dbSSatish Balay 
17353a40ed3dSBarry Smith   PetscFunctionBegin;
1736273d9f13SBarry Smith   m     = A->m;
1737e4d965acSSatish Balay   ai    = a->i;
1738bfeeae90SHong Zhang   aj    = a->j;
17398a047759SSatish Balay 
1740a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
174106763907SSatish Balay 
1742b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17436831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
174406763907SSatish Balay 
1745e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1746b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1747e4d965acSSatish Balay     isz  = 0;
17486831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1749e4d965acSSatish Balay 
1750e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17514dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1752b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1753e4d965acSSatish Balay 
1754dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1755e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1756f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17574dcbc457SBarry Smith     }
175806763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
175906763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1760e4d965acSSatish Balay 
176104a348a9SBarry Smith     k = 0;
176204a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
176304a348a9SBarry Smith       n = isz;
176406763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1765e4d965acSSatish Balay         row   = nidx[k];
1766e4d965acSSatish Balay         start = ai[row];
1767e4d965acSSatish Balay         end   = ai[row+1];
176804a348a9SBarry Smith         for (l = start; l<end ; l++){
1769efb16452SHong Zhang           val = aj[l] ;
1770f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1771e4d965acSSatish Balay         }
1772e4d965acSSatish Balay       }
1773e4d965acSSatish Balay     }
1774029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1775e4d965acSSatish Balay   }
17766831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1777606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17783a40ed3dSBarry Smith   PetscFunctionReturn(0);
17794dcbc457SBarry Smith }
178017ab2063SBarry Smith 
17810513a670SBarry Smith /* -------------------------------------------------------------- */
17824a2ae208SSatish Balay #undef __FUNCT__
17834a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17840513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17850513a670SBarry Smith {
17860513a670SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1787b3cc6726SBarry Smith   int               i,ierr,nz,m = A->m,n = A->n,*col;
1788b3cc6726SBarry Smith   int               *row,*cnew,j,*lens;
178956cd22aeSBarry Smith   IS                icolp,irowp;
1790b3cc6726SBarry Smith   const int         *cwork;
1791b3cc6726SBarry Smith   const PetscScalar *vwork;
17920513a670SBarry Smith 
17933a40ed3dSBarry Smith   PetscFunctionBegin;
17944c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
179556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
17964c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
179756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17980513a670SBarry Smith 
17990513a670SBarry Smith   /* determine lengths of permuted rows */
1800b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
18010513a670SBarry Smith   for (i=0; i<m; i++) {
18020513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18030513a670SBarry Smith   }
1804f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,B);CHKERRQ(ierr);
1805f204ca49SKris Buschelman   ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr);
1806f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(*B,0,lens);CHKERRQ(ierr);
1807606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18080513a670SBarry Smith 
1809b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18100513a670SBarry Smith   for (i=0; i<m; i++) {
18110513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18120513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18130513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18140513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18150513a670SBarry Smith   }
1816606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18170513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18180513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
181956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
182056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
182156cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
182256cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18233a40ed3dSBarry Smith   PetscFunctionReturn(0);
18240513a670SBarry Smith }
18250513a670SBarry Smith 
18264a2ae208SSatish Balay #undef __FUNCT__
18274a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1828682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1829682d7d0cSBarry Smith {
1830c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1831682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1832d132466eSBarry Smith   int               ierr;
1833682d7d0cSBarry Smith 
18343a40ed3dSBarry Smith   PetscFunctionBegin;
1835c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1836d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1837d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1838d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1839d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1840d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
18413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1842682d7d0cSBarry Smith }
184397304618SKris Buschelman 
18444a2ae208SSatish Balay #undef __FUNCT__
18454a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1846cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1847cb5b572fSBarry Smith {
1848be6bf707SBarry Smith   int        ierr;
1849cb5b572fSBarry Smith 
1850cb5b572fSBarry Smith   PetscFunctionBegin;
185133f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
185233f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1853be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1854be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1855be6bf707SBarry Smith 
1856bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
185729bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1858cb5b572fSBarry Smith     }
1859bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1860cb5b572fSBarry Smith   } else {
1861cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1862cb5b572fSBarry Smith   }
1863cb5b572fSBarry Smith   PetscFunctionReturn(0);
1864cb5b572fSBarry Smith }
1865cb5b572fSBarry Smith 
18664a2ae208SSatish Balay #undef __FUNCT__
18674a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1868273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1869273d9f13SBarry Smith {
1870273d9f13SBarry Smith   int        ierr;
1871273d9f13SBarry Smith 
1872273d9f13SBarry Smith   PetscFunctionBegin;
1873273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1874273d9f13SBarry Smith   PetscFunctionReturn(0);
1875273d9f13SBarry Smith }
1876273d9f13SBarry Smith 
18774a2ae208SSatish Balay #undef __FUNCT__
18784a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
18794e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
18806c0721eeSBarry Smith {
18816c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18826c0721eeSBarry Smith   PetscFunctionBegin;
18836c0721eeSBarry Smith   *array = a->a;
18846c0721eeSBarry Smith   PetscFunctionReturn(0);
18856c0721eeSBarry Smith }
18866c0721eeSBarry Smith 
18874a2ae208SSatish Balay #undef __FUNCT__
18884a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
18894e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
18906c0721eeSBarry Smith {
18916c0721eeSBarry Smith   PetscFunctionBegin;
18926c0721eeSBarry Smith   PetscFunctionReturn(0);
18936c0721eeSBarry Smith }
1894273d9f13SBarry Smith 
1895ee4f033dSBarry Smith #undef __FUNCT__
1896ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1897ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1898ee4f033dSBarry Smith {
1899ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1900ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
190187828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
190287828ca2SBarry Smith   PetscScalar   *vscale_array;
1903ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1904ee4f033dSBarry Smith   Vec           w1,w2,w3;
1905ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1906ee4f033dSBarry Smith   PetscTruth    flg;
1907ee4f033dSBarry Smith 
1908ee4f033dSBarry Smith   PetscFunctionBegin;
1909ee4f033dSBarry Smith   if (!coloring->w1) {
1910ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1911ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1912ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1913ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1914ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1915ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1916ee4f033dSBarry Smith   }
1917ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1918ee4f033dSBarry Smith 
1919ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1920e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1921ee4f033dSBarry Smith   if (flg) {
1922ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1923ee4f033dSBarry Smith   } else {
1924ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1925ee4f033dSBarry Smith   }
1926ee4f033dSBarry Smith 
1927ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1928ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1929ee4f033dSBarry Smith 
1930ee4f033dSBarry Smith   /*
1931ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1932ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1933ee4f033dSBarry Smith   */
1934ee4f033dSBarry Smith   if (coloring->F) {
1935ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1936ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1937ee4f033dSBarry Smith     if (m1 != m2) {
1938ee4f033dSBarry Smith       coloring->F = 0;
1939ee4f033dSBarry Smith     }
1940ee4f033dSBarry Smith   }
1941ee4f033dSBarry Smith 
1942ee4f033dSBarry Smith   if (coloring->F) {
1943ee4f033dSBarry Smith     w1          = coloring->F;
1944ee4f033dSBarry Smith     coloring->F = 0;
1945ee4f033dSBarry Smith   } else {
194666f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1947ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
194866f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1949ee4f033dSBarry Smith   }
1950ee4f033dSBarry Smith 
1951ee4f033dSBarry Smith   /*
1952ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1953ee4f033dSBarry Smith   */
19541ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
19551ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1956ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1957ee4f033dSBarry Smith     /*
1958ee4f033dSBarry Smith        Loop over each column associated with color adding the
1959ee4f033dSBarry Smith        perturbation to the vector w3.
1960ee4f033dSBarry Smith     */
1961ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1962ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1963ee4f033dSBarry Smith       dx  = xx[col];
1964ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1965ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1966ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1967ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1968ee4f033dSBarry Smith #else
1969ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1970ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1971ee4f033dSBarry Smith #endif
1972ee4f033dSBarry Smith       dx                *= epsilon;
1973ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1974ee4f033dSBarry Smith     }
1975ee4f033dSBarry Smith   }
19761ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1977ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1978ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1979ee4f033dSBarry Smith 
1980ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
1981ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
1982ee4f033dSBarry Smith 
1983ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
1984ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
1985ee4f033dSBarry Smith 
19861ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1987ee4f033dSBarry Smith   /*
1988ee4f033dSBarry Smith       Loop over each color
1989ee4f033dSBarry Smith   */
1990ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
199149b058dcSBarry Smith     coloring->currentcolor = k;
1992ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
19931ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
1994ee4f033dSBarry Smith     /*
1995ee4f033dSBarry Smith        Loop over each column associated with color adding the
1996ee4f033dSBarry Smith        perturbation to the vector w3.
1997ee4f033dSBarry Smith     */
1998ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1999ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2000ee4f033dSBarry Smith       dx  = xx[col];
2001*5b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2002ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2003ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2004ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2005ee4f033dSBarry Smith #else
2006ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2007ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2008ee4f033dSBarry Smith #endif
2009ee4f033dSBarry Smith       dx            *= epsilon;
2010ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2011ee4f033dSBarry Smith       w3_array[col] += dx;
2012ee4f033dSBarry Smith     }
20131ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2014ee4f033dSBarry Smith 
2015ee4f033dSBarry Smith     /*
2016ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2017ee4f033dSBarry Smith     */
2018ee4f033dSBarry Smith 
201966f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2020ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
202166f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2022ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2023ee4f033dSBarry Smith 
2024ee4f033dSBarry Smith     /*
2025ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2026ee4f033dSBarry Smith     */
20271ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2028ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2029ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2030ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2031ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2032ee4f033dSBarry Smith       srow   = row + start;
2033ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2034ee4f033dSBarry Smith     }
20351ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2036ee4f033dSBarry Smith   }
203749b058dcSBarry Smith   coloring->currentcolor = k;
20381ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
20391ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2040ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2041ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2042ee4f033dSBarry Smith   PetscFunctionReturn(0);
2043ee4f033dSBarry Smith }
2044ee4f033dSBarry Smith 
2045ac90fabeSBarry Smith #include "petscblaslapack.h"
2046ac90fabeSBarry Smith #undef __FUNCT__
2047ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
20487cff1425SSatish Balay int MatAXPY_SeqAIJ(const PetscScalar a[],Mat X,Mat Y,MatStructure str)
2049ac90fabeSBarry Smith {
2050c537a176SHong Zhang   int        ierr,one=1,i;
2051ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2052ac90fabeSBarry Smith 
2053ac90fabeSBarry Smith   PetscFunctionBegin;
2054ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2055268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
2056c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2057a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2058a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2059a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2060a30b2313SHong Zhang     }
2061a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
206224f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2063a30b2313SHong Zhang       y->XtoY = X;
2064c537a176SHong Zhang     }
2065a30b2313SHong Zhang     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]);
2066e2dd4fc4Svictorle     PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);
2067ac90fabeSBarry Smith   } else {
2068ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2069ac90fabeSBarry Smith   }
2070ac90fabeSBarry Smith   PetscFunctionReturn(0);
2071ac90fabeSBarry Smith }
2072ac90fabeSBarry Smith 
2073682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20740a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2075cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2076cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2077cb5b572fSBarry Smith        MatMult_SeqAIJ,
207897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
20797c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20807c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2081cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2082cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20837c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
208497304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2085cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2086cb5b572fSBarry Smith        0,
208717ab2063SBarry Smith        MatRelax_SeqAIJ,
208817ab2063SBarry Smith        MatTranspose_SeqAIJ,
208997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2090cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2091cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2092cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2093cb5b572fSBarry Smith        MatNorm_SeqAIJ,
209497304618SKris Buschelman /*20*/ 0,
2095cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
209617ab2063SBarry Smith        MatCompress_SeqAIJ,
2097cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2098cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
209997304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2100cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2101cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2102f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2103a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
210497304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2105cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2106861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
21076c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21086c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
210997304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2110cb5b572fSBarry Smith        0,
2111cb5b572fSBarry Smith        0,
2112cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2113cb5b572fSBarry Smith        0,
211497304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2115cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2116cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2117cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2118cb5b572fSBarry Smith        MatCopy_SeqAIJ,
211997304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ,
2120cb5b572fSBarry Smith        MatScale_SeqAIJ,
2121cb5b572fSBarry Smith        0,
2122cb5b572fSBarry Smith        0,
21236945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
212497304618SKris Buschelman /*50*/ MatGetBlockSize_SeqAIJ,
21253b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21263b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21273b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2128a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
212997304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2130b9617806SBarry Smith        0,
21310513a670SBarry Smith        0,
2132cda55fadSBarry Smith        MatPermute_SeqAIJ,
2133cda55fadSBarry Smith        0,
213497304618SKris Buschelman /*60*/ 0,
2135b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2136b9b97703SBarry Smith        MatView_SeqAIJ,
21378a124369SBarry Smith        MatGetPetscMaps_Petsc,
2138ee4f033dSBarry Smith        0,
213997304618SKris Buschelman /*65*/ 0,
2140ee4f033dSBarry Smith        0,
2141ee4f033dSBarry Smith        0,
2142ee4f033dSBarry Smith        0,
2143ee4f033dSBarry Smith        0,
214497304618SKris Buschelman /*70*/ 0,
2145ee4f033dSBarry Smith        0,
2146ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2147ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2148ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
214997304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ,
215097304618SKris Buschelman        0,
215197304618SKris Buschelman        0,
215297304618SKris Buschelman        0,
215397304618SKris Buschelman        0,
215497304618SKris Buschelman /*80*/ 0,
215597304618SKris Buschelman        0,
215697304618SKris Buschelman        0,
215797304618SKris Buschelman        0,
21589e29f15eSvictorle /*85*/ MatLoad_SeqAIJ,
21599e29f15eSvictorle        MatIsSymmetric_SeqAIJ,
21606284ec50SHong Zhang        0,
21616284ec50SHong Zhang        0,
21626284ec50SHong Zhang        0,
21636284ec50SHong Zhang /*90*/ 0,
21646284ec50SHong Zhang        MatMatMult_SeqAIJ_SeqAIJ,
21659e29f15eSvictorle };
216617ab2063SBarry Smith 
2167fb2e594dSBarry Smith EXTERN_C_BEGIN
21684a2ae208SSatish Balay #undef __FUNCT__
21694a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
2170bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2171bef8e0ddSBarry Smith {
2172bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2173bef8e0ddSBarry Smith   int        i,nz,n;
2174bef8e0ddSBarry Smith 
2175bef8e0ddSBarry Smith   PetscFunctionBegin;
2176bef8e0ddSBarry Smith 
2177bef8e0ddSBarry Smith   nz = aij->maxnz;
2178273d9f13SBarry Smith   n  = mat->n;
2179bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2180bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2181bef8e0ddSBarry Smith   }
2182bef8e0ddSBarry Smith   aij->nz = nz;
2183bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2184bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2185bef8e0ddSBarry Smith   }
2186bef8e0ddSBarry Smith 
2187bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2188bef8e0ddSBarry Smith }
2189fb2e594dSBarry Smith EXTERN_C_END
2190bef8e0ddSBarry Smith 
21914a2ae208SSatish Balay #undef __FUNCT__
21924a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2193bef8e0ddSBarry Smith /*@
2194bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2195bef8e0ddSBarry Smith        in the matrix.
2196bef8e0ddSBarry Smith 
2197bef8e0ddSBarry Smith   Input Parameters:
2198bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2199bef8e0ddSBarry Smith -  indices - the column indices
2200bef8e0ddSBarry Smith 
220115091d37SBarry Smith   Level: advanced
220215091d37SBarry Smith 
2203bef8e0ddSBarry Smith   Notes:
2204bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2205bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2206bef8e0ddSBarry Smith   of the MatSetValues() operation.
2207bef8e0ddSBarry Smith 
2208bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2209bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2210bef8e0ddSBarry Smith 
2211bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2212bef8e0ddSBarry Smith 
2213b9617806SBarry Smith     The indices should start with zero, not one.
2214b9617806SBarry Smith 
2215bef8e0ddSBarry Smith @*/
2216bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2217bef8e0ddSBarry Smith {
2218bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2219bef8e0ddSBarry Smith 
2220bef8e0ddSBarry Smith   PetscFunctionBegin;
22214482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
22224482741eSBarry Smith   PetscValidPointer(indices,2);
2223c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2224bef8e0ddSBarry Smith   if (f) {
2225bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2226bef8e0ddSBarry Smith   } else {
222729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2228bef8e0ddSBarry Smith   }
2229bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2230bef8e0ddSBarry Smith }
2231bef8e0ddSBarry Smith 
2232be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2233be6bf707SBarry Smith 
2234fb2e594dSBarry Smith EXTERN_C_BEGIN
22354a2ae208SSatish Balay #undef __FUNCT__
22364a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2237be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2238be6bf707SBarry Smith {
2239be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2240bfeeae90SHong Zhang   size_t       nz = aij->i[mat->m],ierr;
2241be6bf707SBarry Smith 
2242be6bf707SBarry Smith   PetscFunctionBegin;
2243be6bf707SBarry Smith   if (aij->nonew != 1) {
224429bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2245be6bf707SBarry Smith   }
2246be6bf707SBarry Smith 
2247be6bf707SBarry Smith   /* allocate space for values if not already there */
2248be6bf707SBarry Smith   if (!aij->saved_values) {
224987828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2250be6bf707SBarry Smith   }
2251be6bf707SBarry Smith 
2252be6bf707SBarry Smith   /* copy values over */
225387828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2254be6bf707SBarry Smith   PetscFunctionReturn(0);
2255be6bf707SBarry Smith }
2256fb2e594dSBarry Smith EXTERN_C_END
2257be6bf707SBarry Smith 
22584a2ae208SSatish Balay #undef __FUNCT__
2259b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2260be6bf707SBarry Smith /*@
2261be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2262be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2263be6bf707SBarry Smith        nonlinear portion.
2264be6bf707SBarry Smith 
2265be6bf707SBarry Smith    Collect on Mat
2266be6bf707SBarry Smith 
2267be6bf707SBarry Smith   Input Parameters:
2268be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2269be6bf707SBarry Smith 
227015091d37SBarry Smith   Level: advanced
227115091d37SBarry Smith 
2272be6bf707SBarry Smith   Common Usage, with SNESSolve():
2273be6bf707SBarry Smith $    Create Jacobian matrix
2274be6bf707SBarry Smith $    Set linear terms into matrix
2275be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2276be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2277be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2278be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2279be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2280be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2281be6bf707SBarry Smith $    In your Jacobian routine
2282be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2283be6bf707SBarry Smith $      Set nonlinear terms in matrix
2284be6bf707SBarry Smith 
2285be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2286be6bf707SBarry Smith $    // build linear portion of Jacobian
2287be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2288be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2289be6bf707SBarry Smith $    loop over nonlinear iterations
2290be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2291be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2292be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2293be6bf707SBarry Smith $       Solve linear system with Jacobian
2294be6bf707SBarry Smith $    endloop
2295be6bf707SBarry Smith 
2296be6bf707SBarry Smith   Notes:
2297be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2298be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2299be6bf707SBarry Smith     calling this routine.
2300be6bf707SBarry Smith 
2301be6bf707SBarry Smith .seealso: MatRetrieveValues()
2302be6bf707SBarry Smith 
2303be6bf707SBarry Smith @*/
2304be6bf707SBarry Smith int MatStoreValues(Mat mat)
2305be6bf707SBarry Smith {
2306be6bf707SBarry Smith   int ierr,(*f)(Mat);
2307be6bf707SBarry Smith 
2308be6bf707SBarry Smith   PetscFunctionBegin;
23094482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
231029bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
231129bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2312be6bf707SBarry Smith 
2313c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2314be6bf707SBarry Smith   if (f) {
2315be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2316be6bf707SBarry Smith   } else {
231729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2318be6bf707SBarry Smith   }
2319be6bf707SBarry Smith   PetscFunctionReturn(0);
2320be6bf707SBarry Smith }
2321be6bf707SBarry Smith 
2322fb2e594dSBarry Smith EXTERN_C_BEGIN
23234a2ae208SSatish Balay #undef __FUNCT__
23244a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2325be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2326be6bf707SBarry Smith {
2327be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2328bfeeae90SHong Zhang   int        nz = aij->i[mat->m],ierr;
2329be6bf707SBarry Smith 
2330be6bf707SBarry Smith   PetscFunctionBegin;
2331be6bf707SBarry Smith   if (aij->nonew != 1) {
233229bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2333be6bf707SBarry Smith   }
2334be6bf707SBarry Smith   if (!aij->saved_values) {
233529bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2336be6bf707SBarry Smith   }
2337be6bf707SBarry Smith 
2338be6bf707SBarry Smith   /* copy values over */
233987828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2340be6bf707SBarry Smith   PetscFunctionReturn(0);
2341be6bf707SBarry Smith }
2342fb2e594dSBarry Smith EXTERN_C_END
2343be6bf707SBarry Smith 
23444a2ae208SSatish Balay #undef __FUNCT__
23454a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2346be6bf707SBarry Smith /*@
2347be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2348be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2349be6bf707SBarry Smith        nonlinear portion.
2350be6bf707SBarry Smith 
2351be6bf707SBarry Smith    Collect on Mat
2352be6bf707SBarry Smith 
2353be6bf707SBarry Smith   Input Parameters:
2354be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2355be6bf707SBarry Smith 
235615091d37SBarry Smith   Level: advanced
235715091d37SBarry Smith 
2358be6bf707SBarry Smith .seealso: MatStoreValues()
2359be6bf707SBarry Smith 
2360be6bf707SBarry Smith @*/
2361be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2362be6bf707SBarry Smith {
2363be6bf707SBarry Smith   int ierr,(*f)(Mat);
2364be6bf707SBarry Smith 
2365be6bf707SBarry Smith   PetscFunctionBegin;
23664482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
236729bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
236829bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369be6bf707SBarry Smith 
2370c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2371be6bf707SBarry Smith   if (f) {
2372be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2373be6bf707SBarry Smith   } else {
237429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2375be6bf707SBarry Smith   }
2376be6bf707SBarry Smith   PetscFunctionReturn(0);
2377be6bf707SBarry Smith }
2378be6bf707SBarry Smith 
2379f83d6046SBarry Smith 
2380be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
23814a2ae208SSatish Balay #undef __FUNCT__
23824a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
238317ab2063SBarry Smith /*@C
2384682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
23850d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
23866e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
238751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
23882bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
238917ab2063SBarry Smith 
2390db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2391db81eaa0SLois Curfman McInnes 
239217ab2063SBarry Smith    Input Parameters:
2393db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
239417ab2063SBarry Smith .  m - number of rows
239517ab2063SBarry Smith .  n - number of columns
239617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
239751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
23982bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
239917ab2063SBarry Smith 
240017ab2063SBarry Smith    Output Parameter:
2401416022c9SBarry Smith .  A - the matrix
240217ab2063SBarry Smith 
2403b259b22eSLois Curfman McInnes    Notes:
240417ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
240517ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24060002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
240744cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
240817ab2063SBarry Smith 
240917ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2410a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24113d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24126da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
241317ab2063SBarry Smith 
2414682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24154fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2416682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24176c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24186c7ebb05SLois Curfman McInnes 
24196c7ebb05SLois Curfman McInnes    Options Database Keys:
2420db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2421db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2422db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2423db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2424db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
242517ab2063SBarry Smith 
2426027ccd11SLois Curfman McInnes    Level: intermediate
2427027ccd11SLois Curfman McInnes 
242836db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
242936db0b34SBarry Smith 
243017ab2063SBarry Smith @*/
2431ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A)
243217ab2063SBarry Smith {
2433273d9f13SBarry Smith   int ierr;
24346945ee14SBarry Smith 
24353a40ed3dSBarry Smith   PetscFunctionBegin;
2436273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2437273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2438273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2439273d9f13SBarry Smith   PetscFunctionReturn(0);
2440273d9f13SBarry Smith }
2441273d9f13SBarry Smith 
24425da197adSKris Buschelman #define SKIP_ALLOCATION -4
24435da197adSKris Buschelman 
24444a2ae208SSatish Balay #undef __FUNCT__
24454a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2446273d9f13SBarry Smith /*@C
2447273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2448273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2449273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2450273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2451273d9f13SBarry Smith 
2452273d9f13SBarry Smith    Collective on MPI_Comm
2453273d9f13SBarry Smith 
2454273d9f13SBarry Smith    Input Parameters:
2455273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2456273d9f13SBarry Smith .  m - number of rows
2457273d9f13SBarry Smith .  n - number of columns
2458273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2459273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2460273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2461273d9f13SBarry Smith 
2462273d9f13SBarry Smith    Output Parameter:
2463273d9f13SBarry Smith .  A - the matrix
2464273d9f13SBarry Smith 
2465273d9f13SBarry Smith    Notes:
2466273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2467273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2468273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2469273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2470273d9f13SBarry Smith 
2471273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2472273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2473273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2474273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2475273d9f13SBarry Smith 
2476273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2477273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2478273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2479273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2480273d9f13SBarry Smith 
2481273d9f13SBarry Smith    Options Database Keys:
2482273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2483273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2484273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2485273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2486273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2487273d9f13SBarry Smith 
2488273d9f13SBarry Smith    Level: intermediate
2489273d9f13SBarry Smith 
2490273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2491273d9f13SBarry Smith 
2492273d9f13SBarry Smith @*/
2493ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[])
2494273d9f13SBarry Smith {
2495ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,const int[]);
2496a23d5eceSKris Buschelman 
2497a23d5eceSKris Buschelman   PetscFunctionBegin;
2498a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2499a23d5eceSKris Buschelman   if (f) {
2500a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2501a23d5eceSKris Buschelman   }
2502a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2503a23d5eceSKris Buschelman }
2504a23d5eceSKris Buschelman 
2505a23d5eceSKris Buschelman EXTERN_C_BEGIN
2506a23d5eceSKris Buschelman #undef __FUNCT__
2507a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2508a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz)
2509a23d5eceSKris Buschelman {
2510273d9f13SBarry Smith   Mat_SeqAIJ *b;
2511a7ed9263SMatthew Knepley   size_t     len = 0;
2512a43ee2ecSKris Buschelman   PetscTruth skipallocation = PETSC_FALSE;
2513a7ed9263SMatthew Knepley   int        i,ierr;
2514273d9f13SBarry Smith 
2515273d9f13SBarry Smith   PetscFunctionBegin;
2516d5d45c9bSBarry Smith 
2517c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2518c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2519c461c341SBarry Smith     nz             = 0;
2520c461c341SBarry Smith   }
2521c461c341SBarry Smith 
2522435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2523435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2524b73539f3SBarry Smith   if (nnz) {
2525273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
252629bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25273a7fca6bSBarry 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);
2528b73539f3SBarry Smith     }
2529b73539f3SBarry Smith   }
2530b73539f3SBarry Smith 
2531273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2532273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2533273d9f13SBarry Smith 
2534b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2535273d9f13SBarry Smith   if (!nnz) {
2536435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2537273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2538273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2539273d9f13SBarry Smith     nz = nz*B->m;
2540273d9f13SBarry Smith   } else {
2541273d9f13SBarry Smith     nz = 0;
2542273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2543273d9f13SBarry Smith   }
2544273d9f13SBarry Smith 
2545c461c341SBarry Smith   if (!skipallocation) {
2546273d9f13SBarry Smith     /* allocate the matrix space */
2547a7ed9263SMatthew Knepley     len             = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2548b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2549273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2550273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2551273d9f13SBarry Smith     b->i            = b->j + nz;
2552bfeeae90SHong Zhang     b->i[0] = 0;
25535da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
25545da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
25555da197adSKris Buschelman     }
2556273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2557273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2558c461c341SBarry Smith   } else {
2559c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2560c461c341SBarry Smith   }
2561273d9f13SBarry Smith 
2562273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2563b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2564b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2565273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2566273d9f13SBarry Smith 
2567273d9f13SBarry Smith   b->nz                = 0;
2568273d9f13SBarry Smith   b->maxnz             = nz;
2569273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2570273d9f13SBarry Smith   PetscFunctionReturn(0);
2571273d9f13SBarry Smith }
2572a23d5eceSKris Buschelman EXTERN_C_END
2573273d9f13SBarry Smith 
25740bad9183SKris Buschelman /*MC
2575fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
25760bad9183SKris Buschelman    based on compressed sparse row format.
25770bad9183SKris Buschelman 
25780bad9183SKris Buschelman    Options Database Keys:
25790bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
25800bad9183SKris Buschelman 
25810bad9183SKris Buschelman   Level: beginner
25820bad9183SKris Buschelman 
2583f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
25840bad9183SKris Buschelman M*/
25850bad9183SKris Buschelman 
2586a6175056SHong Zhang EXTERN_C_BEGIN
25874a2ae208SSatish Balay #undef __FUNCT__
25884a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2589273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2590273d9f13SBarry Smith {
2591273d9f13SBarry Smith   Mat_SeqAIJ *b;
2592273d9f13SBarry Smith   int        ierr,size;
2593273d9f13SBarry Smith 
2594273d9f13SBarry Smith   PetscFunctionBegin;
2595273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2596273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2597273d9f13SBarry Smith 
2598273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2599273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2600273d9f13SBarry Smith 
2601b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2602b0a32e0cSBarry Smith   B->data             = (void*)b;
2603549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2604549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2605416022c9SBarry Smith   B->factor           = 0;
2606416022c9SBarry Smith   B->lupivotthreshold = 1.0;
260790f02eecSBarry Smith   B->mapping          = 0;
2608e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2609e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2610416022c9SBarry Smith   b->row              = 0;
2611416022c9SBarry Smith   b->col              = 0;
261282bf6240SBarry Smith   b->icol             = 0;
2613b810aeb4SBarry Smith   b->reallocs         = 0;
261417ab2063SBarry Smith 
26158a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26168a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2617a5ae1ecdSBarry Smith 
2618f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
261936db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2620f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2621416022c9SBarry Smith   b->nonew             = 0;
2622416022c9SBarry Smith   b->diag              = 0;
2623416022c9SBarry Smith   b->solve_work        = 0;
26242a1b7f2aSHong Zhang   B->spptr             = 0;
2625b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2626754ec7b1SSatish Balay   b->inode.node_count  = 0;
2627754ec7b1SSatish Balay   b->inode.size        = 0;
26286c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26296c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2630be6bf707SBarry Smith   b->saved_values      = 0;
2631d7f994e1SBarry Smith   b->idiag             = 0;
2632d7f994e1SBarry Smith   b->ssor              = 0;
2633f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2634a30b2313SHong Zhang   b->xtoy              = 0;
2635a30b2313SHong Zhang   b->XtoY              = 0;
263617ab2063SBarry Smith 
263735d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
263835d8aa7fSBarry Smith 
2639f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2640bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2641bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2642f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2643be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2644bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2645f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2646be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2647bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2648a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2649a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2650a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
265185fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
265285fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
265385fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
26545fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
26555fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
26565fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
2657a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2658a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2659a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
266005b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
266105b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
266205b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
26630a99d0a2SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C",
26640a99d0a2SKris Buschelman                                      "MatAdjustForInodes_SeqAIJ",
26650a99d0a2SKris Buschelman                                       MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr);
2666d758967fSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C",
2667d758967fSKris Buschelman                                      "MatSeqAIJGetInodeSizes_SeqAIJ",
2668d758967fSKris Buschelman                                       MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr);
2669eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
26703a40ed3dSBarry Smith   PetscFunctionReturn(0);
267117ab2063SBarry Smith }
2672273d9f13SBarry Smith EXTERN_C_END
267317ab2063SBarry Smith 
26744a2ae208SSatish Balay #undef __FUNCT__
26754a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2676be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
267717ab2063SBarry Smith {
2678416022c9SBarry Smith   Mat        C;
2679416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2680bfeeae90SHong Zhang   int        i,m = A->m,ierr;
2681a7ed9263SMatthew Knepley   size_t     len;
268217ab2063SBarry Smith 
26833a40ed3dSBarry Smith   PetscFunctionBegin;
26844043dd9cSLois Curfman McInnes   *B = 0;
2685273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2686be5d1d56SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
26871d5dac46SHong Zhang   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
26881d5dac46SHong Zhang 
2689273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2690273d9f13SBarry Smith 
2691416022c9SBarry Smith   C->factor         = A->factor;
2692416022c9SBarry Smith   c->row            = 0;
2693416022c9SBarry Smith   c->col            = 0;
269482bf6240SBarry Smith   c->icol           = 0;
2695f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2696c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
269717ab2063SBarry Smith 
2698273d9f13SBarry Smith   C->M          = A->m;
2699273d9f13SBarry Smith   C->N          = A->n;
270017ab2063SBarry Smith 
2701b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2702b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
270317ab2063SBarry Smith   for (i=0; i<m; i++) {
2704416022c9SBarry Smith     c->imax[i] = a->imax[i];
2705416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
270617ab2063SBarry Smith   }
270717ab2063SBarry Smith 
270817ab2063SBarry Smith   /* allocate the matrix space */
2709f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2710a7ed9263SMatthew Knepley   len   = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2711b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2712bfeeae90SHong Zhang   c->j  = (int*)(c->a + a->i[m] );
2713bfeeae90SHong Zhang   c->i  = c->j + a->i[m];
2714549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
271517ab2063SBarry Smith   if (m > 0) {
2716bfeeae90SHong Zhang     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr);
2717be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2718bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2719be6bf707SBarry Smith     } else {
2720bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
272117ab2063SBarry Smith     }
272208480c60SBarry Smith   }
272317ab2063SBarry Smith 
2724b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2725416022c9SBarry Smith   c->sorted      = a->sorted;
2726416022c9SBarry Smith   c->roworiented = a->roworiented;
2727416022c9SBarry Smith   c->nonew       = a->nonew;
27287a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2729be6bf707SBarry Smith   c->saved_values = 0;
2730d7f994e1SBarry Smith   c->idiag        = 0;
2731d7f994e1SBarry Smith   c->ssor         = 0;
273236db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
273336db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
273417ab2063SBarry Smith 
2735416022c9SBarry Smith   if (a->diag) {
2736b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2737b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
273817ab2063SBarry Smith     for (i=0; i<m; i++) {
2739416022c9SBarry Smith       c->diag[i] = a->diag[i];
274017ab2063SBarry Smith     }
27413a40ed3dSBarry Smith   } else c->diag        = 0;
2742b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27436c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
27446c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2745754ec7b1SSatish Balay   if (a->inode.size){
2746b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2747754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2748549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2749754ec7b1SSatish Balay   } else {
2750754ec7b1SSatish Balay     c->inode.size       = 0;
2751754ec7b1SSatish Balay     c->inode.node_count = 0;
2752754ec7b1SSatish Balay   }
2753416022c9SBarry Smith   c->nz                 = a->nz;
2754416022c9SBarry Smith   c->maxnz              = a->maxnz;
2755416022c9SBarry Smith   c->solve_work         = 0;
2756273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2757754ec7b1SSatish Balay 
2758416022c9SBarry Smith   *B = C;
2759b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
27603a40ed3dSBarry Smith   PetscFunctionReturn(0);
276117ab2063SBarry Smith }
276217ab2063SBarry Smith 
27634a2ae208SSatish Balay #undef __FUNCT__
27644a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
27658e9aea5cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,const MatType type,Mat *A)
276617ab2063SBarry Smith {
2767416022c9SBarry Smith   Mat_SeqAIJ   *a;
2768416022c9SBarry Smith   Mat          B;
2769efb16452SHong Zhang   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N;
2770bcd2baecSBarry Smith   MPI_Comm     comm;
277117ab2063SBarry Smith 
27723a40ed3dSBarry Smith   PetscFunctionBegin;
2773e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2774d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
277529bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2776b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
27770752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2778552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
277917ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
278017ab2063SBarry Smith 
2781d64ed03dSBarry Smith   if (nz < 0) {
278229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2783d64ed03dSBarry Smith   }
2784d64ed03dSBarry Smith 
278517ab2063SBarry Smith   /* read in row lengths */
2786b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
27870752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
278817ab2063SBarry Smith 
278917ab2063SBarry Smith   /* create our matrix */
2790b3a1e11cSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr);
2791b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
2792b3a1e11cSKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
2793416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
279417ab2063SBarry Smith 
279517ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
27960752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
279717ab2063SBarry Smith 
279817ab2063SBarry Smith   /* read in nonzero values */
27990752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
280017ab2063SBarry Smith 
280117ab2063SBarry Smith   /* set matrix "i" values */
2802efb16452SHong Zhang   a->i[0] = 0;
280317ab2063SBarry Smith   for (i=1; i<= M; i++) {
2804416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2805416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
280617ab2063SBarry Smith   }
2807606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
280817ab2063SBarry Smith 
28096d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28106d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2811b3a1e11cSKris Buschelman   *A = B;
28123a40ed3dSBarry Smith   PetscFunctionReturn(0);
281317ab2063SBarry Smith }
281417ab2063SBarry Smith 
28154a2ae208SSatish Balay #undef __FUNCT__
2816b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28178f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28187264ac53SSatish Balay {
28197264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28200f5bd95cSBarry Smith   int        ierr;
28217264ac53SSatish Balay 
28223a40ed3dSBarry Smith   PetscFunctionBegin;
2823bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
2824bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
2825ca44d042SBarry Smith     *flg = PETSC_FALSE;
2826ca44d042SBarry Smith     PetscFunctionReturn(0);
2827bcd2baecSBarry Smith   }
28287264ac53SSatish Balay 
28297264ac53SSatish Balay   /* if the a->i are the same */
2830273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28310f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28327264ac53SSatish Balay 
28337264ac53SSatish Balay   /* if a->j are the same */
28340f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28350f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2836bcd2baecSBarry Smith 
2837bcd2baecSBarry Smith   /* if a->a are the same */
283887828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
28390f5bd95cSBarry Smith 
28403a40ed3dSBarry Smith   PetscFunctionReturn(0);
28417264ac53SSatish Balay 
28427264ac53SSatish Balay }
284336db0b34SBarry Smith 
28444a2ae208SSatish Balay #undef __FUNCT__
28454a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
284636db0b34SBarry Smith /*@C
284736db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
284836db0b34SBarry Smith               provided by the user.
284936db0b34SBarry Smith 
285036db0b34SBarry Smith       Coolective on MPI_Comm
285136db0b34SBarry Smith 
285236db0b34SBarry Smith    Input Parameters:
285336db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
285436db0b34SBarry Smith .   m - number of rows
285536db0b34SBarry Smith .   n - number of columns
285636db0b34SBarry Smith .   i - row indices
285736db0b34SBarry Smith .   j - column indices
285836db0b34SBarry Smith -   a - matrix values
285936db0b34SBarry Smith 
286036db0b34SBarry Smith    Output Parameter:
286136db0b34SBarry Smith .   mat - the matrix
286236db0b34SBarry Smith 
286336db0b34SBarry Smith    Level: intermediate
286436db0b34SBarry Smith 
286536db0b34SBarry Smith    Notes:
28660551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
286736db0b34SBarry Smith     once the matrix is destroyed
286836db0b34SBarry Smith 
286936db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
287036db0b34SBarry Smith 
2871bfeeae90SHong Zhang        The i and j indices are 0 based
287236db0b34SBarry Smith 
287336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
287436db0b34SBarry Smith 
287536db0b34SBarry Smith @*/
287687828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
287736db0b34SBarry Smith {
287836db0b34SBarry Smith   int        ierr,ii;
287936db0b34SBarry Smith   Mat_SeqAIJ *aij;
288036db0b34SBarry Smith 
288136db0b34SBarry Smith   PetscFunctionBegin;
2882f204ca49SKris Buschelman   ierr = MatCreate(comm,m,n,m,n,mat);CHKERRQ(ierr);
2883f204ca49SKris Buschelman   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
2884f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(*mat,SKIP_ALLOCATION,0);CHKERRQ(ierr);
288536db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
288636db0b34SBarry Smith 
2887bfeeae90SHong Zhang   if (i[0] != 0) {
2888bfeeae90SHong Zhang     SETERRQ(1,"i (row indices) must start with 0");
288936db0b34SBarry Smith   }
289036db0b34SBarry Smith   aij->i = i;
289136db0b34SBarry Smith   aij->j = j;
289236db0b34SBarry Smith   aij->a = a;
289336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
289436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
289536db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
289636db0b34SBarry Smith 
289736db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
289836db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
28999860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
290029bbc08cSBarry 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]);
290136db0b34SBarry Smith #endif
290236db0b34SBarry Smith   }
29039860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
290436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
2905bfeeae90SHong Zhang     if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
2906bfeeae90SHong Zhang     if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
290736db0b34SBarry Smith   }
290836db0b34SBarry Smith #endif
290936db0b34SBarry Smith 
2910b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2911b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
291236db0b34SBarry Smith   PetscFunctionReturn(0);
291336db0b34SBarry Smith }
291436db0b34SBarry Smith 
2915cc8ba8e1SBarry Smith #undef __FUNCT__
2916ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2917ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2918cc8ba8e1SBarry Smith {
2919cc8ba8e1SBarry Smith   int        ierr;
2920cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
292136db0b34SBarry Smith 
2922cc8ba8e1SBarry Smith   PetscFunctionBegin;
292312c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2924cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2925cc8ba8e1SBarry Smith     a->coloring = coloring;
292612c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
292708b6dcc0SBarry Smith     int             i,*larray;
292812c595b3SBarry Smith     ISColoring      ocoloring;
292908b6dcc0SBarry Smith     ISColoringValue *colors;
293012c595b3SBarry Smith 
293112c595b3SBarry Smith     /* set coloring for diagonal portion */
293212c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
293312c595b3SBarry Smith     for (i=0; i<A->n; i++) {
293412c595b3SBarry Smith       larray[i] = i;
293512c595b3SBarry Smith     }
293612c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
293708b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
293812c595b3SBarry Smith     for (i=0; i<A->n; i++) {
293912c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
294012c595b3SBarry Smith     }
294112c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
294212c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
294312c595b3SBarry Smith     a->coloring = ocoloring;
294412c595b3SBarry Smith   }
2945cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
2946cc8ba8e1SBarry Smith }
2947cc8ba8e1SBarry Smith 
294887828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2949ee4f033dSBarry Smith EXTERN_C_BEGIN
295029c1e371SBarry Smith #include "adic/ad_utils.h"
2951ee4f033dSBarry Smith EXTERN_C_END
2952cc8ba8e1SBarry Smith 
2953cc8ba8e1SBarry Smith #undef __FUNCT__
2954ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
2955ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
2956cc8ba8e1SBarry Smith {
2957cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
295808b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
29594440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
296008b6dcc0SBarry Smith   ISColoringValue *color;
2961cc8ba8e1SBarry Smith 
2962cc8ba8e1SBarry Smith   PetscFunctionBegin;
2963cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
29644440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
2965cc8ba8e1SBarry Smith   color = a->coloring->colors;
2966cc8ba8e1SBarry Smith   /* loop over rows */
2967cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
2968cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
2969cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
2970cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
2971cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
2972cc8ba8e1SBarry Smith     }
29734440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
2974ee4f033dSBarry Smith   }
2975ee4f033dSBarry Smith   PetscFunctionReturn(0);
2976ee4f033dSBarry Smith }
2977ee4f033dSBarry Smith 
2978ee4f033dSBarry Smith #else
2979ee4f033dSBarry Smith 
2980ee4f033dSBarry Smith #undef __FUNCT__
2981ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
2982ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
2983ee4f033dSBarry Smith {
2984ee4f033dSBarry Smith   PetscFunctionBegin;
2985ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
2986ee4f033dSBarry Smith }
2987ee4f033dSBarry Smith 
2988ee4f033dSBarry Smith #endif
2989ee4f033dSBarry Smith 
2990ee4f033dSBarry Smith #undef __FUNCT__
2991ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
2992ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
2993ee4f033dSBarry Smith {
2994ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
299508b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
299687828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
299708b6dcc0SBarry Smith   ISColoringValue *color;
2998ee4f033dSBarry Smith 
2999ee4f033dSBarry Smith   PetscFunctionBegin;
3000ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3001ee4f033dSBarry Smith   color = a->coloring->colors;
3002ee4f033dSBarry Smith   /* loop over rows */
3003ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3004ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3005ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3006ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3007ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3008ee4f033dSBarry Smith     }
3009ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3010cc8ba8e1SBarry Smith   }
3011cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3012cc8ba8e1SBarry Smith }
301336db0b34SBarry Smith 
3014