xref: /petsc/src/mat/impls/aij/seq/aij.c (revision f2e71c434dd82edd2fd2bcc534fee5e06218d84a)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2b3cc6726SBarry Smith 
3d5d45c9bSBarry Smith /*
43369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
5d5d45c9bSBarry Smith   matrix storage format.
6d5d45c9bSBarry Smith */
73369ce9aSBarry Smith 
89e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
9f5eb4b81SSatish Balay #include "src/inline/spops.h"
108d195f9aSBarry Smith #include "src/inline/dot.h"
110a835dfdSSatish Balay #include "petscbt.h"
1217ab2063SBarry Smith 
134a2ae208SSatish Balay #undef __FUNCT__
1479299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1579299369SBarry Smith /*   only works if matrix has a full set of diagonal entries */
1679299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
1779299369SBarry Smith {
1879299369SBarry Smith   PetscErrorCode ierr;
1979299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
2079299369SBarry Smith   PetscInt       i,*diag, m = Y->m;
2179299369SBarry Smith   PetscScalar    *v,*aa = aij->a;
2279299369SBarry Smith 
2379299369SBarry Smith   PetscFunctionBegin;
2479299369SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(Y);CHKERRQ(ierr);
2579299369SBarry Smith   diag = aij->diag;
2679299369SBarry Smith   ierr = VecGetArray(D,&v);CHKERRQ(ierr);
2779299369SBarry Smith   if (is == INSERT_VALUES) {
2879299369SBarry Smith     for (i=0; i<m; i++) {
2979299369SBarry Smith       aa[diag[i]] = v[i];
3079299369SBarry Smith     }
3179299369SBarry Smith   } else {
3279299369SBarry Smith     for (i=0; i<m; i++) {
3379299369SBarry Smith       aa[diag[i]] += v[i];
3479299369SBarry Smith     }
3579299369SBarry Smith   }
3679299369SBarry Smith   ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
3779299369SBarry Smith   PetscFunctionReturn(0);
3879299369SBarry Smith }
3979299369SBarry Smith 
4079299369SBarry Smith #undef __FUNCT__
414a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
4297f1f81fSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
4317ab2063SBarry Smith {
44416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
45dfbe8321SBarry Smith   PetscErrorCode ierr;
4697f1f81fSBarry Smith   PetscInt       i,ishift;
4717ab2063SBarry Smith 
483a40ed3dSBarry Smith   PetscFunctionBegin;
4931625ec5SSatish Balay   *m     = A->m;
503a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
51bfeeae90SHong Zhang   ishift = 0;
5253e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
53273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
54bfeeae90SHong Zhang   } else if (oshift == 1) {
5597f1f81fSBarry Smith     PetscInt nz = a->i[A->m];
563b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
5797f1f81fSBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
5897f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
593b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
60273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
616945ee14SBarry Smith   } else {
626945ee14SBarry Smith     *ia = a->i; *ja = a->j;
63a2ce50c7SBarry Smith   }
643a40ed3dSBarry Smith   PetscFunctionReturn(0);
65a2744918SBarry Smith }
66a2744918SBarry Smith 
674a2ae208SSatish Balay #undef __FUNCT__
684a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
6997f1f81fSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
706945ee14SBarry Smith {
71dfbe8321SBarry Smith   PetscErrorCode ierr;
726945ee14SBarry Smith 
733a40ed3dSBarry Smith   PetscFunctionBegin;
743a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
75bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
76606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
77606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
78bcd2baecSBarry Smith   }
793a40ed3dSBarry Smith   PetscFunctionReturn(0);
8017ab2063SBarry Smith }
8117ab2063SBarry Smith 
824a2ae208SSatish Balay #undef __FUNCT__
834a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
8497f1f81fSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
853b2fbd54SBarry Smith {
863b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
87dfbe8321SBarry Smith   PetscErrorCode ierr;
8897f1f81fSBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->n,m = A->m;
8997f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
903b2fbd54SBarry Smith 
913a40ed3dSBarry Smith   PetscFunctionBegin;
923b2fbd54SBarry Smith   *nn     = A->n;
933a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
943b2fbd54SBarry Smith   if (symmetric) {
95bfeeae90SHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
963b2fbd54SBarry Smith   } else {
9797f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
9897f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
9997f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
10097f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
1013b2fbd54SBarry Smith     jj = a->j;
1023b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
103bfeeae90SHong Zhang       collengths[jj[i]]++;
1043b2fbd54SBarry Smith     }
1053b2fbd54SBarry Smith     cia[0] = oshift;
1063b2fbd54SBarry Smith     for (i=0; i<n; i++) {
1073b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1083b2fbd54SBarry Smith     }
10997f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
1103b2fbd54SBarry Smith     jj   = a->j;
111a93ec695SBarry Smith     for (row=0; row<m; row++) {
112a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
113a93ec695SBarry Smith       for (i=0; i<mr; i++) {
114bfeeae90SHong Zhang         col = *jj++;
1153b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1163b2fbd54SBarry Smith       }
1173b2fbd54SBarry Smith     }
118606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1193b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1203b2fbd54SBarry Smith   }
1213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1223b2fbd54SBarry Smith }
1233b2fbd54SBarry Smith 
1244a2ae208SSatish Balay #undef __FUNCT__
1254a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
12697f1f81fSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
1273b2fbd54SBarry Smith {
128dfbe8321SBarry Smith   PetscErrorCode ierr;
129606d414cSSatish Balay 
1303a40ed3dSBarry Smith   PetscFunctionBegin;
1313a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1323b2fbd54SBarry Smith 
133606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
134606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1353b2fbd54SBarry Smith 
1363a40ed3dSBarry Smith   PetscFunctionReturn(0);
1373b2fbd54SBarry Smith }
1383b2fbd54SBarry Smith 
139227d817aSBarry Smith #define CHUNKSIZE   15
14017ab2063SBarry Smith 
1414a2ae208SSatish Balay #undef __FUNCT__
1424a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
14397f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
14417ab2063SBarry Smith {
145416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
146e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
14797f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
1486849ba73SBarry Smith   PetscErrorCode ierr;
149e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
15087828ca2SBarry Smith   PetscScalar    *ap,value,*aa = a->a;
15136db0b34SBarry Smith   PetscTruth     ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
152273d9f13SBarry Smith   PetscTruth     roworiented = a->roworiented;
15317ab2063SBarry Smith 
1543a40ed3dSBarry Smith   PetscFunctionBegin;
15517ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
156416022c9SBarry Smith     row  = im[k];
1575ef9f2a5SBarry Smith     if (row < 0) continue;
1582515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
15977431f27SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->m-1);
1603b2fbd54SBarry Smith #endif
161bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
16217ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
163416022c9SBarry Smith     low  = 0;
164c71e6ed7SBarry Smith     high = nrow;
16517ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1665ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
16877431f27SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->n-1);
1693b2fbd54SBarry Smith #endif
170bfeeae90SHong Zhang       col = in[l];
1714b0e389bSBarry Smith       if (roworiented) {
1725ef9f2a5SBarry Smith         value = v[l + k*n];
173bef8e0ddSBarry Smith       } else {
1744b0e389bSBarry Smith         value = v[k + l*m];
1754b0e389bSBarry Smith       }
176abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
17736db0b34SBarry Smith 
1787cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
179e2ee6c50SBarry Smith       lastcol = col;
180416022c9SBarry Smith       while (high-low > 5) {
181416022c9SBarry Smith         t = (low+high)/2;
182416022c9SBarry Smith         if (rp[t] > col) high = t;
183416022c9SBarry Smith         else             low  = t;
18417ab2063SBarry Smith       }
185416022c9SBarry Smith       for (i=low; i<high; i++) {
18617ab2063SBarry Smith         if (rp[i] > col) break;
18717ab2063SBarry Smith         if (rp[i] == col) {
188416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
18917ab2063SBarry Smith           else                  ap[i] = value;
19017ab2063SBarry Smith           goto noinsert;
19117ab2063SBarry Smith         }
19217ab2063SBarry Smith       }
193abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
194c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
195cc72174dSBarry Smith       if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
196ed1caa07SMatthew Knepley       MatSeqXAIJReallocateAIJ(a,1,nrow,row,col,rmax,aa,ai,aj,A->m,rp,ap,imax,nonew);
197416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
198416022c9SBarry Smith       /* shift up all the later entries in this row */
199416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
20017ab2063SBarry Smith         rp[ii+1] = rp[ii];
20117ab2063SBarry Smith         ap[ii+1] = ap[ii];
20217ab2063SBarry Smith       }
20317ab2063SBarry Smith       rp[i] = col;
20417ab2063SBarry Smith       ap[i] = value;
20517ab2063SBarry Smith       noinsert:;
206416022c9SBarry Smith       low = i + 1;
20717ab2063SBarry Smith     }
20817ab2063SBarry Smith     ailen[row] = nrow;
20917ab2063SBarry Smith   }
21088e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
2113a40ed3dSBarry Smith   PetscFunctionReturn(0);
21217ab2063SBarry Smith }
21317ab2063SBarry Smith 
2144a2ae208SSatish Balay #undef __FUNCT__
2154a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
21697f1f81fSBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
2177eb43aa7SLois Curfman McInnes {
2187eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
21997f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
22097f1f81fSBarry Smith   PetscInt     *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];
22677431f27SBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row);
22777431f27SBarry 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 */
23177431f27SBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]);
23277431f27SBarry 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"
257dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
25817ab2063SBarry Smith {
259416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2606849ba73SBarry Smith   PetscErrorCode ierr;
2616f69ff64SBarry Smith   PetscInt       i,*col_lens;
2626f69ff64SBarry Smith   int            fd;
26317ab2063SBarry Smith 
2643a40ed3dSBarry Smith   PetscFunctionBegin;
265b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
26697f1f81fSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
267552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
268273d9f13SBarry Smith   col_lens[1] = A->m;
269273d9f13SBarry Smith   col_lens[2] = A->n;
270416022c9SBarry Smith   col_lens[3] = a->nz;
271416022c9SBarry Smith 
272416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
273273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
274416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
27517ab2063SBarry Smith   }
2766f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
277606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
278416022c9SBarry Smith 
279416022c9SBarry Smith   /* store column indices (zero start index) */
2806f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
281416022c9SBarry Smith 
282416022c9SBarry Smith   /* store nonzero values */
2836f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
2843a40ed3dSBarry Smith   PetscFunctionReturn(0);
28517ab2063SBarry Smith }
286416022c9SBarry Smith 
287dfbe8321SBarry Smith EXTERN PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
288cd155464SBarry Smith 
2894a2ae208SSatish Balay #undef __FUNCT__
2904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
291dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
292416022c9SBarry Smith {
293416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
294dfbe8321SBarry Smith   PetscErrorCode    ierr;
29597f1f81fSBarry Smith   PetscInt          i,j,m = A->m,shift=0;
296e060cb09SBarry Smith   const char        *name;
297f3ef73ceSBarry Smith   PetscViewerFormat format;
29817ab2063SBarry Smith 
2993a40ed3dSBarry Smith   PetscFunctionBegin;
300435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
301b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
30271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
30397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
304273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
305d00d2cf4SBarry Smith       nofinalvalue = 1;
306d00d2cf4SBarry Smith     }
307b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
30877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->n);CHKERRQ(ierr);
30977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
31077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
311b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
31217ab2063SBarry Smith 
31317ab2063SBarry Smith     for (i=0; i<m; i++) {
314416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
315aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
31677431f27SBarry 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);
31717ab2063SBarry Smith #else
31877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
31917ab2063SBarry Smith #endif
32017ab2063SBarry Smith       }
32117ab2063SBarry Smith     }
322d00d2cf4SBarry Smith     if (nofinalvalue) {
32377431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
324d00d2cf4SBarry Smith     }
325fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
326b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
32768369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
328cd155464SBarry Smith      PetscFunctionReturn(0);
329fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
330b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
33144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
33277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
33344cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
334aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
33536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
33677431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
33736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
33877431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
33936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
34077431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3416831982aSBarry Smith         }
34244cd7ae7SLois Curfman McInnes #else
34377431f27SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
34444cd7ae7SLois Curfman McInnes #endif
34544cd7ae7SLois Curfman McInnes       }
346b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
34744cd7ae7SLois Curfman McInnes     }
348b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
349fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
35097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
351b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
35297f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
353496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
354496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
355496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
356496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
357aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
35836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
359496be53dSLois Curfman McInnes #else
360496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
361496be53dSLois Curfman McInnes #endif
362496be53dSLois Curfman McInnes         }
363496be53dSLois Curfman McInnes       }
364496be53dSLois Curfman McInnes     }
3652e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
36677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
3672e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
36877431f27SBarry 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);}
36977431f27SBarry 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);}
37077431f27SBarry 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);}
37177431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
37277431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
37377431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
374496be53dSLois Curfman McInnes     }
375b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
376606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
377496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
378496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
37977431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
380496be53dSLois Curfman McInnes       }
381b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
382496be53dSLois Curfman McInnes     }
383b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
384496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
385496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
386496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
387aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
38836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
389b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
3906831982aSBarry Smith           }
391496be53dSLois Curfman McInnes #else
392b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
393496be53dSLois Curfman McInnes #endif
394496be53dSLois Curfman McInnes         }
395496be53dSLois Curfman McInnes       }
396b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
397496be53dSLois Curfman McInnes     }
398b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
399fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
40097f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
40187828ca2SBarry Smith     PetscScalar value;
40202594712SBarry Smith 
403b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
40402594712SBarry Smith     for (i=0; i<m; i++) {
40502594712SBarry Smith       jcnt = 0;
406273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
407e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
40802594712SBarry Smith           value = a->a[cnt++];
409e24b481bSBarry Smith           jcnt++;
41002594712SBarry Smith         } else {
41102594712SBarry Smith           value = 0.0;
41202594712SBarry Smith         }
413aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
414b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
41502594712SBarry Smith #else
416b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
41702594712SBarry Smith #endif
41802594712SBarry Smith       }
419b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42002594712SBarry Smith     }
421b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4223a40ed3dSBarry Smith   } else {
423b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
42417ab2063SBarry Smith     for (i=0; i<m; i++) {
42577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
426416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
427aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
42836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
42977431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
43036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
43177431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4323a40ed3dSBarry Smith         } else {
43377431f27SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
43417ab2063SBarry Smith         }
43517ab2063SBarry Smith #else
43677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
43717ab2063SBarry Smith #endif
43817ab2063SBarry Smith       }
439b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44017ab2063SBarry Smith     }
441b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
44217ab2063SBarry Smith   }
443b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4443a40ed3dSBarry Smith   PetscFunctionReturn(0);
445416022c9SBarry Smith }
446416022c9SBarry Smith 
4474a2ae208SSatish Balay #undef __FUNCT__
4484a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
449dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
450416022c9SBarry Smith {
451480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
452416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
453dfbe8321SBarry Smith   PetscErrorCode    ierr;
45497f1f81fSBarry Smith   PetscInt          i,j,m = A->m,color;
45536db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
456b0a32e0cSBarry Smith   PetscViewer       viewer;
457f3ef73ceSBarry Smith   PetscViewerFormat format;
458cddf8d76SBarry Smith 
4593a40ed3dSBarry Smith   PetscFunctionBegin;
460480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
461b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
46219bcc07fSBarry Smith 
463b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
464416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4650513a670SBarry Smith 
466fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4670513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
468b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
469416022c9SBarry Smith     for (i=0; i<m; i++) {
470cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
471bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
472bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
473aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
47436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
475cddf8d76SBarry Smith #else
476cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
477cddf8d76SBarry Smith #endif
478b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
479cddf8d76SBarry Smith       }
480cddf8d76SBarry Smith     }
481b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
482cddf8d76SBarry Smith     for (i=0; i<m; i++) {
483cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
484bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
485bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
486cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
487b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
488cddf8d76SBarry Smith       }
489cddf8d76SBarry Smith     }
490b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
491cddf8d76SBarry Smith     for (i=0; i<m; i++) {
492cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
493bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
494bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
495aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
497cddf8d76SBarry Smith #else
498cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
499cddf8d76SBarry Smith #endif
500b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
501416022c9SBarry Smith       }
502416022c9SBarry Smith     }
5030513a670SBarry Smith   } else {
5040513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5050513a670SBarry Smith     /* first determine max of all nonzero values */
50697f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
507b0a32e0cSBarry Smith     PetscDraw   popup;
50836db0b34SBarry Smith     PetscReal scale;
5090513a670SBarry Smith 
5100513a670SBarry Smith     for (i=0; i<nz; i++) {
5110513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5120513a670SBarry Smith     }
513b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
514b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
515b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5160513a670SBarry Smith     count = 0;
5170513a670SBarry Smith     for (i=0; i<m; i++) {
5180513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
519bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
520bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
52197f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
522b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5230513a670SBarry Smith         count++;
5240513a670SBarry Smith       }
5250513a670SBarry Smith     }
5260513a670SBarry Smith   }
527480ef9eaSBarry Smith   PetscFunctionReturn(0);
528480ef9eaSBarry Smith }
529cddf8d76SBarry Smith 
5304a2ae208SSatish Balay #undef __FUNCT__
5314a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
532dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
533480ef9eaSBarry Smith {
534dfbe8321SBarry Smith   PetscErrorCode ierr;
535b0a32e0cSBarry Smith   PetscDraw      draw;
53636db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
537480ef9eaSBarry Smith   PetscTruth     isnull;
538480ef9eaSBarry Smith 
539480ef9eaSBarry Smith   PetscFunctionBegin;
540b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
541b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
542480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
543480ef9eaSBarry Smith 
544480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
545273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
546480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
547b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
548b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
549480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5503a40ed3dSBarry Smith   PetscFunctionReturn(0);
551416022c9SBarry Smith }
552416022c9SBarry Smith 
5534a2ae208SSatish Balay #undef __FUNCT__
5544a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
555dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
556416022c9SBarry Smith {
557dfbe8321SBarry Smith   PetscErrorCode ierr;
55832077d6dSBarry Smith   PetscTruth     issocket,iascii,isbinary,isdraw;
559416022c9SBarry Smith 
5603a40ed3dSBarry Smith   PetscFunctionBegin;
561b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
56232077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
563fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
564fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
565c45a1595SBarry Smith   if (iascii) {
5663a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5674cf18111SSatish Balay #if defined(PETSC_USE_SOCKET_VIEWER)
568c45a1595SBarry Smith   } else if (issocket) {
5694cf18111SSatish Balay     Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
570c45a1595SBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
571c45a1595SBarry Smith #endif
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 {
577958c9bccSBarry Smith     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
57817ab2063SBarry Smith   }
5794846f1f5SKris Buschelman   ierr = MatView_Inode(A,viewer);CHKERRQ(ierr);
5803a40ed3dSBarry Smith   PetscFunctionReturn(0);
58117ab2063SBarry Smith }
58219bcc07fSBarry Smith 
5834a2ae208SSatish Balay #undef __FUNCT__
5844a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
585dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
58617ab2063SBarry Smith {
587416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5886849ba73SBarry Smith   PetscErrorCode ierr;
58997f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
59097f1f81fSBarry Smith   PetscInt       m = A->m,*ip,N,*ailen = a->ilen,rmax = 0;
59187828ca2SBarry Smith   PetscScalar    *aa = a->a,*ap;
5923447b6efSHong Zhang   PetscReal      ratio=0.6;
59317ab2063SBarry Smith 
5943a40ed3dSBarry Smith   PetscFunctionBegin;
5953a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
59617ab2063SBarry Smith 
59743ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
59817ab2063SBarry Smith   for (i=1; i<m; i++) {
599416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
60017ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
60194a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
60217ab2063SBarry Smith     if (fshift) {
603bfeeae90SHong Zhang       ip = aj + ai[i] ;
604bfeeae90SHong Zhang       ap = aa + ai[i] ;
60517ab2063SBarry Smith       N  = ailen[i];
60617ab2063SBarry Smith       for (j=0; j<N; j++) {
60717ab2063SBarry Smith         ip[j-fshift] = ip[j];
60817ab2063SBarry Smith         ap[j-fshift] = ap[j];
60917ab2063SBarry Smith       }
61017ab2063SBarry Smith     }
61117ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
61217ab2063SBarry Smith   }
61317ab2063SBarry Smith   if (m) {
61417ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
61517ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
61617ab2063SBarry Smith   }
61717ab2063SBarry Smith   /* reset ilen and imax for each row */
61817ab2063SBarry Smith   for (i=0; i<m; i++) {
61917ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
62017ab2063SBarry Smith   }
621bfeeae90SHong Zhang   a->nz = ai[m];
62217ab2063SBarry Smith 
62317ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
624416022c9SBarry Smith   if (fshift && a->diag) {
625606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
62652e6d16bSBarry Smith     ierr = PetscLogObjectMemory(A,-(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
627416022c9SBarry Smith     a->diag = 0;
62817ab2063SBarry Smith   }
62963ba0a88SBarry Smith   ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->n,fshift,a->nz));CHKERRQ(ierr);
63063ba0a88SBarry Smith   ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %D\n",a->reallocs));CHKERRQ(ierr);
63163ba0a88SBarry Smith   ierr = PetscLogInfo((A,"MatAssemblyEnd_SeqAIJ:Maximum nonzeros in any row is %D\n",rmax));CHKERRQ(ierr);
632dd5f02e7SSatish Balay   a->reallocs          = 0;
6334e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
63436db0b34SBarry Smith   a->rmax              = rmax;
6354e220ebcSLois Curfman McInnes 
636cb5d8e9eSHong Zhang   /* check for zero rows. If found a large number of zero rows, use CompressedRow functions */
637317fbc4cSHong Zhang   ierr = Mat_CheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
63888e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
63971c2f376SKris Buschelman 
6404846f1f5SKris Buschelman   ierr = MatAssemblyEnd_Inode(A,mode);CHKERRQ(ierr);
6413a40ed3dSBarry Smith   PetscFunctionReturn(0);
64217ab2063SBarry Smith }
64317ab2063SBarry Smith 
6444a2ae208SSatish Balay #undef __FUNCT__
6454a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
646dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
64717ab2063SBarry Smith {
648416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
649dfbe8321SBarry Smith   PetscErrorCode ierr;
6503a40ed3dSBarry Smith 
6513a40ed3dSBarry Smith   PetscFunctionBegin;
652bfeeae90SHong Zhang   ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
6533a40ed3dSBarry Smith   PetscFunctionReturn(0);
65417ab2063SBarry Smith }
655416022c9SBarry Smith 
6564a2ae208SSatish Balay #undef __FUNCT__
6574a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
658dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
65917ab2063SBarry Smith {
660416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
661dfbe8321SBarry Smith   PetscErrorCode ierr;
662d5d45c9bSBarry Smith 
6633a40ed3dSBarry Smith   PetscFunctionBegin;
664aa482453SBarry Smith #if defined(PETSC_USE_LOG)
66577431f27SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->m,A->n,a->nz);
66617ab2063SBarry Smith #endif
6673cbb7e54SHong Zhang   if (a->freedata){
668085a36d4SBarry Smith     ierr = MatSeqXAIJFreeAIJ(a->singlemalloc,&a->a,&a->j,&a->i);CHKERRQ(ierr);
6693cbb7e54SHong Zhang   }
670c38d4ed2SBarry Smith   if (a->row) {
671c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
672c38d4ed2SBarry Smith   }
673c38d4ed2SBarry Smith   if (a->col) {
674c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
675c38d4ed2SBarry Smith   }
676606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
677ab93d7beSBarry Smith   if (a->ilen) {ierr = PetscFree2(a->imax,a->ilen);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);}
68082bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
681606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
682cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
683a30b2313SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
684d487561eSHong Zhang   if (a->compressedrow.use){ierr = PetscFree(a->compressedrow.i);}
685a30b2313SHong Zhang 
6864846f1f5SKris Buschelman   ierr = MatDestroy_Inode(A);CHKERRQ(ierr);
6874846f1f5SKris Buschelman 
688606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
689901853e0SKris Buschelman 
690901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
691901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
692901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
693901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
694901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
695901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
696901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
697a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
698901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
6993a40ed3dSBarry Smith   PetscFunctionReturn(0);
70017ab2063SBarry Smith }
70117ab2063SBarry Smith 
7024a2ae208SSatish Balay #undef __FUNCT__
7034a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
704dfbe8321SBarry Smith PetscErrorCode MatCompress_SeqAIJ(Mat A)
70517ab2063SBarry Smith {
7063a40ed3dSBarry Smith   PetscFunctionBegin;
7073a40ed3dSBarry Smith   PetscFunctionReturn(0);
70817ab2063SBarry Smith }
70917ab2063SBarry Smith 
7104a2ae208SSatish Balay #undef __FUNCT__
7114a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
712dfbe8321SBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op)
71317ab2063SBarry Smith {
714416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7154846f1f5SKris Buschelman   PetscErrorCode ierr;
7163a40ed3dSBarry Smith 
7173a40ed3dSBarry Smith   PetscFunctionBegin;
718a65d3064SKris Buschelman   switch (op) {
719a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
720a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
721a65d3064SKris Buschelman       break;
722a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
723a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
724a65d3064SKris Buschelman       break;
725a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
726a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
727a65d3064SKris Buschelman       break;
728a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
729a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
730a65d3064SKris Buschelman       break;
731a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
732a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
733a65d3064SKris Buschelman       break;
734a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
735a65d3064SKris Buschelman       a->nonew             = 1;
736a65d3064SKris Buschelman       break;
737a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
738a65d3064SKris Buschelman       a->nonew             = -1;
739a65d3064SKris Buschelman       break;
740a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
741a65d3064SKris Buschelman       a->nonew             = -2;
742a65d3064SKris Buschelman       break;
743a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
744a65d3064SKris Buschelman       a->nonew             = 0;
745a65d3064SKris Buschelman       break;
746a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
747a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
748a65d3064SKris Buschelman       break;
749d487561eSHong Zhang     case MAT_USE_COMPRESSEDROW:
750d487561eSHong Zhang       a->compressedrow.use = PETSC_TRUE;
751d487561eSHong Zhang       break;
752d487561eSHong Zhang     case MAT_DO_NOT_USE_COMPRESSEDROW:
753d487561eSHong Zhang       a->compressedrow.use = PETSC_FALSE;
754d487561eSHong Zhang       break;
755a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
756a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
757a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
758a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
759a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
76063ba0a88SBarry Smith       ierr = PetscLogInfo((A,"MatSetOption_SeqAIJ:Option ignored\n"));CHKERRQ(ierr);
761a65d3064SKris Buschelman       break;
762a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
76329bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
764a65d3064SKris Buschelman     default:
76571c2f376SKris Buschelman       break;
766a65d3064SKris Buschelman   }
7674846f1f5SKris Buschelman   ierr = MatSetOption_Inode(A,op);CHKERRQ(ierr);
7683a40ed3dSBarry Smith   PetscFunctionReturn(0);
76917ab2063SBarry Smith }
77017ab2063SBarry Smith 
7714a2ae208SSatish Balay #undef __FUNCT__
7724a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
773dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
77417ab2063SBarry Smith {
775416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7766849ba73SBarry Smith   PetscErrorCode ierr;
77797f1f81fSBarry Smith   PetscInt       i,j,n;
77887828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
77917ab2063SBarry Smith 
7803a40ed3dSBarry Smith   PetscFunctionBegin;
7812dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
7821ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
78336db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
784273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
785273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
786bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
787bfeeae90SHong Zhang       if (a->j[j] == i) {
788416022c9SBarry Smith         x[i] = a->a[j];
78917ab2063SBarry Smith         break;
79017ab2063SBarry Smith       }
79117ab2063SBarry Smith     }
79217ab2063SBarry Smith   }
7931ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
7943a40ed3dSBarry Smith   PetscFunctionReturn(0);
79517ab2063SBarry Smith }
79617ab2063SBarry Smith 
7974a2ae208SSatish Balay #undef __FUNCT__
7984a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
799dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
80017ab2063SBarry Smith {
801416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
8025c897100SBarry Smith   PetscScalar       *x,*y;
803dfbe8321SBarry Smith   PetscErrorCode    ierr;
80497f1f81fSBarry Smith   PetscInt          m = A->m;
8055c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8065c897100SBarry Smith   PetscScalar       *v,alpha;
8077b2bb3b9SHong Zhang   PetscInt          n,i,*idx,*ii,*ridx=PETSC_NULL;
8083447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
8094eb6d288SHong Zhang   PetscTruth        usecprow = cprow.use;
8105c897100SBarry Smith #endif
81117ab2063SBarry Smith 
8123a40ed3dSBarry Smith   PetscFunctionBegin;
8132e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
8141ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8151ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8165c897100SBarry Smith 
8175c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
818bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8195c897100SBarry Smith #else
8203447b6efSHong Zhang   if (usecprow){
8213447b6efSHong Zhang     m    = cprow.nrows;
8223447b6efSHong Zhang     ii   = cprow.i;
8237b2bb3b9SHong Zhang     ridx = cprow.rindex;
8243447b6efSHong Zhang   } else {
8253447b6efSHong Zhang     ii = a->i;
8263447b6efSHong Zhang   }
82717ab2063SBarry Smith   for (i=0; i<m; i++) {
8283447b6efSHong Zhang     idx   = a->j + ii[i] ;
8293447b6efSHong Zhang     v     = a->a + ii[i] ;
8303447b6efSHong Zhang     n     = ii[i+1] - ii[i];
8313447b6efSHong Zhang     if (usecprow){
8327b2bb3b9SHong Zhang       alpha = x[ridx[i]];
8333447b6efSHong Zhang     } else {
83417ab2063SBarry Smith       alpha = x[i];
8353447b6efSHong Zhang     }
83617ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83717ab2063SBarry Smith   }
8385c897100SBarry Smith #endif
839efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
8401ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8411ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8423a40ed3dSBarry Smith   PetscFunctionReturn(0);
84317ab2063SBarry Smith }
84417ab2063SBarry Smith 
8454a2ae208SSatish Balay #undef __FUNCT__
8465c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
847dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8485c897100SBarry Smith {
8498d5b0100SBarry Smith   PetscScalar    zero = 0.0;
850dfbe8321SBarry Smith   PetscErrorCode ierr;
8515c897100SBarry Smith 
8525c897100SBarry Smith   PetscFunctionBegin;
8532dcb1b2aSMatthew Knepley   ierr = VecSet(yy,zero);CHKERRQ(ierr);
8545c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8555c897100SBarry Smith   PetscFunctionReturn(0);
8565c897100SBarry Smith }
8575c897100SBarry Smith 
8585c897100SBarry Smith 
8595c897100SBarry Smith #undef __FUNCT__
8604a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
861dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
86217ab2063SBarry Smith {
863416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
86497952fefSHong Zhang   PetscScalar    *x,*y,*aa;
865dfbe8321SBarry Smith   PetscErrorCode ierr;
86697952fefSHong Zhang   PetscInt       m=A->m,*aj,*ii;
867*f2e71c43SSatish Balay   PetscInt       n,i,j,*ridx=PETSC_NULL;
868362ced78SSatish Balay   PetscScalar    sum;
86997952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
870*f2e71c43SSatish Balay #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
871*f2e71c43SSatish Balay   PetscInt       jrow;
872e36a17ebSSatish Balay #endif
87317ab2063SBarry Smith 
874b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
87597952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
876fee21e36SBarry Smith #endif
877fee21e36SBarry Smith 
8783a40ed3dSBarry Smith   PetscFunctionBegin;
8791ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8801ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
88197952fefSHong Zhang   aj  = a->j;
88297952fefSHong Zhang   aa    = a->a;
883416022c9SBarry Smith   ii   = a->i;
8844eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
88597952fefSHong Zhang     m    = a->compressedrow.nrows;
88697952fefSHong Zhang     ii   = a->compressedrow.i;
88797952fefSHong Zhang     ridx = a->compressedrow.rindex;
88897952fefSHong Zhang     for (i=0; i<m; i++){
88997952fefSHong Zhang       n   = ii[i+1] - ii[i];
89097952fefSHong Zhang       aj  = a->j + ii[i];
89197952fefSHong Zhang       aa  = a->a + ii[i];
89297952fefSHong Zhang       sum = 0.0;
89397952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
89497952fefSHong Zhang       y[*ridx++] = sum;
89597952fefSHong Zhang     }
89697952fefSHong Zhang   } else { /* do not use compressed row format */
897b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
898b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
899b05257ddSBarry Smith #else
90017ab2063SBarry Smith     for (i=0; i<m; i++) {
9019ea0dfa2SSatish Balay       jrow = ii[i];
9029ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
90317ab2063SBarry Smith       sum  = 0.0;
9049ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
90597952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9069ea0dfa2SSatish Balay       }
90717ab2063SBarry Smith       y[i] = sum;
90817ab2063SBarry Smith     }
9098d195f9aSBarry Smith #endif
910b05257ddSBarry Smith   }
911efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz - m);CHKERRQ(ierr);
9121ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9131ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9143a40ed3dSBarry Smith   PetscFunctionReturn(0);
91517ab2063SBarry Smith }
91617ab2063SBarry Smith 
9174a2ae208SSatish Balay #undef __FUNCT__
9184a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
919dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
92017ab2063SBarry Smith {
921416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
92297952fefSHong Zhang   PetscScalar    *x,*y,*z,*aa;
923dfbe8321SBarry Smith   PetscErrorCode ierr;
92497952fefSHong Zhang   PetscInt       m = A->m,*aj,*ii;
925aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
92697952fefSHong Zhang   PetscInt       n,i,jrow,j,*ridx=PETSC_NULL;
927362ced78SSatish Balay   PetscScalar    sum;
92897952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
929e36a17ebSSatish Balay #endif
9309ea0dfa2SSatish Balay 
9313a40ed3dSBarry Smith   PetscFunctionBegin;
9321ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9331ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9342e8a6d31SBarry Smith   if (zz != yy) {
9351ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9362e8a6d31SBarry Smith   } else {
9372e8a6d31SBarry Smith     z = y;
9382e8a6d31SBarry Smith   }
939bfeeae90SHong Zhang 
94097952fefSHong Zhang   aj  = a->j;
94197952fefSHong Zhang   aa  = a->a;
942cddf8d76SBarry Smith   ii  = a->i;
943aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
94497952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
94502ab625aSSatish Balay #else
9464eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
9474eb6d288SHong Zhang     if (zz != yy){
9484eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
9494eb6d288SHong Zhang     }
95097952fefSHong Zhang     m    = a->compressedrow.nrows;
95197952fefSHong Zhang     ii   = a->compressedrow.i;
95297952fefSHong Zhang     ridx = a->compressedrow.rindex;
95397952fefSHong Zhang     for (i=0; i<m; i++){
95497952fefSHong Zhang       n  = ii[i+1] - ii[i];
95597952fefSHong Zhang       aj  = a->j + ii[i];
95697952fefSHong Zhang       aa  = a->a + ii[i];
95797952fefSHong Zhang       sum = y[*ridx];
95897952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
95997952fefSHong Zhang       z[*ridx++] = sum;
96097952fefSHong Zhang     }
96197952fefSHong Zhang   } else { /* do not use compressed row format */
96217ab2063SBarry Smith     for (i=0; i<m; i++) {
9639ea0dfa2SSatish Balay       jrow = ii[i];
9649ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
96517ab2063SBarry Smith       sum  = y[i];
9669ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
96797952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9689ea0dfa2SSatish Balay       }
96917ab2063SBarry Smith       z[i] = sum;
97017ab2063SBarry Smith     }
97197952fefSHong Zhang   }
97202ab625aSSatish Balay #endif
973efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
9741ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9751ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9762e8a6d31SBarry Smith   if (zz != yy) {
9771ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9782e8a6d31SBarry Smith   }
9793a40ed3dSBarry Smith   PetscFunctionReturn(0);
98017ab2063SBarry Smith }
98117ab2063SBarry Smith 
98217ab2063SBarry Smith /*
98317ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
98417ab2063SBarry Smith */
9854a2ae208SSatish Balay #undef __FUNCT__
9864a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
987dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
98817ab2063SBarry Smith {
989416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9906849ba73SBarry Smith   PetscErrorCode ierr;
99197f1f81fSBarry Smith   PetscInt       i,j,*diag,m = A->m;
99217ab2063SBarry Smith 
9933a40ed3dSBarry Smith   PetscFunctionBegin;
994f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
995f1e2ffcdSBarry Smith 
99697f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&diag);CHKERRQ(ierr);
99752e6d16bSBarry Smith   ierr = PetscLogObjectMemory(A,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
998273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
99935b0346bSBarry Smith     diag[i] = a->i[i+1];
1000bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1001bfeeae90SHong Zhang       if (a->j[j] == i) {
1002bfeeae90SHong Zhang         diag[i] = j;
100317ab2063SBarry Smith         break;
100417ab2063SBarry Smith       }
100517ab2063SBarry Smith     }
100617ab2063SBarry Smith   }
1007416022c9SBarry Smith   a->diag = diag;
10083a40ed3dSBarry Smith   PetscFunctionReturn(0);
100917ab2063SBarry Smith }
101017ab2063SBarry Smith 
1011be5855fcSBarry Smith /*
1012be5855fcSBarry Smith      Checks for missing diagonals
1013be5855fcSBarry Smith */
10144a2ae208SSatish Balay #undef __FUNCT__
10154a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1016dfbe8321SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A)
1017be5855fcSBarry Smith {
1018be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10196849ba73SBarry Smith   PetscErrorCode ierr;
102097f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1021be5855fcSBarry Smith 
1022be5855fcSBarry Smith   PetscFunctionBegin;
1023f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1024f1e2ffcdSBarry Smith   diag = a->diag;
1025273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
1026bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
102777431f27SBarry Smith       SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %D",i);
1028be5855fcSBarry Smith     }
1029be5855fcSBarry Smith   }
1030be5855fcSBarry Smith   PetscFunctionReturn(0);
1031be5855fcSBarry Smith }
1032be5855fcSBarry Smith 
10334a2ae208SSatish Balay #undef __FUNCT__
10344a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
103597f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
103617ab2063SBarry Smith {
1037416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1038beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
1039beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
1040dfbe8321SBarry Smith   PetscErrorCode     ierr;
104197f1f81fSBarry Smith   PetscInt           n = A->n,m = A->m,i;
104297f1f81fSBarry Smith   const PetscInt     *idx,*diag;
104317ab2063SBarry Smith 
10443a40ed3dSBarry Smith   PetscFunctionBegin;
1045b965ef7fSBarry Smith   its = its*lits;
104677431f27SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
104791723122SBarry Smith 
1048ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1049ed480e8bSBarry Smith   diag = a->diag;
1050ed480e8bSBarry Smith   if (!a->idiag) {
1051ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1052ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1053ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1054ed480e8bSBarry Smith 
1055ed480e8bSBarry Smith     v        = a->a;
1056ed480e8bSBarry Smith 
1057ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1058958c9bccSBarry Smith     if (omega == 1.0 && !fshift) {
1059ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1060ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1061ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1062ed480e8bSBarry Smith       }
1063efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
1064ed480e8bSBarry Smith     } else {
1065ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1066ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1067beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1068ed480e8bSBarry Smith       }
1069efee365bSSatish Balay       ierr = PetscLogFlops(2*m);CHKERRQ(ierr);
1070beeb8507SBarry Smith     }
1071ed480e8bSBarry Smith   }
1072ed480e8bSBarry Smith   t     = a->ssor;
1073ed480e8bSBarry Smith   idiag = a->idiag;
1074ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1075ed480e8bSBarry Smith 
10761ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1077fb2e594dSBarry Smith   if (xx != bb) {
10781ebc52fbSHong Zhang     ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1079fb2e594dSBarry Smith   } else {
1080fb2e594dSBarry Smith     b = x;
1081fb2e594dSBarry Smith   }
1082fb2e594dSBarry Smith 
1083ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1084ed480e8bSBarry Smith   xs   = x;
108517ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
108617ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1087ed480e8bSBarry Smith     bs = b;
108817ab2063SBarry Smith     for (i=0; i<m; i++) {
1089ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1090416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1091ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1092ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
109317ab2063SBarry Smith         sum  = b[i]*d/omega;
109417ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
109517ab2063SBarry Smith         x[i] = sum;
109617ab2063SBarry Smith     }
10971ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10981ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1099efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
11003a40ed3dSBarry Smith     PetscFunctionReturn(0);
110117ab2063SBarry Smith   }
1102c783ea89SBarry Smith 
1103ed480e8bSBarry Smith 
1104fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1105fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1106fc3d8934SBarry Smith 
1107fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1108fc3d8934SBarry Smith 
1109fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1110fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
111148af12d7SBarry Smith     is the relaxation factor.
1112fc3d8934SBarry Smith     */
1113fc3d8934SBarry Smith 
111448af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
111529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
11163a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
111717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
111817ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
111917ab2063SBarry Smith 
112017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
112117ab2063SBarry Smith 
112217ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
112317ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
112417ab2063SBarry Smith     is the relaxation factor.
112517ab2063SBarry Smith     */
112617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
112717ab2063SBarry Smith 
112817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
112917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1130416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1131ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1132ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
113317ab2063SBarry Smith       sum  = b[i];
113417ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1135ed480e8bSBarry Smith       x[i] = sum*idiag[i];
113617ab2063SBarry Smith     }
113717ab2063SBarry Smith 
113817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1139416022c9SBarry Smith     v = a->a;
1140ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
114117ab2063SBarry Smith 
114217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1143ed480e8bSBarry Smith     ts = t;
1144416022c9SBarry Smith     diag = a->diag;
114517ab2063SBarry Smith     for (i=0; i<m; i++) {
1146416022c9SBarry Smith       n    = diag[i] - a->i[i];
1147ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1148ed480e8bSBarry Smith       v    = a->a + a->i[i];
114917ab2063SBarry Smith       sum  = t[i];
115017ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1151ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1152733d66baSBarry Smith       /*  x = x + t */
1153733d66baSBarry Smith       x[i] += t[i];
115417ab2063SBarry Smith     }
115517ab2063SBarry Smith 
1156efee365bSSatish Balay     ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr);
11571ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11581ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11593a40ed3dSBarry Smith     PetscFunctionReturn(0);
116017ab2063SBarry Smith   }
116117ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
116217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
116377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
116497f1f81fSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b);
116577d8c4bbSBarry Smith #else
116617ab2063SBarry Smith       for (i=0; i<m; i++) {
1167416022c9SBarry Smith         n    = diag[i] - a->i[i];
1168ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1169ed480e8bSBarry Smith         v    = a->a + a->i[i];
117017ab2063SBarry Smith         sum  = b[i];
117117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1172ed480e8bSBarry Smith         x[i] = sum*idiag[i];
117317ab2063SBarry Smith       }
117477d8c4bbSBarry Smith #endif
117517ab2063SBarry Smith       xb = x;
1176efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
11773a40ed3dSBarry Smith     } else xb = b;
117817ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
117917ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
118017ab2063SBarry Smith       for (i=0; i<m; i++) {
1181ed480e8bSBarry Smith         x[i] *= mdiag[i];
118217ab2063SBarry Smith       }
1183efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
118417ab2063SBarry Smith     }
118517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
118677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
118797f1f81fSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb);
118877d8c4bbSBarry Smith #else
118917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1190416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1191ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1192ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
119317ab2063SBarry Smith         sum  = xb[i];
119417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1195ed480e8bSBarry Smith         x[i] = sum*idiag[i];
119617ab2063SBarry Smith       }
119777d8c4bbSBarry Smith #endif
1198efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
119917ab2063SBarry Smith     }
120017ab2063SBarry Smith     its--;
120117ab2063SBarry Smith   }
120217ab2063SBarry Smith   while (its--) {
120317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
120477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
120597f1f81fSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
120677d8c4bbSBarry Smith #else
120717ab2063SBarry Smith       for (i=0; i<m; i++) {
1208ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1209416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1210ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1211ed480e8bSBarry Smith         v    = a->a + a->i[i];
121217ab2063SBarry Smith         sum  = b[i];
121317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1214ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
121517ab2063SBarry Smith       }
121677d8c4bbSBarry Smith #endif
1217efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
121817ab2063SBarry Smith     }
121917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
122077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
122197f1f81fSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
122277d8c4bbSBarry Smith #else
122317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1224ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1225416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1226ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1227ed480e8bSBarry Smith         v    = a->a + a->i[i];
122817ab2063SBarry Smith         sum  = b[i];
122917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1230ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
123117ab2063SBarry Smith       }
123277d8c4bbSBarry Smith #endif
1233efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
123417ab2063SBarry Smith     }
123517ab2063SBarry Smith   }
12361ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12371ebc52fbSHong Zhang   if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
12383a40ed3dSBarry Smith   PetscFunctionReturn(0);
123917ab2063SBarry Smith }
124017ab2063SBarry Smith 
12414a2ae208SSatish Balay #undef __FUNCT__
12424a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1243dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
124417ab2063SBarry Smith {
1245416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12464e220ebcSLois Curfman McInnes 
12473a40ed3dSBarry Smith   PetscFunctionBegin;
1248273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1249273d9f13SBarry Smith   info->columns_global = (double)A->n;
1250273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1251273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12524e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12534e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12544e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12554e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12564e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12574e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12584e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12594e220ebcSLois Curfman McInnes   if (A->factor) {
12604e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12614e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12624e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12634e220ebcSLois Curfman McInnes   } else {
12644e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12654e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12664e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12674e220ebcSLois Curfman McInnes   }
12683a40ed3dSBarry Smith   PetscFunctionReturn(0);
126917ab2063SBarry Smith }
127017ab2063SBarry Smith 
12714a2ae208SSatish Balay #undef __FUNCT__
12724a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1273f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag)
127417ab2063SBarry Smith {
1275416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1276f4df32b1SMatthew Knepley   PetscInt       i,m = A->m - 1;
12776849ba73SBarry Smith   PetscErrorCode ierr;
127817ab2063SBarry Smith 
12793a40ed3dSBarry Smith   PetscFunctionBegin;
1280f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1281f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
128277431f27SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1283bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1284f1e2ffcdSBarry Smith     }
1285f4df32b1SMatthew Knepley     if (diag != 0.0) {
1286f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1287f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1288f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1289f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1290f1e2ffcdSBarry Smith       }
1291f1e2ffcdSBarry Smith     }
129288e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1293f1e2ffcdSBarry Smith   } else {
1294f4df32b1SMatthew Knepley     if (diag != 0.0) {
129517ab2063SBarry Smith       for (i=0; i<N; i++) {
129677431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
12977ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1298416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1299f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1300bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
13017ae801bdSBarry Smith         } else { /* in case row was completely empty */
1302f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
130317ab2063SBarry Smith         }
130417ab2063SBarry Smith       }
13053a40ed3dSBarry Smith     } else {
130617ab2063SBarry Smith       for (i=0; i<N; i++) {
130777431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1308416022c9SBarry Smith         a->ilen[rows[i]] = 0;
130917ab2063SBarry Smith       }
131017ab2063SBarry Smith     }
131188e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1312f1e2ffcdSBarry Smith   }
131343a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13143a40ed3dSBarry Smith   PetscFunctionReturn(0);
131517ab2063SBarry Smith }
131617ab2063SBarry Smith 
13174a2ae208SSatish Balay #undef __FUNCT__
13184a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
131997f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
132017ab2063SBarry Smith {
1321416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
132297f1f81fSBarry Smith   PetscInt   *itmp;
132317ab2063SBarry Smith 
13243a40ed3dSBarry Smith   PetscFunctionBegin;
132577431f27SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
132617ab2063SBarry Smith 
1327416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1328bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
132917ab2063SBarry Smith   if (idx) {
1330bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1331bfeeae90SHong Zhang     if (*nz) {
13324e093b46SBarry Smith       *idx = itmp;
133317ab2063SBarry Smith     }
133417ab2063SBarry Smith     else *idx = 0;
133517ab2063SBarry Smith   }
13363a40ed3dSBarry Smith   PetscFunctionReturn(0);
133717ab2063SBarry Smith }
133817ab2063SBarry Smith 
1339bfeeae90SHong Zhang /* remove this function? */
13404a2ae208SSatish Balay #undef __FUNCT__
13414a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
134297f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
134317ab2063SBarry Smith {
13443a40ed3dSBarry Smith   PetscFunctionBegin;
13453a40ed3dSBarry Smith   PetscFunctionReturn(0);
134617ab2063SBarry Smith }
134717ab2063SBarry Smith 
13484a2ae208SSatish Balay #undef __FUNCT__
13494a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1350dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
135117ab2063SBarry Smith {
1352416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
135387828ca2SBarry Smith   PetscScalar    *v = a->a;
135436db0b34SBarry Smith   PetscReal      sum = 0.0;
13556849ba73SBarry Smith   PetscErrorCode ierr;
135697f1f81fSBarry Smith   PetscInt       i,j;
135717ab2063SBarry Smith 
13583a40ed3dSBarry Smith   PetscFunctionBegin;
135917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1360416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1361aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
136236db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
136317ab2063SBarry Smith #else
136417ab2063SBarry Smith       sum += (*v)*(*v); v++;
136517ab2063SBarry Smith #endif
136617ab2063SBarry Smith     }
1367064f8208SBarry Smith     *nrm = sqrt(sum);
13683a40ed3dSBarry Smith   } else if (type == NORM_1) {
136936db0b34SBarry Smith     PetscReal *tmp;
137097f1f81fSBarry Smith     PetscInt    *jj = a->j;
1371b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1372273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1373064f8208SBarry Smith     *nrm = 0.0;
1374416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1375bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
137617ab2063SBarry Smith     }
1377273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1378064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
137917ab2063SBarry Smith     }
1380606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13813a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1382064f8208SBarry Smith     *nrm = 0.0;
1383273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1384bfeeae90SHong Zhang       v = a->a + a->i[j];
138517ab2063SBarry Smith       sum = 0.0;
1386416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1387cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
138817ab2063SBarry Smith       }
1389064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
139017ab2063SBarry Smith     }
13913a40ed3dSBarry Smith   } else {
139229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
139317ab2063SBarry Smith   }
13943a40ed3dSBarry Smith   PetscFunctionReturn(0);
139517ab2063SBarry Smith }
139617ab2063SBarry Smith 
13974a2ae208SSatish Balay #undef __FUNCT__
13984a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1399dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B)
140017ab2063SBarry Smith {
1401416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1402416022c9SBarry Smith   Mat            C;
14036849ba73SBarry Smith   PetscErrorCode ierr;
140497f1f81fSBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->m,len,*col;
140587828ca2SBarry Smith   PetscScalar    *array = a->a;
140617ab2063SBarry Smith 
14073a40ed3dSBarry Smith   PetscFunctionBegin;
1408273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
140997f1f81fSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
141097f1f81fSBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(PetscInt));CHKERRQ(ierr);
1411bfeeae90SHong Zhang 
1412bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1413f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1414f69a0ea3SMatthew Knepley   ierr = MatSetSizes(C,A->n,m,A->n,m);CHKERRQ(ierr);
1415f204ca49SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1416ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1417606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
141817ab2063SBarry Smith   for (i=0; i<m; i++) {
141917ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1420416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1421b9b97703SBarry Smith     array += len;
1422b9b97703SBarry Smith     aj    += len;
142317ab2063SBarry Smith   }
142417ab2063SBarry Smith 
14256d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14266d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
142717ab2063SBarry Smith 
1428f1e2ffcdSBarry Smith   if (B) {
1429416022c9SBarry Smith     *B = C;
143017ab2063SBarry Smith   } else {
1431273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
143217ab2063SBarry Smith   }
14333a40ed3dSBarry Smith   PetscFunctionReturn(0);
143417ab2063SBarry Smith }
143517ab2063SBarry Smith 
1436cd0d46ebSvictorle EXTERN_C_BEGIN
1437cd0d46ebSvictorle #undef __FUNCT__
14385fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
1439be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f)
1440cd0d46ebSvictorle {
1441cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
144297f1f81fSBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
14436849ba73SBarry Smith   PetscErrorCode ierr;
144497f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1445cd0d46ebSvictorle 
1446cd0d46ebSvictorle   PetscFunctionBegin;
1447cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1448cd0d46ebSvictorle 
1449cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1450cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
14515485867bSBarry Smith   if (ma!=nb || na!=mb){
14525485867bSBarry Smith     *f = PETSC_FALSE;
14535485867bSBarry Smith     PetscFunctionReturn(0);
14545485867bSBarry Smith   }
1455cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1456cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1457cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
145897f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
145997f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1460cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1461cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1462cd0d46ebSvictorle 
1463cd0d46ebSvictorle   *f = PETSC_TRUE;
1464cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1465cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
146697f1f81fSBarry Smith       PetscInt         idc,idr;
14675485867bSBarry Smith       PetscScalar vc,vr;
1468cd0d46ebSvictorle       /* column/row index/value */
14695485867bSBarry Smith       idc = adx[aptr[i]];
14705485867bSBarry Smith       idr = bdx[bptr[idc]];
14715485867bSBarry Smith       vc  = va[aptr[i]];
14725485867bSBarry Smith       vr  = vb[bptr[idc]];
14735485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
14745485867bSBarry Smith 	*f = PETSC_FALSE;
14755485867bSBarry Smith         goto done;
1476cd0d46ebSvictorle       } else {
14775485867bSBarry Smith 	aptr[i]++;
14785485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1479cd0d46ebSvictorle       }
1480cd0d46ebSvictorle     }
1481cd0d46ebSvictorle   }
1482cd0d46ebSvictorle  done:
1483cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
14843aeef889SHong Zhang   if (B) {
14853aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
14863aeef889SHong Zhang   }
1487cd0d46ebSvictorle   PetscFunctionReturn(0);
1488cd0d46ebSvictorle }
1489cd0d46ebSvictorle EXTERN_C_END
1490cd0d46ebSvictorle 
14919e29f15eSvictorle #undef __FUNCT__
14929e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1493dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f)
14949e29f15eSvictorle {
1495dfbe8321SBarry Smith   PetscErrorCode ierr;
14969e29f15eSvictorle   PetscFunctionBegin;
14975485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
14989e29f15eSvictorle   PetscFunctionReturn(0);
14999e29f15eSvictorle }
15009e29f15eSvictorle 
15014a2ae208SSatish Balay #undef __FUNCT__
15024a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1503dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
150417ab2063SBarry Smith {
1505416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
150687828ca2SBarry Smith   PetscScalar    *l,*r,x,*v;
1507dfbe8321SBarry Smith   PetscErrorCode ierr;
150897f1f81fSBarry Smith   PetscInt       i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
150917ab2063SBarry Smith 
15103a40ed3dSBarry Smith   PetscFunctionBegin;
151117ab2063SBarry Smith   if (ll) {
15123ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
15133ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1514e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1515273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
15161ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1517416022c9SBarry Smith     v = a->a;
151817ab2063SBarry Smith     for (i=0; i<m; i++) {
151917ab2063SBarry Smith       x = l[i];
1520416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
152117ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
152217ab2063SBarry Smith     }
15231ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1524efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
152517ab2063SBarry Smith   }
152617ab2063SBarry Smith   if (rr) {
1527e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1528273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
15291ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1530416022c9SBarry Smith     v = a->a; jj = a->j;
153117ab2063SBarry Smith     for (i=0; i<nz; i++) {
1532bfeeae90SHong Zhang       (*v++) *= r[*jj++];
153317ab2063SBarry Smith     }
15341ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1535efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
153617ab2063SBarry Smith   }
15373a40ed3dSBarry Smith   PetscFunctionReturn(0);
153817ab2063SBarry Smith }
153917ab2063SBarry Smith 
15404a2ae208SSatish Balay #undef __FUNCT__
15414a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
154297f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
154317ab2063SBarry Smith {
1544db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
15456849ba73SBarry Smith   PetscErrorCode ierr;
154697f1f81fSBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->n,*lens;
154797f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
154897f1f81fSBarry Smith   PetscInt       *irow,*icol,nrows,ncols;
154997f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
155087828ca2SBarry Smith   PetscScalar    *a_new,*mat_a;
1551416022c9SBarry Smith   Mat            C;
1552fee21e36SBarry Smith   PetscTruth     stride;
155317ab2063SBarry Smith 
15543a40ed3dSBarry Smith   PetscFunctionBegin;
1555d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
155629bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1557d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
155829bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
155999141d43SSatish Balay 
156017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1561b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1562b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
156317ab2063SBarry Smith 
1564fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1565fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1566fee21e36SBarry Smith   if (stride && step == 1) {
156702834360SBarry Smith     /* special case of contiguous rows */
156897f1f81fSBarry Smith     ierr   = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
156931ebf83bSSatish Balay     starts = lens + nrows;
157002834360SBarry Smith     /* loop over new rows determining lens and starting points */
157102834360SBarry Smith     for (i=0; i<nrows; i++) {
1572bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1573a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
157402834360SBarry Smith       for (k=kstart; k<kend; k++) {
1575bfeeae90SHong Zhang         if (aj[k] >= first) {
157602834360SBarry Smith           starts[i] = k;
157702834360SBarry Smith           break;
157802834360SBarry Smith 	}
157902834360SBarry Smith       }
1580a2744918SBarry Smith       sum = 0;
158102834360SBarry Smith       while (k < kend) {
1582bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1583a2744918SBarry Smith         sum++;
158402834360SBarry Smith       }
1585a2744918SBarry Smith       lens[i] = sum;
158602834360SBarry Smith     }
158702834360SBarry Smith     /* create submatrix */
1588cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
158997f1f81fSBarry Smith       PetscInt n_cols,n_rows;
159008480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
159129bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1592d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
159308480c60SBarry Smith       C = *B;
15943a40ed3dSBarry Smith     } else {
1595f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1596f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1597e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1598ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
159908480c60SBarry Smith     }
1600db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1601db02288aSLois Curfman McInnes 
160202834360SBarry Smith     /* loop over rows inserting into submatrix */
1603db02288aSLois Curfman McInnes     a_new    = c->a;
1604db02288aSLois Curfman McInnes     j_new    = c->j;
1605db02288aSLois Curfman McInnes     i_new    = c->i;
1606bfeeae90SHong Zhang 
160702834360SBarry Smith     for (i=0; i<nrows; i++) {
1608a2744918SBarry Smith       ii    = starts[i];
1609a2744918SBarry Smith       lensi = lens[i];
1610a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1611a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
161202834360SBarry Smith       }
161387828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1614a2744918SBarry Smith       a_new      += lensi;
1615a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1616a2744918SBarry Smith       c->ilen[i]  = lensi;
161702834360SBarry Smith     }
1618606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
16193a40ed3dSBarry Smith   } else {
162002834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
162197f1f81fSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr);
1622bfeeae90SHong Zhang 
162397f1f81fSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
162497f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
162517ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
162602834360SBarry Smith     /* determine lens of each row */
162702834360SBarry Smith     for (i=0; i<nrows; i++) {
1628bfeeae90SHong Zhang       kstart  = ai[irow[i]];
162902834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
163002834360SBarry Smith       lens[i] = 0;
163102834360SBarry Smith       for (k=kstart; k<kend; k++) {
1632bfeeae90SHong Zhang         if (smap[aj[k]]) {
163302834360SBarry Smith           lens[i]++;
163402834360SBarry Smith         }
163502834360SBarry Smith       }
163602834360SBarry Smith     }
163717ab2063SBarry Smith     /* Create and fill new matrix */
1638a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16390f5bd95cSBarry Smith       PetscTruth equal;
16400f5bd95cSBarry Smith 
164199141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1642273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
164397f1f81fSBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(PetscInt),&equal);CHKERRQ(ierr);
16440f5bd95cSBarry Smith       if (!equal) {
164529bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
164699141d43SSatish Balay       }
164797f1f81fSBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(PetscInt));CHKERRQ(ierr);
164808480c60SBarry Smith       C = *B;
16493a40ed3dSBarry Smith     } else {
1650f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1651f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1652e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1653ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
165408480c60SBarry Smith     }
165599141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
165617ab2063SBarry Smith     for (i=0; i<nrows; i++) {
165799141d43SSatish Balay       row    = irow[i];
1658bfeeae90SHong Zhang       kstart = ai[row];
165999141d43SSatish Balay       kend   = kstart + a->ilen[row];
1660bfeeae90SHong Zhang       mat_i  = c->i[i];
166199141d43SSatish Balay       mat_j  = c->j + mat_i;
166299141d43SSatish Balay       mat_a  = c->a + mat_i;
166399141d43SSatish Balay       mat_ilen = c->ilen + i;
166417ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1665bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1666ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
166799141d43SSatish Balay           *mat_a++ = a->a[k];
166899141d43SSatish Balay           (*mat_ilen)++;
166999141d43SSatish Balay 
167017ab2063SBarry Smith         }
167117ab2063SBarry Smith       }
167217ab2063SBarry Smith     }
167302834360SBarry Smith     /* Free work space */
167402834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1675606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1676606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
167702834360SBarry Smith   }
16786d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16796d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
168017ab2063SBarry Smith 
168117ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1682416022c9SBarry Smith   *B = C;
16833a40ed3dSBarry Smith   PetscFunctionReturn(0);
168417ab2063SBarry Smith }
168517ab2063SBarry Smith 
1686a871dcd8SBarry Smith /*
1687a871dcd8SBarry Smith */
16884a2ae208SSatish Balay #undef __FUNCT__
16894a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1690dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1691a871dcd8SBarry Smith {
169263b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
1693dfbe8321SBarry Smith   PetscErrorCode ierr;
169463b91edcSBarry Smith   Mat            outA;
1695b8a78c4aSBarry Smith   PetscTruth     row_identity,col_identity;
169663b91edcSBarry Smith 
16973a40ed3dSBarry Smith   PetscFunctionBegin;
1698d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1699b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1700b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1701b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1702634064b4SBarry Smith     SETERRQ(PETSC_ERR_ARG_WRONG,"Row and column permutations must be identity for in-place ILU");
1703b8a78c4aSBarry Smith   }
1704a871dcd8SBarry Smith 
170563b91edcSBarry Smith   outA          = inA;
170663b91edcSBarry Smith   inA->factor   = FACTOR_LU;
170763b91edcSBarry Smith   a->row        = row;
170863b91edcSBarry Smith   a->col        = col;
1709c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1710c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
171163b91edcSBarry Smith 
171236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1713b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
17144c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
171552e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
1716f0ec6fceSSatish Balay 
171794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
171887828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
171994a9d846SBarry Smith   }
172063b91edcSBarry Smith 
172108480c60SBarry Smith   if (!a->diag) {
1722f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
172363b91edcSBarry Smith   }
1724af281ebdSHong Zhang   ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr);
17253a40ed3dSBarry Smith   PetscFunctionReturn(0);
1726a871dcd8SBarry Smith }
1727a871dcd8SBarry Smith 
1728d9eff348SSatish Balay #include "petscblaslapack.h"
17294a2ae208SSatish Balay #undef __FUNCT__
17304a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1731f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
1732f0b747eeSBarry Smith {
1733f0b747eeSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)inA->data;
17344ce68768SBarry Smith   PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1;
1735f4df32b1SMatthew Knepley   PetscScalar oalpha = alpha;
1736efee365bSSatish Balay   PetscErrorCode ierr;
1737efee365bSSatish Balay 
17383a40ed3dSBarry Smith 
17393a40ed3dSBarry Smith   PetscFunctionBegin;
1740f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
1741efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1743f0b747eeSBarry Smith }
1744f0b747eeSBarry Smith 
17454a2ae208SSatish Balay #undef __FUNCT__
17464a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
174797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1748cddf8d76SBarry Smith {
1749dfbe8321SBarry Smith   PetscErrorCode ierr;
175097f1f81fSBarry Smith   PetscInt       i;
1751cddf8d76SBarry Smith 
17523a40ed3dSBarry Smith   PetscFunctionBegin;
1753cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1754b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1755cddf8d76SBarry Smith   }
1756cddf8d76SBarry Smith 
1757cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17586a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1759cddf8d76SBarry Smith   }
17603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1761cddf8d76SBarry Smith }
1762cddf8d76SBarry Smith 
17634a2ae208SSatish Balay #undef __FUNCT__
17644a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
176597f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
17664dcbc457SBarry Smith {
1767e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
17686849ba73SBarry Smith   PetscErrorCode ierr;
176997f1f81fSBarry Smith   PetscInt       row,i,j,k,l,m,n,*idx,*nidx,isz,val;
177097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
1771f1af5d2fSBarry Smith   PetscBT        table;
1772bbd702dbSSatish Balay 
17733a40ed3dSBarry Smith   PetscFunctionBegin;
1774273d9f13SBarry Smith   m     = A->m;
1775e4d965acSSatish Balay   ai    = a->i;
1776bfeeae90SHong Zhang   aj    = a->j;
17778a047759SSatish Balay 
1778a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
177906763907SSatish Balay 
178097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
17816831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
178206763907SSatish Balay 
1783e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1784b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1785e4d965acSSatish Balay     isz  = 0;
17866831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1787e4d965acSSatish Balay 
1788e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17894dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1790b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1791e4d965acSSatish Balay 
1792dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1793e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1794f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17954dcbc457SBarry Smith     }
179606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
179706763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1798e4d965acSSatish Balay 
179904a348a9SBarry Smith     k = 0;
180004a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
180104a348a9SBarry Smith       n = isz;
180206763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1803e4d965acSSatish Balay         row   = nidx[k];
1804e4d965acSSatish Balay         start = ai[row];
1805e4d965acSSatish Balay         end   = ai[row+1];
180604a348a9SBarry Smith         for (l = start; l<end ; l++){
1807efb16452SHong Zhang           val = aj[l] ;
1808f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1809e4d965acSSatish Balay         }
1810e4d965acSSatish Balay       }
1811e4d965acSSatish Balay     }
1812029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1813e4d965acSSatish Balay   }
18146831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1815606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
18163a40ed3dSBarry Smith   PetscFunctionReturn(0);
18174dcbc457SBarry Smith }
181817ab2063SBarry Smith 
18190513a670SBarry Smith /* -------------------------------------------------------------- */
18204a2ae208SSatish Balay #undef __FUNCT__
18214a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
1822dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
18230513a670SBarry Smith {
18240513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
18256849ba73SBarry Smith   PetscErrorCode ierr;
182697f1f81fSBarry Smith   PetscInt       i,nz,m = A->m,n = A->n,*col;
182797f1f81fSBarry Smith   PetscInt       *row,*cnew,j,*lens;
182856cd22aeSBarry Smith   IS             icolp,irowp;
182997f1f81fSBarry Smith   PetscInt       *cwork;
183032ec9ce4SBarry Smith   PetscScalar    *vwork;
18310513a670SBarry Smith 
18323a40ed3dSBarry Smith   PetscFunctionBegin;
18334c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
183456cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18354c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
183656cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18370513a670SBarry Smith 
18380513a670SBarry Smith   /* determine lengths of permuted rows */
183997f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
18400513a670SBarry Smith   for (i=0; i<m; i++) {
18410513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18420513a670SBarry Smith   }
1843f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,B);CHKERRQ(ierr);
1844f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
1845f204ca49SKris Buschelman   ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr);
1846ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
1847606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18480513a670SBarry Smith 
184997f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
18500513a670SBarry Smith   for (i=0; i<m; i++) {
185132ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18520513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
1853cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
185432ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18550513a670SBarry Smith   }
1856606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18573c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
18580513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18590513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
186056cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
186156cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
186256cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
186356cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18643a40ed3dSBarry Smith   PetscFunctionReturn(0);
18650513a670SBarry Smith }
18660513a670SBarry Smith 
18674a2ae208SSatish Balay #undef __FUNCT__
18684a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1869dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_SeqAIJ(Mat A)
1870682d7d0cSBarry Smith {
1871c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1872682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1873dfbe8321SBarry Smith   PetscErrorCode    ierr;
1874682d7d0cSBarry Smith 
18753a40ed3dSBarry Smith   PetscFunctionBegin;
18764846f1f5SKris Buschelman   ierr = MatPrintHelp_Inode(A);CHKERRQ(ierr);
1877c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1878d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1879d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1880d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
188173e7a558SHong Zhang   ierr = (*PetscHelpPrintf)(comm,"  -mat_no_compressedrow: Do not use compressedrow\n");CHKERRQ(ierr);
18823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1883682d7d0cSBarry Smith }
188497304618SKris Buschelman 
18854a2ae208SSatish Balay #undef __FUNCT__
18864a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1887dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1888cb5b572fSBarry Smith {
1889dfbe8321SBarry Smith   PetscErrorCode ierr;
1890cb5b572fSBarry Smith 
1891cb5b572fSBarry Smith   PetscFunctionBegin;
189233f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
189333f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1894be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1895be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1896be6bf707SBarry Smith 
1897bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
1898634064b4SBarry Smith       SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different");
1899cb5b572fSBarry Smith     }
1900bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1901cb5b572fSBarry Smith   } else {
1902cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1903cb5b572fSBarry Smith   }
1904cb5b572fSBarry Smith   PetscFunctionReturn(0);
1905cb5b572fSBarry Smith }
1906cb5b572fSBarry Smith 
19074a2ae208SSatish Balay #undef __FUNCT__
19084a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1909dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
1910273d9f13SBarry Smith {
1911dfbe8321SBarry Smith   PetscErrorCode ierr;
1912273d9f13SBarry Smith 
1913273d9f13SBarry Smith   PetscFunctionBegin;
1914ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1915273d9f13SBarry Smith   PetscFunctionReturn(0);
1916273d9f13SBarry Smith }
1917273d9f13SBarry Smith 
19184a2ae208SSatish Balay #undef __FUNCT__
19194a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
1920dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
19216c0721eeSBarry Smith {
19226c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19236c0721eeSBarry Smith   PetscFunctionBegin;
19246c0721eeSBarry Smith   *array = a->a;
19256c0721eeSBarry Smith   PetscFunctionReturn(0);
19266c0721eeSBarry Smith }
19276c0721eeSBarry Smith 
19284a2ae208SSatish Balay #undef __FUNCT__
19294a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
1930dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
19316c0721eeSBarry Smith {
19326c0721eeSBarry Smith   PetscFunctionBegin;
19336c0721eeSBarry Smith   PetscFunctionReturn(0);
19346c0721eeSBarry Smith }
1935273d9f13SBarry Smith 
1936ee4f033dSBarry Smith #undef __FUNCT__
1937ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1938dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1939ee4f033dSBarry Smith {
19406849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
19416849ba73SBarry Smith   PetscErrorCode ierr;
194297f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
1943efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
194487828ca2SBarry Smith   PetscScalar    *vscale_array;
1945ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
1946ee4f033dSBarry Smith   Vec            w1,w2,w3;
1947ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
1948ee4f033dSBarry Smith   PetscTruth     flg;
1949ee4f033dSBarry Smith 
1950ee4f033dSBarry Smith   PetscFunctionBegin;
1951ee4f033dSBarry Smith   if (!coloring->w1) {
1952ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
195352e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
1954ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
195552e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
1956ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
195752e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
1958ee4f033dSBarry Smith   }
1959ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1960ee4f033dSBarry Smith 
1961ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1962e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1963ee4f033dSBarry Smith   if (flg) {
196463ba0a88SBarry Smith     ierr = PetscLogInfo((coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"));CHKERRQ(ierr);
1965ee4f033dSBarry Smith   } else {
19660b9b6f31SBarry Smith     PetscTruth assembled;
19670b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
19680b9b6f31SBarry Smith     if (assembled) {
1969ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
1970ee4f033dSBarry Smith     }
19710b9b6f31SBarry Smith   }
1972ee4f033dSBarry Smith 
1973ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1974ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1975ee4f033dSBarry Smith 
1976ee4f033dSBarry Smith   /*
1977ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1978ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1979ee4f033dSBarry Smith   */
1980ee4f033dSBarry Smith   if (coloring->F) {
1981ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1982ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1983ee4f033dSBarry Smith     if (m1 != m2) {
1984ee4f033dSBarry Smith       coloring->F = 0;
1985ee4f033dSBarry Smith     }
1986ee4f033dSBarry Smith   }
1987ee4f033dSBarry Smith 
1988ee4f033dSBarry Smith   if (coloring->F) {
1989ee4f033dSBarry Smith     w1          = coloring->F;
1990ee4f033dSBarry Smith     coloring->F = 0;
1991ee4f033dSBarry Smith   } else {
199266f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1993ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
199466f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1995ee4f033dSBarry Smith   }
1996ee4f033dSBarry Smith 
1997ee4f033dSBarry Smith   /*
1998ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1999ee4f033dSBarry Smith   */
20001ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
20011ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2002ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2003ee4f033dSBarry Smith     /*
2004ee4f033dSBarry Smith        Loop over each column associated with color adding the
2005ee4f033dSBarry Smith        perturbation to the vector w3.
2006ee4f033dSBarry Smith     */
2007ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2008ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2009ee4f033dSBarry Smith       dx  = xx[col];
2010ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2011ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2012ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2013ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2014ee4f033dSBarry Smith #else
2015ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2016ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2017ee4f033dSBarry Smith #endif
2018ee4f033dSBarry Smith       dx                *= epsilon;
2019ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2020ee4f033dSBarry Smith     }
2021ee4f033dSBarry Smith   }
20221ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2023ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2024ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2025ee4f033dSBarry Smith 
2026ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2027ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2028ee4f033dSBarry Smith 
2029ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2030ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2031ee4f033dSBarry Smith 
20321ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2033ee4f033dSBarry Smith   /*
2034ee4f033dSBarry Smith       Loop over each color
2035ee4f033dSBarry Smith   */
2036ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
203749b058dcSBarry Smith     coloring->currentcolor = k;
2038ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
20391ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2040ee4f033dSBarry Smith     /*
2041ee4f033dSBarry Smith        Loop over each column associated with color adding the
2042ee4f033dSBarry Smith        perturbation to the vector w3.
2043ee4f033dSBarry Smith     */
2044ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2045ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2046ee4f033dSBarry Smith       dx  = xx[col];
20475b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2048ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2049ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2050ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2051ee4f033dSBarry Smith #else
2052ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2053ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2054ee4f033dSBarry Smith #endif
2055ee4f033dSBarry Smith       dx            *= epsilon;
2056634064b4SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2057ee4f033dSBarry Smith       w3_array[col] += dx;
2058ee4f033dSBarry Smith     }
20591ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2060ee4f033dSBarry Smith 
2061ee4f033dSBarry Smith     /*
2062ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2063ee4f033dSBarry Smith     */
2064ee4f033dSBarry Smith 
206566f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2066ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
206766f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2068efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2069ee4f033dSBarry Smith 
2070ee4f033dSBarry Smith     /*
2071ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2072ee4f033dSBarry Smith     */
20731ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2074ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2075ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2076ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2077ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2078ee4f033dSBarry Smith       srow   = row + start;
2079ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2080ee4f033dSBarry Smith     }
20811ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2082ee4f033dSBarry Smith   }
208349b058dcSBarry Smith   coloring->currentcolor = k;
20841ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
20851ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2086ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2087ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2088ee4f033dSBarry Smith   PetscFunctionReturn(0);
2089ee4f033dSBarry Smith }
2090ee4f033dSBarry Smith 
2091ac90fabeSBarry Smith #include "petscblaslapack.h"
2092ac90fabeSBarry Smith #undef __FUNCT__
2093ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2094f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2095ac90fabeSBarry Smith {
2096dfbe8321SBarry Smith   PetscErrorCode ierr;
209797f1f81fSBarry Smith   PetscInt       i;
2098ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
20994ce68768SBarry Smith   PetscBLASInt   one=1,bnz = (PetscBLASInt)x->nz;
2100ac90fabeSBarry Smith 
2101ac90fabeSBarry Smith   PetscFunctionBegin;
2102ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2103f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2104f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2105c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2106a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2107a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2108a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2109a30b2313SHong Zhang     }
2110a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
211124f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2112a30b2313SHong Zhang       y->XtoY = X;
2113c537a176SHong Zhang     }
2114f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
211563ba0a88SBarry Smith     ierr = PetscLogInfo((0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz));CHKERRQ(ierr);
2116ac90fabeSBarry Smith   } else {
2117f4df32b1SMatthew Knepley     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2118ac90fabeSBarry Smith   }
2119ac90fabeSBarry Smith   PetscFunctionReturn(0);
2120ac90fabeSBarry Smith }
2121ac90fabeSBarry Smith 
2122521d7252SBarry Smith #undef __FUNCT__
2123521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2124521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2125521d7252SBarry Smith {
2126521d7252SBarry Smith   PetscFunctionBegin;
2127521d7252SBarry Smith   PetscFunctionReturn(0);
2128521d7252SBarry Smith }
2129521d7252SBarry Smith 
2130354c94deSBarry Smith #undef __FUNCT__
2131354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
2132354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat)
2133354c94deSBarry Smith {
2134354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2135354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2136354c94deSBarry Smith   PetscInt    i,nz;
2137354c94deSBarry Smith   PetscScalar *a;
2138354c94deSBarry Smith 
2139354c94deSBarry Smith   PetscFunctionBegin;
2140354c94deSBarry Smith   nz = aij->nz;
2141354c94deSBarry Smith   a  = aij->a;
2142354c94deSBarry Smith   for (i=0; i<nz; i++) {
2143354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2144354c94deSBarry Smith   }
2145354c94deSBarry Smith #else
2146354c94deSBarry Smith   PetscFunctionBegin;
2147354c94deSBarry Smith #endif
2148354c94deSBarry Smith   PetscFunctionReturn(0);
2149354c94deSBarry Smith }
2150354c94deSBarry Smith 
2151e34fafa9SBarry Smith #undef __FUNCT__
2152e34fafa9SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2153e34fafa9SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v)
2154e34fafa9SBarry Smith {
2155e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2156e34fafa9SBarry Smith   PetscErrorCode ierr;
2157e34fafa9SBarry Smith   PetscInt       i,j,m = A->m,*ai,*aj,ncols,n;
2158e34fafa9SBarry Smith   PetscReal      atmp;
2159e34fafa9SBarry Smith   PetscScalar    *x,zero = 0.0;
2160e34fafa9SBarry Smith   MatScalar      *aa;
2161e34fafa9SBarry Smith 
2162e34fafa9SBarry Smith   PetscFunctionBegin;
2163e34fafa9SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2164e34fafa9SBarry Smith   aa   = a->a;
2165e34fafa9SBarry Smith   ai   = a->i;
2166e34fafa9SBarry Smith   aj   = a->j;
2167e34fafa9SBarry Smith 
216843e18e04SHong Zhang   ierr = VecSet(v,zero);CHKERRQ(ierr);
2169e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2170e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2171e34fafa9SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2172e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2173e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2174e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2175e34fafa9SBarry Smith       atmp = PetscAbsScalar(*aa); aa++;
2176e34fafa9SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) x[i] = atmp;
2177e34fafa9SBarry Smith       aj++;
2178e34fafa9SBarry Smith     }
2179e34fafa9SBarry Smith   }
2180e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2181e34fafa9SBarry Smith   PetscFunctionReturn(0);
2182e34fafa9SBarry Smith }
2183e34fafa9SBarry Smith 
2184682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
21850a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2186cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2187cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2188cb5b572fSBarry Smith        MatMult_SeqAIJ,
218997304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
21907c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
21917c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2192cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2193cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
21947c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
219597304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2196cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2197cb5b572fSBarry Smith        0,
219817ab2063SBarry Smith        MatRelax_SeqAIJ,
219917ab2063SBarry Smith        MatTranspose_SeqAIJ,
220097304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2201cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2202cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2203cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2204cb5b572fSBarry Smith        MatNorm_SeqAIJ,
220597304618SKris Buschelman /*20*/ 0,
2206cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
220717ab2063SBarry Smith        MatCompress_SeqAIJ,
2208cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2209cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
221097304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2211cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2212cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2213f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2214a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
221597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2216cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2217861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
22186c0721eeSBarry Smith        MatGetArray_SeqAIJ,
22196c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
222097304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2221cb5b572fSBarry Smith        0,
2222cb5b572fSBarry Smith        0,
2223cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2224cb5b572fSBarry Smith        0,
222597304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2226cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2227cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2228cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2229cb5b572fSBarry Smith        MatCopy_SeqAIJ,
223097304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ,
2231cb5b572fSBarry Smith        MatScale_SeqAIJ,
2232cb5b572fSBarry Smith        0,
223379299369SBarry Smith        MatDiagonalSet_SeqAIJ,
22346945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
2235521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ,
22363b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
22373b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
22383b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2239a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
224097304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2241b9617806SBarry Smith        0,
22420513a670SBarry Smith        0,
2243cda55fadSBarry Smith        MatPermute_SeqAIJ,
2244cda55fadSBarry Smith        0,
224597304618SKris Buschelman /*60*/ 0,
2246b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2247b9b97703SBarry Smith        MatView_SeqAIJ,
22488a124369SBarry Smith        MatGetPetscMaps_Petsc,
2249ee4f033dSBarry Smith        0,
225097304618SKris Buschelman /*65*/ 0,
2251ee4f033dSBarry Smith        0,
2252ee4f033dSBarry Smith        0,
2253ee4f033dSBarry Smith        0,
2254ee4f033dSBarry Smith        0,
2255e34fafa9SBarry Smith /*70*/ MatGetRowMax_SeqAIJ,
2256ee4f033dSBarry Smith        0,
2257ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2258dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2259ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2260dcf5cc72SBarry Smith #else
2261dcf5cc72SBarry Smith        0,
2262dcf5cc72SBarry Smith #endif
2263ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
226497304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ,
226597304618SKris Buschelman        0,
226697304618SKris Buschelman        0,
226797304618SKris Buschelman        0,
226897304618SKris Buschelman        0,
226997304618SKris Buschelman /*80*/ 0,
227097304618SKris Buschelman        0,
227197304618SKris Buschelman        0,
227297304618SKris Buschelman        0,
2273bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2274bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ,
22756284ec50SHong Zhang        0,
22766284ec50SHong Zhang        0,
22776284ec50SHong Zhang        0,
2278bc011b1eSHong Zhang        0,
2279bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ,
228026be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
228126be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2282d439da42SKris Buschelman        MatPtAP_Basic,
22837ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
22847ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ,
2285bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2286bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2287bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
22887ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
22897ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ,
2290609c6c4dSKris Buschelman        0,
2291609c6c4dSKris Buschelman        0,
2292354c94deSBarry Smith        MatConjugate_SeqAIJ
22939e29f15eSvictorle };
229417ab2063SBarry Smith 
2295fb2e594dSBarry Smith EXTERN_C_BEGIN
22964a2ae208SSatish Balay #undef __FUNCT__
22974a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
2298be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2299bef8e0ddSBarry Smith {
2300bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
230197f1f81fSBarry Smith   PetscInt   i,nz,n;
2302bef8e0ddSBarry Smith 
2303bef8e0ddSBarry Smith   PetscFunctionBegin;
2304bef8e0ddSBarry Smith 
2305bef8e0ddSBarry Smith   nz = aij->maxnz;
2306273d9f13SBarry Smith   n  = mat->n;
2307bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2308bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2309bef8e0ddSBarry Smith   }
2310bef8e0ddSBarry Smith   aij->nz = nz;
2311bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2312bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2313bef8e0ddSBarry Smith   }
2314bef8e0ddSBarry Smith 
2315bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2316bef8e0ddSBarry Smith }
2317fb2e594dSBarry Smith EXTERN_C_END
2318bef8e0ddSBarry Smith 
23194a2ae208SSatish Balay #undef __FUNCT__
23204a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2321bef8e0ddSBarry Smith /*@
2322bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2323bef8e0ddSBarry Smith        in the matrix.
2324bef8e0ddSBarry Smith 
2325bef8e0ddSBarry Smith   Input Parameters:
2326bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2327bef8e0ddSBarry Smith -  indices - the column indices
2328bef8e0ddSBarry Smith 
232915091d37SBarry Smith   Level: advanced
233015091d37SBarry Smith 
2331bef8e0ddSBarry Smith   Notes:
2332bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2333bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2334bef8e0ddSBarry Smith   of the MatSetValues() operation.
2335bef8e0ddSBarry Smith 
2336bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2337d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2338bef8e0ddSBarry Smith 
2339bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2340bef8e0ddSBarry Smith 
2341b9617806SBarry Smith     The indices should start with zero, not one.
2342b9617806SBarry Smith 
2343bef8e0ddSBarry Smith @*/
2344be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2345bef8e0ddSBarry Smith {
234697f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt *);
2347bef8e0ddSBarry Smith 
2348bef8e0ddSBarry Smith   PetscFunctionBegin;
23494482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
23504482741eSBarry Smith   PetscValidPointer(indices,2);
2351c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2352bef8e0ddSBarry Smith   if (f) {
2353bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2354bef8e0ddSBarry Smith   } else {
2355634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices");
2356bef8e0ddSBarry Smith   }
2357bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2358bef8e0ddSBarry Smith }
2359bef8e0ddSBarry Smith 
2360be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2361be6bf707SBarry Smith 
2362fb2e594dSBarry Smith EXTERN_C_BEGIN
23634a2ae208SSatish Balay #undef __FUNCT__
23644a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2365be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat)
2366be6bf707SBarry Smith {
2367be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
23686849ba73SBarry Smith   PetscErrorCode ierr;
23696849ba73SBarry Smith   size_t         nz = aij->i[mat->m];
2370be6bf707SBarry Smith 
2371be6bf707SBarry Smith   PetscFunctionBegin;
2372be6bf707SBarry Smith   if (aij->nonew != 1) {
2373634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2374be6bf707SBarry Smith   }
2375be6bf707SBarry Smith 
2376be6bf707SBarry Smith   /* allocate space for values if not already there */
2377be6bf707SBarry Smith   if (!aij->saved_values) {
237887828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2379be6bf707SBarry Smith   }
2380be6bf707SBarry Smith 
2381be6bf707SBarry Smith   /* copy values over */
238287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2383be6bf707SBarry Smith   PetscFunctionReturn(0);
2384be6bf707SBarry Smith }
2385fb2e594dSBarry Smith EXTERN_C_END
2386be6bf707SBarry Smith 
23874a2ae208SSatish Balay #undef __FUNCT__
2388b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2389be6bf707SBarry Smith /*@
2390be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2391be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2392be6bf707SBarry Smith        nonlinear portion.
2393be6bf707SBarry Smith 
2394be6bf707SBarry Smith    Collect on Mat
2395be6bf707SBarry Smith 
2396be6bf707SBarry Smith   Input Parameters:
23970e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2398be6bf707SBarry Smith 
239915091d37SBarry Smith   Level: advanced
240015091d37SBarry Smith 
2401be6bf707SBarry Smith   Common Usage, with SNESSolve():
2402be6bf707SBarry Smith $    Create Jacobian matrix
2403be6bf707SBarry Smith $    Set linear terms into matrix
2404be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2405be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2406be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2407be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2408be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2409be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2410be6bf707SBarry Smith $    In your Jacobian routine
2411be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2412be6bf707SBarry Smith $      Set nonlinear terms in matrix
2413be6bf707SBarry Smith 
2414be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2415be6bf707SBarry Smith $    // build linear portion of Jacobian
2416be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2417be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2418be6bf707SBarry Smith $    loop over nonlinear iterations
2419be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2420be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2421be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2422be6bf707SBarry Smith $       Solve linear system with Jacobian
2423be6bf707SBarry Smith $    endloop
2424be6bf707SBarry Smith 
2425be6bf707SBarry Smith   Notes:
2426be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2427be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2428be6bf707SBarry Smith     calling this routine.
2429be6bf707SBarry Smith 
24300c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
24310c468ba9SBarry Smith     and does not allocated additional space.
24320c468ba9SBarry Smith 
2433be6bf707SBarry Smith .seealso: MatRetrieveValues()
2434be6bf707SBarry Smith 
2435be6bf707SBarry Smith @*/
2436be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat)
2437be6bf707SBarry Smith {
2438dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2439be6bf707SBarry Smith 
2440be6bf707SBarry Smith   PetscFunctionBegin;
24414482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
244229bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
244329bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2444be6bf707SBarry Smith 
2445c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2446be6bf707SBarry Smith   if (f) {
2447be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2448be6bf707SBarry Smith   } else {
2449634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values");
2450be6bf707SBarry Smith   }
2451be6bf707SBarry Smith   PetscFunctionReturn(0);
2452be6bf707SBarry Smith }
2453be6bf707SBarry Smith 
2454fb2e594dSBarry Smith EXTERN_C_BEGIN
24554a2ae208SSatish Balay #undef __FUNCT__
24564a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2457be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat)
2458be6bf707SBarry Smith {
2459be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
24606849ba73SBarry Smith   PetscErrorCode ierr;
246197f1f81fSBarry Smith   PetscInt       nz = aij->i[mat->m];
2462be6bf707SBarry Smith 
2463be6bf707SBarry Smith   PetscFunctionBegin;
2464be6bf707SBarry Smith   if (aij->nonew != 1) {
2465634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2466be6bf707SBarry Smith   }
2467be6bf707SBarry Smith   if (!aij->saved_values) {
2468634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2469be6bf707SBarry Smith   }
2470be6bf707SBarry Smith   /* copy values over */
247187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2472be6bf707SBarry Smith   PetscFunctionReturn(0);
2473be6bf707SBarry Smith }
2474fb2e594dSBarry Smith EXTERN_C_END
2475be6bf707SBarry Smith 
24764a2ae208SSatish Balay #undef __FUNCT__
24774a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2478be6bf707SBarry Smith /*@
2479be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2480be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2481be6bf707SBarry Smith        nonlinear portion.
2482be6bf707SBarry Smith 
2483be6bf707SBarry Smith    Collect on Mat
2484be6bf707SBarry Smith 
2485be6bf707SBarry Smith   Input Parameters:
2486be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2487be6bf707SBarry Smith 
248815091d37SBarry Smith   Level: advanced
248915091d37SBarry Smith 
2490be6bf707SBarry Smith .seealso: MatStoreValues()
2491be6bf707SBarry Smith 
2492be6bf707SBarry Smith @*/
2493be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat)
2494be6bf707SBarry Smith {
2495dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2496be6bf707SBarry Smith 
2497be6bf707SBarry Smith   PetscFunctionBegin;
24984482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
249929bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
250029bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501be6bf707SBarry Smith 
2502c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2503be6bf707SBarry Smith   if (f) {
2504be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2505be6bf707SBarry Smith   } else {
2506634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values");
2507be6bf707SBarry Smith   }
2508be6bf707SBarry Smith   PetscFunctionReturn(0);
2509be6bf707SBarry Smith }
2510be6bf707SBarry Smith 
2511f83d6046SBarry Smith 
2512be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
25134a2ae208SSatish Balay #undef __FUNCT__
25144a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
251517ab2063SBarry Smith /*@C
2516682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
25170d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
25186e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
251951c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
25202bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
252117ab2063SBarry Smith 
2522db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2523db81eaa0SLois Curfman McInnes 
252417ab2063SBarry Smith    Input Parameters:
2525db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
252617ab2063SBarry Smith .  m - number of rows
252717ab2063SBarry Smith .  n - number of columns
252817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
252951c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
25302bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
253117ab2063SBarry Smith 
253217ab2063SBarry Smith    Output Parameter:
2533416022c9SBarry Smith .  A - the matrix
253417ab2063SBarry Smith 
2535b259b22eSLois Curfman McInnes    Notes:
253649a6f317SBarry Smith    If nnz is given then nz is ignored
253749a6f317SBarry Smith 
253817ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
253917ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
25400002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
254144cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
254217ab2063SBarry Smith 
254317ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2544a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
25453d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
25466da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
254717ab2063SBarry Smith 
2548682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
25494fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2550682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
25516c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
25526c7ebb05SLois Curfman McInnes 
25536c7ebb05SLois Curfman McInnes    Options Database Keys:
2554698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2555698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2556db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2557db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2558db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
255917ab2063SBarry Smith 
2560027ccd11SLois Curfman McInnes    Level: intermediate
2561027ccd11SLois Curfman McInnes 
256236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
256336db0b34SBarry Smith 
256417ab2063SBarry Smith @*/
2565be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
256617ab2063SBarry Smith {
2567dfbe8321SBarry Smith   PetscErrorCode ierr;
25686945ee14SBarry Smith 
25693a40ed3dSBarry Smith   PetscFunctionBegin;
2570f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2571f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2572273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2573ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr);
2574273d9f13SBarry Smith   PetscFunctionReturn(0);
2575273d9f13SBarry Smith }
2576273d9f13SBarry Smith 
25774a2ae208SSatish Balay #undef __FUNCT__
25784a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2579273d9f13SBarry Smith /*@C
2580273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2581273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2582273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2583273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2584273d9f13SBarry Smith 
2585273d9f13SBarry Smith    Collective on MPI_Comm
2586273d9f13SBarry Smith 
2587273d9f13SBarry Smith    Input Parameters:
258845bfc511SMatthew Knepley +  B - The matrix
2589273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2590273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2591273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2592273d9f13SBarry Smith 
2593273d9f13SBarry Smith    Notes:
259449a6f317SBarry Smith      If nnz is given then nz is ignored
259549a6f317SBarry Smith 
2596273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
2597273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2598273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2599273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2600273d9f13SBarry Smith 
2601273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2602273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2603273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2604273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2605273d9f13SBarry Smith 
2606a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
2607a96a251dSBarry Smith    entries or columns indices
2608a96a251dSBarry Smith 
2609273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2610273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2611273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2612273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2613273d9f13SBarry Smith 
2614273d9f13SBarry Smith    Options Database Keys:
2615698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2616698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2617273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2618273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2619273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2620273d9f13SBarry Smith 
2621273d9f13SBarry Smith    Level: intermediate
2622273d9f13SBarry Smith 
2623273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2624273d9f13SBarry Smith 
2625273d9f13SBarry Smith @*/
2626be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
2627273d9f13SBarry Smith {
262897f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]);
2629a23d5eceSKris Buschelman 
2630a23d5eceSKris Buschelman   PetscFunctionBegin;
2631a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2632a23d5eceSKris Buschelman   if (f) {
2633a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2634a23d5eceSKris Buschelman   }
2635a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2636a23d5eceSKris Buschelman }
2637a23d5eceSKris Buschelman 
2638a23d5eceSKris Buschelman EXTERN_C_BEGIN
2639a23d5eceSKris Buschelman #undef __FUNCT__
2640a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2641be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz)
2642a23d5eceSKris Buschelman {
2643273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2644a43ee2ecSKris Buschelman   PetscTruth     skipallocation = PETSC_FALSE;
26456849ba73SBarry Smith   PetscErrorCode ierr;
264697f1f81fSBarry Smith   PetscInt       i;
2647273d9f13SBarry Smith 
2648273d9f13SBarry Smith   PetscFunctionBegin;
2649d5d45c9bSBarry Smith 
2650a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
2651c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2652c461c341SBarry Smith     nz             = 0;
2653c461c341SBarry Smith   }
2654c461c341SBarry Smith 
2655435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2656435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2657b73539f3SBarry Smith   if (nnz) {
2658273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
265929bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
26603a7fca6bSBarry 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);
2661b73539f3SBarry Smith     }
2662b73539f3SBarry Smith   }
2663b73539f3SBarry Smith 
2664273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2665273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2666273d9f13SBarry Smith 
2667ab93d7beSBarry Smith   if (!skipallocation) {
2668ab93d7beSBarry Smith     ierr = PetscMalloc2(B->m,PetscInt,&b->imax,B->m,PetscInt,&b->ilen);CHKERRQ(ierr);
2669273d9f13SBarry Smith     if (!nnz) {
2670435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2671273d9f13SBarry Smith       else if (nz <= 0)        nz = 1;
2672273d9f13SBarry Smith       for (i=0; i<B->m; i++) b->imax[i] = nz;
2673273d9f13SBarry Smith       nz = nz*B->m;
2674273d9f13SBarry Smith     } else {
2675273d9f13SBarry Smith       nz = 0;
2676273d9f13SBarry Smith       for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2677273d9f13SBarry Smith     }
2678273d9f13SBarry Smith 
2679ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
2680ab93d7beSBarry Smith     for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2681ab93d7beSBarry Smith 
2682273d9f13SBarry Smith     /* allocate the matrix space */
2683a96a251dSBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->m+1,PetscInt,&b->i);CHKERRQ(ierr);
2684bfeeae90SHong Zhang     b->i[0] = 0;
26855da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26865da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26875da197adSKris Buschelman     }
2688273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2689273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2690c461c341SBarry Smith   } else {
2691c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2692c461c341SBarry Smith   }
2693273d9f13SBarry Smith 
2694273d9f13SBarry Smith   b->nz                = 0;
2695273d9f13SBarry Smith   b->maxnz             = nz;
2696273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2697273d9f13SBarry Smith   PetscFunctionReturn(0);
2698273d9f13SBarry Smith }
2699a23d5eceSKris Buschelman EXTERN_C_END
2700273d9f13SBarry Smith 
2701a1661176SMatthew Knepley #undef  __FUNCT__
2702a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
2703a1661176SMatthew Knepley /*@C
2704a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
2705a1661176SMatthew Knepley 
2706a1661176SMatthew Knepley    Input Parameters:
2707a1661176SMatthew Knepley +  B - the matrix
2708a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
2709a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
2710a1661176SMatthew Knepley -  v - optional values in the matrix
2711a1661176SMatthew Knepley 
2712d58b2322SMatthew Knepley    Contributed by: Lisandro Dalchin
2713d58b2322SMatthew Knepley 
2714a1661176SMatthew Knepley    Level: developer
2715a1661176SMatthew Knepley 
2716a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
2717a1661176SMatthew Knepley 
2718a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
2719a1661176SMatthew Knepley @*/
2720a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
2721a1661176SMatthew Knepley {
2722a1661176SMatthew Knepley   PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]);
2723a1661176SMatthew Knepley   PetscErrorCode ierr;
2724a1661176SMatthew Knepley 
2725a1661176SMatthew Knepley   PetscFunctionBegin;
2726a1661176SMatthew Knepley   PetscValidHeaderSpecific(B,MAT_COOKIE,1);
2727a1661176SMatthew Knepley   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr);
2728a1661176SMatthew Knepley   if (f) {
2729a1661176SMatthew Knepley     ierr = (*f)(B,i,j,v);CHKERRQ(ierr);
2730a1661176SMatthew Knepley   }
2731a1661176SMatthew Knepley   PetscFunctionReturn(0);
2732a1661176SMatthew Knepley }
2733a1661176SMatthew Knepley 
2734a1661176SMatthew Knepley EXTERN_C_BEGIN
2735a1661176SMatthew Knepley #undef  __FUNCT__
2736a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
2737a1661176SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt I[],const PetscInt J[],const PetscScalar v[])
2738a1661176SMatthew Knepley {
2739a1661176SMatthew Knepley   PetscInt       i;
2740a1661176SMatthew Knepley   PetscInt       m,n;
2741a1661176SMatthew Knepley   PetscInt       nz;
2742a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
2743a1661176SMatthew Knepley   PetscScalar    *values;
2744a1661176SMatthew Knepley   PetscErrorCode ierr;
2745a1661176SMatthew Knepley 
2746a1661176SMatthew Knepley   PetscFunctionBegin;
2747a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
2748a1661176SMatthew Knepley 
2749a1661176SMatthew Knepley   if (I[0]) {
2750a1661176SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "I[0] must be 0 it is %D", I[0]);
2751a1661176SMatthew Knepley   }
2752a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
2753a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2754a1661176SMatthew Knepley     nz     = I[i+1]- I[i];
2755a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
2756a1661176SMatthew Knepley     if (nz < 0) {
2757a1661176SMatthew Knepley       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
2758a1661176SMatthew Knepley     }
2759a1661176SMatthew Knepley     nnz[i] = nz;
2760a1661176SMatthew Knepley   }
2761a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
2762a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
2763a1661176SMatthew Knepley 
2764a1661176SMatthew Knepley   if (v) {
2765a1661176SMatthew Knepley     values = (PetscScalar*) v;
2766a1661176SMatthew Knepley   } else {
2767a1661176SMatthew Knepley     ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr);
2768a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
2769a1661176SMatthew Knepley   }
2770a1661176SMatthew Knepley 
2771a1661176SMatthew Knepley   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
2772a1661176SMatthew Knepley 
2773a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2774a1661176SMatthew Knepley     nz  = I[i+1] - I[i];
2775a1661176SMatthew Knepley     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+I[i], values + (v ? I[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
2776a1661176SMatthew Knepley   }
2777a1661176SMatthew Knepley 
2778a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2779a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2780a1661176SMatthew Knepley   ierr = MatSetOption(B,MAT_COLUMNS_UNSORTED);CHKERRQ(ierr);
2781a1661176SMatthew Knepley 
2782a1661176SMatthew Knepley   if (!v) {
2783a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
2784a1661176SMatthew Knepley   }
2785a1661176SMatthew Knepley   PetscFunctionReturn(0);
2786a1661176SMatthew Knepley }
2787a1661176SMatthew Knepley EXTERN_C_END
2788a1661176SMatthew Knepley 
27890bad9183SKris Buschelman /*MC
2790fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
27910bad9183SKris Buschelman    based on compressed sparse row format.
27920bad9183SKris Buschelman 
27930bad9183SKris Buschelman    Options Database Keys:
27940bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
27950bad9183SKris Buschelman 
27960bad9183SKris Buschelman   Level: beginner
27970bad9183SKris Buschelman 
2798f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
27990bad9183SKris Buschelman M*/
28000bad9183SKris Buschelman 
2801a6175056SHong Zhang EXTERN_C_BEGIN
28024a2ae208SSatish Balay #undef __FUNCT__
28034a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2804be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B)
2805273d9f13SBarry Smith {
2806273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2807dfbe8321SBarry Smith   PetscErrorCode ierr;
280838baddfdSBarry Smith   PetscMPIInt    size;
2809273d9f13SBarry Smith 
2810273d9f13SBarry Smith   PetscFunctionBegin;
2811273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2812273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2813273d9f13SBarry Smith 
2814273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2815273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2816273d9f13SBarry Smith 
2817b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2818b0a32e0cSBarry Smith   B->data             = (void*)b;
2819549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2820416022c9SBarry Smith   B->factor           = 0;
282190f02eecSBarry Smith   B->mapping          = 0;
2822416022c9SBarry Smith   b->row              = 0;
2823416022c9SBarry Smith   b->col              = 0;
282482bf6240SBarry Smith   b->icol             = 0;
2825b810aeb4SBarry Smith   b->reallocs         = 0;
282617ab2063SBarry Smith 
28278a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
28288a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2829a5ae1ecdSBarry Smith 
2830f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
283136db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2832f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2833416022c9SBarry Smith   b->nonew             = 0;
2834416022c9SBarry Smith   b->diag              = 0;
2835416022c9SBarry Smith   b->solve_work        = 0;
28362a1b7f2aSHong Zhang   B->spptr             = 0;
2837be6bf707SBarry Smith   b->saved_values      = 0;
2838d7f994e1SBarry Smith   b->idiag             = 0;
2839d7f994e1SBarry Smith   b->ssor              = 0;
2840f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2841a30b2313SHong Zhang   b->xtoy              = 0;
2842a30b2313SHong Zhang   b->XtoY              = 0;
284373e7a558SHong Zhang   b->compressedrow.use     = PETSC_FALSE;
2844d487561eSHong Zhang   b->compressedrow.nrows   = B->m;
2845d487561eSHong Zhang   b->compressedrow.i       = PETSC_NULL;
2846d487561eSHong Zhang   b->compressedrow.rindex  = PETSC_NULL;
2847d487561eSHong Zhang   b->compressedrow.checked = PETSC_FALSE;
284888e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
284917ab2063SBarry Smith 
285035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
285135d8aa7fSBarry Smith 
2852f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2853bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2854bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2855f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2856be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2857bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2858f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2859be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2860bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2861a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2862a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2863a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
286485fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
286585fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
286685fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
28675fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
28685fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
28695fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
2870a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2871a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2872a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
2873a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",
2874a1661176SMatthew Knepley 				     "MatSeqAIJSetPreallocationCSR_SeqAIJ",
2875a1661176SMatthew Knepley 				      MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
287605b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
287705b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
287805b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
28794846f1f5SKris Buschelman   ierr = MatCreate_Inode(B);CHKERRQ(ierr);
28803a40ed3dSBarry Smith   PetscFunctionReturn(0);
288117ab2063SBarry Smith }
2882273d9f13SBarry Smith EXTERN_C_END
288317ab2063SBarry Smith 
28844a2ae208SSatish Balay #undef __FUNCT__
28854a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2886dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
288717ab2063SBarry Smith {
2888416022c9SBarry Smith   Mat            C;
2889416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
28906849ba73SBarry Smith   PetscErrorCode ierr;
289197f1f81fSBarry Smith   PetscInt       i,m = A->m;
289217ab2063SBarry Smith 
28933a40ed3dSBarry Smith   PetscFunctionBegin;
28944043dd9cSLois Curfman McInnes   *B = 0;
2895f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
2896f69a0ea3SMatthew Knepley   ierr = MatSetSizes(C,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
2897be5d1d56SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
28981d5dac46SHong Zhang   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
28991d5dac46SHong Zhang 
2900273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
2901273d9f13SBarry Smith 
2902416022c9SBarry Smith   C->factor           = A->factor;
29036ad4291fSHong Zhang 
2904416022c9SBarry Smith   c->row            = 0;
2905416022c9SBarry Smith   c->col            = 0;
290682bf6240SBarry Smith   c->icol           = 0;
29076ad4291fSHong Zhang   c->reallocs       = 0;
290817ab2063SBarry Smith 
29096ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
291017ab2063SBarry Smith 
291133b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
291217ab2063SBarry Smith   for (i=0; i<m; i++) {
2913416022c9SBarry Smith     c->imax[i] = a->imax[i];
2914416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
291517ab2063SBarry Smith   }
291617ab2063SBarry Smith 
291717ab2063SBarry Smith   /* allocate the matrix space */
2918a96a251dSBarry Smith   ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
2919f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
292097f1f81fSBarry Smith   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
292117ab2063SBarry Smith   if (m > 0) {
292297f1f81fSBarry Smith     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
2923be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2924bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2925be6bf707SBarry Smith     } else {
2926bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
292717ab2063SBarry Smith     }
292808480c60SBarry Smith   }
292917ab2063SBarry Smith 
2930416022c9SBarry Smith   c->sorted            = a->sorted;
29316ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
2932416022c9SBarry Smith   c->roworiented       = a->roworiented;
2933416022c9SBarry Smith   c->nonew             = a->nonew;
2934416022c9SBarry Smith   if (a->diag) {
293597f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
293652e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
293717ab2063SBarry Smith     for (i=0; i<m; i++) {
2938416022c9SBarry Smith       c->diag[i] = a->diag[i];
293917ab2063SBarry Smith     }
29403a40ed3dSBarry Smith   } else c->diag        = 0;
29416ad4291fSHong Zhang   c->solve_work         = 0;
29426ad4291fSHong Zhang   c->saved_values          = 0;
29436ad4291fSHong Zhang   c->idiag                 = 0;
29446ad4291fSHong Zhang   c->ssor                  = 0;
29456ad4291fSHong Zhang   c->keepzeroedrows        = a->keepzeroedrows;
29466ad4291fSHong Zhang   c->freedata              = PETSC_TRUE;
29476ad4291fSHong Zhang   c->xtoy                  = 0;
29486ad4291fSHong Zhang   c->XtoY                  = 0;
29496ad4291fSHong Zhang 
2950416022c9SBarry Smith   c->nz                 = a->nz;
2951416022c9SBarry Smith   c->maxnz              = a->maxnz;
2952273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2953754ec7b1SSatish Balay 
29546ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
29556ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
29566ad4291fSHong Zhang   c->compressedrow.checked = a->compressedrow.checked;
29576ad4291fSHong Zhang   if ( a->compressedrow.checked && a->compressedrow.use){
29586ad4291fSHong Zhang     i = a->compressedrow.nrows;
29596ad4291fSHong Zhang     ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr);
29606ad4291fSHong Zhang     c->compressedrow.rindex = c->compressedrow.i + i + 1;
29616ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
29626ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
296327ea64f8SHong Zhang   } else {
296427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
296527ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
296627ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
29676ad4291fSHong Zhang   }
296888e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
29696ad4291fSHong Zhang 
29704846f1f5SKris Buschelman   ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr);
29714846f1f5SKris Buschelman 
2972416022c9SBarry Smith   *B = C;
2973b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
29743a40ed3dSBarry Smith   PetscFunctionReturn(0);
297517ab2063SBarry Smith }
297617ab2063SBarry Smith 
29774a2ae208SSatish Balay #undef __FUNCT__
29784a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2979f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A)
298017ab2063SBarry Smith {
2981416022c9SBarry Smith   Mat_SeqAIJ     *a;
2982416022c9SBarry Smith   Mat            B;
29836849ba73SBarry Smith   PetscErrorCode ierr;
29843c601197SSatish Balay   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N;
298538baddfdSBarry Smith   int            fd;
298638baddfdSBarry Smith   PetscMPIInt    size;
2987bcd2baecSBarry Smith   MPI_Comm       comm;
298817ab2063SBarry Smith 
29893a40ed3dSBarry Smith   PetscFunctionBegin;
2990e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2991d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
299229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2993b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
29940752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2995552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
299617ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
299717ab2063SBarry Smith 
2998d64ed03dSBarry Smith   if (nz < 0) {
299929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3000d64ed03dSBarry Smith   }
3001d64ed03dSBarry Smith 
300217ab2063SBarry Smith   /* read in row lengths */
300397f1f81fSBarry Smith   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
30040752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
300517ab2063SBarry Smith 
30063c601197SSatish Balay   /* check if sum of rowlengths is same as nz */
30073c601197SSatish Balay   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
30083c601197SSatish Balay   if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
30093c601197SSatish Balay 
301017ab2063SBarry Smith   /* create our matrix */
3011f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,&B);CHKERRQ(ierr);
3012f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3013b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
3014ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr);
3015416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
301617ab2063SBarry Smith 
301717ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
30180752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
301917ab2063SBarry Smith 
302017ab2063SBarry Smith   /* read in nonzero values */
30210752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
302217ab2063SBarry Smith 
302317ab2063SBarry Smith   /* set matrix "i" values */
3024efb16452SHong Zhang   a->i[0] = 0;
302517ab2063SBarry Smith   for (i=1; i<= M; i++) {
3026416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3027416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
302817ab2063SBarry Smith   }
3029606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
303017ab2063SBarry Smith 
30316d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
30326d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3033b3a1e11cSKris Buschelman   *A = B;
30343a40ed3dSBarry Smith   PetscFunctionReturn(0);
303517ab2063SBarry Smith }
303617ab2063SBarry Smith 
30374a2ae208SSatish Balay #undef __FUNCT__
3038b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3039dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
30407264ac53SSatish Balay {
30417264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3042dfbe8321SBarry Smith   PetscErrorCode ierr;
30437264ac53SSatish Balay 
30443a40ed3dSBarry Smith   PetscFunctionBegin;
3045bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3046bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
3047ca44d042SBarry Smith     *flg = PETSC_FALSE;
3048ca44d042SBarry Smith     PetscFunctionReturn(0);
3049bcd2baecSBarry Smith   }
30507264ac53SSatish Balay 
30517264ac53SSatish Balay   /* if the a->i are the same */
305297f1f81fSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3053abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
30547264ac53SSatish Balay 
30557264ac53SSatish Balay   /* if a->j are the same */
305697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3057abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3058bcd2baecSBarry Smith 
3059bcd2baecSBarry Smith   /* if a->a are the same */
306087828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
30610f5bd95cSBarry Smith 
30623a40ed3dSBarry Smith   PetscFunctionReturn(0);
30637264ac53SSatish Balay 
30647264ac53SSatish Balay }
306536db0b34SBarry Smith 
30664a2ae208SSatish Balay #undef __FUNCT__
30674a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
306805869f15SSatish Balay /*@
306936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
307036db0b34SBarry Smith               provided by the user.
307136db0b34SBarry Smith 
307236db0b34SBarry Smith       Coolective on MPI_Comm
307336db0b34SBarry Smith 
307436db0b34SBarry Smith    Input Parameters:
307536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
307636db0b34SBarry Smith .   m - number of rows
307736db0b34SBarry Smith .   n - number of columns
307836db0b34SBarry Smith .   i - row indices
307936db0b34SBarry Smith .   j - column indices
308036db0b34SBarry Smith -   a - matrix values
308136db0b34SBarry Smith 
308236db0b34SBarry Smith    Output Parameter:
308336db0b34SBarry Smith .   mat - the matrix
308436db0b34SBarry Smith 
308536db0b34SBarry Smith    Level: intermediate
308636db0b34SBarry Smith 
308736db0b34SBarry Smith    Notes:
30880551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
308936db0b34SBarry Smith     once the matrix is destroyed
309036db0b34SBarry Smith 
309136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
309236db0b34SBarry Smith 
3093bfeeae90SHong Zhang        The i and j indices are 0 based
309436db0b34SBarry Smith 
309536db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
309636db0b34SBarry Smith 
309736db0b34SBarry Smith @*/
3098be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
309936db0b34SBarry Smith {
3100dfbe8321SBarry Smith   PetscErrorCode ierr;
310197f1f81fSBarry Smith   PetscInt       ii;
310236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
310336db0b34SBarry Smith 
310436db0b34SBarry Smith   PetscFunctionBegin;
3105a96a251dSBarry Smith   if (i[0]) {
3106634064b4SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
310736db0b34SBarry Smith   }
3108f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3109f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3110ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3111ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3112ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3113ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3114ab93d7beSBarry Smith 
311536db0b34SBarry Smith   aij->i = i;
311636db0b34SBarry Smith   aij->j = j;
311736db0b34SBarry Smith   aij->a = a;
311836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
311936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
312036db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
312136db0b34SBarry Smith 
312236db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
312336db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
31242515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
312579a5c55eSBarry Smith     if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]);
312636db0b34SBarry Smith #endif
312736db0b34SBarry Smith   }
31282515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
312936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
313079a5c55eSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
313179a5c55eSBarry Smith     if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]);
313236db0b34SBarry Smith   }
313336db0b34SBarry Smith #endif
313436db0b34SBarry Smith 
3135b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3136b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
313736db0b34SBarry Smith   PetscFunctionReturn(0);
313836db0b34SBarry Smith }
313936db0b34SBarry Smith 
3140cc8ba8e1SBarry Smith #undef __FUNCT__
3141ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3142dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3143cc8ba8e1SBarry Smith {
3144dfbe8321SBarry Smith   PetscErrorCode ierr;
3145cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
314636db0b34SBarry Smith 
3147cc8ba8e1SBarry Smith   PetscFunctionBegin;
314812c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
3149cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3150cc8ba8e1SBarry Smith     a->coloring = coloring;
315112c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
315297f1f81fSBarry Smith     PetscInt             i,*larray;
315312c595b3SBarry Smith     ISColoring      ocoloring;
315408b6dcc0SBarry Smith     ISColoringValue *colors;
315512c595b3SBarry Smith 
315612c595b3SBarry Smith     /* set coloring for diagonal portion */
315797f1f81fSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr);
315812c595b3SBarry Smith     for (i=0; i<A->n; i++) {
315912c595b3SBarry Smith       larray[i] = i;
316012c595b3SBarry Smith     }
316112c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
316208b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
316312c595b3SBarry Smith     for (i=0; i<A->n; i++) {
316412c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
316512c595b3SBarry Smith     }
316612c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
316712c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
316812c595b3SBarry Smith     a->coloring = ocoloring;
316912c595b3SBarry Smith   }
3170cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3171cc8ba8e1SBarry Smith }
3172cc8ba8e1SBarry Smith 
3173dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3174ee4f033dSBarry Smith EXTERN_C_BEGIN
317529c1e371SBarry Smith #include "adic/ad_utils.h"
3176ee4f033dSBarry Smith EXTERN_C_END
3177cc8ba8e1SBarry Smith 
3178cc8ba8e1SBarry Smith #undef __FUNCT__
3179ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3180dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3181cc8ba8e1SBarry Smith {
3182cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
318397f1f81fSBarry Smith   PetscInt        m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
31844440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
318508b6dcc0SBarry Smith   ISColoringValue *color;
3186cc8ba8e1SBarry Smith 
3187cc8ba8e1SBarry Smith   PetscFunctionBegin;
3188e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
31894440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3190cc8ba8e1SBarry Smith   color = a->coloring->colors;
3191cc8ba8e1SBarry Smith   /* loop over rows */
3192cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3193cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3194cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3195cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3196cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3197cc8ba8e1SBarry Smith     }
31984440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3199ee4f033dSBarry Smith   }
3200ee4f033dSBarry Smith   PetscFunctionReturn(0);
3201ee4f033dSBarry Smith }
3202ee4f033dSBarry Smith #endif
3203ee4f033dSBarry Smith 
3204ee4f033dSBarry Smith #undef __FUNCT__
3205ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
320697f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3207ee4f033dSBarry Smith {
3208ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
320997f1f81fSBarry Smith   PetscInt             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
321087828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
321108b6dcc0SBarry Smith   ISColoringValue *color;
3212ee4f033dSBarry Smith 
3213ee4f033dSBarry Smith   PetscFunctionBegin;
3214e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3215ee4f033dSBarry Smith   color = a->coloring->colors;
3216ee4f033dSBarry Smith   /* loop over rows */
3217ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3218ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3219ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3220ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3221ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3222ee4f033dSBarry Smith     }
3223ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3224cc8ba8e1SBarry Smith   }
3225cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3226cc8ba8e1SBarry Smith }
322736db0b34SBarry Smith 
3228