xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 1d5dac46e5bf6fbea62f3101f11553ee697c545e)
1d5d45c9bSBarry Smith /*
23369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
3d5d45c9bSBarry Smith   matrix storage format.
4d5d45c9bSBarry Smith */
53369ce9aSBarry Smith 
69e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
7f5eb4b81SSatish Balay #include "src/inline/spops.h"
88d195f9aSBarry Smith #include "src/inline/dot.h"
90a835dfdSSatish Balay #include "petscbt.h"
1017ab2063SBarry Smith 
114a2ae208SSatish Balay #undef __FUNCT__
124a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
134e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done)
1417ab2063SBarry Smith {
15416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
166945ee14SBarry Smith   int        ierr,i,ishift;
1717ab2063SBarry Smith 
183a40ed3dSBarry Smith   PetscFunctionBegin;
1931625ec5SSatish Balay   *m     = A->m;
203a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
21bfeeae90SHong Zhang   ishift = 0;
2253e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
23273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
24bfeeae90SHong Zhang   } else if (oshift == 1) {
25435da068SBarry Smith     int nz = a->i[A->m];
263b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
271bc30dd5SBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
28b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
293b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
30273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
316945ee14SBarry Smith   } else {
326945ee14SBarry Smith     *ia = a->i; *ja = a->j;
33a2ce50c7SBarry Smith   }
343a40ed3dSBarry Smith   PetscFunctionReturn(0);
35a2744918SBarry Smith }
36a2744918SBarry Smith 
374a2ae208SSatish Balay #undef __FUNCT__
384a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
394e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
406945ee14SBarry Smith {
41bfeeae90SHong Zhang   int ierr;
426945ee14SBarry Smith 
433a40ed3dSBarry Smith   PetscFunctionBegin;
443a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
45bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
46606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
47606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
48bcd2baecSBarry Smith   }
493a40ed3dSBarry Smith   PetscFunctionReturn(0);
5017ab2063SBarry Smith }
5117ab2063SBarry Smith 
524a2ae208SSatish Balay #undef __FUNCT__
534a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
544e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
553b2fbd54SBarry Smith {
563b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
57bfeeae90SHong Zhang   int        ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m;
58bfeeae90SHong Zhang   int        nz = a->i[m],row,*jj,mr,col;
593b2fbd54SBarry Smith 
603a40ed3dSBarry Smith   PetscFunctionBegin;
613b2fbd54SBarry Smith   *nn     = A->n;
623a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
633b2fbd54SBarry Smith   if (symmetric) {
64bfeeae90SHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
653b2fbd54SBarry Smith   } else {
66b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr);
67549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
68b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr);
69b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr);
703b2fbd54SBarry Smith     jj = a->j;
713b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
72bfeeae90SHong Zhang       collengths[jj[i]]++;
733b2fbd54SBarry Smith     }
743b2fbd54SBarry Smith     cia[0] = oshift;
753b2fbd54SBarry Smith     for (i=0; i<n; i++) {
763b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
773b2fbd54SBarry Smith     }
78549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
793b2fbd54SBarry Smith     jj   = a->j;
80a93ec695SBarry Smith     for (row=0; row<m; row++) {
81a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
82a93ec695SBarry Smith       for (i=0; i<mr; i++) {
83bfeeae90SHong Zhang         col = *jj++;
843b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
853b2fbd54SBarry Smith       }
863b2fbd54SBarry Smith     }
87606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
883b2fbd54SBarry Smith     *ia = cia; *ja = cja;
893b2fbd54SBarry Smith   }
903a40ed3dSBarry Smith   PetscFunctionReturn(0);
913b2fbd54SBarry Smith }
923b2fbd54SBarry Smith 
934a2ae208SSatish Balay #undef __FUNCT__
944a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
954e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done)
963b2fbd54SBarry Smith {
97606d414cSSatish Balay   int ierr;
98606d414cSSatish Balay 
993a40ed3dSBarry Smith   PetscFunctionBegin;
1003a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1013b2fbd54SBarry Smith 
102606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
103606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1043b2fbd54SBarry Smith 
1053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1063b2fbd54SBarry Smith }
1073b2fbd54SBarry Smith 
108227d817aSBarry Smith #define CHUNKSIZE   15
10917ab2063SBarry Smith 
1104a2ae208SSatish Balay #undef __FUNCT__
1114a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
112f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11317ab2063SBarry Smith {
114416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
115416022c9SBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
116273d9f13SBarry Smith   int         *imax = a->imax,*ai = a->i,*ailen = a->ilen;
117bfeeae90SHong Zhang   int         *aj = a->j,nonew = a->nonew,ierr;
11887828ca2SBarry Smith   PetscScalar *ap,value,*aa = a->a;
11936db0b34SBarry Smith   PetscTruth  ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
120273d9f13SBarry Smith   PetscTruth  roworiented = a->roworiented;
12117ab2063SBarry Smith 
1223a40ed3dSBarry Smith   PetscFunctionBegin;
12317ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
124416022c9SBarry Smith     row  = im[k];
1255ef9f2a5SBarry Smith     if (row < 0) continue;
126aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
127590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
1283b2fbd54SBarry Smith #endif
129bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
13017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
131416022c9SBarry Smith     low = 0;
13217ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1335ef9f2a5SBarry Smith       if (in[l] < 0) continue;
134aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
135590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
1363b2fbd54SBarry Smith #endif
137bfeeae90SHong Zhang       col = in[l];
1384b0e389bSBarry Smith       if (roworiented) {
1395ef9f2a5SBarry Smith         value = v[l + k*n];
140bef8e0ddSBarry Smith       } else {
1414b0e389bSBarry Smith         value = v[k + l*m];
1424b0e389bSBarry Smith       }
14336db0b34SBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
14436db0b34SBarry Smith 
145416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
146416022c9SBarry Smith       while (high-low > 5) {
147416022c9SBarry Smith         t = (low+high)/2;
148416022c9SBarry Smith         if (rp[t] > col) high = t;
149416022c9SBarry Smith         else             low  = t;
15017ab2063SBarry Smith       }
151416022c9SBarry Smith       for (i=low; i<high; i++) {
15217ab2063SBarry Smith         if (rp[i] > col) break;
15317ab2063SBarry Smith         if (rp[i] == col) {
154416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
15517ab2063SBarry Smith           else                  ap[i] = value;
15617ab2063SBarry Smith           goto noinsert;
15717ab2063SBarry Smith         }
15817ab2063SBarry Smith       }
159c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
16029bbc08cSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
16117ab2063SBarry Smith       if (nrow >= rmax) {
16217ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
163a7ed9263SMatthew Knepley         int         new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j;
164a7ed9263SMatthew Knepley         size_t      len;
16587828ca2SBarry Smith         PetscScalar *new_a;
16617ab2063SBarry Smith 
16729bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
16896854ed6SLois Curfman McInnes 
16917ab2063SBarry Smith         /* malloc new storage space */
170a7ed9263SMatthew Knepley         len     = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
171b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
17217ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
17317ab2063SBarry Smith         new_i   = new_j + new_nz;
17417ab2063SBarry Smith 
17517ab2063SBarry Smith         /* copy over old data into new slots */
17617ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
177273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
178bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
179bfeeae90SHong Zhang         len  = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow );
180bfeeae90SHong Zhang         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
181bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr);
182bfeeae90SHong Zhang         ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
18317ab2063SBarry Smith         /* free up old matrix storage */
184606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
185606d414cSSatish Balay         if (!a->singlemalloc) {
186606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
187606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
188606d414cSSatish Balay         }
189416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
190f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
19117ab2063SBarry Smith 
192bfeeae90SHong Zhang         rp   = aj + ai[row]; ap = aa + ai[row] ;
193416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
19487828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
195416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
196b810aeb4SBarry Smith         a->reallocs++;
19717ab2063SBarry Smith       }
198416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
199416022c9SBarry Smith       /* shift up all the later entries in this row */
200416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
20117ab2063SBarry Smith         rp[ii+1] = rp[ii];
20217ab2063SBarry Smith         ap[ii+1] = ap[ii];
20317ab2063SBarry Smith       }
20417ab2063SBarry Smith       rp[i] = col;
20517ab2063SBarry Smith       ap[i] = value;
20617ab2063SBarry Smith       noinsert:;
207416022c9SBarry Smith       low = i + 1;
20817ab2063SBarry Smith     }
20917ab2063SBarry Smith     ailen[row] = nrow;
21017ab2063SBarry Smith   }
2113a40ed3dSBarry Smith   PetscFunctionReturn(0);
21217ab2063SBarry Smith }
21317ab2063SBarry Smith 
2144a2ae208SSatish Balay #undef __FUNCT__
2154a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
216f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
2177eb43aa7SLois Curfman McInnes {
2187eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
219b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
220bfeeae90SHong Zhang   int          *ai = a->i,*ailen = a->ilen;
22187828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2227eb43aa7SLois Curfman McInnes 
2233a40ed3dSBarry Smith   PetscFunctionBegin;
2247eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2257eb43aa7SLois Curfman McInnes     row  = im[k];
22629bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
227590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
228bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2297eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2307eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
23129bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
232590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
233bfeeae90SHong Zhang       col = in[l] ;
2347eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2357eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2367eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2377eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2387eb43aa7SLois Curfman McInnes         else             low  = t;
2397eb43aa7SLois Curfman McInnes       }
2407eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2417eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2427eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
243b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2447eb43aa7SLois Curfman McInnes           goto finished;
2457eb43aa7SLois Curfman McInnes         }
2467eb43aa7SLois Curfman McInnes       }
247b49de8d1SLois Curfman McInnes       *v++ = zero;
2487eb43aa7SLois Curfman McInnes       finished:;
2497eb43aa7SLois Curfman McInnes     }
2507eb43aa7SLois Curfman McInnes   }
2513a40ed3dSBarry Smith   PetscFunctionReturn(0);
2527eb43aa7SLois Curfman McInnes }
2537eb43aa7SLois Curfman McInnes 
25417ab2063SBarry Smith 
2554a2ae208SSatish Balay #undef __FUNCT__
2564a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
257b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
25817ab2063SBarry Smith {
259416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
260416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
26117ab2063SBarry Smith 
2623a40ed3dSBarry Smith   PetscFunctionBegin;
263b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
264b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
265552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
266273d9f13SBarry Smith   col_lens[1] = A->m;
267273d9f13SBarry Smith   col_lens[2] = A->n;
268416022c9SBarry Smith   col_lens[3] = a->nz;
269416022c9SBarry Smith 
270416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
271273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
272416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
27317ab2063SBarry Smith   }
274273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
275606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
276416022c9SBarry Smith 
277416022c9SBarry Smith   /* store column indices (zero start index) */
2780752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
279416022c9SBarry Smith 
280416022c9SBarry Smith   /* store nonzero values */
2810752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
2823a40ed3dSBarry Smith   PetscFunctionReturn(0);
28317ab2063SBarry Smith }
284416022c9SBarry Smith 
2854ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
286cd155464SBarry Smith 
2874a2ae208SSatish Balay #undef __FUNCT__
2884a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
289b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
290416022c9SBarry Smith {
291416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
292bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,shift=0;
293fb9695e5SSatish Balay   char              *name;
294f3ef73ceSBarry Smith   PetscViewerFormat format;
29517ab2063SBarry Smith 
2963a40ed3dSBarry Smith   PetscFunctionBegin;
297435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
298b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
299456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3006831982aSBarry Smith     if (a->inode.size) {
301b0a32e0cSBarry 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);
3026831982aSBarry Smith     } else {
303b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3046831982aSBarry Smith     }
305fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
306d00d2cf4SBarry Smith     int nofinalvalue = 0;
307273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
308d00d2cf4SBarry Smith       nofinalvalue = 1;
309d00d2cf4SBarry Smith     }
310b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
311b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
312b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
313b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
314b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
31517ab2063SBarry Smith 
31617ab2063SBarry Smith     for (i=0; i<m; i++) {
317416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
318aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
319b0a32e0cSBarry 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);
32017ab2063SBarry Smith #else
321b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
32217ab2063SBarry Smith #endif
32317ab2063SBarry Smith       }
32417ab2063SBarry Smith     }
325d00d2cf4SBarry Smith     if (nofinalvalue) {
326b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
327d00d2cf4SBarry Smith     }
328fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
329b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
330cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
331cd155464SBarry Smith      PetscFunctionReturn(0);
332fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
333b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
33444cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
335b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
33644cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
337aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
33836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
33962b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
34162b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34236db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
34362b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3446831982aSBarry Smith         }
34544cd7ae7SLois Curfman McInnes #else
34662b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
34744cd7ae7SLois Curfman McInnes #endif
34844cd7ae7SLois Curfman McInnes       }
349b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
35044cd7ae7SLois Curfman McInnes     }
351b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
352fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
353496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
354b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
355b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
356496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
357496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
358496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
359496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
360aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
36136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
362496be53dSLois Curfman McInnes #else
363496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
364496be53dSLois Curfman McInnes #endif
365496be53dSLois Curfman McInnes         }
366496be53dSLois Curfman McInnes       }
367496be53dSLois Curfman McInnes     }
3682e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
369b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
3702e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
371b0a32e0cSBarry 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);}
372b0a32e0cSBarry 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);}
373b0a32e0cSBarry 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);}
374b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
375b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
376b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
377496be53dSLois Curfman McInnes     }
378b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
379606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
380496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
381496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
382b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
383496be53dSLois Curfman McInnes       }
384b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
385496be53dSLois Curfman McInnes     }
386b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
387496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
388496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
389496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
390aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
392b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
3936831982aSBarry Smith           }
394496be53dSLois Curfman McInnes #else
395b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
396496be53dSLois Curfman McInnes #endif
397496be53dSLois Curfman McInnes         }
398496be53dSLois Curfman McInnes       }
399b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
400496be53dSLois Curfman McInnes     }
401b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
402fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
40302594712SBarry Smith     int         cnt = 0,jcnt;
40487828ca2SBarry Smith     PetscScalar value;
40502594712SBarry Smith 
406b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
40702594712SBarry Smith     for (i=0; i<m; i++) {
40802594712SBarry Smith       jcnt = 0;
409273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
410e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
41102594712SBarry Smith           value = a->a[cnt++];
412e24b481bSBarry Smith           jcnt++;
41302594712SBarry Smith         } else {
41402594712SBarry Smith           value = 0.0;
41502594712SBarry Smith         }
416aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
417b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
41802594712SBarry Smith #else
419b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
42002594712SBarry Smith #endif
42102594712SBarry Smith       }
422b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42302594712SBarry Smith     }
424b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4253a40ed3dSBarry Smith   } else {
426b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
42717ab2063SBarry Smith     for (i=0; i<m; i++) {
428b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
429416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
430aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
43136db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
43262b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
43336db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
43462b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4353a40ed3dSBarry Smith         } else {
43662b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
43717ab2063SBarry Smith         }
43817ab2063SBarry Smith #else
43962b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
44017ab2063SBarry Smith #endif
44117ab2063SBarry Smith       }
442b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44317ab2063SBarry Smith     }
444b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
44517ab2063SBarry Smith   }
446b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4473a40ed3dSBarry Smith   PetscFunctionReturn(0);
448416022c9SBarry Smith }
449416022c9SBarry Smith 
4504a2ae208SSatish Balay #undef __FUNCT__
4514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
452b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
453416022c9SBarry Smith {
454480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
455416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
456bfeeae90SHong Zhang   int               ierr,i,j,m = A->m,color;
45736db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
458b0a32e0cSBarry Smith   PetscViewer       viewer;
459f3ef73ceSBarry Smith   PetscViewerFormat format;
460cddf8d76SBarry Smith 
4613a40ed3dSBarry Smith   PetscFunctionBegin;
462480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
463b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
46419bcc07fSBarry Smith 
465b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
466416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4670513a670SBarry Smith 
468fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4690513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
470b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
471416022c9SBarry Smith     for (i=0; i<m; i++) {
472cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
473bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
474bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
475aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
47636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
477cddf8d76SBarry Smith #else
478cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
479cddf8d76SBarry Smith #endif
480b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
481cddf8d76SBarry Smith       }
482cddf8d76SBarry Smith     }
483b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
484cddf8d76SBarry Smith     for (i=0; i<m; i++) {
485cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
486bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
487bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
488cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
489b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
490cddf8d76SBarry Smith       }
491cddf8d76SBarry Smith     }
492b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
493cddf8d76SBarry Smith     for (i=0; i<m; i++) {
494cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
495bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
496bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
497aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
499cddf8d76SBarry Smith #else
500cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
501cddf8d76SBarry Smith #endif
502b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
503416022c9SBarry Smith       }
504416022c9SBarry Smith     }
5050513a670SBarry Smith   } else {
5060513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5070513a670SBarry Smith     /* first determine max of all nonzero values */
5080513a670SBarry Smith     int    nz = a->nz,count;
509b0a32e0cSBarry Smith     PetscDraw   popup;
51036db0b34SBarry Smith     PetscReal scale;
5110513a670SBarry Smith 
5120513a670SBarry Smith     for (i=0; i<nz; i++) {
5130513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5140513a670SBarry Smith     }
515b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
516b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
517b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5180513a670SBarry Smith     count = 0;
5190513a670SBarry Smith     for (i=0; i<m; i++) {
5200513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
521bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
522bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
523b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
524b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5250513a670SBarry Smith         count++;
5260513a670SBarry Smith       }
5270513a670SBarry Smith     }
5280513a670SBarry Smith   }
529480ef9eaSBarry Smith   PetscFunctionReturn(0);
530480ef9eaSBarry Smith }
531cddf8d76SBarry Smith 
5324a2ae208SSatish Balay #undef __FUNCT__
5334a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
534b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
535480ef9eaSBarry Smith {
536480ef9eaSBarry Smith   int        ierr;
537b0a32e0cSBarry Smith   PetscDraw  draw;
53836db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
539480ef9eaSBarry Smith   PetscTruth isnull;
540480ef9eaSBarry Smith 
541480ef9eaSBarry Smith   PetscFunctionBegin;
542b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
543b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
544480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
545480ef9eaSBarry Smith 
546480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
547273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
548480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
549b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
550b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
551480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5523a40ed3dSBarry Smith   PetscFunctionReturn(0);
553416022c9SBarry Smith }
554416022c9SBarry Smith 
5554a2ae208SSatish Balay #undef __FUNCT__
5564a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
557b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
558416022c9SBarry Smith {
559416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
560bcd2baecSBarry Smith   int         ierr;
5616831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
562416022c9SBarry Smith 
5633a40ed3dSBarry Smith   PetscFunctionBegin;
564b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
565b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
566fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
567fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5680f5bd95cSBarry Smith   if (issocket) {
569b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
5700f5bd95cSBarry Smith   } else if (isascii) {
5713a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5720f5bd95cSBarry Smith   } else if (isbinary) {
5733a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
5740f5bd95cSBarry Smith   } else if (isdraw) {
5753a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
5765cd90555SBarry Smith   } else {
57729bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
57817ab2063SBarry Smith   }
5793a40ed3dSBarry Smith   PetscFunctionReturn(0);
58017ab2063SBarry Smith }
58119bcc07fSBarry Smith 
5824a2ae208SSatish Balay #undef __FUNCT__
5834a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
5848f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
58517ab2063SBarry Smith {
586416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
58741c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
588bfeeae90SHong Zhang   int          m = A->m,*ip,N,*ailen = a->ilen,rmax = 0;
58987828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
59017ab2063SBarry Smith 
5913a40ed3dSBarry Smith   PetscFunctionBegin;
5923a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
59317ab2063SBarry Smith 
59443ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
59517ab2063SBarry Smith   for (i=1; i<m; i++) {
596416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
59717ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
59894a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
59917ab2063SBarry Smith     if (fshift) {
600bfeeae90SHong Zhang       ip = aj + ai[i] ;
601bfeeae90SHong Zhang       ap = aa + ai[i] ;
60217ab2063SBarry Smith       N  = ailen[i];
60317ab2063SBarry Smith       for (j=0; j<N; j++) {
60417ab2063SBarry Smith         ip[j-fshift] = ip[j];
60517ab2063SBarry Smith         ap[j-fshift] = ap[j];
60617ab2063SBarry Smith       }
60717ab2063SBarry Smith     }
60817ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
60917ab2063SBarry Smith   }
61017ab2063SBarry Smith   if (m) {
61117ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
61217ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
61317ab2063SBarry Smith   }
61417ab2063SBarry Smith   /* reset ilen and imax for each row */
61517ab2063SBarry Smith   for (i=0; i<m; i++) {
61617ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
61717ab2063SBarry Smith   }
618bfeeae90SHong Zhang   a->nz = ai[m];
61917ab2063SBarry Smith 
62017ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
621416022c9SBarry Smith   if (fshift && a->diag) {
622606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
623b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
624416022c9SBarry Smith     a->diag = 0;
62517ab2063SBarry Smith   }
626b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
627b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
628b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
629dd5f02e7SSatish Balay   a->reallocs          = 0;
6304e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
63136db0b34SBarry Smith   a->rmax              = rmax;
6324e220ebcSLois Curfman McInnes 
63376dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6343a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
635cfef3cccSHong Zhang 
6363a40ed3dSBarry Smith   PetscFunctionReturn(0);
63717ab2063SBarry Smith }
63817ab2063SBarry Smith 
6394a2ae208SSatish Balay #undef __FUNCT__
6404a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6418f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
64217ab2063SBarry Smith {
643416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
644549d3d68SSatish Balay   int        ierr;
6453a40ed3dSBarry Smith 
6463a40ed3dSBarry Smith   PetscFunctionBegin;
647bfeeae90SHong Zhang   ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
6483a40ed3dSBarry Smith   PetscFunctionReturn(0);
64917ab2063SBarry Smith }
650416022c9SBarry Smith 
6514a2ae208SSatish Balay #undef __FUNCT__
6524a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
653e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
65417ab2063SBarry Smith {
655416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
65682bf6240SBarry Smith   int        ierr;
657d5d45c9bSBarry Smith 
6583a40ed3dSBarry Smith   PetscFunctionBegin;
659aa482453SBarry Smith #if defined(PETSC_USE_LOG)
660b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
66117ab2063SBarry Smith #endif
66236db0b34SBarry Smith   if (a->freedata) {
663606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
664606d414cSSatish Balay     if (!a->singlemalloc) {
665606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
666606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
667606d414cSSatish Balay     }
66836db0b34SBarry Smith   }
669c38d4ed2SBarry Smith   if (a->row) {
670c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
671c38d4ed2SBarry Smith   }
672c38d4ed2SBarry Smith   if (a->col) {
673c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
674c38d4ed2SBarry Smith   }
675606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
676606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
677606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
678273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
679606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
680606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
68182bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
682606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
683cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
684a30b2313SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
685a30b2313SHong Zhang 
686606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
6873a40ed3dSBarry Smith   PetscFunctionReturn(0);
68817ab2063SBarry Smith }
68917ab2063SBarry Smith 
6904a2ae208SSatish Balay #undef __FUNCT__
6914a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
6928f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
69317ab2063SBarry Smith {
6943a40ed3dSBarry Smith   PetscFunctionBegin;
6953a40ed3dSBarry Smith   PetscFunctionReturn(0);
69617ab2063SBarry Smith }
69717ab2063SBarry Smith 
6984a2ae208SSatish Balay #undef __FUNCT__
6994a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7008f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
70117ab2063SBarry Smith {
702416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7033a40ed3dSBarry Smith 
7043a40ed3dSBarry Smith   PetscFunctionBegin;
705a65d3064SKris Buschelman   switch (op) {
706a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
707a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
708a65d3064SKris Buschelman       break;
709a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
710a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
711a65d3064SKris Buschelman       break;
712a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
713a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
714a65d3064SKris Buschelman       break;
715a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
716a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
717a65d3064SKris Buschelman       break;
718a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
719a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
720a65d3064SKris Buschelman       break;
721a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
722a65d3064SKris Buschelman       a->nonew             = 1;
723a65d3064SKris Buschelman       break;
724a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
725a65d3064SKris Buschelman       a->nonew             = -1;
726a65d3064SKris Buschelman       break;
727a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
728a65d3064SKris Buschelman       a->nonew             = -2;
729a65d3064SKris Buschelman       break;
730a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
731a65d3064SKris Buschelman       a->nonew             = 0;
732a65d3064SKris Buschelman       break;
733a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
734a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
735a65d3064SKris Buschelman       break;
736a65d3064SKris Buschelman     case MAT_USE_INODES:
737a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
738a65d3064SKris Buschelman       break;
739a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
740a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
741a65d3064SKris Buschelman       break;
742a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
743a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
744a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
745a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
746a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
747b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
748a65d3064SKris Buschelman       break;
749a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
75029bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
751a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
752a65d3064SKris Buschelman       a->inode.limit  = 1;
753a65d3064SKris Buschelman       break;
754a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
755a65d3064SKris Buschelman       a->inode.limit  = 2;
756a65d3064SKris Buschelman       break;
757a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
758a65d3064SKris Buschelman       a->inode.limit  = 3;
759a65d3064SKris Buschelman       break;
760a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
761a65d3064SKris Buschelman       a->inode.limit  = 4;
762a65d3064SKris Buschelman       break;
763a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
764a65d3064SKris Buschelman       a->inode.limit  = 5;
765a65d3064SKris Buschelman       break;
76677e54ba9SKris Buschelman     case MAT_SYMMETRIC:
76777e54ba9SKris Buschelman     case MAT_STRUCTURALLY_SYMMETRIC:
7689a4540c5SBarry Smith     case MAT_NOT_SYMMETRIC:
7699a4540c5SBarry Smith     case MAT_NOT_STRUCTURALLY_SYMMETRIC:
7709a4540c5SBarry Smith     case MAT_HERMITIAN:
7719a4540c5SBarry Smith     case MAT_NOT_HERMITIAN:
7729a4540c5SBarry Smith     case MAT_SYMMETRY_ETERNAL:
7739a4540c5SBarry Smith     case MAT_NOT_SYMMETRY_ETERNAL:
77477e54ba9SKris Buschelman       break;
775a65d3064SKris Buschelman     default:
776a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
777a65d3064SKris Buschelman   }
7783a40ed3dSBarry Smith   PetscFunctionReturn(0);
77917ab2063SBarry Smith }
78017ab2063SBarry Smith 
7814a2ae208SSatish Balay #undef __FUNCT__
7824a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
7838f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78417ab2063SBarry Smith {
785416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
786bfeeae90SHong Zhang   int          i,j,n,ierr;
78787828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
78817ab2063SBarry Smith 
7893a40ed3dSBarry Smith   PetscFunctionBegin;
7903a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
7911ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
79236db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
793273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
794273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
795bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
796bfeeae90SHong Zhang       if (a->j[j] == i) {
797416022c9SBarry Smith         x[i] = a->a[j];
79817ab2063SBarry Smith         break;
79917ab2063SBarry Smith       }
80017ab2063SBarry Smith     }
80117ab2063SBarry Smith   }
8021ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8033a40ed3dSBarry Smith   PetscFunctionReturn(0);
80417ab2063SBarry Smith }
80517ab2063SBarry Smith 
806d5d45c9bSBarry Smith 
8074a2ae208SSatish Balay #undef __FUNCT__
8084a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8097c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
81017ab2063SBarry Smith {
811416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8125c897100SBarry Smith   PetscScalar  *x,*y;
813bfeeae90SHong Zhang   int          ierr,m = A->m;
8145c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8155c897100SBarry Smith   PetscScalar  *v,alpha;
8165c897100SBarry Smith   int          n,i,*idx;
8175c897100SBarry Smith #endif
81817ab2063SBarry Smith 
8193a40ed3dSBarry Smith   PetscFunctionBegin;
8202e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
8211ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8221ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8235c897100SBarry Smith 
8245c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
825bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8265c897100SBarry Smith #else
82717ab2063SBarry Smith   for (i=0; i<m; i++) {
828bfeeae90SHong Zhang     idx   = a->j + a->i[i] ;
829bfeeae90SHong Zhang     v     = a->a + a->i[i] ;
830416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83117ab2063SBarry Smith     alpha = x[i];
83217ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83317ab2063SBarry Smith   }
8345c897100SBarry Smith #endif
835b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
8361ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8371ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8383a40ed3dSBarry Smith   PetscFunctionReturn(0);
83917ab2063SBarry Smith }
84017ab2063SBarry Smith 
8414a2ae208SSatish Balay #undef __FUNCT__
8425c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8435c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8445c897100SBarry Smith {
8458d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8465c897100SBarry Smith   int          ierr;
8475c897100SBarry Smith 
8485c897100SBarry Smith   PetscFunctionBegin;
8495c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8505c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8515c897100SBarry Smith   PetscFunctionReturn(0);
8525c897100SBarry Smith }
8535c897100SBarry Smith 
8545c897100SBarry Smith 
8555c897100SBarry Smith #undef __FUNCT__
8564a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
85744cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
85817ab2063SBarry Smith {
859416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
860362ced78SSatish Balay   PetscScalar  *x,*y,*v;
861bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
862aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
863e36a17ebSSatish Balay   int          n,i,jrow,j;
864362ced78SSatish Balay   PetscScalar  sum;
865e36a17ebSSatish Balay #endif
86617ab2063SBarry Smith 
867b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
868fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
869fee21e36SBarry Smith #endif
870fee21e36SBarry Smith 
8713a40ed3dSBarry Smith   PetscFunctionBegin;
8721ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8731ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
874416022c9SBarry Smith   idx  = a->j;
875d64ed03dSBarry Smith   v    = a->a;
876416022c9SBarry Smith   ii   = a->i;
877aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
878bfeeae90SHong Zhang   fortranmultaij_(&m,x,ii,idx,v,y);
8798d195f9aSBarry Smith #else
88017ab2063SBarry Smith   for (i=0; i<m; i++) {
8819ea0dfa2SSatish Balay     jrow = ii[i];
8829ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
88317ab2063SBarry Smith     sum  = 0.0;
8849ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
8859ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8869ea0dfa2SSatish Balay      }
88717ab2063SBarry Smith     y[i] = sum;
88817ab2063SBarry Smith   }
8898d195f9aSBarry Smith #endif
890b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
8911ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8921ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8933a40ed3dSBarry Smith   PetscFunctionReturn(0);
89417ab2063SBarry Smith }
89517ab2063SBarry Smith 
8964a2ae208SSatish Balay #undef __FUNCT__
8974a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
89844cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
89917ab2063SBarry Smith {
900416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
901362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
902bfeeae90SHong Zhang   int          ierr,m = A->m,*idx,*ii;
903aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
904e36a17ebSSatish Balay   int          n,i,jrow,j;
905362ced78SSatish Balay PetscScalar    sum;
906e36a17ebSSatish Balay #endif
9079ea0dfa2SSatish Balay 
9083a40ed3dSBarry Smith   PetscFunctionBegin;
9091ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9101ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9112e8a6d31SBarry Smith   if (zz != yy) {
9121ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9132e8a6d31SBarry Smith   } else {
9142e8a6d31SBarry Smith     z = y;
9152e8a6d31SBarry Smith   }
916bfeeae90SHong Zhang 
917cddf8d76SBarry Smith   idx  = a->j;
918d64ed03dSBarry Smith   v    = a->a;
919cddf8d76SBarry Smith   ii   = a->i;
920aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
921bfeeae90SHong Zhang   fortranmultaddaij_(&m,x,ii,idx,v,y,z);
92202ab625aSSatish Balay #else
92317ab2063SBarry Smith   for (i=0; i<m; i++) {
9249ea0dfa2SSatish Balay     jrow = ii[i];
9259ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
92617ab2063SBarry Smith     sum  = y[i];
9279ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9289ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9299ea0dfa2SSatish Balay      }
93017ab2063SBarry Smith     z[i] = sum;
93117ab2063SBarry Smith   }
93202ab625aSSatish Balay #endif
933b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
9341ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9351ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9362e8a6d31SBarry Smith   if (zz != yy) {
9371ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9382e8a6d31SBarry Smith   }
9393a40ed3dSBarry Smith   PetscFunctionReturn(0);
94017ab2063SBarry Smith }
94117ab2063SBarry Smith 
94217ab2063SBarry Smith /*
94317ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
94417ab2063SBarry Smith */
9454a2ae208SSatish Balay #undef __FUNCT__
9464a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
947f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
94817ab2063SBarry Smith {
949416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
950bfeeae90SHong Zhang   int        i,j,*diag,m = A->m,ierr;
95117ab2063SBarry Smith 
9523a40ed3dSBarry Smith   PetscFunctionBegin;
953f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
954f1e2ffcdSBarry Smith 
955b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
956b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
957273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
95835b0346bSBarry Smith     diag[i] = a->i[i+1];
959bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
960bfeeae90SHong Zhang       if (a->j[j] == i) {
961bfeeae90SHong Zhang         diag[i] = j;
96217ab2063SBarry Smith         break;
96317ab2063SBarry Smith       }
96417ab2063SBarry Smith     }
96517ab2063SBarry Smith   }
966416022c9SBarry Smith   a->diag = diag;
9673a40ed3dSBarry Smith   PetscFunctionReturn(0);
96817ab2063SBarry Smith }
96917ab2063SBarry Smith 
970be5855fcSBarry Smith /*
971be5855fcSBarry Smith      Checks for missing diagonals
972be5855fcSBarry Smith */
9734a2ae208SSatish Balay #undef __FUNCT__
9744a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
975f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
976be5855fcSBarry Smith {
977be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
978bfeeae90SHong Zhang   int        *diag,*jj = a->j,i,ierr;
979be5855fcSBarry Smith 
980be5855fcSBarry Smith   PetscFunctionBegin;
981f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
982f1e2ffcdSBarry Smith   diag = a->diag;
983273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
984bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
98529bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
986be5855fcSBarry Smith     }
987be5855fcSBarry Smith   }
988be5855fcSBarry Smith   PetscFunctionReturn(0);
989be5855fcSBarry Smith }
990be5855fcSBarry Smith 
9914a2ae208SSatish Balay #undef __FUNCT__
9924a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
993c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
99417ab2063SBarry Smith {
995416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
996beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
997beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
998beeb8507SBarry Smith   int                ierr,n = A->n,m = A->m,i;
999beeb8507SBarry Smith   const int          *idx,*diag;
100017ab2063SBarry Smith 
10013a40ed3dSBarry Smith   PetscFunctionBegin;
1002b965ef7fSBarry Smith   its = its*lits;
100391723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
100491723122SBarry Smith 
1005ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1006ed480e8bSBarry Smith   diag = a->diag;
1007ed480e8bSBarry Smith   if (!a->idiag) {
1008ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1009ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1010ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1011ed480e8bSBarry Smith 
1012ed480e8bSBarry Smith     v        = a->a;
1013ed480e8bSBarry Smith 
1014ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1015ed480e8bSBarry Smith     if (omega == 1.0 && fshift == 0.0) {
1016ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1017ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1018ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1019ed480e8bSBarry Smith       }
1020beeb8507SBarry Smith       PetscLogFlops(m);
1021ed480e8bSBarry Smith     } else {
1022ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1023ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1024beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1025ed480e8bSBarry Smith       }
1026beeb8507SBarry Smith       PetscLogFlops(2*m);
1027beeb8507SBarry Smith     }
1028ed480e8bSBarry Smith   }
1029ed480e8bSBarry Smith   t     = a->ssor;
1030ed480e8bSBarry Smith   idiag = a->idiag;
1031ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1032ed480e8bSBarry Smith 
10331ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1034fb2e594dSBarry Smith   if (xx != bb) {
10351ebc52fbSHong Zhang     ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1036fb2e594dSBarry Smith   } else {
1037fb2e594dSBarry Smith     b = x;
1038fb2e594dSBarry Smith   }
1039fb2e594dSBarry Smith 
1040ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1041ed480e8bSBarry Smith   xs   = x;
104217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
104317ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1044ed480e8bSBarry Smith     bs = b;
104517ab2063SBarry Smith     for (i=0; i<m; i++) {
1046ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1047416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1048ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1049ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
105017ab2063SBarry Smith         sum  = b[i]*d/omega;
105117ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
105217ab2063SBarry Smith         x[i] = sum;
105317ab2063SBarry Smith     }
10541ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10551ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1056ed480e8bSBarry Smith     PetscLogFlops(a->nz);
10573a40ed3dSBarry Smith     PetscFunctionReturn(0);
105817ab2063SBarry Smith   }
1059c783ea89SBarry Smith 
1060ed480e8bSBarry Smith 
1061fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1062fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1063fc3d8934SBarry Smith 
1064fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1065fc3d8934SBarry Smith 
1066fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1067fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
106848af12d7SBarry Smith     is the relaxation factor.
1069fc3d8934SBarry Smith     */
1070fc3d8934SBarry Smith 
107148af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
107229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
10733a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
107417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
107517ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
107617ab2063SBarry Smith 
107717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
107817ab2063SBarry Smith 
107917ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
108017ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
108117ab2063SBarry Smith     is the relaxation factor.
108217ab2063SBarry Smith     */
108317ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
108417ab2063SBarry Smith 
108517ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
108617ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1087416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1088ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1089ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
109017ab2063SBarry Smith       sum  = b[i];
109117ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1092ed480e8bSBarry Smith       x[i] = sum*idiag[i];
109317ab2063SBarry Smith     }
109417ab2063SBarry Smith 
109517ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1096416022c9SBarry Smith     v = a->a;
1097ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
109817ab2063SBarry Smith 
109917ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1100ed480e8bSBarry Smith     ts = t;
1101416022c9SBarry Smith     diag = a->diag;
110217ab2063SBarry Smith     for (i=0; i<m; i++) {
1103416022c9SBarry Smith       n    = diag[i] - a->i[i];
1104ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1105ed480e8bSBarry Smith       v    = a->a + a->i[i];
110617ab2063SBarry Smith       sum  = t[i];
110717ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1108ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1109733d66baSBarry Smith       /*  x = x + t */
1110733d66baSBarry Smith       x[i] += t[i];
111117ab2063SBarry Smith     }
111217ab2063SBarry Smith 
1113b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
11141ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11151ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11163a40ed3dSBarry Smith     PetscFunctionReturn(0);
111717ab2063SBarry Smith   }
111817ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
111917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
112077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11210c559628SSatish Balay       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b);
112277d8c4bbSBarry Smith #else
112317ab2063SBarry Smith       for (i=0; i<m; i++) {
1124416022c9SBarry Smith         n    = diag[i] - a->i[i];
1125ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1126ed480e8bSBarry Smith         v    = a->a + a->i[i];
112717ab2063SBarry Smith         sum  = b[i];
112817ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1129ed480e8bSBarry Smith         x[i] = sum*idiag[i];
113017ab2063SBarry Smith       }
113177d8c4bbSBarry Smith #endif
113217ab2063SBarry Smith       xb = x;
1133ed480e8bSBarry Smith       PetscLogFlops(a->nz);
11343a40ed3dSBarry Smith     } else xb = b;
113517ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
113617ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
113717ab2063SBarry Smith       for (i=0; i<m; i++) {
1138ed480e8bSBarry Smith         x[i] *= mdiag[i];
113917ab2063SBarry Smith       }
1140b0a32e0cSBarry Smith       PetscLogFlops(m);
114117ab2063SBarry Smith     }
114217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
114377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11440c559628SSatish Balay       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb);
114577d8c4bbSBarry Smith #else
114617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1147416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1148ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1149ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
115017ab2063SBarry Smith         sum  = xb[i];
115117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1152ed480e8bSBarry Smith         x[i] = sum*idiag[i];
115317ab2063SBarry Smith       }
115477d8c4bbSBarry Smith #endif
1155ed480e8bSBarry Smith       PetscLogFlops(a->nz);
115617ab2063SBarry Smith     }
115717ab2063SBarry Smith     its--;
115817ab2063SBarry Smith   }
115917ab2063SBarry Smith   while (its--) {
116017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
116177d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11620c559628SSatish Balay       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
116377d8c4bbSBarry Smith #else
116417ab2063SBarry Smith       for (i=0; i<m; i++) {
1165ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1166416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1167ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1168ed480e8bSBarry Smith         v    = a->a + a->i[i];
116917ab2063SBarry Smith         sum  = b[i];
117017ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1171ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
117217ab2063SBarry Smith       }
117377d8c4bbSBarry Smith #endif
1174ed480e8bSBarry Smith       PetscLogFlops(a->nz);
117517ab2063SBarry Smith     }
117617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
117777d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
11780c559628SSatish Balay       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b);
117977d8c4bbSBarry Smith #else
118017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1181ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1182416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1183ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1184ed480e8bSBarry Smith         v    = a->a + a->i[i];
118517ab2063SBarry Smith         sum  = b[i];
118617ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1187ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
118817ab2063SBarry Smith       }
118977d8c4bbSBarry Smith #endif
1190ed480e8bSBarry Smith       PetscLogFlops(a->nz);
119117ab2063SBarry Smith     }
119217ab2063SBarry Smith   }
11931ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11941ebc52fbSHong Zhang   if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11953a40ed3dSBarry Smith   PetscFunctionReturn(0);
119617ab2063SBarry Smith }
119717ab2063SBarry Smith 
11984a2ae208SSatish Balay #undef __FUNCT__
11994a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12008f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
120117ab2063SBarry Smith {
1202416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12034e220ebcSLois Curfman McInnes 
12043a40ed3dSBarry Smith   PetscFunctionBegin;
1205273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1206273d9f13SBarry Smith   info->columns_global = (double)A->n;
1207273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1208273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12094e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12104e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12114e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12124e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12134e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12144e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12154e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12164e220ebcSLois Curfman McInnes   if (A->factor) {
12174e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12184e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12194e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12204e220ebcSLois Curfman McInnes   } else {
12214e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12224e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12234e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12244e220ebcSLois Curfman McInnes   }
12253a40ed3dSBarry Smith   PetscFunctionReturn(0);
122617ab2063SBarry Smith }
122717ab2063SBarry Smith 
12284a2ae208SSatish Balay #undef __FUNCT__
12294a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1230268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag)
123117ab2063SBarry Smith {
1232416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1233bfeeae90SHong Zhang   int         i,ierr,N,*rows,m = A->m - 1;
123417ab2063SBarry Smith 
12353a40ed3dSBarry Smith   PetscFunctionBegin;
1236b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
123717ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1238f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1239f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1240a45adfd6SMatthew Knepley       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1241bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1242f1e2ffcdSBarry Smith     }
1243f1e2ffcdSBarry Smith     if (diag) {
1244f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1245f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1246f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1247f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1248f1e2ffcdSBarry Smith       }
1249f1e2ffcdSBarry Smith     }
1250f1e2ffcdSBarry Smith   } else {
125117ab2063SBarry Smith     if (diag) {
125217ab2063SBarry Smith       for (i=0; i<N; i++) {
1253a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
12547ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1255416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1256bfeeae90SHong Zhang           a->a[a->i[rows[i]]] = *diag;
1257bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
12587ae801bdSBarry Smith         } else { /* in case row was completely empty */
1259d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126017ab2063SBarry Smith         }
126117ab2063SBarry Smith       }
12623a40ed3dSBarry Smith     } else {
126317ab2063SBarry Smith       for (i=0; i<N; i++) {
1264a45adfd6SMatthew Knepley         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range", rows[i]);
1265416022c9SBarry Smith         a->ilen[rows[i]] = 0;
126617ab2063SBarry Smith       }
126717ab2063SBarry Smith     }
1268f1e2ffcdSBarry Smith   }
12697ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12713a40ed3dSBarry Smith   PetscFunctionReturn(0);
127217ab2063SBarry Smith }
127317ab2063SBarry Smith 
12744a2ae208SSatish Balay #undef __FUNCT__
12754a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
127687828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
127717ab2063SBarry Smith {
1278416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1279b3fb0a6cSMatthew Knepley   int        *itmp;
128017ab2063SBarry Smith 
12813a40ed3dSBarry Smith   PetscFunctionBegin;
1282273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
128317ab2063SBarry Smith 
1284416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1285bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
128617ab2063SBarry Smith   if (idx) {
1287bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1288bfeeae90SHong Zhang     if (*nz) {
12894e093b46SBarry Smith       *idx = itmp;
129017ab2063SBarry Smith     }
129117ab2063SBarry Smith     else *idx = 0;
129217ab2063SBarry Smith   }
12933a40ed3dSBarry Smith   PetscFunctionReturn(0);
129417ab2063SBarry Smith }
129517ab2063SBarry Smith 
1296bfeeae90SHong Zhang /* remove this function? */
12974a2ae208SSatish Balay #undef __FUNCT__
12984a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
129987828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
130017ab2063SBarry Smith {
1301bfeeae90SHong Zhang   /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1302bfeeae90SHong Zhang      int ierr; */
13033a40ed3dSBarry Smith 
13043a40ed3dSBarry Smith   PetscFunctionBegin;
1305bfeeae90SHong Zhang   /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */
13063a40ed3dSBarry Smith   PetscFunctionReturn(0);
130717ab2063SBarry Smith }
130817ab2063SBarry Smith 
13094a2ae208SSatish Balay #undef __FUNCT__
13104a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1311064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
131217ab2063SBarry Smith {
1313416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
131487828ca2SBarry Smith   PetscScalar  *v = a->a;
131536db0b34SBarry Smith   PetscReal    sum = 0.0;
1316bfeeae90SHong Zhang   int          i,j,ierr;
131717ab2063SBarry Smith 
13183a40ed3dSBarry Smith   PetscFunctionBegin;
131917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1320416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1321aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
132236db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
132317ab2063SBarry Smith #else
132417ab2063SBarry Smith       sum += (*v)*(*v); v++;
132517ab2063SBarry Smith #endif
132617ab2063SBarry Smith     }
1327064f8208SBarry Smith     *nrm = sqrt(sum);
13283a40ed3dSBarry Smith   } else if (type == NORM_1) {
132936db0b34SBarry Smith     PetscReal *tmp;
1330416022c9SBarry Smith     int    *jj = a->j;
1331b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1332273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1333064f8208SBarry Smith     *nrm = 0.0;
1334416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1335bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
133617ab2063SBarry Smith     }
1337273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1338064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
133917ab2063SBarry Smith     }
1340606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13413a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1342064f8208SBarry Smith     *nrm = 0.0;
1343273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1344bfeeae90SHong Zhang       v = a->a + a->i[j];
134517ab2063SBarry Smith       sum = 0.0;
1346416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1347cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
134817ab2063SBarry Smith       }
1349064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
135017ab2063SBarry Smith     }
13513a40ed3dSBarry Smith   } else {
135229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
135317ab2063SBarry Smith   }
13543a40ed3dSBarry Smith   PetscFunctionReturn(0);
135517ab2063SBarry Smith }
135617ab2063SBarry Smith 
13574a2ae208SSatish Balay #undef __FUNCT__
13584a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
13598f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
136017ab2063SBarry Smith {
1361416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1362416022c9SBarry Smith   Mat          C;
1363273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
136487828ca2SBarry Smith   PetscScalar  *array = a->a;
136517ab2063SBarry Smith 
13663a40ed3dSBarry Smith   PetscFunctionBegin;
1367273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1368b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1369273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
1370bfeeae90SHong Zhang 
1371bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1372f204ca49SKris Buschelman   ierr = MatCreate(A->comm,A->n,m,A->n,m,&C);CHKERRQ(ierr);
1373f204ca49SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1374f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(C,0,col);CHKERRQ(ierr);
1375606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
137617ab2063SBarry Smith   for (i=0; i<m; i++) {
137717ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1378416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1379b9b97703SBarry Smith     array += len;
1380b9b97703SBarry Smith     aj    += len;
138117ab2063SBarry Smith   }
138217ab2063SBarry Smith 
13836d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13846d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
138517ab2063SBarry Smith 
1386f1e2ffcdSBarry Smith   if (B) {
1387416022c9SBarry Smith     *B = C;
138817ab2063SBarry Smith   } else {
1389273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
139017ab2063SBarry Smith   }
13913a40ed3dSBarry Smith   PetscFunctionReturn(0);
139217ab2063SBarry Smith }
139317ab2063SBarry Smith 
1394cd0d46ebSvictorle EXTERN_C_BEGIN
1395cd0d46ebSvictorle #undef __FUNCT__
13965fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
13975fbd3699SBarry Smith int MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscTruth *f)
1398cd0d46ebSvictorle {
1399cd0d46ebSvictorle   Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
1400cd0d46ebSvictorle   int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
1401cd0d46ebSvictorle   int ma,na,mb,nb, i,ierr;
1402cd0d46ebSvictorle 
1403cd0d46ebSvictorle   PetscFunctionBegin;
1404cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1405cd0d46ebSvictorle 
1406cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1407cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
1408cd0d46ebSvictorle   if (ma!=nb || na!=mb)
1409cd0d46ebSvictorle     SETERRQ(1,"Incompatible A/B sizes for symmetry test");
1410cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1411cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1412cd0d46ebSvictorle   va = aij->a; vb = bij->a;
1413cd0d46ebSvictorle   ierr = PetscMalloc(ma*sizeof(int),&aptr);CHKERRQ(ierr);
1414cd0d46ebSvictorle   ierr = PetscMalloc(mb*sizeof(int),&bptr);CHKERRQ(ierr);
1415cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1416cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1417cd0d46ebSvictorle 
1418cd0d46ebSvictorle   *f = PETSC_TRUE;
1419cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1420cd0d46ebSvictorle     /*printf("row %d spans %d--%d; we start @ %d\n",
1421cd0d46ebSvictorle       i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/
1422cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
1423cd0d46ebSvictorle       int idc,idr; PetscScalar vc,vr;
1424cd0d46ebSvictorle       /* column/row index/value */
1425cd0d46ebSvictorle       idc = adx[aptr[i]]; idr = bdx[bptr[idc]];
1426cd0d46ebSvictorle       vc = va[aptr[i]]; vr = vb[bptr[idc]];
1427cd0d46ebSvictorle       /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n",
1428cd0d46ebSvictorle 	aptr[i],i,idc,vc,idc,idr,vr);*/
1429cd0d46ebSvictorle       if (i!=idr || vc!=vr) {
1430cd0d46ebSvictorle 	*f = PETSC_FALSE; goto done;
1431cd0d46ebSvictorle       } else {
14323aeef889SHong Zhang 	aptr[i]++; if (B || i!=idc) bptr[idc]++;
1433cd0d46ebSvictorle       }
1434cd0d46ebSvictorle     }
1435cd0d46ebSvictorle   }
1436cd0d46ebSvictorle  done:
1437cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
14383aeef889SHong Zhang   if (B) {
14393aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
14403aeef889SHong Zhang   }
1441cd0d46ebSvictorle 
1442cd0d46ebSvictorle   PetscFunctionReturn(0);
1443cd0d46ebSvictorle }
1444cd0d46ebSvictorle EXTERN_C_END
1445cd0d46ebSvictorle 
14469e29f15eSvictorle #undef __FUNCT__
14479e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
14489e29f15eSvictorle int MatIsSymmetric_SeqAIJ(Mat A,PetscTruth *f)
14499e29f15eSvictorle {
1450dee28dbaSBarry Smith   int ierr;
14519e29f15eSvictorle   PetscFunctionBegin;
14529e29f15eSvictorle   ierr = MatIsTranspose_SeqAIJ(A,A,f);CHKERRQ(ierr);
14539e29f15eSvictorle   PetscFunctionReturn(0);
14549e29f15eSvictorle }
14559e29f15eSvictorle 
14564a2ae208SSatish Balay #undef __FUNCT__
14574a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14588f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
145917ab2063SBarry Smith {
1460416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
146187828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1462bfeeae90SHong Zhang   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
146317ab2063SBarry Smith 
14643a40ed3dSBarry Smith   PetscFunctionBegin;
146517ab2063SBarry Smith   if (ll) {
14663ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14673ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1468e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1469273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
14701ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1471416022c9SBarry Smith     v = a->a;
147217ab2063SBarry Smith     for (i=0; i<m; i++) {
147317ab2063SBarry Smith       x = l[i];
1474416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
147517ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
147617ab2063SBarry Smith     }
14771ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1478b0a32e0cSBarry Smith     PetscLogFlops(nz);
147917ab2063SBarry Smith   }
148017ab2063SBarry Smith   if (rr) {
1481e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1482273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
14831ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1484416022c9SBarry Smith     v = a->a; jj = a->j;
148517ab2063SBarry Smith     for (i=0; i<nz; i++) {
1486bfeeae90SHong Zhang       (*v++) *= r[*jj++];
148717ab2063SBarry Smith     }
14881ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1489b0a32e0cSBarry Smith     PetscLogFlops(nz);
149017ab2063SBarry Smith   }
14913a40ed3dSBarry Smith   PetscFunctionReturn(0);
149217ab2063SBarry Smith }
149317ab2063SBarry Smith 
14944a2ae208SSatish Balay #undef __FUNCT__
14954a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
14967b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
149717ab2063SBarry Smith {
1498db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1499273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
150036db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
1501bfeeae90SHong Zhang   int          *irow,*icol,nrows,ncols;
150299141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
150387828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1504416022c9SBarry Smith   Mat          C;
1505fee21e36SBarry Smith   PetscTruth   stride;
150617ab2063SBarry Smith 
15073a40ed3dSBarry Smith   PetscFunctionBegin;
1508d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
150929bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1510d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
151129bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
151299141d43SSatish Balay 
151317ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1514b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1515b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
151617ab2063SBarry Smith 
1517fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1518fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1519fee21e36SBarry Smith   if (stride && step == 1) {
152002834360SBarry Smith     /* special case of contiguous rows */
152131ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
152231ebf83bSSatish Balay     starts = lens + nrows;
152302834360SBarry Smith     /* loop over new rows determining lens and starting points */
152402834360SBarry Smith     for (i=0; i<nrows; i++) {
1525bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1526a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
152702834360SBarry Smith       for (k=kstart; k<kend; k++) {
1528bfeeae90SHong Zhang         if (aj[k] >= first) {
152902834360SBarry Smith           starts[i] = k;
153002834360SBarry Smith           break;
153102834360SBarry Smith 	}
153202834360SBarry Smith       }
1533a2744918SBarry Smith       sum = 0;
153402834360SBarry Smith       while (k < kend) {
1535bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1536a2744918SBarry Smith         sum++;
153702834360SBarry Smith       }
1538a2744918SBarry Smith       lens[i] = sum;
153902834360SBarry Smith     }
154002834360SBarry Smith     /* create submatrix */
1541cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
154208480c60SBarry Smith       int n_cols,n_rows;
154308480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
154429bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1545d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
154608480c60SBarry Smith       C = *B;
15473a40ed3dSBarry Smith     } else {
1548e2d9671bSKris Buschelman       ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr);
1549e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1550e2d9671bSKris Buschelman       ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr);
155108480c60SBarry Smith     }
1552db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1553db02288aSLois Curfman McInnes 
155402834360SBarry Smith     /* loop over rows inserting into submatrix */
1555db02288aSLois Curfman McInnes     a_new    = c->a;
1556db02288aSLois Curfman McInnes     j_new    = c->j;
1557db02288aSLois Curfman McInnes     i_new    = c->i;
1558bfeeae90SHong Zhang 
155902834360SBarry Smith     for (i=0; i<nrows; i++) {
1560a2744918SBarry Smith       ii    = starts[i];
1561a2744918SBarry Smith       lensi = lens[i];
1562a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1563a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
156402834360SBarry Smith       }
156587828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1566a2744918SBarry Smith       a_new      += lensi;
1567a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1568a2744918SBarry Smith       c->ilen[i]  = lensi;
156902834360SBarry Smith     }
1570606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15713a40ed3dSBarry Smith   } else {
157202834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1573b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
1574bfeeae90SHong Zhang 
1575b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1576549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
157717ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
157802834360SBarry Smith     /* determine lens of each row */
157902834360SBarry Smith     for (i=0; i<nrows; i++) {
1580bfeeae90SHong Zhang       kstart  = ai[irow[i]];
158102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
158202834360SBarry Smith       lens[i] = 0;
158302834360SBarry Smith       for (k=kstart; k<kend; k++) {
1584bfeeae90SHong Zhang         if (smap[aj[k]]) {
158502834360SBarry Smith           lens[i]++;
158602834360SBarry Smith         }
158702834360SBarry Smith       }
158802834360SBarry Smith     }
158917ab2063SBarry Smith     /* Create and fill new matrix */
1590a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15910f5bd95cSBarry Smith       PetscTruth equal;
15920f5bd95cSBarry Smith 
159399141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1594273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1595273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
15960f5bd95cSBarry Smith       if (!equal) {
159729bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
159899141d43SSatish Balay       }
1599273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
160008480c60SBarry Smith       C = *B;
16013a40ed3dSBarry Smith     } else {
1602e2d9671bSKris Buschelman       ierr = MatCreate(A->comm,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE,&C);CHKERRQ(ierr);
1603e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1604e2d9671bSKris Buschelman       ierr = MatSeqAIJSetPreallocation(C,0,lens);CHKERRQ(ierr);
160508480c60SBarry Smith     }
160699141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
160717ab2063SBarry Smith     for (i=0; i<nrows; i++) {
160899141d43SSatish Balay       row    = irow[i];
1609bfeeae90SHong Zhang       kstart = ai[row];
161099141d43SSatish Balay       kend   = kstart + a->ilen[row];
1611bfeeae90SHong Zhang       mat_i  = c->i[i];
161299141d43SSatish Balay       mat_j  = c->j + mat_i;
161399141d43SSatish Balay       mat_a  = c->a + mat_i;
161499141d43SSatish Balay       mat_ilen = c->ilen + i;
161517ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1616bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1617ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
161899141d43SSatish Balay           *mat_a++ = a->a[k];
161999141d43SSatish Balay           (*mat_ilen)++;
162099141d43SSatish Balay 
162117ab2063SBarry Smith         }
162217ab2063SBarry Smith       }
162317ab2063SBarry Smith     }
162402834360SBarry Smith     /* Free work space */
162502834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1626606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1627606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
162802834360SBarry Smith   }
16296d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16306d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163117ab2063SBarry Smith 
163217ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1633416022c9SBarry Smith   *B = C;
16343a40ed3dSBarry Smith   PetscFunctionReturn(0);
163517ab2063SBarry Smith }
163617ab2063SBarry Smith 
1637a871dcd8SBarry Smith /*
1638a871dcd8SBarry Smith */
16394a2ae208SSatish Balay #undef __FUNCT__
16404a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1641b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1642a871dcd8SBarry Smith {
164363b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
164408480c60SBarry Smith   int        ierr;
164563b91edcSBarry Smith   Mat        outA;
1646b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
164763b91edcSBarry Smith 
16483a40ed3dSBarry Smith   PetscFunctionBegin;
1649d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1650b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1651b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1652b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
165329bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1654b8a78c4aSBarry Smith   }
1655a871dcd8SBarry Smith 
165663b91edcSBarry Smith   outA          = inA;
165763b91edcSBarry Smith   inA->factor   = FACTOR_LU;
165863b91edcSBarry Smith   a->row        = row;
165963b91edcSBarry Smith   a->col        = col;
1660c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1661c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
166263b91edcSBarry Smith 
166336db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1664b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16654c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1666b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1667f0ec6fceSSatish Balay 
166894a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
166987828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
167094a9d846SBarry Smith   }
167163b91edcSBarry Smith 
167208480c60SBarry Smith   if (!a->diag) {
1673f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
167463b91edcSBarry Smith   }
167563b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16763a40ed3dSBarry Smith   PetscFunctionReturn(0);
1677a871dcd8SBarry Smith }
1678a871dcd8SBarry Smith 
1679d9eff348SSatish Balay #include "petscblaslapack.h"
16804a2ae208SSatish Balay #undef __FUNCT__
16814a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1682268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA)
1683f0b747eeSBarry Smith {
1684f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1685f0b747eeSBarry Smith   int        one = 1;
16863a40ed3dSBarry Smith 
16873a40ed3dSBarry Smith   PetscFunctionBegin;
1688268466fbSBarry Smith   BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one);
1689b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
16903a40ed3dSBarry Smith   PetscFunctionReturn(0);
1691f0b747eeSBarry Smith }
1692f0b747eeSBarry Smith 
16934a2ae208SSatish Balay #undef __FUNCT__
16944a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
1695268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1696cddf8d76SBarry Smith {
1697cddf8d76SBarry Smith   int        ierr,i;
1698cddf8d76SBarry Smith 
16993a40ed3dSBarry Smith   PetscFunctionBegin;
1700cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1701b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1702cddf8d76SBarry Smith   }
1703cddf8d76SBarry Smith 
1704cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17056a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1706cddf8d76SBarry Smith   }
17073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1708cddf8d76SBarry Smith }
1709cddf8d76SBarry Smith 
17104a2ae208SSatish Balay #undef __FUNCT__
17114a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17128f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17135a838052SSatish Balay {
1714f830108cSBarry Smith   PetscFunctionBegin;
17155a838052SSatish Balay   *bs = 1;
17163a40ed3dSBarry Smith   PetscFunctionReturn(0);
17175a838052SSatish Balay }
17185a838052SSatish Balay 
17194a2ae208SSatish Balay #undef __FUNCT__
17204a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
1721268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov)
17224dcbc457SBarry Smith {
1723e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1724efb16452SHong Zhang   int        row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17258a047759SSatish Balay   int        start,end,*ai,*aj;
1726f1af5d2fSBarry Smith   PetscBT    table;
1727bbd702dbSSatish Balay 
17283a40ed3dSBarry Smith   PetscFunctionBegin;
1729273d9f13SBarry Smith   m     = A->m;
1730e4d965acSSatish Balay   ai    = a->i;
1731bfeeae90SHong Zhang   aj    = a->j;
17328a047759SSatish Balay 
1733a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
173406763907SSatish Balay 
1735b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17366831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
173706763907SSatish Balay 
1738e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1739b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1740e4d965acSSatish Balay     isz  = 0;
17416831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1742e4d965acSSatish Balay 
1743e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17444dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1745b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1746e4d965acSSatish Balay 
1747dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1748e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1749f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17504dcbc457SBarry Smith     }
175106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
175206763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1753e4d965acSSatish Balay 
175404a348a9SBarry Smith     k = 0;
175504a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
175604a348a9SBarry Smith       n = isz;
175706763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1758e4d965acSSatish Balay         row   = nidx[k];
1759e4d965acSSatish Balay         start = ai[row];
1760e4d965acSSatish Balay         end   = ai[row+1];
176104a348a9SBarry Smith         for (l = start; l<end ; l++){
1762efb16452SHong Zhang           val = aj[l] ;
1763f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1764e4d965acSSatish Balay         }
1765e4d965acSSatish Balay       }
1766e4d965acSSatish Balay     }
1767029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1768e4d965acSSatish Balay   }
17696831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1770606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17713a40ed3dSBarry Smith   PetscFunctionReturn(0);
17724dcbc457SBarry Smith }
177317ab2063SBarry Smith 
17740513a670SBarry Smith /* -------------------------------------------------------------- */
17754a2ae208SSatish Balay #undef __FUNCT__
17764a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17770513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
17780513a670SBarry Smith {
17790513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
178087828ca2SBarry Smith   PetscScalar  *vwork;
1781273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
17820513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
178356cd22aeSBarry Smith   IS           icolp,irowp;
17840513a670SBarry Smith 
17853a40ed3dSBarry Smith   PetscFunctionBegin;
17864c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
178756cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
17884c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
178956cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17900513a670SBarry Smith 
17910513a670SBarry Smith   /* determine lengths of permuted rows */
1792b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
17930513a670SBarry Smith   for (i=0; i<m; i++) {
17940513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
17950513a670SBarry Smith   }
1796f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,B);CHKERRQ(ierr);
1797f204ca49SKris Buschelman   ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr);
1798f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(*B,0,lens);CHKERRQ(ierr);
1799606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18000513a670SBarry Smith 
1801b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18020513a670SBarry Smith   for (i=0; i<m; i++) {
18030513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18040513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18050513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18060513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18070513a670SBarry Smith   }
1808606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18090513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18100513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
181156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
181256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
181356cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
181456cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18153a40ed3dSBarry Smith   PetscFunctionReturn(0);
18160513a670SBarry Smith }
18170513a670SBarry Smith 
18184a2ae208SSatish Balay #undef __FUNCT__
18194a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1820682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1821682d7d0cSBarry Smith {
1822c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1823682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1824d132466eSBarry Smith   int               ierr;
1825682d7d0cSBarry Smith 
18263a40ed3dSBarry Smith   PetscFunctionBegin;
1827c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1828d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1829d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1830d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1831d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1832d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
18333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1834682d7d0cSBarry Smith }
183597304618SKris Buschelman 
18364a2ae208SSatish Balay #undef __FUNCT__
18374a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1838cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1839cb5b572fSBarry Smith {
1840be6bf707SBarry Smith   int        ierr;
1841cb5b572fSBarry Smith 
1842cb5b572fSBarry Smith   PetscFunctionBegin;
184333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
184433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1845be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1846be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1847be6bf707SBarry Smith 
1848bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
184929bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1850cb5b572fSBarry Smith     }
1851bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1852cb5b572fSBarry Smith   } else {
1853cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1854cb5b572fSBarry Smith   }
1855cb5b572fSBarry Smith   PetscFunctionReturn(0);
1856cb5b572fSBarry Smith }
1857cb5b572fSBarry Smith 
18584a2ae208SSatish Balay #undef __FUNCT__
18594a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1860273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1861273d9f13SBarry Smith {
1862273d9f13SBarry Smith   int        ierr;
1863273d9f13SBarry Smith 
1864273d9f13SBarry Smith   PetscFunctionBegin;
1865273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1866273d9f13SBarry Smith   PetscFunctionReturn(0);
1867273d9f13SBarry Smith }
1868273d9f13SBarry Smith 
18694a2ae208SSatish Balay #undef __FUNCT__
18704a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
18714e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
18726c0721eeSBarry Smith {
18736c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18746c0721eeSBarry Smith   PetscFunctionBegin;
18756c0721eeSBarry Smith   *array = a->a;
18766c0721eeSBarry Smith   PetscFunctionReturn(0);
18776c0721eeSBarry Smith }
18786c0721eeSBarry Smith 
18794a2ae208SSatish Balay #undef __FUNCT__
18804a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
18814e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
18826c0721eeSBarry Smith {
18836c0721eeSBarry Smith   PetscFunctionBegin;
18846c0721eeSBarry Smith   PetscFunctionReturn(0);
18856c0721eeSBarry Smith }
1886273d9f13SBarry Smith 
1887ee4f033dSBarry Smith #undef __FUNCT__
1888ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1889ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1890ee4f033dSBarry Smith {
1891ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1892ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
189387828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
189487828ca2SBarry Smith   PetscScalar   *vscale_array;
1895ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1896ee4f033dSBarry Smith   Vec           w1,w2,w3;
1897ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1898ee4f033dSBarry Smith   PetscTruth    flg;
1899ee4f033dSBarry Smith 
1900ee4f033dSBarry Smith   PetscFunctionBegin;
1901ee4f033dSBarry Smith   if (!coloring->w1) {
1902ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1903ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1904ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1905ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1906ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1907ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1908ee4f033dSBarry Smith   }
1909ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1910ee4f033dSBarry Smith 
1911ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1912e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1913ee4f033dSBarry Smith   if (flg) {
1914ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1915ee4f033dSBarry Smith   } else {
1916ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1917ee4f033dSBarry Smith   }
1918ee4f033dSBarry Smith 
1919ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1920ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1921ee4f033dSBarry Smith 
1922ee4f033dSBarry Smith   /*
1923ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1924ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1925ee4f033dSBarry Smith   */
1926ee4f033dSBarry Smith   if (coloring->F) {
1927ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1928ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1929ee4f033dSBarry Smith     if (m1 != m2) {
1930ee4f033dSBarry Smith       coloring->F = 0;
1931ee4f033dSBarry Smith     }
1932ee4f033dSBarry Smith   }
1933ee4f033dSBarry Smith 
1934ee4f033dSBarry Smith   if (coloring->F) {
1935ee4f033dSBarry Smith     w1          = coloring->F;
1936ee4f033dSBarry Smith     coloring->F = 0;
1937ee4f033dSBarry Smith   } else {
193866f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1939ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
194066f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1941ee4f033dSBarry Smith   }
1942ee4f033dSBarry Smith 
1943ee4f033dSBarry Smith   /*
1944ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1945ee4f033dSBarry Smith   */
19461ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
19471ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1948ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1949ee4f033dSBarry Smith     /*
1950ee4f033dSBarry Smith        Loop over each column associated with color adding the
1951ee4f033dSBarry Smith        perturbation to the vector w3.
1952ee4f033dSBarry Smith     */
1953ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1954ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1955ee4f033dSBarry Smith       dx  = xx[col];
1956ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1957ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1958ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1959ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1960ee4f033dSBarry Smith #else
1961ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1962ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1963ee4f033dSBarry Smith #endif
1964ee4f033dSBarry Smith       dx                *= epsilon;
1965ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1966ee4f033dSBarry Smith     }
1967ee4f033dSBarry Smith   }
19681ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1969ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1970ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1971ee4f033dSBarry Smith 
1972ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
1973ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
1974ee4f033dSBarry Smith 
1975ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
1976ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
1977ee4f033dSBarry Smith 
19781ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1979ee4f033dSBarry Smith   /*
1980ee4f033dSBarry Smith       Loop over each color
1981ee4f033dSBarry Smith   */
1982ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
198349b058dcSBarry Smith     coloring->currentcolor = k;
1984ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
19851ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
1986ee4f033dSBarry Smith     /*
1987ee4f033dSBarry Smith        Loop over each column associated with color adding the
1988ee4f033dSBarry Smith        perturbation to the vector w3.
1989ee4f033dSBarry Smith     */
1990ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1991ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1992ee4f033dSBarry Smith       dx  = xx[col];
1993ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1994ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1995ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1996ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1997ee4f033dSBarry Smith #else
1998ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1999ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2000ee4f033dSBarry Smith #endif
2001ee4f033dSBarry Smith       dx            *= epsilon;
2002ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2003ee4f033dSBarry Smith       w3_array[col] += dx;
2004ee4f033dSBarry Smith     }
20051ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2006ee4f033dSBarry Smith 
2007ee4f033dSBarry Smith     /*
2008ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2009ee4f033dSBarry Smith     */
2010ee4f033dSBarry Smith 
201166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2012ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
201366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2014ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2015ee4f033dSBarry Smith 
2016ee4f033dSBarry Smith     /*
2017ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2018ee4f033dSBarry Smith     */
20191ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2020ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2021ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2022ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2023ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2024ee4f033dSBarry Smith       srow   = row + start;
2025ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2026ee4f033dSBarry Smith     }
20271ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2028ee4f033dSBarry Smith   }
202949b058dcSBarry Smith   coloring->currentcolor = k;
20301ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
20311ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2032ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2033ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2034ee4f033dSBarry Smith   PetscFunctionReturn(0);
2035ee4f033dSBarry Smith }
2036ee4f033dSBarry Smith 
2037ac90fabeSBarry Smith #include "petscblaslapack.h"
2038ac90fabeSBarry Smith #undef __FUNCT__
2039ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
20407cff1425SSatish Balay int MatAXPY_SeqAIJ(const PetscScalar a[],Mat X,Mat Y,MatStructure str)
2041ac90fabeSBarry Smith {
2042c537a176SHong Zhang   int        ierr,one=1,i;
2043ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2044ac90fabeSBarry Smith 
2045ac90fabeSBarry Smith   PetscFunctionBegin;
2046ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2047268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
2048c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2049a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2050a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2051a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2052a30b2313SHong Zhang     }
2053a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
205424f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2055a30b2313SHong Zhang       y->XtoY = X;
2056c537a176SHong Zhang     }
2057a30b2313SHong Zhang     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]);
2058e2dd4fc4Svictorle     PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);
2059ac90fabeSBarry Smith   } else {
2060ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2061ac90fabeSBarry Smith   }
2062ac90fabeSBarry Smith   PetscFunctionReturn(0);
2063ac90fabeSBarry Smith }
2064ac90fabeSBarry Smith 
2065682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20660a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2067cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2068cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2069cb5b572fSBarry Smith        MatMult_SeqAIJ,
207097304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
20717c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20727c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2073cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2074cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20757c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
207697304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2077cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2078cb5b572fSBarry Smith        0,
207917ab2063SBarry Smith        MatRelax_SeqAIJ,
208017ab2063SBarry Smith        MatTranspose_SeqAIJ,
208197304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2082cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2083cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2084cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2085cb5b572fSBarry Smith        MatNorm_SeqAIJ,
208697304618SKris Buschelman /*20*/ 0,
2087cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
208817ab2063SBarry Smith        MatCompress_SeqAIJ,
2089cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2090cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
209197304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2092cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2093cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2094f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2095a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
209697304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2097cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2098861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
20996c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21006c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
210197304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2102cb5b572fSBarry Smith        0,
2103cb5b572fSBarry Smith        0,
2104cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2105cb5b572fSBarry Smith        0,
210697304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2107cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2108cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2109cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2110cb5b572fSBarry Smith        MatCopy_SeqAIJ,
211197304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ,
2112cb5b572fSBarry Smith        MatScale_SeqAIJ,
2113cb5b572fSBarry Smith        0,
2114cb5b572fSBarry Smith        0,
21156945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
211697304618SKris Buschelman /*50*/ MatGetBlockSize_SeqAIJ,
21173b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21183b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21193b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2120a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
212197304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2122b9617806SBarry Smith        0,
21230513a670SBarry Smith        0,
2124cda55fadSBarry Smith        MatPermute_SeqAIJ,
2125cda55fadSBarry Smith        0,
212697304618SKris Buschelman /*60*/ 0,
2127b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2128b9b97703SBarry Smith        MatView_SeqAIJ,
21298a124369SBarry Smith        MatGetPetscMaps_Petsc,
2130ee4f033dSBarry Smith        0,
213197304618SKris Buschelman /*65*/ 0,
2132ee4f033dSBarry Smith        0,
2133ee4f033dSBarry Smith        0,
2134ee4f033dSBarry Smith        0,
2135ee4f033dSBarry Smith        0,
213697304618SKris Buschelman /*70*/ 0,
2137ee4f033dSBarry Smith        0,
2138ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2139ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2140ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
214197304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ,
214297304618SKris Buschelman        0,
214397304618SKris Buschelman        0,
214497304618SKris Buschelman        0,
214597304618SKris Buschelman        0,
214697304618SKris Buschelman /*80*/ 0,
214797304618SKris Buschelman        0,
214897304618SKris Buschelman        0,
214997304618SKris Buschelman        0,
21509e29f15eSvictorle /*85*/ MatLoad_SeqAIJ,
21519e29f15eSvictorle        MatIsSymmetric_SeqAIJ,
21529e29f15eSvictorle };
215317ab2063SBarry Smith 
2154fb2e594dSBarry Smith EXTERN_C_BEGIN
21554a2ae208SSatish Balay #undef __FUNCT__
21564a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
2157bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2158bef8e0ddSBarry Smith {
2159bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2160bef8e0ddSBarry Smith   int        i,nz,n;
2161bef8e0ddSBarry Smith 
2162bef8e0ddSBarry Smith   PetscFunctionBegin;
2163bef8e0ddSBarry Smith 
2164bef8e0ddSBarry Smith   nz = aij->maxnz;
2165273d9f13SBarry Smith   n  = mat->n;
2166bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2167bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2168bef8e0ddSBarry Smith   }
2169bef8e0ddSBarry Smith   aij->nz = nz;
2170bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2171bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2172bef8e0ddSBarry Smith   }
2173bef8e0ddSBarry Smith 
2174bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2175bef8e0ddSBarry Smith }
2176fb2e594dSBarry Smith EXTERN_C_END
2177bef8e0ddSBarry Smith 
21784a2ae208SSatish Balay #undef __FUNCT__
21794a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2180bef8e0ddSBarry Smith /*@
2181bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2182bef8e0ddSBarry Smith        in the matrix.
2183bef8e0ddSBarry Smith 
2184bef8e0ddSBarry Smith   Input Parameters:
2185bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2186bef8e0ddSBarry Smith -  indices - the column indices
2187bef8e0ddSBarry Smith 
218815091d37SBarry Smith   Level: advanced
218915091d37SBarry Smith 
2190bef8e0ddSBarry Smith   Notes:
2191bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2192bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2193bef8e0ddSBarry Smith   of the MatSetValues() operation.
2194bef8e0ddSBarry Smith 
2195bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2196bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2197bef8e0ddSBarry Smith 
2198bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2199bef8e0ddSBarry Smith 
2200b9617806SBarry Smith     The indices should start with zero, not one.
2201b9617806SBarry Smith 
2202bef8e0ddSBarry Smith @*/
2203bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2204bef8e0ddSBarry Smith {
2205bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2206bef8e0ddSBarry Smith 
2207bef8e0ddSBarry Smith   PetscFunctionBegin;
22084482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
22094482741eSBarry Smith   PetscValidPointer(indices,2);
2210c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2211bef8e0ddSBarry Smith   if (f) {
2212bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2213bef8e0ddSBarry Smith   } else {
221429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2215bef8e0ddSBarry Smith   }
2216bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2217bef8e0ddSBarry Smith }
2218bef8e0ddSBarry Smith 
2219be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2220be6bf707SBarry Smith 
2221fb2e594dSBarry Smith EXTERN_C_BEGIN
22224a2ae208SSatish Balay #undef __FUNCT__
22234a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2224be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2225be6bf707SBarry Smith {
2226be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2227bfeeae90SHong Zhang   size_t       nz = aij->i[mat->m],ierr;
2228be6bf707SBarry Smith 
2229be6bf707SBarry Smith   PetscFunctionBegin;
2230be6bf707SBarry Smith   if (aij->nonew != 1) {
223129bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2232be6bf707SBarry Smith   }
2233be6bf707SBarry Smith 
2234be6bf707SBarry Smith   /* allocate space for values if not already there */
2235be6bf707SBarry Smith   if (!aij->saved_values) {
223687828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2237be6bf707SBarry Smith   }
2238be6bf707SBarry Smith 
2239be6bf707SBarry Smith   /* copy values over */
224087828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2241be6bf707SBarry Smith   PetscFunctionReturn(0);
2242be6bf707SBarry Smith }
2243fb2e594dSBarry Smith EXTERN_C_END
2244be6bf707SBarry Smith 
22454a2ae208SSatish Balay #undef __FUNCT__
2246b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2247be6bf707SBarry Smith /*@
2248be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2249be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2250be6bf707SBarry Smith        nonlinear portion.
2251be6bf707SBarry Smith 
2252be6bf707SBarry Smith    Collect on Mat
2253be6bf707SBarry Smith 
2254be6bf707SBarry Smith   Input Parameters:
2255be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2256be6bf707SBarry Smith 
225715091d37SBarry Smith   Level: advanced
225815091d37SBarry Smith 
2259be6bf707SBarry Smith   Common Usage, with SNESSolve():
2260be6bf707SBarry Smith $    Create Jacobian matrix
2261be6bf707SBarry Smith $    Set linear terms into matrix
2262be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2263be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2264be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2265be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2266be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2267be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2268be6bf707SBarry Smith $    In your Jacobian routine
2269be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2270be6bf707SBarry Smith $      Set nonlinear terms in matrix
2271be6bf707SBarry Smith 
2272be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2273be6bf707SBarry Smith $    // build linear portion of Jacobian
2274be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2275be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2276be6bf707SBarry Smith $    loop over nonlinear iterations
2277be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2278be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2279be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2280be6bf707SBarry Smith $       Solve linear system with Jacobian
2281be6bf707SBarry Smith $    endloop
2282be6bf707SBarry Smith 
2283be6bf707SBarry Smith   Notes:
2284be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2285be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2286be6bf707SBarry Smith     calling this routine.
2287be6bf707SBarry Smith 
2288be6bf707SBarry Smith .seealso: MatRetrieveValues()
2289be6bf707SBarry Smith 
2290be6bf707SBarry Smith @*/
2291be6bf707SBarry Smith int MatStoreValues(Mat mat)
2292be6bf707SBarry Smith {
2293be6bf707SBarry Smith   int ierr,(*f)(Mat);
2294be6bf707SBarry Smith 
2295be6bf707SBarry Smith   PetscFunctionBegin;
22964482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
229729bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
229829bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2299be6bf707SBarry Smith 
2300c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2301be6bf707SBarry Smith   if (f) {
2302be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2303be6bf707SBarry Smith   } else {
230429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2305be6bf707SBarry Smith   }
2306be6bf707SBarry Smith   PetscFunctionReturn(0);
2307be6bf707SBarry Smith }
2308be6bf707SBarry Smith 
2309fb2e594dSBarry Smith EXTERN_C_BEGIN
23104a2ae208SSatish Balay #undef __FUNCT__
23114a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2312be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2313be6bf707SBarry Smith {
2314be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2315bfeeae90SHong Zhang   int        nz = aij->i[mat->m],ierr;
2316be6bf707SBarry Smith 
2317be6bf707SBarry Smith   PetscFunctionBegin;
2318be6bf707SBarry Smith   if (aij->nonew != 1) {
231929bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2320be6bf707SBarry Smith   }
2321be6bf707SBarry Smith   if (!aij->saved_values) {
232229bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2323be6bf707SBarry Smith   }
2324be6bf707SBarry Smith 
2325be6bf707SBarry Smith   /* copy values over */
232687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2327be6bf707SBarry Smith   PetscFunctionReturn(0);
2328be6bf707SBarry Smith }
2329fb2e594dSBarry Smith EXTERN_C_END
2330be6bf707SBarry Smith 
23314a2ae208SSatish Balay #undef __FUNCT__
23324a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2333be6bf707SBarry Smith /*@
2334be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2335be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2336be6bf707SBarry Smith        nonlinear portion.
2337be6bf707SBarry Smith 
2338be6bf707SBarry Smith    Collect on Mat
2339be6bf707SBarry Smith 
2340be6bf707SBarry Smith   Input Parameters:
2341be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2342be6bf707SBarry Smith 
234315091d37SBarry Smith   Level: advanced
234415091d37SBarry Smith 
2345be6bf707SBarry Smith .seealso: MatStoreValues()
2346be6bf707SBarry Smith 
2347be6bf707SBarry Smith @*/
2348be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2349be6bf707SBarry Smith {
2350be6bf707SBarry Smith   int ierr,(*f)(Mat);
2351be6bf707SBarry Smith 
2352be6bf707SBarry Smith   PetscFunctionBegin;
23534482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
235429bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
235529bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2356be6bf707SBarry Smith 
2357c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2358be6bf707SBarry Smith   if (f) {
2359be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2360be6bf707SBarry Smith   } else {
236129bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2362be6bf707SBarry Smith   }
2363be6bf707SBarry Smith   PetscFunctionReturn(0);
2364be6bf707SBarry Smith }
2365be6bf707SBarry Smith 
2366f83d6046SBarry Smith 
2367be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
23684a2ae208SSatish Balay #undef __FUNCT__
23694a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
237017ab2063SBarry Smith /*@C
2371682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
23720d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
23736e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
237451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
23752bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
237617ab2063SBarry Smith 
2377db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2378db81eaa0SLois Curfman McInnes 
237917ab2063SBarry Smith    Input Parameters:
2380db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
238117ab2063SBarry Smith .  m - number of rows
238217ab2063SBarry Smith .  n - number of columns
238317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
238451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
23852bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
238617ab2063SBarry Smith 
238717ab2063SBarry Smith    Output Parameter:
2388416022c9SBarry Smith .  A - the matrix
238917ab2063SBarry Smith 
2390b259b22eSLois Curfman McInnes    Notes:
239117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
239217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
23930002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
239444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
239517ab2063SBarry Smith 
239617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2397a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
23983d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
23996da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
240017ab2063SBarry Smith 
2401682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24024fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2403682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24046c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24056c7ebb05SLois Curfman McInnes 
24066c7ebb05SLois Curfman McInnes    Options Database Keys:
2407db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2408db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2409db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2410db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2411db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
241217ab2063SBarry Smith 
2413027ccd11SLois Curfman McInnes    Level: intermediate
2414027ccd11SLois Curfman McInnes 
241536db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
241636db0b34SBarry Smith 
241717ab2063SBarry Smith @*/
2418ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A)
241917ab2063SBarry Smith {
2420273d9f13SBarry Smith   int ierr;
24216945ee14SBarry Smith 
24223a40ed3dSBarry Smith   PetscFunctionBegin;
2423273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2424273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2425273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2426273d9f13SBarry Smith   PetscFunctionReturn(0);
2427273d9f13SBarry Smith }
2428273d9f13SBarry Smith 
24295da197adSKris Buschelman #define SKIP_ALLOCATION -4
24305da197adSKris Buschelman 
24314a2ae208SSatish Balay #undef __FUNCT__
24324a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2433273d9f13SBarry Smith /*@C
2434273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2435273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2436273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2437273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2438273d9f13SBarry Smith 
2439273d9f13SBarry Smith    Collective on MPI_Comm
2440273d9f13SBarry Smith 
2441273d9f13SBarry Smith    Input Parameters:
2442273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2443273d9f13SBarry Smith .  m - number of rows
2444273d9f13SBarry Smith .  n - number of columns
2445273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2446273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2447273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2448273d9f13SBarry Smith 
2449273d9f13SBarry Smith    Output Parameter:
2450273d9f13SBarry Smith .  A - the matrix
2451273d9f13SBarry Smith 
2452273d9f13SBarry Smith    Notes:
2453273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2454273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2455273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2456273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2457273d9f13SBarry Smith 
2458273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2459273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2460273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2461273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2462273d9f13SBarry Smith 
2463273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2464273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2465273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2466273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2467273d9f13SBarry Smith 
2468273d9f13SBarry Smith    Options Database Keys:
2469273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2470273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2471273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2472273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2473273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2474273d9f13SBarry Smith 
2475273d9f13SBarry Smith    Level: intermediate
2476273d9f13SBarry Smith 
2477273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2478273d9f13SBarry Smith 
2479273d9f13SBarry Smith @*/
2480ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[])
2481273d9f13SBarry Smith {
2482ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,const int[]);
2483a23d5eceSKris Buschelman 
2484a23d5eceSKris Buschelman   PetscFunctionBegin;
2485a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2486a23d5eceSKris Buschelman   if (f) {
2487a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2488a23d5eceSKris Buschelman   }
2489a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2490a23d5eceSKris Buschelman }
2491a23d5eceSKris Buschelman 
2492a23d5eceSKris Buschelman EXTERN_C_BEGIN
2493a23d5eceSKris Buschelman #undef __FUNCT__
2494a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2495a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz)
2496a23d5eceSKris Buschelman {
2497273d9f13SBarry Smith   Mat_SeqAIJ *b;
2498a7ed9263SMatthew Knepley   size_t     len = 0;
2499a43ee2ecSKris Buschelman   PetscTruth skipallocation = PETSC_FALSE;
2500a7ed9263SMatthew Knepley   int        i,ierr;
2501273d9f13SBarry Smith 
2502273d9f13SBarry Smith   PetscFunctionBegin;
2503d5d45c9bSBarry Smith 
2504c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2505c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2506c461c341SBarry Smith     nz             = 0;
2507c461c341SBarry Smith   }
2508c461c341SBarry Smith 
2509435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2510435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2511b73539f3SBarry Smith   if (nnz) {
2512273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
251329bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25143a7fca6bSBarry 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);
2515b73539f3SBarry Smith     }
2516b73539f3SBarry Smith   }
2517b73539f3SBarry Smith 
2518273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2519273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2520273d9f13SBarry Smith 
2521b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2522273d9f13SBarry Smith   if (!nnz) {
2523435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2524273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2525273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2526273d9f13SBarry Smith     nz = nz*B->m;
2527273d9f13SBarry Smith   } else {
2528273d9f13SBarry Smith     nz = 0;
2529273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2530273d9f13SBarry Smith   }
2531273d9f13SBarry Smith 
2532c461c341SBarry Smith   if (!skipallocation) {
2533273d9f13SBarry Smith     /* allocate the matrix space */
2534a7ed9263SMatthew Knepley     len             = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2535b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2536273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2537273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2538273d9f13SBarry Smith     b->i            = b->j + nz;
2539bfeeae90SHong Zhang     b->i[0] = 0;
25405da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
25415da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
25425da197adSKris Buschelman     }
2543273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2544273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2545c461c341SBarry Smith   } else {
2546c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2547c461c341SBarry Smith   }
2548273d9f13SBarry Smith 
2549273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2550b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2551b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2552273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2553273d9f13SBarry Smith 
2554273d9f13SBarry Smith   b->nz                = 0;
2555273d9f13SBarry Smith   b->maxnz             = nz;
2556273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2557273d9f13SBarry Smith   PetscFunctionReturn(0);
2558273d9f13SBarry Smith }
2559a23d5eceSKris Buschelman EXTERN_C_END
2560273d9f13SBarry Smith 
25610bad9183SKris Buschelman /*MC
2562fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
25630bad9183SKris Buschelman    based on compressed sparse row format.
25640bad9183SKris Buschelman 
25650bad9183SKris Buschelman    Options Database Keys:
25660bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
25670bad9183SKris Buschelman 
25680bad9183SKris Buschelman   Level: beginner
25690bad9183SKris Buschelman 
2570f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
25710bad9183SKris Buschelman M*/
25720bad9183SKris Buschelman 
2573a6175056SHong Zhang EXTERN_C_BEGIN
25744a2ae208SSatish Balay #undef __FUNCT__
25754a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2576273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2577273d9f13SBarry Smith {
2578273d9f13SBarry Smith   Mat_SeqAIJ *b;
2579273d9f13SBarry Smith   int        ierr,size;
2580273d9f13SBarry Smith 
2581273d9f13SBarry Smith   PetscFunctionBegin;
2582273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2583273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2584273d9f13SBarry Smith 
2585273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2586273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2587273d9f13SBarry Smith 
2588b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2589b0a32e0cSBarry Smith   B->data             = (void*)b;
2590549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2591549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2592416022c9SBarry Smith   B->factor           = 0;
2593416022c9SBarry Smith   B->lupivotthreshold = 1.0;
259490f02eecSBarry Smith   B->mapping          = 0;
2595e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2596e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2597416022c9SBarry Smith   b->row              = 0;
2598416022c9SBarry Smith   b->col              = 0;
259982bf6240SBarry Smith   b->icol             = 0;
2600b810aeb4SBarry Smith   b->reallocs         = 0;
260117ab2063SBarry Smith 
26028a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26038a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2604a5ae1ecdSBarry Smith 
2605f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
260636db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2607f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2608416022c9SBarry Smith   b->nonew             = 0;
2609416022c9SBarry Smith   b->diag              = 0;
2610416022c9SBarry Smith   b->solve_work        = 0;
26112a1b7f2aSHong Zhang   B->spptr             = 0;
2612b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2613754ec7b1SSatish Balay   b->inode.node_count  = 0;
2614754ec7b1SSatish Balay   b->inode.size        = 0;
26156c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26166c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2617be6bf707SBarry Smith   b->saved_values      = 0;
2618d7f994e1SBarry Smith   b->idiag             = 0;
2619d7f994e1SBarry Smith   b->ssor              = 0;
2620f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2621a30b2313SHong Zhang   b->xtoy              = 0;
2622a30b2313SHong Zhang   b->XtoY              = 0;
262317ab2063SBarry Smith 
262435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
262535d8aa7fSBarry Smith 
2626f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2627bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2628bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2629f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2630be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2631bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2632f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2633be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2634bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2635a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2636a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2637a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
263885fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
263985fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
264085fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
26415fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
26425fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
26435fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
2644a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2645a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2646a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
264705b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
264805b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
264905b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
26500a99d0a2SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C",
26510a99d0a2SKris Buschelman                                      "MatAdjustForInodes_SeqAIJ",
26520a99d0a2SKris Buschelman                                       MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr);
2653d758967fSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C",
2654d758967fSKris Buschelman                                      "MatSeqAIJGetInodeSizes_SeqAIJ",
2655d758967fSKris Buschelman                                       MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr);
2656eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
26573a40ed3dSBarry Smith   PetscFunctionReturn(0);
265817ab2063SBarry Smith }
2659273d9f13SBarry Smith EXTERN_C_END
266017ab2063SBarry Smith 
26614a2ae208SSatish Balay #undef __FUNCT__
26624a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2663be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
266417ab2063SBarry Smith {
2665416022c9SBarry Smith   Mat        C;
2666416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2667bfeeae90SHong Zhang   int        i,m = A->m,ierr;
2668a7ed9263SMatthew Knepley   size_t     len;
266917ab2063SBarry Smith 
26703a40ed3dSBarry Smith   PetscFunctionBegin;
26714043dd9cSLois Curfman McInnes   *B = 0;
2672273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2673be5d1d56SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
2674*1d5dac46SHong Zhang   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2675*1d5dac46SHong Zhang 
2676273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2677273d9f13SBarry Smith 
2678416022c9SBarry Smith   C->factor         = A->factor;
2679416022c9SBarry Smith   c->row            = 0;
2680416022c9SBarry Smith   c->col            = 0;
268182bf6240SBarry Smith   c->icol           = 0;
2682f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2683c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
268417ab2063SBarry Smith 
2685273d9f13SBarry Smith   C->M          = A->m;
2686273d9f13SBarry Smith   C->N          = A->n;
268717ab2063SBarry Smith 
2688b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2689b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
269017ab2063SBarry Smith   for (i=0; i<m; i++) {
2691416022c9SBarry Smith     c->imax[i] = a->imax[i];
2692416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
269317ab2063SBarry Smith   }
269417ab2063SBarry Smith 
269517ab2063SBarry Smith   /* allocate the matrix space */
2696f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2697a7ed9263SMatthew Knepley   len   = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2698b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2699bfeeae90SHong Zhang   c->j  = (int*)(c->a + a->i[m] );
2700bfeeae90SHong Zhang   c->i  = c->j + a->i[m];
2701549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
270217ab2063SBarry Smith   if (m > 0) {
2703bfeeae90SHong Zhang     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr);
2704be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2705bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2706be6bf707SBarry Smith     } else {
2707bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
270817ab2063SBarry Smith     }
270908480c60SBarry Smith   }
271017ab2063SBarry Smith 
2711b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2712416022c9SBarry Smith   c->sorted      = a->sorted;
2713416022c9SBarry Smith   c->roworiented = a->roworiented;
2714416022c9SBarry Smith   c->nonew       = a->nonew;
27157a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2716be6bf707SBarry Smith   c->saved_values = 0;
2717d7f994e1SBarry Smith   c->idiag        = 0;
2718d7f994e1SBarry Smith   c->ssor         = 0;
271936db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
272036db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
272117ab2063SBarry Smith 
2722416022c9SBarry Smith   if (a->diag) {
2723b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2724b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
272517ab2063SBarry Smith     for (i=0; i<m; i++) {
2726416022c9SBarry Smith       c->diag[i] = a->diag[i];
272717ab2063SBarry Smith     }
27283a40ed3dSBarry Smith   } else c->diag        = 0;
2729b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27306c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
27316c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2732754ec7b1SSatish Balay   if (a->inode.size){
2733b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2734754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2735549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2736754ec7b1SSatish Balay   } else {
2737754ec7b1SSatish Balay     c->inode.size       = 0;
2738754ec7b1SSatish Balay     c->inode.node_count = 0;
2739754ec7b1SSatish Balay   }
2740416022c9SBarry Smith   c->nz                 = a->nz;
2741416022c9SBarry Smith   c->maxnz              = a->maxnz;
2742416022c9SBarry Smith   c->solve_work         = 0;
2743273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2744754ec7b1SSatish Balay 
2745416022c9SBarry Smith   *B = C;
2746b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
27473a40ed3dSBarry Smith   PetscFunctionReturn(0);
274817ab2063SBarry Smith }
274917ab2063SBarry Smith 
27504a2ae208SSatish Balay #undef __FUNCT__
27514a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
27528e9aea5cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,const MatType type,Mat *A)
275317ab2063SBarry Smith {
2754416022c9SBarry Smith   Mat_SeqAIJ   *a;
2755416022c9SBarry Smith   Mat          B;
2756efb16452SHong Zhang   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N;
2757bcd2baecSBarry Smith   MPI_Comm     comm;
275817ab2063SBarry Smith 
27593a40ed3dSBarry Smith   PetscFunctionBegin;
2760e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2761d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
276229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2763b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
27640752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2765552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
276617ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
276717ab2063SBarry Smith 
2768d64ed03dSBarry Smith   if (nz < 0) {
276929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2770d64ed03dSBarry Smith   }
2771d64ed03dSBarry Smith 
277217ab2063SBarry Smith   /* read in row lengths */
2773b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
27740752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
277517ab2063SBarry Smith 
277617ab2063SBarry Smith   /* create our matrix */
2777b3a1e11cSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr);
2778b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
2779b3a1e11cSKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
2780416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
278117ab2063SBarry Smith 
278217ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
27830752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
278417ab2063SBarry Smith 
278517ab2063SBarry Smith   /* read in nonzero values */
27860752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
278717ab2063SBarry Smith 
278817ab2063SBarry Smith   /* set matrix "i" values */
2789efb16452SHong Zhang   a->i[0] = 0;
279017ab2063SBarry Smith   for (i=1; i<= M; i++) {
2791416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2792416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
279317ab2063SBarry Smith   }
2794606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
279517ab2063SBarry Smith 
27966d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
27976d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2798b3a1e11cSKris Buschelman   *A = B;
27993a40ed3dSBarry Smith   PetscFunctionReturn(0);
280017ab2063SBarry Smith }
280117ab2063SBarry Smith 
28024a2ae208SSatish Balay #undef __FUNCT__
2803b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28048f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28057264ac53SSatish Balay {
28067264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28070f5bd95cSBarry Smith   int        ierr;
28087264ac53SSatish Balay 
28093a40ed3dSBarry Smith   PetscFunctionBegin;
2810bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
2811bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
2812ca44d042SBarry Smith     *flg = PETSC_FALSE;
2813ca44d042SBarry Smith     PetscFunctionReturn(0);
2814bcd2baecSBarry Smith   }
28157264ac53SSatish Balay 
28167264ac53SSatish Balay   /* if the a->i are the same */
2817273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28180f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28197264ac53SSatish Balay 
28207264ac53SSatish Balay   /* if a->j are the same */
28210f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28220f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2823bcd2baecSBarry Smith 
2824bcd2baecSBarry Smith   /* if a->a are the same */
282587828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
28260f5bd95cSBarry Smith 
28273a40ed3dSBarry Smith   PetscFunctionReturn(0);
28287264ac53SSatish Balay 
28297264ac53SSatish Balay }
283036db0b34SBarry Smith 
28314a2ae208SSatish Balay #undef __FUNCT__
28324a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
283336db0b34SBarry Smith /*@C
283436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
283536db0b34SBarry Smith               provided by the user.
283636db0b34SBarry Smith 
283736db0b34SBarry Smith       Coolective on MPI_Comm
283836db0b34SBarry Smith 
283936db0b34SBarry Smith    Input Parameters:
284036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
284136db0b34SBarry Smith .   m - number of rows
284236db0b34SBarry Smith .   n - number of columns
284336db0b34SBarry Smith .   i - row indices
284436db0b34SBarry Smith .   j - column indices
284536db0b34SBarry Smith -   a - matrix values
284636db0b34SBarry Smith 
284736db0b34SBarry Smith    Output Parameter:
284836db0b34SBarry Smith .   mat - the matrix
284936db0b34SBarry Smith 
285036db0b34SBarry Smith    Level: intermediate
285136db0b34SBarry Smith 
285236db0b34SBarry Smith    Notes:
28530551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
285436db0b34SBarry Smith     once the matrix is destroyed
285536db0b34SBarry Smith 
285636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
285736db0b34SBarry Smith 
2858bfeeae90SHong Zhang        The i and j indices are 0 based
285936db0b34SBarry Smith 
286036db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
286136db0b34SBarry Smith 
286236db0b34SBarry Smith @*/
286387828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
286436db0b34SBarry Smith {
286536db0b34SBarry Smith   int        ierr,ii;
286636db0b34SBarry Smith   Mat_SeqAIJ *aij;
286736db0b34SBarry Smith 
286836db0b34SBarry Smith   PetscFunctionBegin;
2869f204ca49SKris Buschelman   ierr = MatCreate(comm,m,n,m,n,mat);CHKERRQ(ierr);
2870f204ca49SKris Buschelman   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
2871f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(*mat,SKIP_ALLOCATION,0);CHKERRQ(ierr);
287236db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
287336db0b34SBarry Smith 
2874bfeeae90SHong Zhang   if (i[0] != 0) {
2875bfeeae90SHong Zhang     SETERRQ(1,"i (row indices) must start with 0");
287636db0b34SBarry Smith   }
287736db0b34SBarry Smith   aij->i = i;
287836db0b34SBarry Smith   aij->j = j;
287936db0b34SBarry Smith   aij->a = a;
288036db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
288136db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
288236db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
288336db0b34SBarry Smith 
288436db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
288536db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
28869860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
288729bbc08cSBarry 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]);
288836db0b34SBarry Smith #endif
288936db0b34SBarry Smith   }
28909860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
289136db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
2892bfeeae90SHong Zhang     if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
2893bfeeae90SHong Zhang     if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
289436db0b34SBarry Smith   }
289536db0b34SBarry Smith #endif
289636db0b34SBarry Smith 
2897b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2898b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
289936db0b34SBarry Smith   PetscFunctionReturn(0);
290036db0b34SBarry Smith }
290136db0b34SBarry Smith 
2902cc8ba8e1SBarry Smith #undef __FUNCT__
2903ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2904ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2905cc8ba8e1SBarry Smith {
2906cc8ba8e1SBarry Smith   int        ierr;
2907cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
290836db0b34SBarry Smith 
2909cc8ba8e1SBarry Smith   PetscFunctionBegin;
291012c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2911cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2912cc8ba8e1SBarry Smith     a->coloring = coloring;
291312c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
291408b6dcc0SBarry Smith     int             i,*larray;
291512c595b3SBarry Smith     ISColoring      ocoloring;
291608b6dcc0SBarry Smith     ISColoringValue *colors;
291712c595b3SBarry Smith 
291812c595b3SBarry Smith     /* set coloring for diagonal portion */
291912c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
292012c595b3SBarry Smith     for (i=0; i<A->n; i++) {
292112c595b3SBarry Smith       larray[i] = i;
292212c595b3SBarry Smith     }
292312c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
292408b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
292512c595b3SBarry Smith     for (i=0; i<A->n; i++) {
292612c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
292712c595b3SBarry Smith     }
292812c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
292912c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
293012c595b3SBarry Smith     a->coloring = ocoloring;
293112c595b3SBarry Smith   }
2932cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
2933cc8ba8e1SBarry Smith }
2934cc8ba8e1SBarry Smith 
293587828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2936ee4f033dSBarry Smith EXTERN_C_BEGIN
293729c1e371SBarry Smith #include "adic/ad_utils.h"
2938ee4f033dSBarry Smith EXTERN_C_END
2939cc8ba8e1SBarry Smith 
2940cc8ba8e1SBarry Smith #undef __FUNCT__
2941ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
2942ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
2943cc8ba8e1SBarry Smith {
2944cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
294508b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
29464440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
294708b6dcc0SBarry Smith   ISColoringValue *color;
2948cc8ba8e1SBarry Smith 
2949cc8ba8e1SBarry Smith   PetscFunctionBegin;
2950cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
29514440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
2952cc8ba8e1SBarry Smith   color = a->coloring->colors;
2953cc8ba8e1SBarry Smith   /* loop over rows */
2954cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
2955cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
2956cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
2957cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
2958cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
2959cc8ba8e1SBarry Smith     }
29604440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
2961ee4f033dSBarry Smith   }
2962ee4f033dSBarry Smith   PetscFunctionReturn(0);
2963ee4f033dSBarry Smith }
2964ee4f033dSBarry Smith 
2965ee4f033dSBarry Smith #else
2966ee4f033dSBarry Smith 
2967ee4f033dSBarry Smith #undef __FUNCT__
2968ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
2969ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
2970ee4f033dSBarry Smith {
2971ee4f033dSBarry Smith   PetscFunctionBegin;
2972ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
2973ee4f033dSBarry Smith }
2974ee4f033dSBarry Smith 
2975ee4f033dSBarry Smith #endif
2976ee4f033dSBarry Smith 
2977ee4f033dSBarry Smith #undef __FUNCT__
2978ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
2979ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
2980ee4f033dSBarry Smith {
2981ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
298208b6dcc0SBarry Smith   int             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
298387828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
298408b6dcc0SBarry Smith   ISColoringValue *color;
2985ee4f033dSBarry Smith 
2986ee4f033dSBarry Smith   PetscFunctionBegin;
2987ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
2988ee4f033dSBarry Smith   color = a->coloring->colors;
2989ee4f033dSBarry Smith   /* loop over rows */
2990ee4f033dSBarry Smith   for (i=0; i<m; i++) {
2991ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
2992ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
2993ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
2994ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
2995ee4f033dSBarry Smith     }
2996ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
2997cc8ba8e1SBarry Smith   }
2998cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
2999cc8ba8e1SBarry Smith }
300036db0b34SBarry Smith 
3001