xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 79299369c476447a506f61cd6bc42de1d356e227)
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__
14*79299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
15*79299369SBarry Smith /*   only works if matrix has a full set of diagonal entries */
16*79299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
17*79299369SBarry Smith {
18*79299369SBarry Smith   PetscErrorCode ierr;
19*79299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
20*79299369SBarry Smith   PetscInt       i,*diag, m = Y->m;
21*79299369SBarry Smith   PetscScalar    *v,*aa = aij->a;
22*79299369SBarry Smith 
23*79299369SBarry Smith   PetscFunctionBegin;
24*79299369SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(Y);CHKERRQ(ierr);
25*79299369SBarry Smith   diag = aij->diag;
26*79299369SBarry Smith   ierr = VecGetArray(D,&v);CHKERRQ(ierr);
27*79299369SBarry Smith   if (is == INSERT_VALUES) {
28*79299369SBarry Smith     for (i=0; i<m; i++) {
29*79299369SBarry Smith       aa[diag[i]] = v[i];
30*79299369SBarry Smith     }
31*79299369SBarry Smith   } else {
32*79299369SBarry Smith     for (i=0; i<m; i++) {
33*79299369SBarry Smith       aa[diag[i]] += v[i];
34*79299369SBarry Smith     }
35*79299369SBarry Smith   }
36*79299369SBarry Smith   ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
37*79299369SBarry Smith   PetscFunctionReturn(0);
38*79299369SBarry Smith }
39*79299369SBarry Smith 
40*79299369SBarry 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;
867aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
86897952fefSHong Zhang   PetscInt       n,i,jrow,j,*ridx=PETSC_NULL;
869362ced78SSatish Balay   PetscScalar    sum;
87097952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
871e36a17ebSSatish Balay #endif
87217ab2063SBarry Smith 
873b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
87497952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
875fee21e36SBarry Smith #endif
876fee21e36SBarry Smith 
8773a40ed3dSBarry Smith   PetscFunctionBegin;
8781ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8791ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
88097952fefSHong Zhang   aj  = a->j;
88197952fefSHong Zhang   aa    = a->a;
882416022c9SBarry Smith   ii   = a->i;
8834eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
88497952fefSHong Zhang     m    = a->compressedrow.nrows;
88597952fefSHong Zhang     ii   = a->compressedrow.i;
88697952fefSHong Zhang     ridx = a->compressedrow.rindex;
88797952fefSHong Zhang     for (i=0; i<m; i++){
88897952fefSHong Zhang       n   = ii[i+1] - ii[i];
88997952fefSHong Zhang       aj  = a->j + ii[i];
89097952fefSHong Zhang       aa  = a->a + ii[i];
89197952fefSHong Zhang       sum = 0.0;
89297952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
89397952fefSHong Zhang       y[*ridx++] = sum;
89497952fefSHong Zhang     }
89597952fefSHong Zhang   } else { /* do not use compressed row format */
896b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
897b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
898b05257ddSBarry Smith #else
89917ab2063SBarry Smith     for (i=0; i<m; i++) {
9009ea0dfa2SSatish Balay       jrow = ii[i];
9019ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
90217ab2063SBarry Smith       sum  = 0.0;
9039ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
90497952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9059ea0dfa2SSatish Balay       }
90617ab2063SBarry Smith       y[i] = sum;
90717ab2063SBarry Smith     }
9088d195f9aSBarry Smith #endif
909b05257ddSBarry Smith   }
910efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz - m);CHKERRQ(ierr);
9111ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9121ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9133a40ed3dSBarry Smith   PetscFunctionReturn(0);
91417ab2063SBarry Smith }
91517ab2063SBarry Smith 
9164a2ae208SSatish Balay #undef __FUNCT__
9174a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
918dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
91917ab2063SBarry Smith {
920416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
92197952fefSHong Zhang   PetscScalar    *x,*y,*z,*aa;
922dfbe8321SBarry Smith   PetscErrorCode ierr;
92397952fefSHong Zhang   PetscInt       m = A->m,*aj,*ii;
924aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
92597952fefSHong Zhang   PetscInt       n,i,jrow,j,*ridx=PETSC_NULL;
926362ced78SSatish Balay   PetscScalar    sum;
92797952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
928e36a17ebSSatish Balay #endif
9299ea0dfa2SSatish Balay 
9303a40ed3dSBarry Smith   PetscFunctionBegin;
9311ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9321ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9332e8a6d31SBarry Smith   if (zz != yy) {
9341ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9352e8a6d31SBarry Smith   } else {
9362e8a6d31SBarry Smith     z = y;
9372e8a6d31SBarry Smith   }
938bfeeae90SHong Zhang 
93997952fefSHong Zhang   aj  = a->j;
94097952fefSHong Zhang   aa  = a->a;
941cddf8d76SBarry Smith   ii  = a->i;
942aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
94397952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
94402ab625aSSatish Balay #else
9454eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
9464eb6d288SHong Zhang     if (zz != yy){
9474eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
9484eb6d288SHong Zhang     }
94997952fefSHong Zhang     m    = a->compressedrow.nrows;
95097952fefSHong Zhang     ii   = a->compressedrow.i;
95197952fefSHong Zhang     ridx = a->compressedrow.rindex;
95297952fefSHong Zhang     for (i=0; i<m; i++){
95397952fefSHong Zhang       n  = ii[i+1] - ii[i];
95497952fefSHong Zhang       aj  = a->j + ii[i];
95597952fefSHong Zhang       aa  = a->a + ii[i];
95697952fefSHong Zhang       sum = y[*ridx];
95797952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
95897952fefSHong Zhang       z[*ridx++] = sum;
95997952fefSHong Zhang     }
96097952fefSHong Zhang   } else { /* do not use compressed row format */
96117ab2063SBarry Smith     for (i=0; i<m; i++) {
9629ea0dfa2SSatish Balay       jrow = ii[i];
9639ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
96417ab2063SBarry Smith       sum  = y[i];
9659ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
96697952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9679ea0dfa2SSatish Balay       }
96817ab2063SBarry Smith       z[i] = sum;
96917ab2063SBarry Smith     }
97097952fefSHong Zhang   }
97102ab625aSSatish Balay #endif
972efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
9731ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9741ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9752e8a6d31SBarry Smith   if (zz != yy) {
9761ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9772e8a6d31SBarry Smith   }
9783a40ed3dSBarry Smith   PetscFunctionReturn(0);
97917ab2063SBarry Smith }
98017ab2063SBarry Smith 
98117ab2063SBarry Smith /*
98217ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
98317ab2063SBarry Smith */
9844a2ae208SSatish Balay #undef __FUNCT__
9854a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
986dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
98717ab2063SBarry Smith {
988416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9896849ba73SBarry Smith   PetscErrorCode ierr;
99097f1f81fSBarry Smith   PetscInt       i,j,*diag,m = A->m;
99117ab2063SBarry Smith 
9923a40ed3dSBarry Smith   PetscFunctionBegin;
993f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
994f1e2ffcdSBarry Smith 
99597f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&diag);CHKERRQ(ierr);
99652e6d16bSBarry Smith   ierr = PetscLogObjectMemory(A,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
997273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
99835b0346bSBarry Smith     diag[i] = a->i[i+1];
999bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1000bfeeae90SHong Zhang       if (a->j[j] == i) {
1001bfeeae90SHong Zhang         diag[i] = j;
100217ab2063SBarry Smith         break;
100317ab2063SBarry Smith       }
100417ab2063SBarry Smith     }
100517ab2063SBarry Smith   }
1006416022c9SBarry Smith   a->diag = diag;
10073a40ed3dSBarry Smith   PetscFunctionReturn(0);
100817ab2063SBarry Smith }
100917ab2063SBarry Smith 
1010be5855fcSBarry Smith /*
1011be5855fcSBarry Smith      Checks for missing diagonals
1012be5855fcSBarry Smith */
10134a2ae208SSatish Balay #undef __FUNCT__
10144a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1015dfbe8321SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A)
1016be5855fcSBarry Smith {
1017be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10186849ba73SBarry Smith   PetscErrorCode ierr;
101997f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1020be5855fcSBarry Smith 
1021be5855fcSBarry Smith   PetscFunctionBegin;
1022f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1023f1e2ffcdSBarry Smith   diag = a->diag;
1024273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
1025bfeeae90SHong Zhang     if (jj[diag[i]] != i) {
102677431f27SBarry Smith       SETERRQ1(PETSC_ERR_PLIB,"Matrix is missing diagonal number %D",i);
1027be5855fcSBarry Smith     }
1028be5855fcSBarry Smith   }
1029be5855fcSBarry Smith   PetscFunctionReturn(0);
1030be5855fcSBarry Smith }
1031be5855fcSBarry Smith 
10324a2ae208SSatish Balay #undef __FUNCT__
10334a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
103497f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
103517ab2063SBarry Smith {
1036416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1037beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
1038beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
1039dfbe8321SBarry Smith   PetscErrorCode     ierr;
104097f1f81fSBarry Smith   PetscInt           n = A->n,m = A->m,i;
104197f1f81fSBarry Smith   const PetscInt     *idx,*diag;
104217ab2063SBarry Smith 
10433a40ed3dSBarry Smith   PetscFunctionBegin;
1044b965ef7fSBarry Smith   its = its*lits;
104577431f27SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
104691723122SBarry Smith 
1047ed480e8bSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1048ed480e8bSBarry Smith   diag = a->diag;
1049ed480e8bSBarry Smith   if (!a->idiag) {
1050ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1051ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1052ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1053ed480e8bSBarry Smith 
1054ed480e8bSBarry Smith     v        = a->a;
1055ed480e8bSBarry Smith 
1056ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1057958c9bccSBarry Smith     if (omega == 1.0 && !fshift) {
1058ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1059ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1060ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1061ed480e8bSBarry Smith       }
1062efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
1063ed480e8bSBarry Smith     } else {
1064ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1065ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1066beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1067ed480e8bSBarry Smith       }
1068efee365bSSatish Balay       ierr = PetscLogFlops(2*m);CHKERRQ(ierr);
1069beeb8507SBarry Smith     }
1070ed480e8bSBarry Smith   }
1071ed480e8bSBarry Smith   t     = a->ssor;
1072ed480e8bSBarry Smith   idiag = a->idiag;
1073ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1074ed480e8bSBarry Smith 
10751ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1076fb2e594dSBarry Smith   if (xx != bb) {
10771ebc52fbSHong Zhang     ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1078fb2e594dSBarry Smith   } else {
1079fb2e594dSBarry Smith     b = x;
1080fb2e594dSBarry Smith   }
1081fb2e594dSBarry Smith 
1082ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1083ed480e8bSBarry Smith   xs   = x;
108417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
108517ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1086ed480e8bSBarry Smith     bs = b;
108717ab2063SBarry Smith     for (i=0; i<m; i++) {
1088ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1089416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1090ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1091ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
109217ab2063SBarry Smith         sum  = b[i]*d/omega;
109317ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
109417ab2063SBarry Smith         x[i] = sum;
109517ab2063SBarry Smith     }
10961ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10971ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1098efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
10993a40ed3dSBarry Smith     PetscFunctionReturn(0);
110017ab2063SBarry Smith   }
1101c783ea89SBarry Smith 
1102ed480e8bSBarry Smith 
1103fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1104fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1105fc3d8934SBarry Smith 
1106fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1107fc3d8934SBarry Smith 
1108fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1109fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
111048af12d7SBarry Smith     is the relaxation factor.
1111fc3d8934SBarry Smith     */
1112fc3d8934SBarry Smith 
111348af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
111429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
11153a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
111617ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
111717ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
111817ab2063SBarry Smith 
111917ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
112017ab2063SBarry Smith 
112117ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
112217ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
112317ab2063SBarry Smith     is the relaxation factor.
112417ab2063SBarry Smith     */
112517ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
112617ab2063SBarry Smith 
112717ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
112817ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1129416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1130ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1131ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
113217ab2063SBarry Smith       sum  = b[i];
113317ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1134ed480e8bSBarry Smith       x[i] = sum*idiag[i];
113517ab2063SBarry Smith     }
113617ab2063SBarry Smith 
113717ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1138416022c9SBarry Smith     v = a->a;
1139ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
114017ab2063SBarry Smith 
114117ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1142ed480e8bSBarry Smith     ts = t;
1143416022c9SBarry Smith     diag = a->diag;
114417ab2063SBarry Smith     for (i=0; i<m; i++) {
1145416022c9SBarry Smith       n    = diag[i] - a->i[i];
1146ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1147ed480e8bSBarry Smith       v    = a->a + a->i[i];
114817ab2063SBarry Smith       sum  = t[i];
114917ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1150ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1151733d66baSBarry Smith       /*  x = x + t */
1152733d66baSBarry Smith       x[i] += t[i];
115317ab2063SBarry Smith     }
115417ab2063SBarry Smith 
1155efee365bSSatish Balay     ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr);
11561ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11571ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11583a40ed3dSBarry Smith     PetscFunctionReturn(0);
115917ab2063SBarry Smith   }
116017ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
116117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
116277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
116397f1f81fSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b);
116477d8c4bbSBarry Smith #else
116517ab2063SBarry Smith       for (i=0; i<m; i++) {
1166416022c9SBarry Smith         n    = diag[i] - a->i[i];
1167ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1168ed480e8bSBarry Smith         v    = a->a + a->i[i];
116917ab2063SBarry Smith         sum  = b[i];
117017ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1171ed480e8bSBarry Smith         x[i] = sum*idiag[i];
117217ab2063SBarry Smith       }
117377d8c4bbSBarry Smith #endif
117417ab2063SBarry Smith       xb = x;
1175efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
11763a40ed3dSBarry Smith     } else xb = b;
117717ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
117817ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
117917ab2063SBarry Smith       for (i=0; i<m; i++) {
1180ed480e8bSBarry Smith         x[i] *= mdiag[i];
118117ab2063SBarry Smith       }
1182efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
118317ab2063SBarry Smith     }
118417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
118577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
118697f1f81fSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb);
118777d8c4bbSBarry Smith #else
118817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1189416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1190ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1191ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
119217ab2063SBarry Smith         sum  = xb[i];
119317ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1194ed480e8bSBarry Smith         x[i] = sum*idiag[i];
119517ab2063SBarry Smith       }
119677d8c4bbSBarry Smith #endif
1197efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
119817ab2063SBarry Smith     }
119917ab2063SBarry Smith     its--;
120017ab2063SBarry Smith   }
120117ab2063SBarry Smith   while (its--) {
120217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
120377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
120497f1f81fSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
120577d8c4bbSBarry Smith #else
120617ab2063SBarry Smith       for (i=0; i<m; i++) {
1207ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1208416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1209ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1210ed480e8bSBarry Smith         v    = a->a + a->i[i];
121117ab2063SBarry Smith         sum  = b[i];
121217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1213ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
121417ab2063SBarry Smith       }
121577d8c4bbSBarry Smith #endif
1216efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
121717ab2063SBarry Smith     }
121817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
121977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
122097f1f81fSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
122177d8c4bbSBarry Smith #else
122217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1223ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1224416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1225ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1226ed480e8bSBarry Smith         v    = a->a + a->i[i];
122717ab2063SBarry Smith         sum  = b[i];
122817ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1229ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
123017ab2063SBarry Smith       }
123177d8c4bbSBarry Smith #endif
1232efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
123317ab2063SBarry Smith     }
123417ab2063SBarry Smith   }
12351ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12361ebc52fbSHong Zhang   if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
12373a40ed3dSBarry Smith   PetscFunctionReturn(0);
123817ab2063SBarry Smith }
123917ab2063SBarry Smith 
12404a2ae208SSatish Balay #undef __FUNCT__
12414a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1242dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
124317ab2063SBarry Smith {
1244416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12454e220ebcSLois Curfman McInnes 
12463a40ed3dSBarry Smith   PetscFunctionBegin;
1247273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1248273d9f13SBarry Smith   info->columns_global = (double)A->n;
1249273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1250273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12514e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12524e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12534e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12544e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12554e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12564e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12574e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12584e220ebcSLois Curfman McInnes   if (A->factor) {
12594e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12604e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12614e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12624e220ebcSLois Curfman McInnes   } else {
12634e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12644e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12654e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12664e220ebcSLois Curfman McInnes   }
12673a40ed3dSBarry Smith   PetscFunctionReturn(0);
126817ab2063SBarry Smith }
126917ab2063SBarry Smith 
12704a2ae208SSatish Balay #undef __FUNCT__
12714a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1272f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag)
127317ab2063SBarry Smith {
1274416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1275f4df32b1SMatthew Knepley   PetscInt       i,m = A->m - 1;
12766849ba73SBarry Smith   PetscErrorCode ierr;
127717ab2063SBarry Smith 
12783a40ed3dSBarry Smith   PetscFunctionBegin;
1279f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1280f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
128177431f27SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1282bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1283f1e2ffcdSBarry Smith     }
1284f4df32b1SMatthew Knepley     if (diag != 0.0) {
1285f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1286f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1287f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1288f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1289f1e2ffcdSBarry Smith       }
1290f1e2ffcdSBarry Smith     }
129188e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1292f1e2ffcdSBarry Smith   } else {
1293f4df32b1SMatthew Knepley     if (diag != 0.0) {
129417ab2063SBarry Smith       for (i=0; i<N; i++) {
129577431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
12967ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1297416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1298f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1299bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
13007ae801bdSBarry Smith         } else { /* in case row was completely empty */
1301f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
130217ab2063SBarry Smith         }
130317ab2063SBarry Smith       }
13043a40ed3dSBarry Smith     } else {
130517ab2063SBarry Smith       for (i=0; i<N; i++) {
130677431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1307416022c9SBarry Smith         a->ilen[rows[i]] = 0;
130817ab2063SBarry Smith       }
130917ab2063SBarry Smith     }
131088e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1311f1e2ffcdSBarry Smith   }
131243a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13133a40ed3dSBarry Smith   PetscFunctionReturn(0);
131417ab2063SBarry Smith }
131517ab2063SBarry Smith 
13164a2ae208SSatish Balay #undef __FUNCT__
13174a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
131897f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
131917ab2063SBarry Smith {
1320416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
132197f1f81fSBarry Smith   PetscInt   *itmp;
132217ab2063SBarry Smith 
13233a40ed3dSBarry Smith   PetscFunctionBegin;
132477431f27SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
132517ab2063SBarry Smith 
1326416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1327bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
132817ab2063SBarry Smith   if (idx) {
1329bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1330bfeeae90SHong Zhang     if (*nz) {
13314e093b46SBarry Smith       *idx = itmp;
133217ab2063SBarry Smith     }
133317ab2063SBarry Smith     else *idx = 0;
133417ab2063SBarry Smith   }
13353a40ed3dSBarry Smith   PetscFunctionReturn(0);
133617ab2063SBarry Smith }
133717ab2063SBarry Smith 
1338bfeeae90SHong Zhang /* remove this function? */
13394a2ae208SSatish Balay #undef __FUNCT__
13404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
134197f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
134217ab2063SBarry Smith {
13433a40ed3dSBarry Smith   PetscFunctionBegin;
13443a40ed3dSBarry Smith   PetscFunctionReturn(0);
134517ab2063SBarry Smith }
134617ab2063SBarry Smith 
13474a2ae208SSatish Balay #undef __FUNCT__
13484a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1349dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
135017ab2063SBarry Smith {
1351416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
135287828ca2SBarry Smith   PetscScalar    *v = a->a;
135336db0b34SBarry Smith   PetscReal      sum = 0.0;
13546849ba73SBarry Smith   PetscErrorCode ierr;
135597f1f81fSBarry Smith   PetscInt       i,j;
135617ab2063SBarry Smith 
13573a40ed3dSBarry Smith   PetscFunctionBegin;
135817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1359416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1360aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
136136db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
136217ab2063SBarry Smith #else
136317ab2063SBarry Smith       sum += (*v)*(*v); v++;
136417ab2063SBarry Smith #endif
136517ab2063SBarry Smith     }
1366064f8208SBarry Smith     *nrm = sqrt(sum);
13673a40ed3dSBarry Smith   } else if (type == NORM_1) {
136836db0b34SBarry Smith     PetscReal *tmp;
136997f1f81fSBarry Smith     PetscInt    *jj = a->j;
1370b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1371273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1372064f8208SBarry Smith     *nrm = 0.0;
1373416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1374bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
137517ab2063SBarry Smith     }
1376273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1377064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
137817ab2063SBarry Smith     }
1379606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13803a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1381064f8208SBarry Smith     *nrm = 0.0;
1382273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1383bfeeae90SHong Zhang       v = a->a + a->i[j];
138417ab2063SBarry Smith       sum = 0.0;
1385416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1386cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
138717ab2063SBarry Smith       }
1388064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
138917ab2063SBarry Smith     }
13903a40ed3dSBarry Smith   } else {
139129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
139217ab2063SBarry Smith   }
13933a40ed3dSBarry Smith   PetscFunctionReturn(0);
139417ab2063SBarry Smith }
139517ab2063SBarry Smith 
13964a2ae208SSatish Balay #undef __FUNCT__
13974a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1398dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B)
139917ab2063SBarry Smith {
1400416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1401416022c9SBarry Smith   Mat            C;
14026849ba73SBarry Smith   PetscErrorCode ierr;
140397f1f81fSBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->m,len,*col;
140487828ca2SBarry Smith   PetscScalar    *array = a->a;
140517ab2063SBarry Smith 
14063a40ed3dSBarry Smith   PetscFunctionBegin;
1407273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
140897f1f81fSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
140997f1f81fSBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(PetscInt));CHKERRQ(ierr);
1410bfeeae90SHong Zhang 
1411bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1412f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1413f69a0ea3SMatthew Knepley   ierr = MatSetSizes(C,A->n,m,A->n,m);CHKERRQ(ierr);
1414f204ca49SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1415ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1416606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
141717ab2063SBarry Smith   for (i=0; i<m; i++) {
141817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1419416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1420b9b97703SBarry Smith     array += len;
1421b9b97703SBarry Smith     aj    += len;
142217ab2063SBarry Smith   }
142317ab2063SBarry Smith 
14246d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14256d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
142617ab2063SBarry Smith 
1427f1e2ffcdSBarry Smith   if (B) {
1428416022c9SBarry Smith     *B = C;
142917ab2063SBarry Smith   } else {
1430273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
143117ab2063SBarry Smith   }
14323a40ed3dSBarry Smith   PetscFunctionReturn(0);
143317ab2063SBarry Smith }
143417ab2063SBarry Smith 
1435cd0d46ebSvictorle EXTERN_C_BEGIN
1436cd0d46ebSvictorle #undef __FUNCT__
14375fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
1438be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f)
1439cd0d46ebSvictorle {
1440cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
144197f1f81fSBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
14426849ba73SBarry Smith   PetscErrorCode ierr;
144397f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1444cd0d46ebSvictorle 
1445cd0d46ebSvictorle   PetscFunctionBegin;
1446cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1447cd0d46ebSvictorle 
1448cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1449cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
14505485867bSBarry Smith   if (ma!=nb || na!=mb){
14515485867bSBarry Smith     *f = PETSC_FALSE;
14525485867bSBarry Smith     PetscFunctionReturn(0);
14535485867bSBarry Smith   }
1454cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1455cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1456cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
145797f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
145897f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1459cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1460cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1461cd0d46ebSvictorle 
1462cd0d46ebSvictorle   *f = PETSC_TRUE;
1463cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1464cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
146597f1f81fSBarry Smith       PetscInt         idc,idr;
14665485867bSBarry Smith       PetscScalar vc,vr;
1467cd0d46ebSvictorle       /* column/row index/value */
14685485867bSBarry Smith       idc = adx[aptr[i]];
14695485867bSBarry Smith       idr = bdx[bptr[idc]];
14705485867bSBarry Smith       vc  = va[aptr[i]];
14715485867bSBarry Smith       vr  = vb[bptr[idc]];
14725485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
14735485867bSBarry Smith 	*f = PETSC_FALSE;
14745485867bSBarry Smith         goto done;
1475cd0d46ebSvictorle       } else {
14765485867bSBarry Smith 	aptr[i]++;
14775485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1478cd0d46ebSvictorle       }
1479cd0d46ebSvictorle     }
1480cd0d46ebSvictorle   }
1481cd0d46ebSvictorle  done:
1482cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
14833aeef889SHong Zhang   if (B) {
14843aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
14853aeef889SHong Zhang   }
1486cd0d46ebSvictorle   PetscFunctionReturn(0);
1487cd0d46ebSvictorle }
1488cd0d46ebSvictorle EXTERN_C_END
1489cd0d46ebSvictorle 
14909e29f15eSvictorle #undef __FUNCT__
14919e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1492dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f)
14939e29f15eSvictorle {
1494dfbe8321SBarry Smith   PetscErrorCode ierr;
14959e29f15eSvictorle   PetscFunctionBegin;
14965485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
14979e29f15eSvictorle   PetscFunctionReturn(0);
14989e29f15eSvictorle }
14999e29f15eSvictorle 
15004a2ae208SSatish Balay #undef __FUNCT__
15014a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1502dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
150317ab2063SBarry Smith {
1504416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
150587828ca2SBarry Smith   PetscScalar    *l,*r,x,*v;
1506dfbe8321SBarry Smith   PetscErrorCode ierr;
150797f1f81fSBarry Smith   PetscInt       i,j,m = A->m,n = A->n,M,nz = a->nz,*jj;
150817ab2063SBarry Smith 
15093a40ed3dSBarry Smith   PetscFunctionBegin;
151017ab2063SBarry Smith   if (ll) {
15113ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
15123ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1513e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1514273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
15151ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1516416022c9SBarry Smith     v = a->a;
151717ab2063SBarry Smith     for (i=0; i<m; i++) {
151817ab2063SBarry Smith       x = l[i];
1519416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
152017ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
152117ab2063SBarry Smith     }
15221ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1523efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
152417ab2063SBarry Smith   }
152517ab2063SBarry Smith   if (rr) {
1526e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1527273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
15281ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1529416022c9SBarry Smith     v = a->a; jj = a->j;
153017ab2063SBarry Smith     for (i=0; i<nz; i++) {
1531bfeeae90SHong Zhang       (*v++) *= r[*jj++];
153217ab2063SBarry Smith     }
15331ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1534efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
153517ab2063SBarry Smith   }
15363a40ed3dSBarry Smith   PetscFunctionReturn(0);
153717ab2063SBarry Smith }
153817ab2063SBarry Smith 
15394a2ae208SSatish Balay #undef __FUNCT__
15404a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
154197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
154217ab2063SBarry Smith {
1543db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
15446849ba73SBarry Smith   PetscErrorCode ierr;
154597f1f81fSBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->n,*lens;
154697f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
154797f1f81fSBarry Smith   PetscInt       *irow,*icol,nrows,ncols;
154897f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
154987828ca2SBarry Smith   PetscScalar    *a_new,*mat_a;
1550416022c9SBarry Smith   Mat            C;
1551fee21e36SBarry Smith   PetscTruth     stride;
155217ab2063SBarry Smith 
15533a40ed3dSBarry Smith   PetscFunctionBegin;
1554d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
155529bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1556d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
155729bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
155899141d43SSatish Balay 
155917ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1560b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1561b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
156217ab2063SBarry Smith 
1563fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1564fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1565fee21e36SBarry Smith   if (stride && step == 1) {
156602834360SBarry Smith     /* special case of contiguous rows */
156797f1f81fSBarry Smith     ierr   = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
156831ebf83bSSatish Balay     starts = lens + nrows;
156902834360SBarry Smith     /* loop over new rows determining lens and starting points */
157002834360SBarry Smith     for (i=0; i<nrows; i++) {
1571bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1572a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
157302834360SBarry Smith       for (k=kstart; k<kend; k++) {
1574bfeeae90SHong Zhang         if (aj[k] >= first) {
157502834360SBarry Smith           starts[i] = k;
157602834360SBarry Smith           break;
157702834360SBarry Smith 	}
157802834360SBarry Smith       }
1579a2744918SBarry Smith       sum = 0;
158002834360SBarry Smith       while (k < kend) {
1581bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1582a2744918SBarry Smith         sum++;
158302834360SBarry Smith       }
1584a2744918SBarry Smith       lens[i] = sum;
158502834360SBarry Smith     }
158602834360SBarry Smith     /* create submatrix */
1587cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
158897f1f81fSBarry Smith       PetscInt n_cols,n_rows;
158908480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
159029bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1591d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
159208480c60SBarry Smith       C = *B;
15933a40ed3dSBarry Smith     } else {
1594f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1595f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1596e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1597ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
159808480c60SBarry Smith     }
1599db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1600db02288aSLois Curfman McInnes 
160102834360SBarry Smith     /* loop over rows inserting into submatrix */
1602db02288aSLois Curfman McInnes     a_new    = c->a;
1603db02288aSLois Curfman McInnes     j_new    = c->j;
1604db02288aSLois Curfman McInnes     i_new    = c->i;
1605bfeeae90SHong Zhang 
160602834360SBarry Smith     for (i=0; i<nrows; i++) {
1607a2744918SBarry Smith       ii    = starts[i];
1608a2744918SBarry Smith       lensi = lens[i];
1609a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1610a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
161102834360SBarry Smith       }
161287828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1613a2744918SBarry Smith       a_new      += lensi;
1614a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1615a2744918SBarry Smith       c->ilen[i]  = lensi;
161602834360SBarry Smith     }
1617606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
16183a40ed3dSBarry Smith   } else {
161902834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
162097f1f81fSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr);
1621bfeeae90SHong Zhang 
162297f1f81fSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
162397f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
162417ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
162502834360SBarry Smith     /* determine lens of each row */
162602834360SBarry Smith     for (i=0; i<nrows; i++) {
1627bfeeae90SHong Zhang       kstart  = ai[irow[i]];
162802834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
162902834360SBarry Smith       lens[i] = 0;
163002834360SBarry Smith       for (k=kstart; k<kend; k++) {
1631bfeeae90SHong Zhang         if (smap[aj[k]]) {
163202834360SBarry Smith           lens[i]++;
163302834360SBarry Smith         }
163402834360SBarry Smith       }
163502834360SBarry Smith     }
163617ab2063SBarry Smith     /* Create and fill new matrix */
1637a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16380f5bd95cSBarry Smith       PetscTruth equal;
16390f5bd95cSBarry Smith 
164099141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1641273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
164297f1f81fSBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(PetscInt),&equal);CHKERRQ(ierr);
16430f5bd95cSBarry Smith       if (!equal) {
164429bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
164599141d43SSatish Balay       }
164697f1f81fSBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(PetscInt));CHKERRQ(ierr);
164708480c60SBarry Smith       C = *B;
16483a40ed3dSBarry Smith     } else {
1649f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1650f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1651e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1652ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
165308480c60SBarry Smith     }
165499141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
165517ab2063SBarry Smith     for (i=0; i<nrows; i++) {
165699141d43SSatish Balay       row    = irow[i];
1657bfeeae90SHong Zhang       kstart = ai[row];
165899141d43SSatish Balay       kend   = kstart + a->ilen[row];
1659bfeeae90SHong Zhang       mat_i  = c->i[i];
166099141d43SSatish Balay       mat_j  = c->j + mat_i;
166199141d43SSatish Balay       mat_a  = c->a + mat_i;
166299141d43SSatish Balay       mat_ilen = c->ilen + i;
166317ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1664bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1665ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
166699141d43SSatish Balay           *mat_a++ = a->a[k];
166799141d43SSatish Balay           (*mat_ilen)++;
166899141d43SSatish Balay 
166917ab2063SBarry Smith         }
167017ab2063SBarry Smith       }
167117ab2063SBarry Smith     }
167202834360SBarry Smith     /* Free work space */
167302834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1674606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1675606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
167602834360SBarry Smith   }
16776d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16786d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
167917ab2063SBarry Smith 
168017ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1681416022c9SBarry Smith   *B = C;
16823a40ed3dSBarry Smith   PetscFunctionReturn(0);
168317ab2063SBarry Smith }
168417ab2063SBarry Smith 
1685a871dcd8SBarry Smith /*
1686a871dcd8SBarry Smith */
16874a2ae208SSatish Balay #undef __FUNCT__
16884a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1689dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1690a871dcd8SBarry Smith {
169163b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
1692dfbe8321SBarry Smith   PetscErrorCode ierr;
169363b91edcSBarry Smith   Mat            outA;
1694b8a78c4aSBarry Smith   PetscTruth     row_identity,col_identity;
169563b91edcSBarry Smith 
16963a40ed3dSBarry Smith   PetscFunctionBegin;
1697d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1698b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1699b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1700b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1701634064b4SBarry Smith     SETERRQ(PETSC_ERR_ARG_WRONG,"Row and column permutations must be identity for in-place ILU");
1702b8a78c4aSBarry Smith   }
1703a871dcd8SBarry Smith 
170463b91edcSBarry Smith   outA          = inA;
170563b91edcSBarry Smith   inA->factor   = FACTOR_LU;
170663b91edcSBarry Smith   a->row        = row;
170763b91edcSBarry Smith   a->col        = col;
1708c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1709c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
171063b91edcSBarry Smith 
171136db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1712b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
17134c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
171452e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
1715f0ec6fceSSatish Balay 
171694a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
171787828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
171894a9d846SBarry Smith   }
171963b91edcSBarry Smith 
172008480c60SBarry Smith   if (!a->diag) {
1721f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
172263b91edcSBarry Smith   }
1723af281ebdSHong Zhang   ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr);
17243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1725a871dcd8SBarry Smith }
1726a871dcd8SBarry Smith 
1727d9eff348SSatish Balay #include "petscblaslapack.h"
17284a2ae208SSatish Balay #undef __FUNCT__
17294a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1730f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
1731f0b747eeSBarry Smith {
1732f0b747eeSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)inA->data;
17334ce68768SBarry Smith   PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1;
1734f4df32b1SMatthew Knepley   PetscScalar oalpha = alpha;
1735efee365bSSatish Balay   PetscErrorCode ierr;
1736efee365bSSatish Balay 
17373a40ed3dSBarry Smith 
17383a40ed3dSBarry Smith   PetscFunctionBegin;
1739f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
1740efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1742f0b747eeSBarry Smith }
1743f0b747eeSBarry Smith 
17444a2ae208SSatish Balay #undef __FUNCT__
17454a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
174697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1747cddf8d76SBarry Smith {
1748dfbe8321SBarry Smith   PetscErrorCode ierr;
174997f1f81fSBarry Smith   PetscInt       i;
1750cddf8d76SBarry Smith 
17513a40ed3dSBarry Smith   PetscFunctionBegin;
1752cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1753b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1754cddf8d76SBarry Smith   }
1755cddf8d76SBarry Smith 
1756cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17576a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1758cddf8d76SBarry Smith   }
17593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1760cddf8d76SBarry Smith }
1761cddf8d76SBarry Smith 
17624a2ae208SSatish Balay #undef __FUNCT__
17634a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
176497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
17654dcbc457SBarry Smith {
1766e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
17676849ba73SBarry Smith   PetscErrorCode ierr;
176897f1f81fSBarry Smith   PetscInt       row,i,j,k,l,m,n,*idx,*nidx,isz,val;
176997f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
1770f1af5d2fSBarry Smith   PetscBT        table;
1771bbd702dbSSatish Balay 
17723a40ed3dSBarry Smith   PetscFunctionBegin;
1773273d9f13SBarry Smith   m     = A->m;
1774e4d965acSSatish Balay   ai    = a->i;
1775bfeeae90SHong Zhang   aj    = a->j;
17768a047759SSatish Balay 
1777a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
177806763907SSatish Balay 
177997f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
17806831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
178106763907SSatish Balay 
1782e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1783b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1784e4d965acSSatish Balay     isz  = 0;
17856831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1786e4d965acSSatish Balay 
1787e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17884dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1789b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1790e4d965acSSatish Balay 
1791dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1792e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1793f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17944dcbc457SBarry Smith     }
179506763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
179606763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1797e4d965acSSatish Balay 
179804a348a9SBarry Smith     k = 0;
179904a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
180004a348a9SBarry Smith       n = isz;
180106763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1802e4d965acSSatish Balay         row   = nidx[k];
1803e4d965acSSatish Balay         start = ai[row];
1804e4d965acSSatish Balay         end   = ai[row+1];
180504a348a9SBarry Smith         for (l = start; l<end ; l++){
1806efb16452SHong Zhang           val = aj[l] ;
1807f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1808e4d965acSSatish Balay         }
1809e4d965acSSatish Balay       }
1810e4d965acSSatish Balay     }
1811029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1812e4d965acSSatish Balay   }
18136831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1814606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
18153a40ed3dSBarry Smith   PetscFunctionReturn(0);
18164dcbc457SBarry Smith }
181717ab2063SBarry Smith 
18180513a670SBarry Smith /* -------------------------------------------------------------- */
18194a2ae208SSatish Balay #undef __FUNCT__
18204a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
1821dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
18220513a670SBarry Smith {
18230513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
18246849ba73SBarry Smith   PetscErrorCode ierr;
182597f1f81fSBarry Smith   PetscInt       i,nz,m = A->m,n = A->n,*col;
182697f1f81fSBarry Smith   PetscInt       *row,*cnew,j,*lens;
182756cd22aeSBarry Smith   IS             icolp,irowp;
182897f1f81fSBarry Smith   PetscInt       *cwork;
182932ec9ce4SBarry Smith   PetscScalar    *vwork;
18300513a670SBarry Smith 
18313a40ed3dSBarry Smith   PetscFunctionBegin;
18324c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
183356cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18344c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
183556cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18360513a670SBarry Smith 
18370513a670SBarry Smith   /* determine lengths of permuted rows */
183897f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
18390513a670SBarry Smith   for (i=0; i<m; i++) {
18400513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18410513a670SBarry Smith   }
1842f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,B);CHKERRQ(ierr);
1843f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
1844f204ca49SKris Buschelman   ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr);
1845ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
1846606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18470513a670SBarry Smith 
184897f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
18490513a670SBarry Smith   for (i=0; i<m; i++) {
185032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18510513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
1852cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
185332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18540513a670SBarry Smith   }
1855606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18563c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
18570513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18580513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
185956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
186056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
186156cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
186256cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18633a40ed3dSBarry Smith   PetscFunctionReturn(0);
18640513a670SBarry Smith }
18650513a670SBarry Smith 
18664a2ae208SSatish Balay #undef __FUNCT__
18674a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1868dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_SeqAIJ(Mat A)
1869682d7d0cSBarry Smith {
1870c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1871682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1872dfbe8321SBarry Smith   PetscErrorCode    ierr;
1873682d7d0cSBarry Smith 
18743a40ed3dSBarry Smith   PetscFunctionBegin;
18754846f1f5SKris Buschelman   ierr = MatPrintHelp_Inode(A);CHKERRQ(ierr);
1876c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1877d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1878d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1879d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
188073e7a558SHong Zhang   ierr = (*PetscHelpPrintf)(comm,"  -mat_no_compressedrow: Do not use compressedrow\n");CHKERRQ(ierr);
18813a40ed3dSBarry Smith   PetscFunctionReturn(0);
1882682d7d0cSBarry Smith }
188397304618SKris Buschelman 
18844a2ae208SSatish Balay #undef __FUNCT__
18854a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1886dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1887cb5b572fSBarry Smith {
1888dfbe8321SBarry Smith   PetscErrorCode ierr;
1889cb5b572fSBarry Smith 
1890cb5b572fSBarry Smith   PetscFunctionBegin;
189133f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
189233f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1893be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1894be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1895be6bf707SBarry Smith 
1896bfeeae90SHong Zhang     if (a->i[A->m] != b->i[B->m]) {
1897634064b4SBarry Smith       SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different");
1898cb5b572fSBarry Smith     }
1899bfeeae90SHong Zhang     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr);
1900cb5b572fSBarry Smith   } else {
1901cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1902cb5b572fSBarry Smith   }
1903cb5b572fSBarry Smith   PetscFunctionReturn(0);
1904cb5b572fSBarry Smith }
1905cb5b572fSBarry Smith 
19064a2ae208SSatish Balay #undef __FUNCT__
19074a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1908dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
1909273d9f13SBarry Smith {
1910dfbe8321SBarry Smith   PetscErrorCode ierr;
1911273d9f13SBarry Smith 
1912273d9f13SBarry Smith   PetscFunctionBegin;
1913ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1914273d9f13SBarry Smith   PetscFunctionReturn(0);
1915273d9f13SBarry Smith }
1916273d9f13SBarry Smith 
19174a2ae208SSatish Balay #undef __FUNCT__
19184a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
1919dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
19206c0721eeSBarry Smith {
19216c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19226c0721eeSBarry Smith   PetscFunctionBegin;
19236c0721eeSBarry Smith   *array = a->a;
19246c0721eeSBarry Smith   PetscFunctionReturn(0);
19256c0721eeSBarry Smith }
19266c0721eeSBarry Smith 
19274a2ae208SSatish Balay #undef __FUNCT__
19284a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
1929dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
19306c0721eeSBarry Smith {
19316c0721eeSBarry Smith   PetscFunctionBegin;
19326c0721eeSBarry Smith   PetscFunctionReturn(0);
19336c0721eeSBarry Smith }
1934273d9f13SBarry Smith 
1935ee4f033dSBarry Smith #undef __FUNCT__
1936ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1937dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1938ee4f033dSBarry Smith {
19396849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
19406849ba73SBarry Smith   PetscErrorCode ierr;
194197f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
1942efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
194387828ca2SBarry Smith   PetscScalar    *vscale_array;
1944ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
1945ee4f033dSBarry Smith   Vec            w1,w2,w3;
1946ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
1947ee4f033dSBarry Smith   PetscTruth     flg;
1948ee4f033dSBarry Smith 
1949ee4f033dSBarry Smith   PetscFunctionBegin;
1950ee4f033dSBarry Smith   if (!coloring->w1) {
1951ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
195252e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
1953ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
195452e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
1955ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
195652e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
1957ee4f033dSBarry Smith   }
1958ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1959ee4f033dSBarry Smith 
1960ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1961e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1962ee4f033dSBarry Smith   if (flg) {
196363ba0a88SBarry Smith     ierr = PetscLogInfo((coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"));CHKERRQ(ierr);
1964ee4f033dSBarry Smith   } else {
19650b9b6f31SBarry Smith     PetscTruth assembled;
19660b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
19670b9b6f31SBarry Smith     if (assembled) {
1968ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
1969ee4f033dSBarry Smith     }
19700b9b6f31SBarry Smith   }
1971ee4f033dSBarry Smith 
1972ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1973ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1974ee4f033dSBarry Smith 
1975ee4f033dSBarry Smith   /*
1976ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1977ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1978ee4f033dSBarry Smith   */
1979ee4f033dSBarry Smith   if (coloring->F) {
1980ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1981ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1982ee4f033dSBarry Smith     if (m1 != m2) {
1983ee4f033dSBarry Smith       coloring->F = 0;
1984ee4f033dSBarry Smith     }
1985ee4f033dSBarry Smith   }
1986ee4f033dSBarry Smith 
1987ee4f033dSBarry Smith   if (coloring->F) {
1988ee4f033dSBarry Smith     w1          = coloring->F;
1989ee4f033dSBarry Smith     coloring->F = 0;
1990ee4f033dSBarry Smith   } else {
199166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1992ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
199366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
1994ee4f033dSBarry Smith   }
1995ee4f033dSBarry Smith 
1996ee4f033dSBarry Smith   /*
1997ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1998ee4f033dSBarry Smith   */
19991ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
20001ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2001ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2002ee4f033dSBarry Smith     /*
2003ee4f033dSBarry Smith        Loop over each column associated with color adding the
2004ee4f033dSBarry Smith        perturbation to the vector w3.
2005ee4f033dSBarry Smith     */
2006ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2007ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2008ee4f033dSBarry Smith       dx  = xx[col];
2009ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2010ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2011ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2012ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2013ee4f033dSBarry Smith #else
2014ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2015ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2016ee4f033dSBarry Smith #endif
2017ee4f033dSBarry Smith       dx                *= epsilon;
2018ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2019ee4f033dSBarry Smith     }
2020ee4f033dSBarry Smith   }
20211ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2022ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2023ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2024ee4f033dSBarry Smith 
2025ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2026ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2027ee4f033dSBarry Smith 
2028ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2029ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2030ee4f033dSBarry Smith 
20311ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2032ee4f033dSBarry Smith   /*
2033ee4f033dSBarry Smith       Loop over each color
2034ee4f033dSBarry Smith   */
2035ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
203649b058dcSBarry Smith     coloring->currentcolor = k;
2037ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
20381ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2039ee4f033dSBarry Smith     /*
2040ee4f033dSBarry Smith        Loop over each column associated with color adding the
2041ee4f033dSBarry Smith        perturbation to the vector w3.
2042ee4f033dSBarry Smith     */
2043ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2044ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2045ee4f033dSBarry Smith       dx  = xx[col];
20465b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2047ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2048ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2049ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2050ee4f033dSBarry Smith #else
2051ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2052ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2053ee4f033dSBarry Smith #endif
2054ee4f033dSBarry Smith       dx            *= epsilon;
2055634064b4SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2056ee4f033dSBarry Smith       w3_array[col] += dx;
2057ee4f033dSBarry Smith     }
20581ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2059ee4f033dSBarry Smith 
2060ee4f033dSBarry Smith     /*
2061ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2062ee4f033dSBarry Smith     */
2063ee4f033dSBarry Smith 
206466f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2065ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
206666f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2067efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2068ee4f033dSBarry Smith 
2069ee4f033dSBarry Smith     /*
2070ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2071ee4f033dSBarry Smith     */
20721ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2073ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2074ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2075ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2076ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2077ee4f033dSBarry Smith       srow   = row + start;
2078ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2079ee4f033dSBarry Smith     }
20801ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2081ee4f033dSBarry Smith   }
208249b058dcSBarry Smith   coloring->currentcolor = k;
20831ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
20841ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2085ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2086ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2087ee4f033dSBarry Smith   PetscFunctionReturn(0);
2088ee4f033dSBarry Smith }
2089ee4f033dSBarry Smith 
2090ac90fabeSBarry Smith #include "petscblaslapack.h"
2091ac90fabeSBarry Smith #undef __FUNCT__
2092ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2093f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2094ac90fabeSBarry Smith {
2095dfbe8321SBarry Smith   PetscErrorCode ierr;
209697f1f81fSBarry Smith   PetscInt       i;
2097ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
20984ce68768SBarry Smith   PetscBLASInt   one=1,bnz = (PetscBLASInt)x->nz;
2099ac90fabeSBarry Smith 
2100ac90fabeSBarry Smith   PetscFunctionBegin;
2101ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2102f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2103f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2104c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2105a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2106a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2107a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2108a30b2313SHong Zhang     }
2109a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
211024f910e3SHong Zhang       ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2111a30b2313SHong Zhang       y->XtoY = X;
2112c537a176SHong Zhang     }
2113f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
211463ba0a88SBarry 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);
2115ac90fabeSBarry Smith   } else {
2116f4df32b1SMatthew Knepley     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2117ac90fabeSBarry Smith   }
2118ac90fabeSBarry Smith   PetscFunctionReturn(0);
2119ac90fabeSBarry Smith }
2120ac90fabeSBarry Smith 
2121521d7252SBarry Smith #undef __FUNCT__
2122521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2123521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2124521d7252SBarry Smith {
2125521d7252SBarry Smith   PetscFunctionBegin;
2126521d7252SBarry Smith   PetscFunctionReturn(0);
2127521d7252SBarry Smith }
2128521d7252SBarry Smith 
2129354c94deSBarry Smith #undef __FUNCT__
2130354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
2131354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat)
2132354c94deSBarry Smith {
2133354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2134354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2135354c94deSBarry Smith   PetscInt    i,nz;
2136354c94deSBarry Smith   PetscScalar *a;
2137354c94deSBarry Smith 
2138354c94deSBarry Smith   PetscFunctionBegin;
2139354c94deSBarry Smith   nz = aij->nz;
2140354c94deSBarry Smith   a  = aij->a;
2141354c94deSBarry Smith   for (i=0; i<nz; i++) {
2142354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2143354c94deSBarry Smith   }
2144354c94deSBarry Smith #else
2145354c94deSBarry Smith   PetscFunctionBegin;
2146354c94deSBarry Smith #endif
2147354c94deSBarry Smith   PetscFunctionReturn(0);
2148354c94deSBarry Smith }
2149354c94deSBarry Smith 
2150e34fafa9SBarry Smith #undef __FUNCT__
2151e34fafa9SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2152e34fafa9SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v)
2153e34fafa9SBarry Smith {
2154e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2155e34fafa9SBarry Smith   PetscErrorCode ierr;
2156e34fafa9SBarry Smith   PetscInt       i,j,m = A->m,*ai,*aj,ncols,n;
2157e34fafa9SBarry Smith   PetscReal      atmp;
2158e34fafa9SBarry Smith   PetscScalar    *x,zero = 0.0;
2159e34fafa9SBarry Smith   MatScalar      *aa;
2160e34fafa9SBarry Smith 
2161e34fafa9SBarry Smith   PetscFunctionBegin;
2162e34fafa9SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2163e34fafa9SBarry Smith   aa   = a->a;
2164e34fafa9SBarry Smith   ai   = a->i;
2165e34fafa9SBarry Smith   aj   = a->j;
2166e34fafa9SBarry Smith 
216743e18e04SHong Zhang   ierr = VecSet(v,zero);CHKERRQ(ierr);
2168e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2169e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2170e34fafa9SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2171e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2172e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2173e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2174e34fafa9SBarry Smith       atmp = PetscAbsScalar(*aa); aa++;
2175e34fafa9SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) x[i] = atmp;
2176e34fafa9SBarry Smith       aj++;
2177e34fafa9SBarry Smith     }
2178e34fafa9SBarry Smith   }
2179e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2180e34fafa9SBarry Smith   PetscFunctionReturn(0);
2181e34fafa9SBarry Smith }
2182e34fafa9SBarry Smith 
2183682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
21840a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2185cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2186cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2187cb5b572fSBarry Smith        MatMult_SeqAIJ,
218897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
21897c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
21907c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2191cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2192cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
21937c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
219497304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2195cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2196cb5b572fSBarry Smith        0,
219717ab2063SBarry Smith        MatRelax_SeqAIJ,
219817ab2063SBarry Smith        MatTranspose_SeqAIJ,
219997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2200cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2201cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2202cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2203cb5b572fSBarry Smith        MatNorm_SeqAIJ,
220497304618SKris Buschelman /*20*/ 0,
2205cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
220617ab2063SBarry Smith        MatCompress_SeqAIJ,
2207cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2208cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
220997304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2210cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2211cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2212f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2213a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
221497304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2215cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2216861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
22176c0721eeSBarry Smith        MatGetArray_SeqAIJ,
22186c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
221997304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2220cb5b572fSBarry Smith        0,
2221cb5b572fSBarry Smith        0,
2222cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2223cb5b572fSBarry Smith        0,
222497304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2225cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2226cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2227cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2228cb5b572fSBarry Smith        MatCopy_SeqAIJ,
222997304618SKris Buschelman /*45*/ MatPrintHelp_SeqAIJ,
2230cb5b572fSBarry Smith        MatScale_SeqAIJ,
2231cb5b572fSBarry Smith        0,
2232*79299369SBarry Smith        MatDiagonalSet_SeqAIJ,
22336945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
2234521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ,
22353b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
22363b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
22373b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2238a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
223997304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2240b9617806SBarry Smith        0,
22410513a670SBarry Smith        0,
2242cda55fadSBarry Smith        MatPermute_SeqAIJ,
2243cda55fadSBarry Smith        0,
224497304618SKris Buschelman /*60*/ 0,
2245b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2246b9b97703SBarry Smith        MatView_SeqAIJ,
22478a124369SBarry Smith        MatGetPetscMaps_Petsc,
2248ee4f033dSBarry Smith        0,
224997304618SKris Buschelman /*65*/ 0,
2250ee4f033dSBarry Smith        0,
2251ee4f033dSBarry Smith        0,
2252ee4f033dSBarry Smith        0,
2253ee4f033dSBarry Smith        0,
2254e34fafa9SBarry Smith /*70*/ MatGetRowMax_SeqAIJ,
2255ee4f033dSBarry Smith        0,
2256ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2257dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2258ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2259dcf5cc72SBarry Smith #else
2260dcf5cc72SBarry Smith        0,
2261dcf5cc72SBarry Smith #endif
2262ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
226397304618SKris Buschelman /*75*/ MatFDColoringApply_SeqAIJ,
226497304618SKris Buschelman        0,
226597304618SKris Buschelman        0,
226697304618SKris Buschelman        0,
226797304618SKris Buschelman        0,
226897304618SKris Buschelman /*80*/ 0,
226997304618SKris Buschelman        0,
227097304618SKris Buschelman        0,
227197304618SKris Buschelman        0,
2272bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2273bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ,
22746284ec50SHong Zhang        0,
22756284ec50SHong Zhang        0,
22766284ec50SHong Zhang        0,
2277bc011b1eSHong Zhang        0,
2278bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ,
227926be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
228026be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2281d439da42SKris Buschelman        MatPtAP_Basic,
22827ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
22837ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ,
2284bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2285bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2286bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
22877ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
22887ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ,
2289609c6c4dSKris Buschelman        0,
2290609c6c4dSKris Buschelman        0,
2291354c94deSBarry Smith        MatConjugate_SeqAIJ
22929e29f15eSvictorle };
229317ab2063SBarry Smith 
2294fb2e594dSBarry Smith EXTERN_C_BEGIN
22954a2ae208SSatish Balay #undef __FUNCT__
22964a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
2297be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2298bef8e0ddSBarry Smith {
2299bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
230097f1f81fSBarry Smith   PetscInt   i,nz,n;
2301bef8e0ddSBarry Smith 
2302bef8e0ddSBarry Smith   PetscFunctionBegin;
2303bef8e0ddSBarry Smith 
2304bef8e0ddSBarry Smith   nz = aij->maxnz;
2305273d9f13SBarry Smith   n  = mat->n;
2306bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2307bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2308bef8e0ddSBarry Smith   }
2309bef8e0ddSBarry Smith   aij->nz = nz;
2310bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2311bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2312bef8e0ddSBarry Smith   }
2313bef8e0ddSBarry Smith 
2314bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2315bef8e0ddSBarry Smith }
2316fb2e594dSBarry Smith EXTERN_C_END
2317bef8e0ddSBarry Smith 
23184a2ae208SSatish Balay #undef __FUNCT__
23194a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2320bef8e0ddSBarry Smith /*@
2321bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2322bef8e0ddSBarry Smith        in the matrix.
2323bef8e0ddSBarry Smith 
2324bef8e0ddSBarry Smith   Input Parameters:
2325bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2326bef8e0ddSBarry Smith -  indices - the column indices
2327bef8e0ddSBarry Smith 
232815091d37SBarry Smith   Level: advanced
232915091d37SBarry Smith 
2330bef8e0ddSBarry Smith   Notes:
2331bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2332bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2333bef8e0ddSBarry Smith   of the MatSetValues() operation.
2334bef8e0ddSBarry Smith 
2335bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2336d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2337bef8e0ddSBarry Smith 
2338bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2339bef8e0ddSBarry Smith 
2340b9617806SBarry Smith     The indices should start with zero, not one.
2341b9617806SBarry Smith 
2342bef8e0ddSBarry Smith @*/
2343be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2344bef8e0ddSBarry Smith {
234597f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt *);
2346bef8e0ddSBarry Smith 
2347bef8e0ddSBarry Smith   PetscFunctionBegin;
23484482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
23494482741eSBarry Smith   PetscValidPointer(indices,2);
2350c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2351bef8e0ddSBarry Smith   if (f) {
2352bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2353bef8e0ddSBarry Smith   } else {
2354634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices");
2355bef8e0ddSBarry Smith   }
2356bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2357bef8e0ddSBarry Smith }
2358bef8e0ddSBarry Smith 
2359be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2360be6bf707SBarry Smith 
2361fb2e594dSBarry Smith EXTERN_C_BEGIN
23624a2ae208SSatish Balay #undef __FUNCT__
23634a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2364be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat)
2365be6bf707SBarry Smith {
2366be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
23676849ba73SBarry Smith   PetscErrorCode ierr;
23686849ba73SBarry Smith   size_t         nz = aij->i[mat->m];
2369be6bf707SBarry Smith 
2370be6bf707SBarry Smith   PetscFunctionBegin;
2371be6bf707SBarry Smith   if (aij->nonew != 1) {
2372634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2373be6bf707SBarry Smith   }
2374be6bf707SBarry Smith 
2375be6bf707SBarry Smith   /* allocate space for values if not already there */
2376be6bf707SBarry Smith   if (!aij->saved_values) {
237787828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2378be6bf707SBarry Smith   }
2379be6bf707SBarry Smith 
2380be6bf707SBarry Smith   /* copy values over */
238187828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2382be6bf707SBarry Smith   PetscFunctionReturn(0);
2383be6bf707SBarry Smith }
2384fb2e594dSBarry Smith EXTERN_C_END
2385be6bf707SBarry Smith 
23864a2ae208SSatish Balay #undef __FUNCT__
2387b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2388be6bf707SBarry Smith /*@
2389be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2390be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2391be6bf707SBarry Smith        nonlinear portion.
2392be6bf707SBarry Smith 
2393be6bf707SBarry Smith    Collect on Mat
2394be6bf707SBarry Smith 
2395be6bf707SBarry Smith   Input Parameters:
23960e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2397be6bf707SBarry Smith 
239815091d37SBarry Smith   Level: advanced
239915091d37SBarry Smith 
2400be6bf707SBarry Smith   Common Usage, with SNESSolve():
2401be6bf707SBarry Smith $    Create Jacobian matrix
2402be6bf707SBarry Smith $    Set linear terms into matrix
2403be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2404be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2405be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2406be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2407be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2408be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2409be6bf707SBarry Smith $    In your Jacobian routine
2410be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2411be6bf707SBarry Smith $      Set nonlinear terms in matrix
2412be6bf707SBarry Smith 
2413be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2414be6bf707SBarry Smith $    // build linear portion of Jacobian
2415be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2416be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2417be6bf707SBarry Smith $    loop over nonlinear iterations
2418be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2419be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2420be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2421be6bf707SBarry Smith $       Solve linear system with Jacobian
2422be6bf707SBarry Smith $    endloop
2423be6bf707SBarry Smith 
2424be6bf707SBarry Smith   Notes:
2425be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2426be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2427be6bf707SBarry Smith     calling this routine.
2428be6bf707SBarry Smith 
24290c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
24300c468ba9SBarry Smith     and does not allocated additional space.
24310c468ba9SBarry Smith 
2432be6bf707SBarry Smith .seealso: MatRetrieveValues()
2433be6bf707SBarry Smith 
2434be6bf707SBarry Smith @*/
2435be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat)
2436be6bf707SBarry Smith {
2437dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2438be6bf707SBarry Smith 
2439be6bf707SBarry Smith   PetscFunctionBegin;
24404482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
244129bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
244229bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2443be6bf707SBarry Smith 
2444c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2445be6bf707SBarry Smith   if (f) {
2446be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2447be6bf707SBarry Smith   } else {
2448634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values");
2449be6bf707SBarry Smith   }
2450be6bf707SBarry Smith   PetscFunctionReturn(0);
2451be6bf707SBarry Smith }
2452be6bf707SBarry Smith 
2453fb2e594dSBarry Smith EXTERN_C_BEGIN
24544a2ae208SSatish Balay #undef __FUNCT__
24554a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2456be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat)
2457be6bf707SBarry Smith {
2458be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
24596849ba73SBarry Smith   PetscErrorCode ierr;
246097f1f81fSBarry Smith   PetscInt       nz = aij->i[mat->m];
2461be6bf707SBarry Smith 
2462be6bf707SBarry Smith   PetscFunctionBegin;
2463be6bf707SBarry Smith   if (aij->nonew != 1) {
2464634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2465be6bf707SBarry Smith   }
2466be6bf707SBarry Smith   if (!aij->saved_values) {
2467634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2468be6bf707SBarry Smith   }
2469be6bf707SBarry Smith   /* copy values over */
247087828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2471be6bf707SBarry Smith   PetscFunctionReturn(0);
2472be6bf707SBarry Smith }
2473fb2e594dSBarry Smith EXTERN_C_END
2474be6bf707SBarry Smith 
24754a2ae208SSatish Balay #undef __FUNCT__
24764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2477be6bf707SBarry Smith /*@
2478be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2479be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2480be6bf707SBarry Smith        nonlinear portion.
2481be6bf707SBarry Smith 
2482be6bf707SBarry Smith    Collect on Mat
2483be6bf707SBarry Smith 
2484be6bf707SBarry Smith   Input Parameters:
2485be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2486be6bf707SBarry Smith 
248715091d37SBarry Smith   Level: advanced
248815091d37SBarry Smith 
2489be6bf707SBarry Smith .seealso: MatStoreValues()
2490be6bf707SBarry Smith 
2491be6bf707SBarry Smith @*/
2492be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat)
2493be6bf707SBarry Smith {
2494dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2495be6bf707SBarry Smith 
2496be6bf707SBarry Smith   PetscFunctionBegin;
24974482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
249829bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
249929bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2500be6bf707SBarry Smith 
2501c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2502be6bf707SBarry Smith   if (f) {
2503be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2504be6bf707SBarry Smith   } else {
2505634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values");
2506be6bf707SBarry Smith   }
2507be6bf707SBarry Smith   PetscFunctionReturn(0);
2508be6bf707SBarry Smith }
2509be6bf707SBarry Smith 
2510f83d6046SBarry Smith 
2511be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
25124a2ae208SSatish Balay #undef __FUNCT__
25134a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
251417ab2063SBarry Smith /*@C
2515682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
25160d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
25176e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
251851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
25192bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
252017ab2063SBarry Smith 
2521db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2522db81eaa0SLois Curfman McInnes 
252317ab2063SBarry Smith    Input Parameters:
2524db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
252517ab2063SBarry Smith .  m - number of rows
252617ab2063SBarry Smith .  n - number of columns
252717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
252851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
25292bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
253017ab2063SBarry Smith 
253117ab2063SBarry Smith    Output Parameter:
2532416022c9SBarry Smith .  A - the matrix
253317ab2063SBarry Smith 
2534b259b22eSLois Curfman McInnes    Notes:
253549a6f317SBarry Smith    If nnz is given then nz is ignored
253649a6f317SBarry Smith 
253717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
253817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
25390002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
254044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
254117ab2063SBarry Smith 
254217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2543a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
25443d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
25456da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
254617ab2063SBarry Smith 
2547682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
25484fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2549682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
25506c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
25516c7ebb05SLois Curfman McInnes 
25526c7ebb05SLois Curfman McInnes    Options Database Keys:
2553698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2554698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2555db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2556db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2557db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
255817ab2063SBarry Smith 
2559027ccd11SLois Curfman McInnes    Level: intermediate
2560027ccd11SLois Curfman McInnes 
256136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
256236db0b34SBarry Smith 
256317ab2063SBarry Smith @*/
2564be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
256517ab2063SBarry Smith {
2566dfbe8321SBarry Smith   PetscErrorCode ierr;
25676945ee14SBarry Smith 
25683a40ed3dSBarry Smith   PetscFunctionBegin;
2569f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2570f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2571273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2572ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr);
2573273d9f13SBarry Smith   PetscFunctionReturn(0);
2574273d9f13SBarry Smith }
2575273d9f13SBarry Smith 
25764a2ae208SSatish Balay #undef __FUNCT__
25774a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2578273d9f13SBarry Smith /*@C
2579273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2580273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2581273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2582273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2583273d9f13SBarry Smith 
2584273d9f13SBarry Smith    Collective on MPI_Comm
2585273d9f13SBarry Smith 
2586273d9f13SBarry Smith    Input Parameters:
258745bfc511SMatthew Knepley +  B - The matrix
2588273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2589273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2590273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2591273d9f13SBarry Smith 
2592273d9f13SBarry Smith    Notes:
259349a6f317SBarry Smith      If nnz is given then nz is ignored
259449a6f317SBarry Smith 
2595273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
2596273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2597273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2598273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2599273d9f13SBarry Smith 
2600273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2601273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2602273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2603273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2604273d9f13SBarry Smith 
2605a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
2606a96a251dSBarry Smith    entries or columns indices
2607a96a251dSBarry Smith 
2608273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2609273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2610273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2611273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2612273d9f13SBarry Smith 
2613273d9f13SBarry Smith    Options Database Keys:
2614698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2615698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2616273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2617273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2618273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2619273d9f13SBarry Smith 
2620273d9f13SBarry Smith    Level: intermediate
2621273d9f13SBarry Smith 
2622273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2623273d9f13SBarry Smith 
2624273d9f13SBarry Smith @*/
2625be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
2626273d9f13SBarry Smith {
262797f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]);
2628a23d5eceSKris Buschelman 
2629a23d5eceSKris Buschelman   PetscFunctionBegin;
2630a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2631a23d5eceSKris Buschelman   if (f) {
2632a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2633a23d5eceSKris Buschelman   }
2634a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2635a23d5eceSKris Buschelman }
2636a23d5eceSKris Buschelman 
2637a23d5eceSKris Buschelman EXTERN_C_BEGIN
2638a23d5eceSKris Buschelman #undef __FUNCT__
2639a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2640be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz)
2641a23d5eceSKris Buschelman {
2642273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2643a43ee2ecSKris Buschelman   PetscTruth     skipallocation = PETSC_FALSE;
26446849ba73SBarry Smith   PetscErrorCode ierr;
264597f1f81fSBarry Smith   PetscInt       i;
2646273d9f13SBarry Smith 
2647273d9f13SBarry Smith   PetscFunctionBegin;
2648d5d45c9bSBarry Smith 
2649a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
2650c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2651c461c341SBarry Smith     nz             = 0;
2652c461c341SBarry Smith   }
2653c461c341SBarry Smith 
2654435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2655435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2656b73539f3SBarry Smith   if (nnz) {
2657273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
265829bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
26593a7fca6bSBarry 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);
2660b73539f3SBarry Smith     }
2661b73539f3SBarry Smith   }
2662b73539f3SBarry Smith 
2663273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2664273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2665273d9f13SBarry Smith 
2666ab93d7beSBarry Smith   if (!skipallocation) {
2667ab93d7beSBarry Smith     ierr = PetscMalloc2(B->m,PetscInt,&b->imax,B->m,PetscInt,&b->ilen);CHKERRQ(ierr);
2668273d9f13SBarry Smith     if (!nnz) {
2669435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2670273d9f13SBarry Smith       else if (nz <= 0)        nz = 1;
2671273d9f13SBarry Smith       for (i=0; i<B->m; i++) b->imax[i] = nz;
2672273d9f13SBarry Smith       nz = nz*B->m;
2673273d9f13SBarry Smith     } else {
2674273d9f13SBarry Smith       nz = 0;
2675273d9f13SBarry Smith       for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2676273d9f13SBarry Smith     }
2677273d9f13SBarry Smith 
2678ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
2679ab93d7beSBarry Smith     for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2680ab93d7beSBarry Smith 
2681273d9f13SBarry Smith     /* allocate the matrix space */
2682a96a251dSBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->m+1,PetscInt,&b->i);CHKERRQ(ierr);
2683bfeeae90SHong Zhang     b->i[0] = 0;
26845da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26855da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26865da197adSKris Buschelman     }
2687273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2688273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2689c461c341SBarry Smith   } else {
2690c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2691c461c341SBarry Smith   }
2692273d9f13SBarry Smith 
2693273d9f13SBarry Smith   b->nz                = 0;
2694273d9f13SBarry Smith   b->maxnz             = nz;
2695273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2696273d9f13SBarry Smith   PetscFunctionReturn(0);
2697273d9f13SBarry Smith }
2698a23d5eceSKris Buschelman EXTERN_C_END
2699273d9f13SBarry Smith 
2700a1661176SMatthew Knepley #undef  __FUNCT__
2701a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
2702a1661176SMatthew Knepley /*@C
2703a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
2704a1661176SMatthew Knepley 
2705a1661176SMatthew Knepley    Input Parameters:
2706a1661176SMatthew Knepley +  B - the matrix
2707a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
2708a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
2709a1661176SMatthew Knepley -  v - optional values in the matrix
2710a1661176SMatthew Knepley 
2711d58b2322SMatthew Knepley    Contributed by: Lisandro Dalchin
2712d58b2322SMatthew Knepley 
2713a1661176SMatthew Knepley    Level: developer
2714a1661176SMatthew Knepley 
2715a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
2716a1661176SMatthew Knepley 
2717a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
2718a1661176SMatthew Knepley @*/
2719a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
2720a1661176SMatthew Knepley {
2721a1661176SMatthew Knepley   PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]);
2722a1661176SMatthew Knepley   PetscErrorCode ierr;
2723a1661176SMatthew Knepley 
2724a1661176SMatthew Knepley   PetscFunctionBegin;
2725a1661176SMatthew Knepley   PetscValidHeaderSpecific(B,MAT_COOKIE,1);
2726a1661176SMatthew Knepley   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr);
2727a1661176SMatthew Knepley   if (f) {
2728a1661176SMatthew Knepley     ierr = (*f)(B,i,j,v);CHKERRQ(ierr);
2729a1661176SMatthew Knepley   }
2730a1661176SMatthew Knepley   PetscFunctionReturn(0);
2731a1661176SMatthew Knepley }
2732a1661176SMatthew Knepley 
2733a1661176SMatthew Knepley EXTERN_C_BEGIN
2734a1661176SMatthew Knepley #undef  __FUNCT__
2735a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
2736a1661176SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt I[],const PetscInt J[],const PetscScalar v[])
2737a1661176SMatthew Knepley {
2738a1661176SMatthew Knepley   PetscInt       i;
2739a1661176SMatthew Knepley   PetscInt       m,n;
2740a1661176SMatthew Knepley   PetscInt       nz;
2741a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
2742a1661176SMatthew Knepley   PetscScalar    *values;
2743a1661176SMatthew Knepley   PetscErrorCode ierr;
2744a1661176SMatthew Knepley 
2745a1661176SMatthew Knepley   PetscFunctionBegin;
2746a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
2747a1661176SMatthew Knepley 
2748a1661176SMatthew Knepley   if (I[0]) {
2749a1661176SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "I[0] must be 0 it is %D", I[0]);
2750a1661176SMatthew Knepley   }
2751a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
2752a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2753a1661176SMatthew Knepley     nz     = I[i+1]- I[i];
2754a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
2755a1661176SMatthew Knepley     if (nz < 0) {
2756a1661176SMatthew Knepley       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
2757a1661176SMatthew Knepley     }
2758a1661176SMatthew Knepley     nnz[i] = nz;
2759a1661176SMatthew Knepley   }
2760a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
2761a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
2762a1661176SMatthew Knepley 
2763a1661176SMatthew Knepley   if (v) {
2764a1661176SMatthew Knepley     values = (PetscScalar*) v;
2765a1661176SMatthew Knepley   } else {
2766a1661176SMatthew Knepley     ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr);
2767a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
2768a1661176SMatthew Knepley   }
2769a1661176SMatthew Knepley 
2770a1661176SMatthew Knepley   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
2771a1661176SMatthew Knepley 
2772a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2773a1661176SMatthew Knepley     nz  = I[i+1] - I[i];
2774a1661176SMatthew Knepley     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+I[i], values + (v ? I[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
2775a1661176SMatthew Knepley   }
2776a1661176SMatthew Knepley 
2777a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2778a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2779a1661176SMatthew Knepley   ierr = MatSetOption(B,MAT_COLUMNS_UNSORTED);CHKERRQ(ierr);
2780a1661176SMatthew Knepley 
2781a1661176SMatthew Knepley   if (!v) {
2782a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
2783a1661176SMatthew Knepley   }
2784a1661176SMatthew Knepley   PetscFunctionReturn(0);
2785a1661176SMatthew Knepley }
2786a1661176SMatthew Knepley EXTERN_C_END
2787a1661176SMatthew Knepley 
27880bad9183SKris Buschelman /*MC
2789fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
27900bad9183SKris Buschelman    based on compressed sparse row format.
27910bad9183SKris Buschelman 
27920bad9183SKris Buschelman    Options Database Keys:
27930bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
27940bad9183SKris Buschelman 
27950bad9183SKris Buschelman   Level: beginner
27960bad9183SKris Buschelman 
2797f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
27980bad9183SKris Buschelman M*/
27990bad9183SKris Buschelman 
2800a6175056SHong Zhang EXTERN_C_BEGIN
28014a2ae208SSatish Balay #undef __FUNCT__
28024a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2803be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B)
2804273d9f13SBarry Smith {
2805273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2806dfbe8321SBarry Smith   PetscErrorCode ierr;
280738baddfdSBarry Smith   PetscMPIInt    size;
2808273d9f13SBarry Smith 
2809273d9f13SBarry Smith   PetscFunctionBegin;
2810273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2811273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2812273d9f13SBarry Smith 
2813273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2814273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2815273d9f13SBarry Smith 
2816b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2817b0a32e0cSBarry Smith   B->data             = (void*)b;
2818549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2819416022c9SBarry Smith   B->factor           = 0;
282090f02eecSBarry Smith   B->mapping          = 0;
2821416022c9SBarry Smith   b->row              = 0;
2822416022c9SBarry Smith   b->col              = 0;
282382bf6240SBarry Smith   b->icol             = 0;
2824b810aeb4SBarry Smith   b->reallocs         = 0;
282517ab2063SBarry Smith 
28268a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
28278a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2828a5ae1ecdSBarry Smith 
2829f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
283036db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2831f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2832416022c9SBarry Smith   b->nonew             = 0;
2833416022c9SBarry Smith   b->diag              = 0;
2834416022c9SBarry Smith   b->solve_work        = 0;
28352a1b7f2aSHong Zhang   B->spptr             = 0;
2836be6bf707SBarry Smith   b->saved_values      = 0;
2837d7f994e1SBarry Smith   b->idiag             = 0;
2838d7f994e1SBarry Smith   b->ssor              = 0;
2839f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
2840a30b2313SHong Zhang   b->xtoy              = 0;
2841a30b2313SHong Zhang   b->XtoY              = 0;
284273e7a558SHong Zhang   b->compressedrow.use     = PETSC_FALSE;
2843d487561eSHong Zhang   b->compressedrow.nrows   = B->m;
2844d487561eSHong Zhang   b->compressedrow.i       = PETSC_NULL;
2845d487561eSHong Zhang   b->compressedrow.rindex  = PETSC_NULL;
2846d487561eSHong Zhang   b->compressedrow.checked = PETSC_FALSE;
284788e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
284817ab2063SBarry Smith 
284935d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
285035d8aa7fSBarry Smith 
2851f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2852bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2853bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2854f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2855be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2856bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2857f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2858be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2859bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
2860a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
2861a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
2862a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
286385fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
286485fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
286585fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
28665fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
28675fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
28685fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
2869a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
2870a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
2871a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
2872a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",
2873a1661176SMatthew Knepley 				     "MatSeqAIJSetPreallocationCSR_SeqAIJ",
2874a1661176SMatthew Knepley 				      MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
287505b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
287605b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
287705b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
28784846f1f5SKris Buschelman   ierr = MatCreate_Inode(B);CHKERRQ(ierr);
28793a40ed3dSBarry Smith   PetscFunctionReturn(0);
288017ab2063SBarry Smith }
2881273d9f13SBarry Smith EXTERN_C_END
288217ab2063SBarry Smith 
28834a2ae208SSatish Balay #undef __FUNCT__
28844a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2885dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
288617ab2063SBarry Smith {
2887416022c9SBarry Smith   Mat            C;
2888416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
28896849ba73SBarry Smith   PetscErrorCode ierr;
289097f1f81fSBarry Smith   PetscInt       i,m = A->m;
289117ab2063SBarry Smith 
28923a40ed3dSBarry Smith   PetscFunctionBegin;
28934043dd9cSLois Curfman McInnes   *B = 0;
2894f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
2895f69a0ea3SMatthew Knepley   ierr = MatSetSizes(C,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
2896be5d1d56SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
28971d5dac46SHong Zhang   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
28981d5dac46SHong Zhang 
2899273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
2900273d9f13SBarry Smith 
2901416022c9SBarry Smith   C->factor           = A->factor;
29026ad4291fSHong Zhang 
2903416022c9SBarry Smith   c->row            = 0;
2904416022c9SBarry Smith   c->col            = 0;
290582bf6240SBarry Smith   c->icol           = 0;
29066ad4291fSHong Zhang   c->reallocs       = 0;
290717ab2063SBarry Smith 
29086ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
290917ab2063SBarry Smith 
291033b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
291117ab2063SBarry Smith   for (i=0; i<m; i++) {
2912416022c9SBarry Smith     c->imax[i] = a->imax[i];
2913416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
291417ab2063SBarry Smith   }
291517ab2063SBarry Smith 
291617ab2063SBarry Smith   /* allocate the matrix space */
2917a96a251dSBarry Smith   ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
2918f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
291997f1f81fSBarry Smith   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
292017ab2063SBarry Smith   if (m > 0) {
292197f1f81fSBarry Smith     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
2922be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2923bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
2924be6bf707SBarry Smith     } else {
2925bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
292617ab2063SBarry Smith     }
292708480c60SBarry Smith   }
292817ab2063SBarry Smith 
2929416022c9SBarry Smith   c->sorted            = a->sorted;
29306ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
2931416022c9SBarry Smith   c->roworiented       = a->roworiented;
2932416022c9SBarry Smith   c->nonew             = a->nonew;
2933416022c9SBarry Smith   if (a->diag) {
293497f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
293552e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
293617ab2063SBarry Smith     for (i=0; i<m; i++) {
2937416022c9SBarry Smith       c->diag[i] = a->diag[i];
293817ab2063SBarry Smith     }
29393a40ed3dSBarry Smith   } else c->diag        = 0;
29406ad4291fSHong Zhang   c->solve_work         = 0;
29416ad4291fSHong Zhang   c->saved_values          = 0;
29426ad4291fSHong Zhang   c->idiag                 = 0;
29436ad4291fSHong Zhang   c->ssor                  = 0;
29446ad4291fSHong Zhang   c->keepzeroedrows        = a->keepzeroedrows;
29456ad4291fSHong Zhang   c->freedata              = PETSC_TRUE;
29466ad4291fSHong Zhang   c->xtoy                  = 0;
29476ad4291fSHong Zhang   c->XtoY                  = 0;
29486ad4291fSHong Zhang 
2949416022c9SBarry Smith   c->nz                 = a->nz;
2950416022c9SBarry Smith   c->maxnz              = a->maxnz;
2951273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2952754ec7b1SSatish Balay 
29536ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
29546ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
29556ad4291fSHong Zhang   c->compressedrow.checked = a->compressedrow.checked;
29566ad4291fSHong Zhang   if ( a->compressedrow.checked && a->compressedrow.use){
29576ad4291fSHong Zhang     i = a->compressedrow.nrows;
29586ad4291fSHong Zhang     ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr);
29596ad4291fSHong Zhang     c->compressedrow.rindex = c->compressedrow.i + i + 1;
29606ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
29616ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
296227ea64f8SHong Zhang   } else {
296327ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
296427ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
296527ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
29666ad4291fSHong Zhang   }
296788e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
29686ad4291fSHong Zhang 
29694846f1f5SKris Buschelman   ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr);
29704846f1f5SKris Buschelman 
2971416022c9SBarry Smith   *B = C;
2972b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
29733a40ed3dSBarry Smith   PetscFunctionReturn(0);
297417ab2063SBarry Smith }
297517ab2063SBarry Smith 
29764a2ae208SSatish Balay #undef __FUNCT__
29774a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2978f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A)
297917ab2063SBarry Smith {
2980416022c9SBarry Smith   Mat_SeqAIJ     *a;
2981416022c9SBarry Smith   Mat            B;
29826849ba73SBarry Smith   PetscErrorCode ierr;
29833c601197SSatish Balay   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N;
298438baddfdSBarry Smith   int            fd;
298538baddfdSBarry Smith   PetscMPIInt    size;
2986bcd2baecSBarry Smith   MPI_Comm       comm;
298717ab2063SBarry Smith 
29883a40ed3dSBarry Smith   PetscFunctionBegin;
2989e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2990d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
299129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2992b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
29930752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2994552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
299517ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
299617ab2063SBarry Smith 
2997d64ed03dSBarry Smith   if (nz < 0) {
299829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2999d64ed03dSBarry Smith   }
3000d64ed03dSBarry Smith 
300117ab2063SBarry Smith   /* read in row lengths */
300297f1f81fSBarry Smith   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
30030752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
300417ab2063SBarry Smith 
30053c601197SSatish Balay   /* check if sum of rowlengths is same as nz */
30063c601197SSatish Balay   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
30073c601197SSatish Balay   if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
30083c601197SSatish Balay 
300917ab2063SBarry Smith   /* create our matrix */
3010f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,&B);CHKERRQ(ierr);
3011f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3012b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
3013ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr);
3014416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
301517ab2063SBarry Smith 
301617ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
30170752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
301817ab2063SBarry Smith 
301917ab2063SBarry Smith   /* read in nonzero values */
30200752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
302117ab2063SBarry Smith 
302217ab2063SBarry Smith   /* set matrix "i" values */
3023efb16452SHong Zhang   a->i[0] = 0;
302417ab2063SBarry Smith   for (i=1; i<= M; i++) {
3025416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3026416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
302717ab2063SBarry Smith   }
3028606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
302917ab2063SBarry Smith 
30306d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
30316d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3032b3a1e11cSKris Buschelman   *A = B;
30333a40ed3dSBarry Smith   PetscFunctionReturn(0);
303417ab2063SBarry Smith }
303517ab2063SBarry Smith 
30364a2ae208SSatish Balay #undef __FUNCT__
3037b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3038dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
30397264ac53SSatish Balay {
30407264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3041dfbe8321SBarry Smith   PetscErrorCode ierr;
30427264ac53SSatish Balay 
30433a40ed3dSBarry Smith   PetscFunctionBegin;
3044bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3045bfeeae90SHong Zhang   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) {
3046ca44d042SBarry Smith     *flg = PETSC_FALSE;
3047ca44d042SBarry Smith     PetscFunctionReturn(0);
3048bcd2baecSBarry Smith   }
30497264ac53SSatish Balay 
30507264ac53SSatish Balay   /* if the a->i are the same */
305197f1f81fSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3052abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
30537264ac53SSatish Balay 
30547264ac53SSatish Balay   /* if a->j are the same */
305597f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3056abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3057bcd2baecSBarry Smith 
3058bcd2baecSBarry Smith   /* if a->a are the same */
305987828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
30600f5bd95cSBarry Smith 
30613a40ed3dSBarry Smith   PetscFunctionReturn(0);
30627264ac53SSatish Balay 
30637264ac53SSatish Balay }
306436db0b34SBarry Smith 
30654a2ae208SSatish Balay #undef __FUNCT__
30664a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
306705869f15SSatish Balay /*@
306836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
306936db0b34SBarry Smith               provided by the user.
307036db0b34SBarry Smith 
307136db0b34SBarry Smith       Coolective on MPI_Comm
307236db0b34SBarry Smith 
307336db0b34SBarry Smith    Input Parameters:
307436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
307536db0b34SBarry Smith .   m - number of rows
307636db0b34SBarry Smith .   n - number of columns
307736db0b34SBarry Smith .   i - row indices
307836db0b34SBarry Smith .   j - column indices
307936db0b34SBarry Smith -   a - matrix values
308036db0b34SBarry Smith 
308136db0b34SBarry Smith    Output Parameter:
308236db0b34SBarry Smith .   mat - the matrix
308336db0b34SBarry Smith 
308436db0b34SBarry Smith    Level: intermediate
308536db0b34SBarry Smith 
308636db0b34SBarry Smith    Notes:
30870551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
308836db0b34SBarry Smith     once the matrix is destroyed
308936db0b34SBarry Smith 
309036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
309136db0b34SBarry Smith 
3092bfeeae90SHong Zhang        The i and j indices are 0 based
309336db0b34SBarry Smith 
309436db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
309536db0b34SBarry Smith 
309636db0b34SBarry Smith @*/
3097be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
309836db0b34SBarry Smith {
3099dfbe8321SBarry Smith   PetscErrorCode ierr;
310097f1f81fSBarry Smith   PetscInt       ii;
310136db0b34SBarry Smith   Mat_SeqAIJ     *aij;
310236db0b34SBarry Smith 
310336db0b34SBarry Smith   PetscFunctionBegin;
3104a96a251dSBarry Smith   if (i[0]) {
3105634064b4SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
310636db0b34SBarry Smith   }
3107f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3108f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3109ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3110ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3111ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3112ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3113ab93d7beSBarry Smith 
311436db0b34SBarry Smith   aij->i = i;
311536db0b34SBarry Smith   aij->j = j;
311636db0b34SBarry Smith   aij->a = a;
311736db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
311836db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
311936db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
312036db0b34SBarry Smith 
312136db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
312236db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
31232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
312479a5c55eSBarry 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]);
312536db0b34SBarry Smith #endif
312636db0b34SBarry Smith   }
31272515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
312836db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
312979a5c55eSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
313079a5c55eSBarry Smith     if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]);
313136db0b34SBarry Smith   }
313236db0b34SBarry Smith #endif
313336db0b34SBarry Smith 
3134b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3135b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
313636db0b34SBarry Smith   PetscFunctionReturn(0);
313736db0b34SBarry Smith }
313836db0b34SBarry Smith 
3139cc8ba8e1SBarry Smith #undef __FUNCT__
3140ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3141dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3142cc8ba8e1SBarry Smith {
3143dfbe8321SBarry Smith   PetscErrorCode ierr;
3144cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
314536db0b34SBarry Smith 
3146cc8ba8e1SBarry Smith   PetscFunctionBegin;
314712c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
3148cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3149cc8ba8e1SBarry Smith     a->coloring = coloring;
315012c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
315197f1f81fSBarry Smith     PetscInt             i,*larray;
315212c595b3SBarry Smith     ISColoring      ocoloring;
315308b6dcc0SBarry Smith     ISColoringValue *colors;
315412c595b3SBarry Smith 
315512c595b3SBarry Smith     /* set coloring for diagonal portion */
315697f1f81fSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr);
315712c595b3SBarry Smith     for (i=0; i<A->n; i++) {
315812c595b3SBarry Smith       larray[i] = i;
315912c595b3SBarry Smith     }
316012c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
316108b6dcc0SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
316212c595b3SBarry Smith     for (i=0; i<A->n; i++) {
316312c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
316412c595b3SBarry Smith     }
316512c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
316612c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
316712c595b3SBarry Smith     a->coloring = ocoloring;
316812c595b3SBarry Smith   }
3169cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3170cc8ba8e1SBarry Smith }
3171cc8ba8e1SBarry Smith 
3172dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3173ee4f033dSBarry Smith EXTERN_C_BEGIN
317429c1e371SBarry Smith #include "adic/ad_utils.h"
3175ee4f033dSBarry Smith EXTERN_C_END
3176cc8ba8e1SBarry Smith 
3177cc8ba8e1SBarry Smith #undef __FUNCT__
3178ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3179dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3180cc8ba8e1SBarry Smith {
3181cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
318297f1f81fSBarry Smith   PetscInt        m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen;
31834440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
318408b6dcc0SBarry Smith   ISColoringValue *color;
3185cc8ba8e1SBarry Smith 
3186cc8ba8e1SBarry Smith   PetscFunctionBegin;
3187e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
31884440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3189cc8ba8e1SBarry Smith   color = a->coloring->colors;
3190cc8ba8e1SBarry Smith   /* loop over rows */
3191cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3192cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3193cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3194cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3195cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3196cc8ba8e1SBarry Smith     }
31974440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3198ee4f033dSBarry Smith   }
3199ee4f033dSBarry Smith   PetscFunctionReturn(0);
3200ee4f033dSBarry Smith }
3201ee4f033dSBarry Smith #endif
3202ee4f033dSBarry Smith 
3203ee4f033dSBarry Smith #undef __FUNCT__
3204ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
320597f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3206ee4f033dSBarry Smith {
3207ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
320897f1f81fSBarry Smith   PetscInt             m = A->m,*ii = a->i,*jj = a->j,nz,i,j;
320987828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
321008b6dcc0SBarry Smith   ISColoringValue *color;
3211ee4f033dSBarry Smith 
3212ee4f033dSBarry Smith   PetscFunctionBegin;
3213e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3214ee4f033dSBarry Smith   color = a->coloring->colors;
3215ee4f033dSBarry Smith   /* loop over rows */
3216ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3217ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3218ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3219ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3220ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3221ee4f033dSBarry Smith     }
3222ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3223cc8ba8e1SBarry Smith   }
3224cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3225cc8ba8e1SBarry Smith }
322636db0b34SBarry Smith 
3227