xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 4e0d8c253c5baa1c48327ddb2b78bf7a43f58497)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2b3cc6726SBarry Smith 
3d5d45c9bSBarry Smith /*
43369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
5d5d45c9bSBarry Smith   matrix storage format.
6d5d45c9bSBarry Smith */
73369ce9aSBarry Smith 
89e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
9f5eb4b81SSatish Balay #include "src/inline/spops.h"
108d195f9aSBarry Smith #include "src/inline/dot.h"
110a835dfdSSatish Balay #include "petscbt.h"
1217ab2063SBarry Smith 
134a2ae208SSatish Balay #undef __FUNCT__
1479299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1579299369SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
1679299369SBarry Smith {
1779299369SBarry Smith   PetscErrorCode ierr;
1879299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
19899cda47SBarry Smith   PetscInt       i,*diag, m = Y->rmap.n;
2079299369SBarry Smith   PetscScalar    *v,*aa = aij->a;
2109f38230SBarry Smith   PetscTruth     missing;
2279299369SBarry Smith 
2379299369SBarry Smith   PetscFunctionBegin;
2409f38230SBarry Smith   if (Y->assembled) {
2509f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
2609f38230SBarry Smith     if (!missing) {
2779299369SBarry Smith       diag = aij->diag;
2879299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
2979299369SBarry Smith       if (is == INSERT_VALUES) {
3079299369SBarry Smith 	for (i=0; i<m; i++) {
3179299369SBarry Smith 	  aa[diag[i]] = v[i];
3279299369SBarry Smith 	}
3379299369SBarry Smith       } else {
3479299369SBarry Smith 	for (i=0; i<m; i++) {
3579299369SBarry Smith 	  aa[diag[i]] += v[i];
3679299369SBarry Smith 	}
3779299369SBarry Smith       }
3879299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
3979299369SBarry Smith       PetscFunctionReturn(0);
4079299369SBarry Smith     }
4109f38230SBarry Smith   }
4209f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
4309f38230SBarry Smith   PetscFunctionReturn(0);
4409f38230SBarry Smith }
4579299369SBarry Smith 
4679299369SBarry Smith #undef __FUNCT__
474a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
488f7157efSSatish Balay PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
4917ab2063SBarry Smith {
50416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
51dfbe8321SBarry Smith   PetscErrorCode ierr;
5297f1f81fSBarry Smith   PetscInt       i,ishift;
5317ab2063SBarry Smith 
543a40ed3dSBarry Smith   PetscFunctionBegin;
55899cda47SBarry Smith   *m     = A->rmap.n;
563a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
57bfeeae90SHong Zhang   ishift = 0;
5853e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
59899cda47SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap.n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
60bfeeae90SHong Zhang   } else if (oshift == 1) {
61899cda47SBarry Smith     PetscInt nz = a->i[A->rmap.n];
623b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
63899cda47SBarry Smith     ierr = PetscMalloc((A->rmap.n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
6497f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
653b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
66899cda47SBarry Smith     for (i=0; i<A->rmap.n+1; i++) (*ia)[i] = a->i[i] + 1;
676945ee14SBarry Smith   } else {
686945ee14SBarry Smith     *ia = a->i; *ja = a->j;
69a2ce50c7SBarry Smith   }
703a40ed3dSBarry Smith   PetscFunctionReturn(0);
71a2744918SBarry Smith }
72a2744918SBarry Smith 
734a2ae208SSatish Balay #undef __FUNCT__
744a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
758f7157efSSatish Balay PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
766945ee14SBarry Smith {
77dfbe8321SBarry Smith   PetscErrorCode ierr;
786945ee14SBarry Smith 
793a40ed3dSBarry Smith   PetscFunctionBegin;
803a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
81bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
82606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
83606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
84bcd2baecSBarry Smith   }
853a40ed3dSBarry Smith   PetscFunctionReturn(0);
8617ab2063SBarry Smith }
8717ab2063SBarry Smith 
884a2ae208SSatish Balay #undef __FUNCT__
894a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
908f7157efSSatish Balay PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
913b2fbd54SBarry Smith {
923b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
93dfbe8321SBarry Smith   PetscErrorCode ierr;
94899cda47SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap.n,m = A->rmap.n;
9597f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
963b2fbd54SBarry Smith 
973a40ed3dSBarry Smith   PetscFunctionBegin;
98899cda47SBarry Smith   *nn = n;
993a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1003b2fbd54SBarry Smith   if (symmetric) {
101899cda47SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap.n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
1023b2fbd54SBarry Smith   } else {
10397f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
10497f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
10597f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
10697f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
1073b2fbd54SBarry Smith     jj = a->j;
1083b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
109bfeeae90SHong Zhang       collengths[jj[i]]++;
1103b2fbd54SBarry Smith     }
1113b2fbd54SBarry Smith     cia[0] = oshift;
1123b2fbd54SBarry Smith     for (i=0; i<n; i++) {
1133b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1143b2fbd54SBarry Smith     }
11597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
1163b2fbd54SBarry Smith     jj   = a->j;
117a93ec695SBarry Smith     for (row=0; row<m; row++) {
118a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
119a93ec695SBarry Smith       for (i=0; i<mr; i++) {
120bfeeae90SHong Zhang         col = *jj++;
1213b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1223b2fbd54SBarry Smith       }
1233b2fbd54SBarry Smith     }
124606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1253b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1263b2fbd54SBarry Smith   }
1273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1283b2fbd54SBarry Smith }
1293b2fbd54SBarry Smith 
1304a2ae208SSatish Balay #undef __FUNCT__
1314a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
1328f7157efSSatish Balay PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscTruth *done)
1333b2fbd54SBarry Smith {
134dfbe8321SBarry Smith   PetscErrorCode ierr;
135606d414cSSatish Balay 
1363a40ed3dSBarry Smith   PetscFunctionBegin;
1373a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1383b2fbd54SBarry Smith 
139606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
140606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1413b2fbd54SBarry Smith 
1423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1433b2fbd54SBarry Smith }
1443b2fbd54SBarry Smith 
14587d4246cSBarry Smith #undef __FUNCT__
14687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
14787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
14887d4246cSBarry Smith {
14987d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15087d4246cSBarry Smith   PetscInt       *ai = a->i;
15187d4246cSBarry Smith   PetscErrorCode ierr;
15287d4246cSBarry Smith 
15387d4246cSBarry Smith   PetscFunctionBegin;
15487d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
15587d4246cSBarry Smith   PetscFunctionReturn(0);
15687d4246cSBarry Smith }
15787d4246cSBarry Smith 
158227d817aSBarry Smith #define CHUNKSIZE   15
15917ab2063SBarry Smith 
1604a2ae208SSatish Balay #undef __FUNCT__
1614a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
16297f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
16317ab2063SBarry Smith {
164416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
165e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
16697f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
1676849ba73SBarry Smith   PetscErrorCode ierr;
168e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
16987828ca2SBarry Smith   PetscScalar    *ap,value,*aa = a->a;
170edb03aefSBarry Smith   PetscTruth     ignorezeroentries = a->ignorezeroentries;
171273d9f13SBarry Smith   PetscTruth     roworiented = a->roworiented;
17217ab2063SBarry Smith 
1733a40ed3dSBarry Smith   PetscFunctionBegin;
17417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
175416022c9SBarry Smith     row  = im[k];
1765ef9f2a5SBarry Smith     if (row < 0) continue;
1772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
178899cda47SBarry Smith     if (row >= A->rmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap.n-1);
1793b2fbd54SBarry Smith #endif
180bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
18117ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
182416022c9SBarry Smith     low  = 0;
183c71e6ed7SBarry Smith     high = nrow;
18417ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1855ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1862515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
187899cda47SBarry Smith       if (in[l] >= A->cmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap.n-1);
1883b2fbd54SBarry Smith #endif
189bfeeae90SHong Zhang       col = in[l];
1904b0e389bSBarry Smith       if (roworiented) {
1915ef9f2a5SBarry Smith         value = v[l + k*n];
192bef8e0ddSBarry Smith       } else {
1934b0e389bSBarry Smith         value = v[k + l*m];
1944b0e389bSBarry Smith       }
195abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
19636db0b34SBarry Smith 
1977cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
198e2ee6c50SBarry Smith       lastcol = col;
199416022c9SBarry Smith       while (high-low > 5) {
200416022c9SBarry Smith         t = (low+high)/2;
201416022c9SBarry Smith         if (rp[t] > col) high = t;
202416022c9SBarry Smith         else             low  = t;
20317ab2063SBarry Smith       }
204416022c9SBarry Smith       for (i=low; i<high; i++) {
20517ab2063SBarry Smith         if (rp[i] > col) break;
20617ab2063SBarry Smith         if (rp[i] == col) {
207416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
20817ab2063SBarry Smith           else                  ap[i] = value;
20917ab2063SBarry Smith           goto noinsert;
21017ab2063SBarry Smith         }
21117ab2063SBarry Smith       }
212abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
213c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
214cc72174dSBarry Smith       if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
215421e10b8SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap.n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
216c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
217416022c9SBarry Smith       /* shift up all the later entries in this row */
218416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
21917ab2063SBarry Smith         rp[ii+1] = rp[ii];
22017ab2063SBarry Smith         ap[ii+1] = ap[ii];
22117ab2063SBarry Smith       }
22217ab2063SBarry Smith       rp[i] = col;
22317ab2063SBarry Smith       ap[i] = value;
22417ab2063SBarry Smith       noinsert:;
225416022c9SBarry Smith       low = i + 1;
22617ab2063SBarry Smith     }
22717ab2063SBarry Smith     ailen[row] = nrow;
22817ab2063SBarry Smith   }
22988e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
2303a40ed3dSBarry Smith   PetscFunctionReturn(0);
23117ab2063SBarry Smith }
23217ab2063SBarry Smith 
23381824310SBarry Smith 
2344a2ae208SSatish Balay #undef __FUNCT__
2354a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
23697f1f81fSBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
2377eb43aa7SLois Curfman McInnes {
2387eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
23997f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
24097f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
24197e567efSBarry Smith   PetscScalar  *ap,*aa = a->a;
2427eb43aa7SLois Curfman McInnes 
2433a40ed3dSBarry Smith   PetscFunctionBegin;
2447eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2457eb43aa7SLois Curfman McInnes     row  = im[k];
24697e567efSBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
247899cda47SBarry Smith     if (row >= A->rmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap.n-1);
248bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2497eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2507eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
25197e567efSBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
252899cda47SBarry Smith       if (in[l] >= A->cmap.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap.n-1);
253bfeeae90SHong Zhang       col = in[l] ;
2547eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2557eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2567eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2577eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2587eb43aa7SLois Curfman McInnes         else             low  = t;
2597eb43aa7SLois Curfman McInnes       }
2607eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2617eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2627eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
263b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2647eb43aa7SLois Curfman McInnes           goto finished;
2657eb43aa7SLois Curfman McInnes         }
2667eb43aa7SLois Curfman McInnes       }
26797e567efSBarry Smith       *v++ = 0.0;
2687eb43aa7SLois Curfman McInnes       finished:;
2697eb43aa7SLois Curfman McInnes     }
2707eb43aa7SLois Curfman McInnes   }
2713a40ed3dSBarry Smith   PetscFunctionReturn(0);
2727eb43aa7SLois Curfman McInnes }
2737eb43aa7SLois Curfman McInnes 
27417ab2063SBarry Smith 
2754a2ae208SSatish Balay #undef __FUNCT__
2764a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
277dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
27817ab2063SBarry Smith {
279416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2806849ba73SBarry Smith   PetscErrorCode ierr;
2816f69ff64SBarry Smith   PetscInt       i,*col_lens;
2826f69ff64SBarry Smith   int            fd;
28317ab2063SBarry Smith 
2843a40ed3dSBarry Smith   PetscFunctionBegin;
285b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
286899cda47SBarry Smith   ierr = PetscMalloc((4+A->rmap.n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
287552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
288899cda47SBarry Smith   col_lens[1] = A->rmap.n;
289899cda47SBarry Smith   col_lens[2] = A->cmap.n;
290416022c9SBarry Smith   col_lens[3] = a->nz;
291416022c9SBarry Smith 
292416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
293899cda47SBarry Smith   for (i=0; i<A->rmap.n; i++) {
294416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
29517ab2063SBarry Smith   }
296899cda47SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap.n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
297606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
298416022c9SBarry Smith 
299416022c9SBarry Smith   /* store column indices (zero start index) */
3006f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
301416022c9SBarry Smith 
302416022c9SBarry Smith   /* store nonzero values */
3036f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
3043a40ed3dSBarry Smith   PetscFunctionReturn(0);
30517ab2063SBarry Smith }
306416022c9SBarry Smith 
307dfbe8321SBarry Smith EXTERN PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
308cd155464SBarry Smith 
3094a2ae208SSatish Balay #undef __FUNCT__
3104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
311dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
312416022c9SBarry Smith {
313416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
314dfbe8321SBarry Smith   PetscErrorCode    ierr;
315899cda47SBarry Smith   PetscInt          i,j,m = A->rmap.n,shift=0;
316e060cb09SBarry Smith   const char        *name;
317f3ef73ceSBarry Smith   PetscViewerFormat format;
31817ab2063SBarry Smith 
3193a40ed3dSBarry Smith   PetscFunctionBegin;
320435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
321b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
32271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
32397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
324899cda47SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap.n-!shift)) {
325d00d2cf4SBarry Smith       nofinalvalue = 1;
326d00d2cf4SBarry Smith     }
327b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
328899cda47SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap.n);CHKERRQ(ierr);
32977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
33077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
331b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
33217ab2063SBarry Smith 
33317ab2063SBarry Smith     for (i=0; i<m; i++) {
334416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
335aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
33677431f27SBarry 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);
33717ab2063SBarry Smith #else
33877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
33917ab2063SBarry Smith #endif
34017ab2063SBarry Smith       }
34117ab2063SBarry Smith     }
342d00d2cf4SBarry Smith     if (nofinalvalue) {
343899cda47SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap.n,0.0);CHKERRQ(ierr);
344d00d2cf4SBarry Smith     }
345fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
346b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
34768369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
348cd155464SBarry Smith      PetscFunctionReturn(0);
349fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
350b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
35144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
35277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
35344cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
354aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
35536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
356a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
35736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
358a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
35936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
360a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3616831982aSBarry Smith         }
36244cd7ae7SLois Curfman McInnes #else
363a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
36444cd7ae7SLois Curfman McInnes #endif
36544cd7ae7SLois Curfman McInnes       }
366b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
36744cd7ae7SLois Curfman McInnes     }
368b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
369fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
37097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
371b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
37297f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
373496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
374496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
375496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
376496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
377aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
37836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
379496be53dSLois Curfman McInnes #else
380496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
381496be53dSLois Curfman McInnes #endif
382496be53dSLois Curfman McInnes         }
383496be53dSLois Curfman McInnes       }
384496be53dSLois Curfman McInnes     }
3852e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
38677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
3872e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
38877431f27SBarry 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);}
38977431f27SBarry 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);}
39077431f27SBarry 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);}
39177431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
39277431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
39377431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
394496be53dSLois Curfman McInnes     }
395b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
396606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
397496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
398496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
39977431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
400496be53dSLois Curfman McInnes       }
401b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
402496be53dSLois Curfman McInnes     }
403b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
404496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
405496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
406496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
407aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
40836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
409b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4106831982aSBarry Smith           }
411496be53dSLois Curfman McInnes #else
412b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
413496be53dSLois Curfman McInnes #endif
414496be53dSLois Curfman McInnes         }
415496be53dSLois Curfman McInnes       }
416b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
417496be53dSLois Curfman McInnes     }
418b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
419fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
42097f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
42187828ca2SBarry Smith     PetscScalar value;
42202594712SBarry Smith 
423b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
42402594712SBarry Smith     for (i=0; i<m; i++) {
42502594712SBarry Smith       jcnt = 0;
426899cda47SBarry Smith       for (j=0; j<A->cmap.n; j++) {
427e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
42802594712SBarry Smith           value = a->a[cnt++];
429e24b481bSBarry Smith           jcnt++;
43002594712SBarry Smith         } else {
43102594712SBarry Smith           value = 0.0;
43202594712SBarry Smith         }
433aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
434b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
43502594712SBarry Smith #else
436b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
43702594712SBarry Smith #endif
43802594712SBarry Smith       }
439b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44002594712SBarry Smith     }
441b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4423a40ed3dSBarry Smith   } else {
443b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44417ab2063SBarry Smith     for (i=0; i<m; i++) {
44577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
446416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
447aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
44836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
449a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
45036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
451a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4523a40ed3dSBarry Smith         } else {
453a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
45417ab2063SBarry Smith         }
45517ab2063SBarry Smith #else
456a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
45717ab2063SBarry Smith #endif
45817ab2063SBarry Smith       }
459b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46017ab2063SBarry Smith     }
461b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
46217ab2063SBarry Smith   }
463b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4643a40ed3dSBarry Smith   PetscFunctionReturn(0);
465416022c9SBarry Smith }
466416022c9SBarry Smith 
4674a2ae208SSatish Balay #undef __FUNCT__
4684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
469dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
470416022c9SBarry Smith {
471480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
472416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
473dfbe8321SBarry Smith   PetscErrorCode    ierr;
474899cda47SBarry Smith   PetscInt          i,j,m = A->rmap.n,color;
47536db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
476b0a32e0cSBarry Smith   PetscViewer       viewer;
477f3ef73ceSBarry Smith   PetscViewerFormat format;
478cddf8d76SBarry Smith 
4793a40ed3dSBarry Smith   PetscFunctionBegin;
480480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
481b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
48219bcc07fSBarry Smith 
483b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
484416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
4850513a670SBarry Smith 
486fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
4870513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
488b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
489416022c9SBarry Smith     for (i=0; i<m; i++) {
490cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
491bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
492bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
493aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
495cddf8d76SBarry Smith #else
496cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
497cddf8d76SBarry Smith #endif
498b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
499cddf8d76SBarry Smith       }
500cddf8d76SBarry Smith     }
501b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
502cddf8d76SBarry Smith     for (i=0; i<m; i++) {
503cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
504bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
505bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
506cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
507b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
508cddf8d76SBarry Smith       }
509cddf8d76SBarry Smith     }
510b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
511cddf8d76SBarry Smith     for (i=0; i<m; i++) {
512cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
513bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
514bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
515aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
51636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
517cddf8d76SBarry Smith #else
518cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
519cddf8d76SBarry Smith #endif
520b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
521416022c9SBarry Smith       }
522416022c9SBarry Smith     }
5230513a670SBarry Smith   } else {
5240513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5250513a670SBarry Smith     /* first determine max of all nonzero values */
52697f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
527b0a32e0cSBarry Smith     PetscDraw   popup;
52836db0b34SBarry Smith     PetscReal scale;
5290513a670SBarry Smith 
5300513a670SBarry Smith     for (i=0; i<nz; i++) {
5310513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5320513a670SBarry Smith     }
533b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
534b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
535b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5360513a670SBarry Smith     count = 0;
5370513a670SBarry Smith     for (i=0; i<m; i++) {
5380513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
539bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
540bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
54197f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
542b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5430513a670SBarry Smith         count++;
5440513a670SBarry Smith       }
5450513a670SBarry Smith     }
5460513a670SBarry Smith   }
547480ef9eaSBarry Smith   PetscFunctionReturn(0);
548480ef9eaSBarry Smith }
549cddf8d76SBarry Smith 
5504a2ae208SSatish Balay #undef __FUNCT__
5514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
552dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
553480ef9eaSBarry Smith {
554dfbe8321SBarry Smith   PetscErrorCode ierr;
555b0a32e0cSBarry Smith   PetscDraw      draw;
55636db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
557480ef9eaSBarry Smith   PetscTruth     isnull;
558480ef9eaSBarry Smith 
559480ef9eaSBarry Smith   PetscFunctionBegin;
560b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
561b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
562480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
563480ef9eaSBarry Smith 
564480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
565899cda47SBarry Smith   xr  = A->cmap.n; yr = A->rmap.n; h = yr/10.0; w = xr/10.0;
566480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
567b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
568b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
569480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5703a40ed3dSBarry Smith   PetscFunctionReturn(0);
571416022c9SBarry Smith }
572416022c9SBarry Smith 
5734a2ae208SSatish Balay #undef __FUNCT__
5744a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
575dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
576416022c9SBarry Smith {
577dfbe8321SBarry Smith   PetscErrorCode ierr;
5786805f65bSBarry Smith   PetscTruth     iascii,isbinary,isdraw;
579416022c9SBarry Smith 
5803a40ed3dSBarry Smith   PetscFunctionBegin;
58132077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
582fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
583fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
584c45a1595SBarry Smith   if (iascii) {
5853a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5860f5bd95cSBarry Smith   } else if (isbinary) {
5873a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
5880f5bd95cSBarry Smith   } else if (isdraw) {
5893a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
5905cd90555SBarry Smith   } else {
591958c9bccSBarry Smith     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
59217ab2063SBarry Smith   }
5934846f1f5SKris Buschelman   ierr = MatView_Inode(A,viewer);CHKERRQ(ierr);
5943a40ed3dSBarry Smith   PetscFunctionReturn(0);
59517ab2063SBarry Smith }
59619bcc07fSBarry Smith 
5974a2ae208SSatish Balay #undef __FUNCT__
5984a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
599dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
60017ab2063SBarry Smith {
601416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
6026849ba73SBarry Smith   PetscErrorCode ierr;
60397f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
604899cda47SBarry Smith   PetscInt       m = A->rmap.n,*ip,N,*ailen = a->ilen,rmax = 0;
60587828ca2SBarry Smith   PetscScalar    *aa = a->a,*ap;
6063447b6efSHong Zhang   PetscReal      ratio=0.6;
60717ab2063SBarry Smith 
6083a40ed3dSBarry Smith   PetscFunctionBegin;
6093a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
61017ab2063SBarry Smith 
61143ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
61217ab2063SBarry Smith   for (i=1; i<m; i++) {
613416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
61417ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
61594a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
61617ab2063SBarry Smith     if (fshift) {
617bfeeae90SHong Zhang       ip = aj + ai[i] ;
618bfeeae90SHong Zhang       ap = aa + ai[i] ;
61917ab2063SBarry Smith       N  = ailen[i];
62017ab2063SBarry Smith       for (j=0; j<N; j++) {
62117ab2063SBarry Smith         ip[j-fshift] = ip[j];
62217ab2063SBarry Smith         ap[j-fshift] = ap[j];
62317ab2063SBarry Smith       }
62417ab2063SBarry Smith     }
62517ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
62617ab2063SBarry Smith   }
62717ab2063SBarry Smith   if (m) {
62817ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
62917ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
63017ab2063SBarry Smith   }
63117ab2063SBarry Smith   /* reset ilen and imax for each row */
63217ab2063SBarry Smith   for (i=0; i<m; i++) {
63317ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
63417ab2063SBarry Smith   }
635bfeeae90SHong Zhang   a->nz = ai[m];
63617ab2063SBarry Smith 
63709f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
638899cda47SBarry Smith   ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap.n,fshift,a->nz);CHKERRQ(ierr);
639ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
640ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
641a0e1a203SBarry Smith 
642dd5f02e7SSatish Balay   a->reallocs          = 0;
6434e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
64436db0b34SBarry Smith   a->rmax              = rmax;
6454e220ebcSLois Curfman McInnes 
646cb5d8e9eSHong Zhang   /* check for zero rows. If found a large number of zero rows, use CompressedRow functions */
647317fbc4cSHong Zhang   ierr = Mat_CheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
64888e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
64971c2f376SKris Buschelman 
6504846f1f5SKris Buschelman   ierr = MatAssemblyEnd_Inode(A,mode);CHKERRQ(ierr);
6513a40ed3dSBarry Smith   PetscFunctionReturn(0);
65217ab2063SBarry Smith }
65317ab2063SBarry Smith 
6544a2ae208SSatish Balay #undef __FUNCT__
65599cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
65699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
65799cafbc1SBarry Smith {
65899cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
65999cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
66099cafbc1SBarry Smith   PetscScalar    *aa = a->a;
66199cafbc1SBarry Smith 
66299cafbc1SBarry Smith   PetscFunctionBegin;
66399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
66499cafbc1SBarry Smith   PetscFunctionReturn(0);
66599cafbc1SBarry Smith }
66699cafbc1SBarry Smith 
66799cafbc1SBarry Smith #undef __FUNCT__
66899cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
66999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
67099cafbc1SBarry Smith {
67199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
67299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
67399cafbc1SBarry Smith   PetscScalar    *aa = a->a;
67499cafbc1SBarry Smith 
67599cafbc1SBarry Smith   PetscFunctionBegin;
67699cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
67799cafbc1SBarry Smith   PetscFunctionReturn(0);
67899cafbc1SBarry Smith }
67999cafbc1SBarry Smith 
68099cafbc1SBarry Smith #undef __FUNCT__
6814a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
682dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
68317ab2063SBarry Smith {
684416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
685dfbe8321SBarry Smith   PetscErrorCode ierr;
6863a40ed3dSBarry Smith 
6873a40ed3dSBarry Smith   PetscFunctionBegin;
688899cda47SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap.n])*sizeof(PetscScalar));CHKERRQ(ierr);
6893a40ed3dSBarry Smith   PetscFunctionReturn(0);
69017ab2063SBarry Smith }
691416022c9SBarry Smith 
6924a2ae208SSatish Balay #undef __FUNCT__
6934a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
694dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
69517ab2063SBarry Smith {
696416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
697dfbe8321SBarry Smith   PetscErrorCode ierr;
698d5d45c9bSBarry Smith 
6993a40ed3dSBarry Smith   PetscFunctionBegin;
700aa482453SBarry Smith #if defined(PETSC_USE_LOG)
701899cda47SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap.n,A->cmap.n,a->nz);
70217ab2063SBarry Smith #endif
703e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
704c38d4ed2SBarry Smith   if (a->row) {
705c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
706c38d4ed2SBarry Smith   }
707c38d4ed2SBarry Smith   if (a->col) {
708c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
709c38d4ed2SBarry Smith   }
71005b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
71105b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
71205b42c5fSBarry Smith   ierr = PetscFree(a->idiag);CHKERRQ(ierr);
71305b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
71482bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
71505b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
716cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
71705b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
718407f6b05SHong Zhang   if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);}
719d487561eSHong Zhang   if (a->compressedrow.use){ierr = PetscFree(a->compressedrow.i);}
720a30b2313SHong Zhang 
7214846f1f5SKris Buschelman   ierr = MatDestroy_Inode(A);CHKERRQ(ierr);
7224846f1f5SKris Buschelman 
723606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
724901853e0SKris Buschelman 
725dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
726901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
727901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
728901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
729901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
730901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
731ba03775dSHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqcsrperm_C","",PETSC_NULL);CHKERRQ(ierr);
732901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
733901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
734a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
735901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
7363a40ed3dSBarry Smith   PetscFunctionReturn(0);
73717ab2063SBarry Smith }
73817ab2063SBarry Smith 
7394a2ae208SSatish Balay #undef __FUNCT__
7404a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
741dfbe8321SBarry Smith PetscErrorCode MatCompress_SeqAIJ(Mat A)
74217ab2063SBarry Smith {
7433a40ed3dSBarry Smith   PetscFunctionBegin;
7443a40ed3dSBarry Smith   PetscFunctionReturn(0);
74517ab2063SBarry Smith }
74617ab2063SBarry Smith 
7474a2ae208SSatish Balay #undef __FUNCT__
7484a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
749*4e0d8c25SBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscTruth flg)
75017ab2063SBarry Smith {
751416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7524846f1f5SKris Buschelman   PetscErrorCode ierr;
7533a40ed3dSBarry Smith 
7543a40ed3dSBarry Smith   PetscFunctionBegin;
755a65d3064SKris Buschelman   switch (op) {
756a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
757*4e0d8c25SBarry Smith       a->roworiented       = flg;
758a65d3064SKris Buschelman       break;
759a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
760*4e0d8c25SBarry Smith       a->keepzeroedrows    = flg;
761a65d3064SKris Buschelman       break;
762a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
763*4e0d8c25SBarry Smith       a->sorted            = flg;
764a65d3064SKris Buschelman       break;
765a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
766*4e0d8c25SBarry Smith       a->nonew             = (flg ? 1 : 0);
767a65d3064SKris Buschelman       break;
768a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
769*4e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
770a65d3064SKris Buschelman       break;
771a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
772*4e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
773a65d3064SKris Buschelman       break;
774a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
775*4e0d8c25SBarry Smith       a->ignorezeroentries = flg;
7760df259c2SBarry Smith       break;
777d487561eSHong Zhang     case MAT_USE_COMPRESSEDROW:
778*4e0d8c25SBarry Smith       a->compressedrow.use = flg;
779d487561eSHong Zhang       break;
780a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
781*4e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
782a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
783a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
784290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
785a65d3064SKris Buschelman       break;
786a65d3064SKris Buschelman     default:
78771c2f376SKris Buschelman       break;
788a65d3064SKris Buschelman   }
789*4e0d8c25SBarry Smith   ierr = MatSetOption_Inode(A,op,flg);CHKERRQ(ierr);
7903a40ed3dSBarry Smith   PetscFunctionReturn(0);
79117ab2063SBarry Smith }
79217ab2063SBarry Smith 
7934a2ae208SSatish Balay #undef __FUNCT__
7944a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
795dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
79617ab2063SBarry Smith {
797416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7986849ba73SBarry Smith   PetscErrorCode ierr;
79997f1f81fSBarry Smith   PetscInt       i,j,n;
80087828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
80117ab2063SBarry Smith 
8023a40ed3dSBarry Smith   PetscFunctionBegin;
8032dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
8041ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
80536db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
806899cda47SBarry Smith   if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
807899cda47SBarry Smith   for (i=0; i<A->rmap.n; i++) {
808bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
809bfeeae90SHong Zhang       if (a->j[j] == i) {
810416022c9SBarry Smith         x[i] = a->a[j];
81117ab2063SBarry Smith         break;
81217ab2063SBarry Smith       }
81317ab2063SBarry Smith     }
81417ab2063SBarry Smith   }
8151ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8163a40ed3dSBarry Smith   PetscFunctionReturn(0);
81717ab2063SBarry Smith }
81817ab2063SBarry Smith 
8194a2ae208SSatish Balay #undef __FUNCT__
8204a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
821dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
82217ab2063SBarry Smith {
823416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
8245c897100SBarry Smith   PetscScalar       *x,*y;
825dfbe8321SBarry Smith   PetscErrorCode    ierr;
826899cda47SBarry Smith   PetscInt          m = A->rmap.n;
8275c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8285c897100SBarry Smith   PetscScalar       *v,alpha;
8297b2bb3b9SHong Zhang   PetscInt          n,i,*idx,*ii,*ridx=PETSC_NULL;
8303447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
8314eb6d288SHong Zhang   PetscTruth        usecprow = cprow.use;
8325c897100SBarry Smith #endif
83317ab2063SBarry Smith 
8343a40ed3dSBarry Smith   PetscFunctionBegin;
8352e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
8361ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
8371ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8385c897100SBarry Smith 
8395c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
840bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
8415c897100SBarry Smith #else
8423447b6efSHong Zhang   if (usecprow){
8433447b6efSHong Zhang     m    = cprow.nrows;
8443447b6efSHong Zhang     ii   = cprow.i;
8457b2bb3b9SHong Zhang     ridx = cprow.rindex;
8463447b6efSHong Zhang   } else {
8473447b6efSHong Zhang     ii = a->i;
8483447b6efSHong Zhang   }
84917ab2063SBarry Smith   for (i=0; i<m; i++) {
8503447b6efSHong Zhang     idx   = a->j + ii[i] ;
8513447b6efSHong Zhang     v     = a->a + ii[i] ;
8523447b6efSHong Zhang     n     = ii[i+1] - ii[i];
8533447b6efSHong Zhang     if (usecprow){
8547b2bb3b9SHong Zhang       alpha = x[ridx[i]];
8553447b6efSHong Zhang     } else {
85617ab2063SBarry Smith       alpha = x[i];
8573447b6efSHong Zhang     }
85817ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
85917ab2063SBarry Smith   }
8605c897100SBarry Smith #endif
861efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
8621ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8631ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8643a40ed3dSBarry Smith   PetscFunctionReturn(0);
86517ab2063SBarry Smith }
86617ab2063SBarry Smith 
8674a2ae208SSatish Balay #undef __FUNCT__
8685c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
869dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8705c897100SBarry Smith {
8718d5b0100SBarry Smith   PetscScalar    zero = 0.0;
872dfbe8321SBarry Smith   PetscErrorCode ierr;
8735c897100SBarry Smith 
8745c897100SBarry Smith   PetscFunctionBegin;
8752dcb1b2aSMatthew Knepley   ierr = VecSet(yy,zero);CHKERRQ(ierr);
8765c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8775c897100SBarry Smith   PetscFunctionReturn(0);
8785c897100SBarry Smith }
8795c897100SBarry Smith 
8805c897100SBarry Smith 
8815c897100SBarry Smith #undef __FUNCT__
8824a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
883dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
88417ab2063SBarry Smith {
885416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
88697952fefSHong Zhang   PetscScalar    *x,*y,*aa;
887dfbe8321SBarry Smith   PetscErrorCode ierr;
888899cda47SBarry Smith   PetscInt       m=A->rmap.n,*aj,*ii;
889a46b3154SVictor Eijkhout   PetscInt       n,i,j,nonzerorow=0,*ridx=PETSC_NULL;
890362ced78SSatish Balay   PetscScalar    sum;
89197952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
892f2e71c43SSatish Balay #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
893f2e71c43SSatish Balay   PetscInt       jrow;
894e36a17ebSSatish Balay #endif
89517ab2063SBarry Smith 
896b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
89797952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
898fee21e36SBarry Smith #endif
899fee21e36SBarry Smith 
9003a40ed3dSBarry Smith   PetscFunctionBegin;
9011ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
90397952fefSHong Zhang   aj  = a->j;
90497952fefSHong Zhang   aa  = a->a;
905416022c9SBarry Smith   ii  = a->i;
9064eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
90797952fefSHong Zhang     m    = a->compressedrow.nrows;
90897952fefSHong Zhang     ii   = a->compressedrow.i;
90997952fefSHong Zhang     ridx = a->compressedrow.rindex;
91097952fefSHong Zhang     for (i=0; i<m; i++){
91197952fefSHong Zhang       n   = ii[i+1] - ii[i];
91297952fefSHong Zhang       aj  = a->j + ii[i];
91397952fefSHong Zhang       aa  = a->a + ii[i];
91497952fefSHong Zhang       sum = 0.0;
915a46b3154SVictor Eijkhout       nonzerorow += (n>0);
91697952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
91797952fefSHong Zhang       y[*ridx++] = sum;
91897952fefSHong Zhang     }
91997952fefSHong Zhang   } else { /* do not use compressed row format */
920b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
921b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
922b05257ddSBarry Smith #else
92317ab2063SBarry Smith     for (i=0; i<m; i++) {
9249ea0dfa2SSatish Balay       jrow = ii[i];
9259ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
92617ab2063SBarry Smith       sum  = 0.0;
927a46b3154SVictor Eijkhout       nonzerorow += (n>0);
9289ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
92997952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9309ea0dfa2SSatish Balay       }
93117ab2063SBarry Smith       y[i] = sum;
93217ab2063SBarry Smith     }
9338d195f9aSBarry Smith #endif
934b05257ddSBarry Smith   }
935a46b3154SVictor Eijkhout   ierr = PetscLogFlops(2*a->nz - nonzerorow);CHKERRQ(ierr);
9361ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9371ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9383a40ed3dSBarry Smith   PetscFunctionReturn(0);
93917ab2063SBarry Smith }
94017ab2063SBarry Smith 
9414a2ae208SSatish Balay #undef __FUNCT__
9424a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
943dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
94417ab2063SBarry Smith {
945416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
94697952fefSHong Zhang   PetscScalar    *x,*y,*z,*aa;
947dfbe8321SBarry Smith   PetscErrorCode ierr;
948899cda47SBarry Smith   PetscInt       m = A->rmap.n,*aj,*ii;
949aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
95097952fefSHong Zhang   PetscInt       n,i,jrow,j,*ridx=PETSC_NULL;
951362ced78SSatish Balay   PetscScalar    sum;
95297952fefSHong Zhang   PetscTruth     usecprow=a->compressedrow.use;
953e36a17ebSSatish Balay #endif
9549ea0dfa2SSatish Balay 
9553a40ed3dSBarry Smith   PetscFunctionBegin;
9561ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9571ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9582e8a6d31SBarry Smith   if (zz != yy) {
9591ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9602e8a6d31SBarry Smith   } else {
9612e8a6d31SBarry Smith     z = y;
9622e8a6d31SBarry Smith   }
963bfeeae90SHong Zhang 
96497952fefSHong Zhang   aj  = a->j;
96597952fefSHong Zhang   aa  = a->a;
966cddf8d76SBarry Smith   ii  = a->i;
967aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
96897952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
96902ab625aSSatish Balay #else
9704eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
9714eb6d288SHong Zhang     if (zz != yy){
9724eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
9734eb6d288SHong Zhang     }
97497952fefSHong Zhang     m    = a->compressedrow.nrows;
97597952fefSHong Zhang     ii   = a->compressedrow.i;
97697952fefSHong Zhang     ridx = a->compressedrow.rindex;
97797952fefSHong Zhang     for (i=0; i<m; i++){
97897952fefSHong Zhang       n  = ii[i+1] - ii[i];
97997952fefSHong Zhang       aj  = a->j + ii[i];
98097952fefSHong Zhang       aa  = a->a + ii[i];
98197952fefSHong Zhang       sum = y[*ridx];
98297952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
98397952fefSHong Zhang       z[*ridx++] = sum;
98497952fefSHong Zhang     }
98597952fefSHong Zhang   } else { /* do not use compressed row format */
98617ab2063SBarry Smith     for (i=0; i<m; i++) {
9879ea0dfa2SSatish Balay       jrow = ii[i];
9889ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
98917ab2063SBarry Smith       sum  = y[i];
9909ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
99197952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
9929ea0dfa2SSatish Balay       }
99317ab2063SBarry Smith       z[i] = sum;
99417ab2063SBarry Smith     }
99597952fefSHong Zhang   }
99602ab625aSSatish Balay #endif
997efee365bSSatish Balay   ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
9981ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9991ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10002e8a6d31SBarry Smith   if (zz != yy) {
10011ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
10022e8a6d31SBarry Smith   }
10033a40ed3dSBarry Smith   PetscFunctionReturn(0);
100417ab2063SBarry Smith }
100517ab2063SBarry Smith 
100617ab2063SBarry Smith /*
100717ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
100817ab2063SBarry Smith */
10094a2ae208SSatish Balay #undef __FUNCT__
10104a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1011dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
101217ab2063SBarry Smith {
1013416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10146849ba73SBarry Smith   PetscErrorCode ierr;
101509f38230SBarry Smith   PetscInt       i,j,m = A->rmap.n;
101617ab2063SBarry Smith 
10173a40ed3dSBarry Smith   PetscFunctionBegin;
101809f38230SBarry Smith   if (!a->diag) {
101909f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
10209518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
102109f38230SBarry Smith   }
1022899cda47SBarry Smith   for (i=0; i<A->rmap.n; i++) {
102309f38230SBarry Smith     a->diag[i] = a->i[i+1];
1024bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1025bfeeae90SHong Zhang       if (a->j[j] == i) {
102609f38230SBarry Smith         a->diag[i] = j;
102717ab2063SBarry Smith         break;
102817ab2063SBarry Smith       }
102917ab2063SBarry Smith     }
103017ab2063SBarry Smith   }
10313a40ed3dSBarry Smith   PetscFunctionReturn(0);
103217ab2063SBarry Smith }
103317ab2063SBarry Smith 
1034be5855fcSBarry Smith /*
1035be5855fcSBarry Smith      Checks for missing diagonals
1036be5855fcSBarry Smith */
10374a2ae208SSatish Balay #undef __FUNCT__
10384a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
103909f38230SBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscTruth *missing,PetscInt *d)
1040be5855fcSBarry Smith {
1041be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
104297f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1043be5855fcSBarry Smith 
1044be5855fcSBarry Smith   PetscFunctionBegin;
104509f38230SBarry Smith   *missing = PETSC_FALSE;
104609f38230SBarry Smith   if (A->rmap.n > 0 && !jj) {
104709f38230SBarry Smith     *missing  = PETSC_TRUE;
104809f38230SBarry Smith     if (d) *d = 0;
104909f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
105009f38230SBarry Smith   } else {
1051f1e2ffcdSBarry Smith     diag = a->diag;
1052899cda47SBarry Smith     for (i=0; i<A->rmap.n; i++) {
1053bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
105409f38230SBarry Smith 	*missing = PETSC_TRUE;
105509f38230SBarry Smith 	if (d) *d = i;
105609f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
105709f38230SBarry Smith       }
1058be5855fcSBarry Smith     }
1059be5855fcSBarry Smith   }
1060be5855fcSBarry Smith   PetscFunctionReturn(0);
1061be5855fcSBarry Smith }
1062be5855fcSBarry Smith 
10634a2ae208SSatish Balay #undef __FUNCT__
10644a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
106597f1f81fSBarry Smith PetscErrorCode MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
106617ab2063SBarry Smith {
1067416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1068beeb8507SBarry Smith   PetscScalar        *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag;
1069beeb8507SBarry Smith   const PetscScalar  *v = a->a, *b, *bs,*xb, *ts;
1070dfbe8321SBarry Smith   PetscErrorCode     ierr;
1071899cda47SBarry Smith   PetscInt           n = A->cmap.n,m = A->rmap.n,i;
107297f1f81fSBarry Smith   const PetscInt     *idx,*diag;
107317ab2063SBarry Smith 
10743a40ed3dSBarry Smith   PetscFunctionBegin;
1075b965ef7fSBarry Smith   its = its*lits;
107677431f27SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
107791723122SBarry Smith 
1078ed480e8bSBarry Smith   diag = a->diag;
1079ed480e8bSBarry Smith   if (!a->idiag) {
1080ed480e8bSBarry Smith     ierr     = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
10819518dbb4SMatthew Knepley     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
1082ed480e8bSBarry Smith     a->ssor  = a->idiag + m;
1083ed480e8bSBarry Smith     mdiag    = a->ssor + m;
1084ed480e8bSBarry Smith     v        = a->a;
1085ed480e8bSBarry Smith 
1086ed480e8bSBarry Smith     /* this is wrong when fshift omega changes each iteration */
1087958c9bccSBarry Smith     if (omega == 1.0 && !fshift) {
1088ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1089ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
109029c1d7e0SHong Zhang         if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1091ed480e8bSBarry Smith         a->idiag[i] = 1.0/v[diag[i]];
1092ed480e8bSBarry Smith       }
1093efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
1094ed480e8bSBarry Smith     } else {
1095ed480e8bSBarry Smith       for (i=0; i<m; i++) {
1096ed480e8bSBarry Smith         mdiag[i]    = v[diag[i]];
1097beeb8507SBarry Smith         a->idiag[i] = omega/(fshift + v[diag[i]]);
1098ed480e8bSBarry Smith       }
1099efee365bSSatish Balay       ierr = PetscLogFlops(2*m);CHKERRQ(ierr);
1100beeb8507SBarry Smith     }
1101ed480e8bSBarry Smith   }
1102ed480e8bSBarry Smith   t     = a->ssor;
1103ed480e8bSBarry Smith   idiag = a->idiag;
1104ed480e8bSBarry Smith   mdiag = a->idiag + 2*m;
1105ed480e8bSBarry Smith 
11061ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1107fb2e594dSBarry Smith   if (xx != bb) {
11081ebc52fbSHong Zhang     ierr = VecGetArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);
1109fb2e594dSBarry Smith   } else {
1110fb2e594dSBarry Smith     b = x;
1111fb2e594dSBarry Smith   }
1112fb2e594dSBarry Smith 
1113ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
1114ed480e8bSBarry Smith   xs   = x;
111517ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
111617ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1117ed480e8bSBarry Smith     bs = b;
111817ab2063SBarry Smith     for (i=0; i<m; i++) {
1119ed480e8bSBarry Smith         d    = fshift + a->a[diag[i]];
1120416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1121ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1122ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
112317ab2063SBarry Smith         sum  = b[i]*d/omega;
112417ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
112517ab2063SBarry Smith         x[i] = sum;
112617ab2063SBarry Smith     }
11271ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11281ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
1129efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
11303a40ed3dSBarry Smith     PetscFunctionReturn(0);
113117ab2063SBarry Smith   }
1132c783ea89SBarry Smith 
1133ed480e8bSBarry Smith 
1134fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1135fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1136fc3d8934SBarry Smith 
1137fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1138fc3d8934SBarry Smith 
1139fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1140fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
114148af12d7SBarry Smith     is the relaxation factor.
1142fc3d8934SBarry Smith     */
1143fc3d8934SBarry Smith 
114448af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
114529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
11463a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
114717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
114817ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
114917ab2063SBarry Smith 
115017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
115117ab2063SBarry Smith 
115217ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
115317ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
115417ab2063SBarry Smith     is the relaxation factor.
115517ab2063SBarry Smith     */
115617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
115717ab2063SBarry Smith 
115817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
115917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1160416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1161ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1162ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
116317ab2063SBarry Smith       sum  = b[i];
116417ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1165ed480e8bSBarry Smith       x[i] = sum*idiag[i];
116617ab2063SBarry Smith     }
116717ab2063SBarry Smith 
116817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1169416022c9SBarry Smith     v = a->a;
1170ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
117117ab2063SBarry Smith 
117217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1173ed480e8bSBarry Smith     ts = t;
1174416022c9SBarry Smith     diag = a->diag;
117517ab2063SBarry Smith     for (i=0; i<m; i++) {
1176416022c9SBarry Smith       n    = diag[i] - a->i[i];
1177ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1178ed480e8bSBarry Smith       v    = a->a + a->i[i];
117917ab2063SBarry Smith       sum  = t[i];
118017ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
1181ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1182733d66baSBarry Smith       /*  x = x + t */
1183733d66baSBarry Smith       x[i] += t[i];
118417ab2063SBarry Smith     }
118517ab2063SBarry Smith 
1186efee365bSSatish Balay     ierr = PetscLogFlops(6*m-1 + 2*a->nz);CHKERRQ(ierr);
11871ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11881ebc52fbSHong Zhang     if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
11893a40ed3dSBarry Smith     PetscFunctionReturn(0);
119017ab2063SBarry Smith   }
119117ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
119217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
119377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
119497f1f81fSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)b);
119577d8c4bbSBarry Smith #else
119617ab2063SBarry Smith       for (i=0; i<m; i++) {
1197416022c9SBarry Smith         n    = diag[i] - a->i[i];
1198ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1199ed480e8bSBarry Smith         v    = a->a + a->i[i];
120017ab2063SBarry Smith         sum  = b[i];
120117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1202ed480e8bSBarry Smith         x[i] = sum*idiag[i];
120317ab2063SBarry Smith       }
120477d8c4bbSBarry Smith #endif
120517ab2063SBarry Smith       xb = x;
1206efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
12073a40ed3dSBarry Smith     } else xb = b;
120817ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
120917ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
121017ab2063SBarry Smith       for (i=0; i<m; i++) {
1211ed480e8bSBarry Smith         x[i] *= mdiag[i];
121217ab2063SBarry Smith       }
1213efee365bSSatish Balay       ierr = PetscLogFlops(m);CHKERRQ(ierr);
121417ab2063SBarry Smith     }
121517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
121677d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
121797f1f81fSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,idiag,a->a,(void*)xb);
121877d8c4bbSBarry Smith #else
121917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1220416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1221ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1222ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
122317ab2063SBarry Smith         sum  = xb[i];
122417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1225ed480e8bSBarry Smith         x[i] = sum*idiag[i];
122617ab2063SBarry Smith       }
122777d8c4bbSBarry Smith #endif
1228efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
122917ab2063SBarry Smith     }
123017ab2063SBarry Smith     its--;
123117ab2063SBarry Smith   }
123217ab2063SBarry Smith   while (its--) {
123317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
123477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
123597f1f81fSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
123677d8c4bbSBarry Smith #else
123717ab2063SBarry Smith       for (i=0; i<m; i++) {
1238416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1239ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1240ed480e8bSBarry Smith         v    = a->a + a->i[i];
124117ab2063SBarry Smith         sum  = b[i];
124217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1243ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
124417ab2063SBarry Smith       }
124577d8c4bbSBarry Smith #endif
1246efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
124717ab2063SBarry Smith     }
124817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
124977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
125097f1f81fSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(PetscInt*)diag,a->a,(void*)b);
125177d8c4bbSBarry Smith #else
125217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1253416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1254ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1255ed480e8bSBarry Smith         v    = a->a + a->i[i];
125617ab2063SBarry Smith         sum  = b[i];
125717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
1258ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
125917ab2063SBarry Smith       }
126077d8c4bbSBarry Smith #endif
1261efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
126217ab2063SBarry Smith     }
126317ab2063SBarry Smith   }
12641ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12651ebc52fbSHong Zhang   if (bb != xx) {ierr = VecRestoreArray(bb,(PetscScalar**)&b);CHKERRQ(ierr);}
12663a40ed3dSBarry Smith   PetscFunctionReturn(0);
126717ab2063SBarry Smith }
126817ab2063SBarry Smith 
12694a2ae208SSatish Balay #undef __FUNCT__
12704a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1271dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
127217ab2063SBarry Smith {
1273416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12744e220ebcSLois Curfman McInnes 
12753a40ed3dSBarry Smith   PetscFunctionBegin;
1276899cda47SBarry Smith   info->rows_global    = (double)A->rmap.n;
1277899cda47SBarry Smith   info->columns_global = (double)A->cmap.n;
1278899cda47SBarry Smith   info->rows_local     = (double)A->rmap.n;
1279899cda47SBarry Smith   info->columns_local  = (double)A->cmap.n;
12804e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12814e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12824e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12834e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12844e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12854e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12864e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12874e220ebcSLois Curfman McInnes   if (A->factor) {
12884e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12894e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12904e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12914e220ebcSLois Curfman McInnes   } else {
12924e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12934e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12944e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12954e220ebcSLois Curfman McInnes   }
12963a40ed3dSBarry Smith   PetscFunctionReturn(0);
129717ab2063SBarry Smith }
129817ab2063SBarry Smith 
12994a2ae208SSatish Balay #undef __FUNCT__
13004a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
1301f4df32b1SMatthew Knepley PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag)
130217ab2063SBarry Smith {
1303416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
130409f38230SBarry Smith   PetscInt       i,m = A->rmap.n - 1,d;
13056849ba73SBarry Smith   PetscErrorCode ierr;
130609f38230SBarry Smith   PetscTruth     missing;
130717ab2063SBarry Smith 
13083a40ed3dSBarry Smith   PetscFunctionBegin;
1309f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1310f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
131177431f27SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1312bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1313f1e2ffcdSBarry Smith     }
1314f4df32b1SMatthew Knepley     if (diag != 0.0) {
131509f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
131609f38230SBarry Smith       if (missing) SETERRQ1(PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1317f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1318f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1319f1e2ffcdSBarry Smith       }
1320f1e2ffcdSBarry Smith     }
132188e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1322f1e2ffcdSBarry Smith   } else {
1323f4df32b1SMatthew Knepley     if (diag != 0.0) {
132417ab2063SBarry Smith       for (i=0; i<N; i++) {
132577431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
13267ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1327416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1328f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1329bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
13307ae801bdSBarry Smith         } else { /* in case row was completely empty */
1331f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
133217ab2063SBarry Smith         }
133317ab2063SBarry Smith       }
13343a40ed3dSBarry Smith     } else {
133517ab2063SBarry Smith       for (i=0; i<N; i++) {
133677431f27SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1337416022c9SBarry Smith         a->ilen[rows[i]] = 0;
133817ab2063SBarry Smith       }
133917ab2063SBarry Smith     }
134088e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1341f1e2ffcdSBarry Smith   }
134243a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13433a40ed3dSBarry Smith   PetscFunctionReturn(0);
134417ab2063SBarry Smith }
134517ab2063SBarry Smith 
13464a2ae208SSatish Balay #undef __FUNCT__
13474a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
134897f1f81fSBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
134917ab2063SBarry Smith {
1350416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
135197f1f81fSBarry Smith   PetscInt   *itmp;
135217ab2063SBarry Smith 
13533a40ed3dSBarry Smith   PetscFunctionBegin;
1354899cda47SBarry Smith   if (row < 0 || row >= A->rmap.n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
135517ab2063SBarry Smith 
1356416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1357bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
135817ab2063SBarry Smith   if (idx) {
1359bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1360bfeeae90SHong Zhang     if (*nz) {
13614e093b46SBarry Smith       *idx = itmp;
136217ab2063SBarry Smith     }
136317ab2063SBarry Smith     else *idx = 0;
136417ab2063SBarry Smith   }
13653a40ed3dSBarry Smith   PetscFunctionReturn(0);
136617ab2063SBarry Smith }
136717ab2063SBarry Smith 
1368bfeeae90SHong Zhang /* remove this function? */
13694a2ae208SSatish Balay #undef __FUNCT__
13704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
137197f1f81fSBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
137217ab2063SBarry Smith {
13733a40ed3dSBarry Smith   PetscFunctionBegin;
13743a40ed3dSBarry Smith   PetscFunctionReturn(0);
137517ab2063SBarry Smith }
137617ab2063SBarry Smith 
13774a2ae208SSatish Balay #undef __FUNCT__
13784a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1379dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
138017ab2063SBarry Smith {
1381416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
138287828ca2SBarry Smith   PetscScalar    *v = a->a;
138336db0b34SBarry Smith   PetscReal      sum = 0.0;
13846849ba73SBarry Smith   PetscErrorCode ierr;
138597f1f81fSBarry Smith   PetscInt       i,j;
138617ab2063SBarry Smith 
13873a40ed3dSBarry Smith   PetscFunctionBegin;
138817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1389416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1390aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
139136db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
139217ab2063SBarry Smith #else
139317ab2063SBarry Smith       sum += (*v)*(*v); v++;
139417ab2063SBarry Smith #endif
139517ab2063SBarry Smith     }
1396064f8208SBarry Smith     *nrm = sqrt(sum);
13973a40ed3dSBarry Smith   } else if (type == NORM_1) {
139836db0b34SBarry Smith     PetscReal *tmp;
139997f1f81fSBarry Smith     PetscInt    *jj = a->j;
1400899cda47SBarry Smith     ierr = PetscMalloc((A->cmap.n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1401899cda47SBarry Smith     ierr = PetscMemzero(tmp,A->cmap.n*sizeof(PetscReal));CHKERRQ(ierr);
1402064f8208SBarry Smith     *nrm = 0.0;
1403416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1404bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
140517ab2063SBarry Smith     }
1406899cda47SBarry Smith     for (j=0; j<A->cmap.n; j++) {
1407064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
140817ab2063SBarry Smith     }
1409606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
14103a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1411064f8208SBarry Smith     *nrm = 0.0;
1412899cda47SBarry Smith     for (j=0; j<A->rmap.n; j++) {
1413bfeeae90SHong Zhang       v = a->a + a->i[j];
141417ab2063SBarry Smith       sum = 0.0;
1415416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1416cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
141717ab2063SBarry Smith       }
1418064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
141917ab2063SBarry Smith     }
14203a40ed3dSBarry Smith   } else {
142129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
142217ab2063SBarry Smith   }
14233a40ed3dSBarry Smith   PetscFunctionReturn(0);
142417ab2063SBarry Smith }
142517ab2063SBarry Smith 
14264a2ae208SSatish Balay #undef __FUNCT__
14274a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1428dfbe8321SBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,Mat *B)
142917ab2063SBarry Smith {
1430416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1431416022c9SBarry Smith   Mat            C;
14326849ba73SBarry Smith   PetscErrorCode ierr;
1433899cda47SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap.n,len,*col;
143487828ca2SBarry Smith   PetscScalar    *array = a->a;
143517ab2063SBarry Smith 
14363a40ed3dSBarry Smith   PetscFunctionBegin;
1437899cda47SBarry Smith   if (!B && m != A->cmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1438899cda47SBarry Smith   ierr = PetscMalloc((1+A->cmap.n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1439899cda47SBarry Smith   ierr = PetscMemzero(col,(1+A->cmap.n)*sizeof(PetscInt));CHKERRQ(ierr);
1440bfeeae90SHong Zhang 
1441bfeeae90SHong Zhang   for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1442f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1443899cda47SBarry Smith   ierr = MatSetSizes(C,A->cmap.n,m,A->cmap.n,m);CHKERRQ(ierr);
1444f204ca49SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1445ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1446606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
144717ab2063SBarry Smith   for (i=0; i<m; i++) {
144817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
144987d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1450b9b97703SBarry Smith     array += len;
1451b9b97703SBarry Smith     aj    += len;
145217ab2063SBarry Smith   }
145317ab2063SBarry Smith 
14546d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14556d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
145617ab2063SBarry Smith 
1457f1e2ffcdSBarry Smith   if (B) {
1458416022c9SBarry Smith     *B = C;
145917ab2063SBarry Smith   } else {
1460273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
146117ab2063SBarry Smith   }
14623a40ed3dSBarry Smith   PetscFunctionReturn(0);
146317ab2063SBarry Smith }
146417ab2063SBarry Smith 
1465cd0d46ebSvictorle EXTERN_C_BEGIN
1466cd0d46ebSvictorle #undef __FUNCT__
14675fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
1468be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f)
1469cd0d46ebSvictorle {
1470cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
147197f1f81fSBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
14726849ba73SBarry Smith   PetscErrorCode ierr;
147397f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1474cd0d46ebSvictorle 
1475cd0d46ebSvictorle   PetscFunctionBegin;
1476cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1477cd0d46ebSvictorle 
1478cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1479cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
14805485867bSBarry Smith   if (ma!=nb || na!=mb){
14815485867bSBarry Smith     *f = PETSC_FALSE;
14825485867bSBarry Smith     PetscFunctionReturn(0);
14835485867bSBarry Smith   }
1484cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1485cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1486cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
148797f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
148897f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1489cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1490cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1491cd0d46ebSvictorle 
1492cd0d46ebSvictorle   *f = PETSC_TRUE;
1493cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1494cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
149597f1f81fSBarry Smith       PetscInt         idc,idr;
14965485867bSBarry Smith       PetscScalar vc,vr;
1497cd0d46ebSvictorle       /* column/row index/value */
14985485867bSBarry Smith       idc = adx[aptr[i]];
14995485867bSBarry Smith       idr = bdx[bptr[idc]];
15005485867bSBarry Smith       vc  = va[aptr[i]];
15015485867bSBarry Smith       vr  = vb[bptr[idc]];
15025485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
15035485867bSBarry Smith 	*f = PETSC_FALSE;
15045485867bSBarry Smith         goto done;
1505cd0d46ebSvictorle       } else {
15065485867bSBarry Smith 	aptr[i]++;
15075485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1508cd0d46ebSvictorle       }
1509cd0d46ebSvictorle     }
1510cd0d46ebSvictorle   }
1511cd0d46ebSvictorle  done:
1512cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
15133aeef889SHong Zhang   if (B) {
15143aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
15153aeef889SHong Zhang   }
1516cd0d46ebSvictorle   PetscFunctionReturn(0);
1517cd0d46ebSvictorle }
1518cd0d46ebSvictorle EXTERN_C_END
1519cd0d46ebSvictorle 
15201cbb95d3SBarry Smith EXTERN_C_BEGIN
15211cbb95d3SBarry Smith #undef __FUNCT__
15221cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
15231cbb95d3SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscTruth *f)
15241cbb95d3SBarry Smith {
15251cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
15261cbb95d3SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb;
15271cbb95d3SBarry Smith   PetscErrorCode ierr;
15281cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
15291cbb95d3SBarry Smith 
15301cbb95d3SBarry Smith   PetscFunctionBegin;
15311cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
15321cbb95d3SBarry Smith 
15331cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
15341cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
15351cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
15361cbb95d3SBarry Smith     *f = PETSC_FALSE;
15371cbb95d3SBarry Smith     PetscFunctionReturn(0);
15381cbb95d3SBarry Smith   }
15391cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
15401cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
15411cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
15421cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
15431cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
15441cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
15451cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
15461cbb95d3SBarry Smith 
15471cbb95d3SBarry Smith   *f = PETSC_TRUE;
15481cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
15491cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
15501cbb95d3SBarry Smith       PetscInt         idc,idr;
15511cbb95d3SBarry Smith       PetscScalar vc,vr;
15521cbb95d3SBarry Smith       /* column/row index/value */
15531cbb95d3SBarry Smith       idc = adx[aptr[i]];
15541cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
15551cbb95d3SBarry Smith       vc  = va[aptr[i]];
15561cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
15571cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
15581cbb95d3SBarry Smith 	*f = PETSC_FALSE;
15591cbb95d3SBarry Smith         goto done;
15601cbb95d3SBarry Smith       } else {
15611cbb95d3SBarry Smith 	aptr[i]++;
15621cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
15631cbb95d3SBarry Smith       }
15641cbb95d3SBarry Smith     }
15651cbb95d3SBarry Smith   }
15661cbb95d3SBarry Smith  done:
15671cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
15681cbb95d3SBarry Smith   if (B) {
15691cbb95d3SBarry Smith     ierr = PetscFree(bptr);CHKERRQ(ierr);
15701cbb95d3SBarry Smith   }
15711cbb95d3SBarry Smith   PetscFunctionReturn(0);
15721cbb95d3SBarry Smith }
15731cbb95d3SBarry Smith EXTERN_C_END
15741cbb95d3SBarry Smith 
15759e29f15eSvictorle #undef __FUNCT__
15769e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1577dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f)
15789e29f15eSvictorle {
1579dfbe8321SBarry Smith   PetscErrorCode ierr;
15809e29f15eSvictorle   PetscFunctionBegin;
15815485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
15829e29f15eSvictorle   PetscFunctionReturn(0);
15839e29f15eSvictorle }
15849e29f15eSvictorle 
15854a2ae208SSatish Balay #undef __FUNCT__
15861cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
15871cbb95d3SBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscTruth *f)
15881cbb95d3SBarry Smith {
15891cbb95d3SBarry Smith   PetscErrorCode ierr;
15901cbb95d3SBarry Smith   PetscFunctionBegin;
15911cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
15921cbb95d3SBarry Smith   PetscFunctionReturn(0);
15931cbb95d3SBarry Smith }
15941cbb95d3SBarry Smith 
15951cbb95d3SBarry Smith #undef __FUNCT__
15964a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1597dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
159817ab2063SBarry Smith {
1599416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
160087828ca2SBarry Smith   PetscScalar    *l,*r,x,*v;
1601dfbe8321SBarry Smith   PetscErrorCode ierr;
1602899cda47SBarry Smith   PetscInt       i,j,m = A->rmap.n,n = A->cmap.n,M,nz = a->nz,*jj;
160317ab2063SBarry Smith 
16043a40ed3dSBarry Smith   PetscFunctionBegin;
160517ab2063SBarry Smith   if (ll) {
16063ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
16073ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1608e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1609899cda47SBarry Smith     if (m != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
16101ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1611416022c9SBarry Smith     v = a->a;
161217ab2063SBarry Smith     for (i=0; i<m; i++) {
161317ab2063SBarry Smith       x = l[i];
1614416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
161517ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
161617ab2063SBarry Smith     }
16171ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1618efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
161917ab2063SBarry Smith   }
162017ab2063SBarry Smith   if (rr) {
1621e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1622899cda47SBarry Smith     if (n != A->cmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
16231ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1624416022c9SBarry Smith     v = a->a; jj = a->j;
162517ab2063SBarry Smith     for (i=0; i<nz; i++) {
1626bfeeae90SHong Zhang       (*v++) *= r[*jj++];
162717ab2063SBarry Smith     }
16281ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1629efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
163017ab2063SBarry Smith   }
16313a40ed3dSBarry Smith   PetscFunctionReturn(0);
163217ab2063SBarry Smith }
163317ab2063SBarry Smith 
16344a2ae208SSatish Balay #undef __FUNCT__
16354a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
163697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
163717ab2063SBarry Smith {
1638db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
16396849ba73SBarry Smith   PetscErrorCode ierr;
1640899cda47SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap.n,*lens;
164197f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
164297f1f81fSBarry Smith   PetscInt       *irow,*icol,nrows,ncols;
164397f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
164487828ca2SBarry Smith   PetscScalar    *a_new,*mat_a;
1645416022c9SBarry Smith   Mat            C;
1646fee21e36SBarry Smith   PetscTruth     stride;
164717ab2063SBarry Smith 
16483a40ed3dSBarry Smith   PetscFunctionBegin;
1649d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
165029bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1651d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
165229bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
165399141d43SSatish Balay 
165417ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1655b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1656b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
165717ab2063SBarry Smith 
1658fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1659fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1660fee21e36SBarry Smith   if (stride && step == 1) {
166102834360SBarry Smith     /* special case of contiguous rows */
166297f1f81fSBarry Smith     ierr   = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
166331ebf83bSSatish Balay     starts = lens + nrows;
166402834360SBarry Smith     /* loop over new rows determining lens and starting points */
166502834360SBarry Smith     for (i=0; i<nrows; i++) {
1666bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1667a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
166802834360SBarry Smith       for (k=kstart; k<kend; k++) {
1669bfeeae90SHong Zhang         if (aj[k] >= first) {
167002834360SBarry Smith           starts[i] = k;
167102834360SBarry Smith           break;
167202834360SBarry Smith 	}
167302834360SBarry Smith       }
1674a2744918SBarry Smith       sum = 0;
167502834360SBarry Smith       while (k < kend) {
1676bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1677a2744918SBarry Smith         sum++;
167802834360SBarry Smith       }
1679a2744918SBarry Smith       lens[i] = sum;
168002834360SBarry Smith     }
168102834360SBarry Smith     /* create submatrix */
1682cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
168397f1f81fSBarry Smith       PetscInt n_cols,n_rows;
168408480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
168529bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1686d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
168708480c60SBarry Smith       C = *B;
16883a40ed3dSBarry Smith     } else {
1689f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1690f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1691e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1692ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
169308480c60SBarry Smith     }
1694db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1695db02288aSLois Curfman McInnes 
169602834360SBarry Smith     /* loop over rows inserting into submatrix */
1697db02288aSLois Curfman McInnes     a_new    = c->a;
1698db02288aSLois Curfman McInnes     j_new    = c->j;
1699db02288aSLois Curfman McInnes     i_new    = c->i;
1700bfeeae90SHong Zhang 
170102834360SBarry Smith     for (i=0; i<nrows; i++) {
1702a2744918SBarry Smith       ii    = starts[i];
1703a2744918SBarry Smith       lensi = lens[i];
1704a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1705a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
170602834360SBarry Smith       }
170787828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1708a2744918SBarry Smith       a_new      += lensi;
1709a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1710a2744918SBarry Smith       c->ilen[i]  = lensi;
171102834360SBarry Smith     }
1712606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
17133a40ed3dSBarry Smith   } else {
171402834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
171597f1f81fSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(PetscInt),&smap);CHKERRQ(ierr);
1716bfeeae90SHong Zhang 
171797f1f81fSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
171897f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
171917ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
172002834360SBarry Smith     /* determine lens of each row */
172102834360SBarry Smith     for (i=0; i<nrows; i++) {
1722bfeeae90SHong Zhang       kstart  = ai[irow[i]];
172302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
172402834360SBarry Smith       lens[i] = 0;
172502834360SBarry Smith       for (k=kstart; k<kend; k++) {
1726bfeeae90SHong Zhang         if (smap[aj[k]]) {
172702834360SBarry Smith           lens[i]++;
172802834360SBarry Smith         }
172902834360SBarry Smith       }
173002834360SBarry Smith     }
173117ab2063SBarry Smith     /* Create and fill new matrix */
1732a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
17330f5bd95cSBarry Smith       PetscTruth equal;
17340f5bd95cSBarry Smith 
173599141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1736899cda47SBarry Smith       if ((*B)->rmap.n  != nrows || (*B)->cmap.n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1737899cda47SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap.n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
17380f5bd95cSBarry Smith       if (!equal) {
173929bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
174099141d43SSatish Balay       }
1741899cda47SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap.n*sizeof(PetscInt));CHKERRQ(ierr);
174208480c60SBarry Smith       C = *B;
17433a40ed3dSBarry Smith     } else {
1744f69a0ea3SMatthew Knepley       ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
1745f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
1746e2d9671bSKris Buschelman       ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
1747ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
174808480c60SBarry Smith     }
174999141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
175017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
175199141d43SSatish Balay       row    = irow[i];
1752bfeeae90SHong Zhang       kstart = ai[row];
175399141d43SSatish Balay       kend   = kstart + a->ilen[row];
1754bfeeae90SHong Zhang       mat_i  = c->i[i];
175599141d43SSatish Balay       mat_j  = c->j + mat_i;
175699141d43SSatish Balay       mat_a  = c->a + mat_i;
175799141d43SSatish Balay       mat_ilen = c->ilen + i;
175817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1759bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1760ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
176199141d43SSatish Balay           *mat_a++ = a->a[k];
176299141d43SSatish Balay           (*mat_ilen)++;
176399141d43SSatish Balay 
176417ab2063SBarry Smith         }
176517ab2063SBarry Smith       }
176617ab2063SBarry Smith     }
176702834360SBarry Smith     /* Free work space */
176802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1769606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1770606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
177102834360SBarry Smith   }
17726d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17736d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
177417ab2063SBarry Smith 
177517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1776416022c9SBarry Smith   *B = C;
17773a40ed3dSBarry Smith   PetscFunctionReturn(0);
177817ab2063SBarry Smith }
177917ab2063SBarry Smith 
1780a871dcd8SBarry Smith /*
1781a871dcd8SBarry Smith */
17824a2ae208SSatish Balay #undef __FUNCT__
17834a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
1784dfbe8321SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
1785a871dcd8SBarry Smith {
178663b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
1787dfbe8321SBarry Smith   PetscErrorCode ierr;
178863b91edcSBarry Smith   Mat            outA;
1789b8a78c4aSBarry Smith   PetscTruth     row_identity,col_identity;
179063b91edcSBarry Smith 
17913a40ed3dSBarry Smith   PetscFunctionBegin;
1792d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1793b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1794b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1795a871dcd8SBarry Smith 
179663b91edcSBarry Smith   outA          = inA;
179763b91edcSBarry Smith   inA->factor   = FACTOR_LU;
1798c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1799c3122656SLisandro Dalcin   if (a->row) { ierr = ISDestroy(a->row); CHKERRQ(ierr);}
1800c3122656SLisandro Dalcin   a->row = row;
1801c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1802c3122656SLisandro Dalcin   if (a->col) { ierr = ISDestroy(a->col); CHKERRQ(ierr);}
1803c3122656SLisandro Dalcin   a->col = col;
180463b91edcSBarry Smith 
180536db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1806b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
18074c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
180852e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
1809f0ec6fceSSatish Balay 
181094a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
1811899cda47SBarry Smith      ierr = PetscMalloc((inA->rmap.n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
18129518dbb4SMatthew Knepley      ierr = PetscLogObjectMemory(inA, (inA->rmap.n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
181394a9d846SBarry Smith   }
181463b91edcSBarry Smith 
1815f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
1816137fb511SHong Zhang   if (row_identity && col_identity) {
1817af281ebdSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ(inA,info,&outA);CHKERRQ(ierr);
1818137fb511SHong Zhang   } else {
1819137fb511SHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(inA,info,&outA);CHKERRQ(ierr);
1820137fb511SHong Zhang   }
18213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1822a871dcd8SBarry Smith }
1823a871dcd8SBarry Smith 
1824d9eff348SSatish Balay #include "petscblaslapack.h"
18254a2ae208SSatish Balay #undef __FUNCT__
18264a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
1827f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
1828f0b747eeSBarry Smith {
1829f0b747eeSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)inA->data;
18304ce68768SBarry Smith   PetscBLASInt bnz = (PetscBLASInt)a->nz,one = 1;
1831f4df32b1SMatthew Knepley   PetscScalar oalpha = alpha;
1832efee365bSSatish Balay   PetscErrorCode ierr;
1833efee365bSSatish Balay 
18343a40ed3dSBarry Smith 
18353a40ed3dSBarry Smith   PetscFunctionBegin;
1836f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
1837efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
18383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1839f0b747eeSBarry Smith }
1840f0b747eeSBarry Smith 
18414a2ae208SSatish Balay #undef __FUNCT__
18424a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
184397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1844cddf8d76SBarry Smith {
1845dfbe8321SBarry Smith   PetscErrorCode ierr;
184697f1f81fSBarry Smith   PetscInt       i;
1847cddf8d76SBarry Smith 
18483a40ed3dSBarry Smith   PetscFunctionBegin;
1849cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1850b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1851cddf8d76SBarry Smith   }
1852cddf8d76SBarry Smith 
1853cddf8d76SBarry Smith   for (i=0; i<n; i++) {
18546a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1855cddf8d76SBarry Smith   }
18563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1857cddf8d76SBarry Smith }
1858cddf8d76SBarry Smith 
18594a2ae208SSatish Balay #undef __FUNCT__
18604a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
186197f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
18624dcbc457SBarry Smith {
1863e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
18646849ba73SBarry Smith   PetscErrorCode ierr;
186597f1f81fSBarry Smith   PetscInt       row,i,j,k,l,m,n,*idx,*nidx,isz,val;
186697f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
1867f1af5d2fSBarry Smith   PetscBT        table;
1868bbd702dbSSatish Balay 
18693a40ed3dSBarry Smith   PetscFunctionBegin;
1870899cda47SBarry Smith   m     = A->rmap.n;
1871e4d965acSSatish Balay   ai    = a->i;
1872bfeeae90SHong Zhang   aj    = a->j;
18738a047759SSatish Balay 
1874a45adfd6SMatthew Knepley   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
187506763907SSatish Balay 
187697f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
18776831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
187806763907SSatish Balay 
1879e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1880b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1881e4d965acSSatish Balay     isz  = 0;
18826831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1883e4d965acSSatish Balay 
1884e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
18854dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1886b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1887e4d965acSSatish Balay 
1888dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1889e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1890f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
18914dcbc457SBarry Smith     }
189206763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
189306763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1894e4d965acSSatish Balay 
189504a348a9SBarry Smith     k = 0;
189604a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
189704a348a9SBarry Smith       n = isz;
189806763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1899e4d965acSSatish Balay         row   = nidx[k];
1900e4d965acSSatish Balay         start = ai[row];
1901e4d965acSSatish Balay         end   = ai[row+1];
190204a348a9SBarry Smith         for (l = start; l<end ; l++){
1903efb16452SHong Zhang           val = aj[l] ;
1904f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1905e4d965acSSatish Balay         }
1906e4d965acSSatish Balay       }
1907e4d965acSSatish Balay     }
1908029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1909e4d965acSSatish Balay   }
19106831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1911606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
19123a40ed3dSBarry Smith   PetscFunctionReturn(0);
19134dcbc457SBarry Smith }
191417ab2063SBarry Smith 
19150513a670SBarry Smith /* -------------------------------------------------------------- */
19164a2ae208SSatish Balay #undef __FUNCT__
19174a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
1918dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
19190513a670SBarry Smith {
19200513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
19216849ba73SBarry Smith   PetscErrorCode ierr;
1922899cda47SBarry Smith   PetscInt       i,nz,m = A->rmap.n,n = A->cmap.n,*col;
192397f1f81fSBarry Smith   PetscInt       *row,*cnew,j,*lens;
192456cd22aeSBarry Smith   IS             icolp,irowp;
192597f1f81fSBarry Smith   PetscInt       *cwork;
192632ec9ce4SBarry Smith   PetscScalar    *vwork;
19270513a670SBarry Smith 
19283a40ed3dSBarry Smith   PetscFunctionBegin;
19294c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
193056cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
19314c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
193256cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
19330513a670SBarry Smith 
19340513a670SBarry Smith   /* determine lengths of permuted rows */
193597f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
19360513a670SBarry Smith   for (i=0; i<m; i++) {
19370513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
19380513a670SBarry Smith   }
1939f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,B);CHKERRQ(ierr);
1940f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
1941f204ca49SKris Buschelman   ierr = MatSetType(*B,A->type_name);CHKERRQ(ierr);
1942ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
1943606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
19440513a670SBarry Smith 
194597f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
19460513a670SBarry Smith   for (i=0; i<m; i++) {
194732ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
19480513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
1949cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
195032ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
19510513a670SBarry Smith   }
1952606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
19533c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
19540513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19550513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
195656cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
195756cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
195856cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
195956cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
19603a40ed3dSBarry Smith   PetscFunctionReturn(0);
19610513a670SBarry Smith }
19620513a670SBarry Smith 
19634a2ae208SSatish Balay #undef __FUNCT__
19644a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1965dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1966cb5b572fSBarry Smith {
1967dfbe8321SBarry Smith   PetscErrorCode ierr;
1968cb5b572fSBarry Smith 
1969cb5b572fSBarry Smith   PetscFunctionBegin;
197033f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
197133f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
1972be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1973be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1974be6bf707SBarry Smith 
1975899cda47SBarry Smith     if (a->i[A->rmap.n] != b->i[B->rmap.n]) {
1976634064b4SBarry Smith       SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different");
1977cb5b572fSBarry Smith     }
1978899cda47SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap.n])*sizeof(PetscScalar));CHKERRQ(ierr);
1979cb5b572fSBarry Smith   } else {
1980cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1981cb5b572fSBarry Smith   }
1982cb5b572fSBarry Smith   PetscFunctionReturn(0);
1983cb5b572fSBarry Smith }
1984cb5b572fSBarry Smith 
19854a2ae208SSatish Balay #undef __FUNCT__
19864a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1987dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
1988273d9f13SBarry Smith {
1989dfbe8321SBarry Smith   PetscErrorCode ierr;
1990273d9f13SBarry Smith 
1991273d9f13SBarry Smith   PetscFunctionBegin;
1992ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1993273d9f13SBarry Smith   PetscFunctionReturn(0);
1994273d9f13SBarry Smith }
1995273d9f13SBarry Smith 
19964a2ae208SSatish Balay #undef __FUNCT__
19974a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
1998dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
19996c0721eeSBarry Smith {
20006c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
20016c0721eeSBarry Smith   PetscFunctionBegin;
20026c0721eeSBarry Smith   *array = a->a;
20036c0721eeSBarry Smith   PetscFunctionReturn(0);
20046c0721eeSBarry Smith }
20056c0721eeSBarry Smith 
20064a2ae208SSatish Balay #undef __FUNCT__
20074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2008dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
20096c0721eeSBarry Smith {
20106c0721eeSBarry Smith   PetscFunctionBegin;
20116c0721eeSBarry Smith   PetscFunctionReturn(0);
20126c0721eeSBarry Smith }
2013273d9f13SBarry Smith 
2014ee4f033dSBarry Smith #undef __FUNCT__
2015ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2016dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2017ee4f033dSBarry Smith {
20186849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
20196849ba73SBarry Smith   PetscErrorCode ierr;
202097f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2021efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
202287828ca2SBarry Smith   PetscScalar    *vscale_array;
2023ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2024ee4f033dSBarry Smith   Vec            w1,w2,w3;
2025ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2026ee4f033dSBarry Smith   PetscTruth     flg;
2027ee4f033dSBarry Smith 
2028ee4f033dSBarry Smith   PetscFunctionBegin;
2029ee4f033dSBarry Smith   if (!coloring->w1) {
2030ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
203152e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2032ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
203352e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2034ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
203552e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2036ee4f033dSBarry Smith   }
2037ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2038ee4f033dSBarry Smith 
2039ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2040e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
2041ee4f033dSBarry Smith   if (flg) {
2042ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2043ee4f033dSBarry Smith   } else {
20440b9b6f31SBarry Smith     PetscTruth assembled;
20450b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
20460b9b6f31SBarry Smith     if (assembled) {
2047ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2048ee4f033dSBarry Smith     }
20490b9b6f31SBarry Smith   }
2050ee4f033dSBarry Smith 
2051ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2052ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2053ee4f033dSBarry Smith 
2054ee4f033dSBarry Smith   /*
2055ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2056ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2057ee4f033dSBarry Smith   */
2058ee4f033dSBarry Smith   if (coloring->F) {
2059ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2060ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2061ee4f033dSBarry Smith     if (m1 != m2) {
2062ee4f033dSBarry Smith       coloring->F = 0;
2063ee4f033dSBarry Smith     }
2064ee4f033dSBarry Smith   }
2065ee4f033dSBarry Smith 
2066ee4f033dSBarry Smith   if (coloring->F) {
2067ee4f033dSBarry Smith     w1          = coloring->F;
2068ee4f033dSBarry Smith     coloring->F = 0;
2069ee4f033dSBarry Smith   } else {
207066f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2071ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
207266f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2073ee4f033dSBarry Smith   }
2074ee4f033dSBarry Smith 
2075ee4f033dSBarry Smith   /*
2076ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2077ee4f033dSBarry Smith   */
20781ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
20791ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2080ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2081ee4f033dSBarry Smith     /*
2082ee4f033dSBarry Smith        Loop over each column associated with color adding the
2083ee4f033dSBarry Smith        perturbation to the vector w3.
2084ee4f033dSBarry Smith     */
2085ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2086ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2087ee4f033dSBarry Smith       dx  = xx[col];
2088ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2089ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2090ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2091ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2092ee4f033dSBarry Smith #else
2093ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2094ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2095ee4f033dSBarry Smith #endif
2096ee4f033dSBarry Smith       dx                *= epsilon;
2097ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2098ee4f033dSBarry Smith     }
2099ee4f033dSBarry Smith   }
21001ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2101ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2102ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2103ee4f033dSBarry Smith 
2104ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2105ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2106ee4f033dSBarry Smith 
2107ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2108ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2109ee4f033dSBarry Smith 
21101ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2111ee4f033dSBarry Smith   /*
2112ee4f033dSBarry Smith       Loop over each color
2113ee4f033dSBarry Smith   */
2114ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
211549b058dcSBarry Smith     coloring->currentcolor = k;
2116ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
21171ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2118ee4f033dSBarry Smith     /*
2119ee4f033dSBarry Smith        Loop over each column associated with color adding the
2120ee4f033dSBarry Smith        perturbation to the vector w3.
2121ee4f033dSBarry Smith     */
2122ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2123ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2124ee4f033dSBarry Smith       dx  = xx[col];
21255b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2126ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2127ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2128ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2129ee4f033dSBarry Smith #else
2130ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2131ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2132ee4f033dSBarry Smith #endif
2133ee4f033dSBarry Smith       dx            *= epsilon;
2134634064b4SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2135ee4f033dSBarry Smith       w3_array[col] += dx;
2136ee4f033dSBarry Smith     }
21371ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2138ee4f033dSBarry Smith 
2139ee4f033dSBarry Smith     /*
2140ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2141ee4f033dSBarry Smith     */
2142ee4f033dSBarry Smith 
214366f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2144ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
214566f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2146efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2147ee4f033dSBarry Smith 
2148ee4f033dSBarry Smith     /*
2149ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2150ee4f033dSBarry Smith     */
21511ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2152ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2153ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2154ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2155ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2156ee4f033dSBarry Smith       srow   = row + start;
2157ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2158ee4f033dSBarry Smith     }
21591ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2160ee4f033dSBarry Smith   }
216149b058dcSBarry Smith   coloring->currentcolor = k;
21621ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
21631ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2164ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2165ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2166ee4f033dSBarry Smith   PetscFunctionReturn(0);
2167ee4f033dSBarry Smith }
2168ee4f033dSBarry Smith 
2169ac90fabeSBarry Smith #include "petscblaslapack.h"
2170ac90fabeSBarry Smith #undef __FUNCT__
2171ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2172f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2173ac90fabeSBarry Smith {
2174dfbe8321SBarry Smith   PetscErrorCode ierr;
217597f1f81fSBarry Smith   PetscInt       i;
2176ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
21774ce68768SBarry Smith   PetscBLASInt   one=1,bnz = (PetscBLASInt)x->nz;
2178ac90fabeSBarry Smith 
2179ac90fabeSBarry Smith   PetscFunctionBegin;
2180ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2181f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2182f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2183c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2184a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2185a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2186a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2187a30b2313SHong Zhang     }
2188a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2189899cda47SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap.n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2190a30b2313SHong Zhang       y->XtoY = X;
2191407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2192c537a176SHong Zhang     }
2193f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2194ae15b995SBarry Smith     ierr = PetscInfo3(0,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);CHKERRQ(ierr);
2195ac90fabeSBarry Smith   } else {
2196f4df32b1SMatthew Knepley     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2197ac90fabeSBarry Smith   }
2198ac90fabeSBarry Smith   PetscFunctionReturn(0);
2199ac90fabeSBarry Smith }
2200ac90fabeSBarry Smith 
2201521d7252SBarry Smith #undef __FUNCT__
2202521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2203521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2204521d7252SBarry Smith {
2205521d7252SBarry Smith   PetscFunctionBegin;
2206521d7252SBarry Smith   PetscFunctionReturn(0);
2207521d7252SBarry Smith }
2208521d7252SBarry Smith 
2209354c94deSBarry Smith #undef __FUNCT__
2210354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
2211354c94deSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConjugate_SeqAIJ(Mat mat)
2212354c94deSBarry Smith {
2213354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2214354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2215354c94deSBarry Smith   PetscInt    i,nz;
2216354c94deSBarry Smith   PetscScalar *a;
2217354c94deSBarry Smith 
2218354c94deSBarry Smith   PetscFunctionBegin;
2219354c94deSBarry Smith   nz = aij->nz;
2220354c94deSBarry Smith   a  = aij->a;
2221354c94deSBarry Smith   for (i=0; i<nz; i++) {
2222354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2223354c94deSBarry Smith   }
2224354c94deSBarry Smith #else
2225354c94deSBarry Smith   PetscFunctionBegin;
2226354c94deSBarry Smith #endif
2227354c94deSBarry Smith   PetscFunctionReturn(0);
2228354c94deSBarry Smith }
2229354c94deSBarry Smith 
2230e34fafa9SBarry Smith #undef __FUNCT__
2231985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2232985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2233e34fafa9SBarry Smith {
2234e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2235e34fafa9SBarry Smith   PetscErrorCode ierr;
2236899cda47SBarry Smith   PetscInt       i,j,m = A->rmap.n,*ai,*aj,ncols,n;
2237e34fafa9SBarry Smith   PetscReal      atmp;
2238985db425SBarry Smith   PetscScalar    *x;
2239e34fafa9SBarry Smith   MatScalar      *aa;
2240e34fafa9SBarry Smith 
2241e34fafa9SBarry Smith   PetscFunctionBegin;
2242e34fafa9SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2243e34fafa9SBarry Smith   aa   = a->a;
2244e34fafa9SBarry Smith   ai   = a->i;
2245e34fafa9SBarry Smith   aj   = a->j;
2246e34fafa9SBarry Smith 
2247985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2248e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2249e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2250899cda47SBarry Smith   if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2251e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2252e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2253985db425SBarry Smith     x[i] = 0.0; if (idx) idx[i] = 0;
2254e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2255985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2256985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2257985db425SBarry Smith       aa++; aj++;
2258985db425SBarry Smith     }
2259985db425SBarry Smith   }
2260985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2261985db425SBarry Smith   PetscFunctionReturn(0);
2262985db425SBarry Smith }
2263985db425SBarry Smith 
2264985db425SBarry Smith #undef __FUNCT__
2265985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2266985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2267985db425SBarry Smith {
2268985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2269985db425SBarry Smith   PetscErrorCode ierr;
2270985db425SBarry Smith   PetscInt       i,j,m = A->rmap.n,*ai,*aj,ncols,n;
2271985db425SBarry Smith   PetscScalar    *x;
2272985db425SBarry Smith   MatScalar      *aa;
2273985db425SBarry Smith 
2274985db425SBarry Smith   PetscFunctionBegin;
2275985db425SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2276985db425SBarry Smith   aa   = a->a;
2277985db425SBarry Smith   ai   = a->i;
2278985db425SBarry Smith   aj   = a->j;
2279985db425SBarry Smith 
2280985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2281985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2282985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2283985db425SBarry Smith   if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2284985db425SBarry Smith   for (i=0; i<m; i++) {
2285985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2286985db425SBarry Smith     if (ncols == A->cmap.n) { /* row is dense */
2287985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2288985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2289985db425SBarry Smith       x[i] = 0.0;
2290985db425SBarry Smith       if (idx) {
2291985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2292985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2293985db425SBarry Smith           if (aj[j] > j) {
2294985db425SBarry Smith             idx[i] = j;
2295985db425SBarry Smith             break;
2296985db425SBarry Smith           }
2297985db425SBarry Smith         }
2298985db425SBarry Smith       }
2299985db425SBarry Smith     }
2300985db425SBarry Smith     for (j=0; j<ncols; j++){
2301985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2302985db425SBarry Smith       aa++; aj++;
2303985db425SBarry Smith     }
2304985db425SBarry Smith   }
2305985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2306985db425SBarry Smith   PetscFunctionReturn(0);
2307985db425SBarry Smith }
2308985db425SBarry Smith 
2309985db425SBarry Smith #undef __FUNCT__
2310985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2311985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2312985db425SBarry Smith {
2313985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2314985db425SBarry Smith   PetscErrorCode ierr;
2315985db425SBarry Smith   PetscInt       i,j,m = A->rmap.n,*ai,*aj,ncols,n;
2316985db425SBarry Smith   PetscScalar    *x;
2317985db425SBarry Smith   MatScalar      *aa;
2318985db425SBarry Smith 
2319985db425SBarry Smith   PetscFunctionBegin;
2320985db425SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2321985db425SBarry Smith   aa   = a->a;
2322985db425SBarry Smith   ai   = a->i;
2323985db425SBarry Smith   aj   = a->j;
2324985db425SBarry Smith 
2325985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2326985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2327985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2328985db425SBarry Smith   if (n != A->rmap.n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2329985db425SBarry Smith   for (i=0; i<m; i++) {
2330985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2331985db425SBarry Smith     if (ncols == A->cmap.n) { /* row is dense */
2332985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2333985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2334985db425SBarry Smith       x[i] = 0.0;
2335985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2336985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2337985db425SBarry Smith         for (j=0;j<ncols;j++) {
2338985db425SBarry Smith           if (aj[j] > j) {
2339985db425SBarry Smith             idx[i] = j;
2340985db425SBarry Smith             break;
2341985db425SBarry Smith           }
2342985db425SBarry Smith         }
2343985db425SBarry Smith       }
2344985db425SBarry Smith     }
2345985db425SBarry Smith     for (j=0; j<ncols; j++){
2346985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2347985db425SBarry Smith       aa++; aj++;
2348e34fafa9SBarry Smith     }
2349e34fafa9SBarry Smith   }
2350e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2351e34fafa9SBarry Smith   PetscFunctionReturn(0);
2352e34fafa9SBarry Smith }
2353e34fafa9SBarry Smith 
2354682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
23550a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2356cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2357cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2358cb5b572fSBarry Smith        MatMult_SeqAIJ,
235997304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
23607c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
23617c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2362cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2363cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
23647c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
236597304618SKris Buschelman /*10*/ MatSolveTransposeAdd_SeqAIJ,
2366cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2367cb5b572fSBarry Smith        0,
236817ab2063SBarry Smith        MatRelax_SeqAIJ,
236917ab2063SBarry Smith        MatTranspose_SeqAIJ,
237097304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2371cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2372cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2373cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2374cb5b572fSBarry Smith        MatNorm_SeqAIJ,
237597304618SKris Buschelman /*20*/ 0,
2376cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
237717ab2063SBarry Smith        MatCompress_SeqAIJ,
2378cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2379cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
238097304618SKris Buschelman /*25*/ MatZeroRows_SeqAIJ,
2381cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2382cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2383f76d2b81SHong Zhang        MatCholeskyFactorSymbolic_SeqAIJ,
2384a6175056SHong Zhang        MatCholeskyFactorNumeric_SeqAIJ,
238597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqAIJ,
2386cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2387861ba921SHong Zhang        MatICCFactorSymbolic_SeqAIJ,
23886c0721eeSBarry Smith        MatGetArray_SeqAIJ,
23896c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
239097304618SKris Buschelman /*35*/ MatDuplicate_SeqAIJ,
2391cb5b572fSBarry Smith        0,
2392cb5b572fSBarry Smith        0,
2393cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2394cb5b572fSBarry Smith        0,
239597304618SKris Buschelman /*40*/ MatAXPY_SeqAIJ,
2396cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2397cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2398cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2399cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2400985db425SBarry Smith /*45*/ MatGetRowMax_SeqAIJ,
2401cb5b572fSBarry Smith        MatScale_SeqAIJ,
2402cb5b572fSBarry Smith        0,
240379299369SBarry Smith        MatDiagonalSet_SeqAIJ,
24046945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
2405521d7252SBarry Smith /*50*/ MatSetBlockSize_SeqAIJ,
24063b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
24073b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
24083b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2409a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
241097304618SKris Buschelman /*55*/ MatFDColoringCreate_SeqAIJ,
2411b9617806SBarry Smith        0,
24120513a670SBarry Smith        0,
2413cda55fadSBarry Smith        MatPermute_SeqAIJ,
2414cda55fadSBarry Smith        0,
241597304618SKris Buschelman /*60*/ 0,
2416b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2417b9b97703SBarry Smith        MatView_SeqAIJ,
2418357abbc8SBarry Smith        0,
2419ee4f033dSBarry Smith        0,
242097304618SKris Buschelman /*65*/ 0,
2421ee4f033dSBarry Smith        0,
2422ee4f033dSBarry Smith        0,
2423ee4f033dSBarry Smith        0,
2424ee4f033dSBarry Smith        0,
2425985db425SBarry Smith /*70*/ MatGetRowMaxAbs_SeqAIJ,
2426ee4f033dSBarry Smith        0,
2427ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2428dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2429ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2430dcf5cc72SBarry Smith #else
2431dcf5cc72SBarry Smith        0,
2432dcf5cc72SBarry Smith #endif
2433ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
2434b8f8c88eSHong Zhang /*75*/ 0,
243597304618SKris Buschelman        0,
243697304618SKris Buschelman        0,
243797304618SKris Buschelman        0,
243897304618SKris Buschelman        0,
243997304618SKris Buschelman /*80*/ 0,
244097304618SKris Buschelman        0,
244197304618SKris Buschelman        0,
244297304618SKris Buschelman        0,
2443bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2444bc011b1eSHong Zhang /*85*/ MatIsSymmetric_SeqAIJ,
24451cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
24466284ec50SHong Zhang        0,
24476284ec50SHong Zhang        0,
2448bc011b1eSHong Zhang        0,
2449bc011b1eSHong Zhang /*90*/ MatMatMult_SeqAIJ_SeqAIJ,
245026be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
245126be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2452d439da42SKris Buschelman        MatPtAP_Basic,
24537ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
24547ba1a0bfSKris Buschelman /*95*/ MatPtAPNumeric_SeqAIJ,
2455bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2456bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2457bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
24587ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
24597ba1a0bfSKris Buschelman /*100*/MatPtAPNumeric_SeqAIJ_SeqAIJ,
2460609c6c4dSKris Buschelman        0,
2461609c6c4dSKris Buschelman        0,
246287d4246cSBarry Smith        MatConjugate_SeqAIJ,
246387d4246cSBarry Smith        0,
246499cafbc1SBarry Smith /*105*/MatSetValuesRow_SeqAIJ,
246599cafbc1SBarry Smith        MatRealPart_SeqAIJ,
2466f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
2467f5edf698SHong Zhang        0,
24682bebee5dSHong Zhang        0,
2469985db425SBarry Smith /*110*/MatMatSolve_SeqAIJ,
2470985db425SBarry Smith        0,
2471985db425SBarry Smith        MatGetRowMin_SeqAIJ
24729e29f15eSvictorle };
247317ab2063SBarry Smith 
2474fb2e594dSBarry Smith EXTERN_C_BEGIN
24754a2ae208SSatish Balay #undef __FUNCT__
24764a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
2477be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2478bef8e0ddSBarry Smith {
2479bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
248097f1f81fSBarry Smith   PetscInt   i,nz,n;
2481bef8e0ddSBarry Smith 
2482bef8e0ddSBarry Smith   PetscFunctionBegin;
2483bef8e0ddSBarry Smith 
2484bef8e0ddSBarry Smith   nz = aij->maxnz;
248511c9b30cSMatthew Knepley   n  = mat->rmap.n;
2486bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2487bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2488bef8e0ddSBarry Smith   }
2489bef8e0ddSBarry Smith   aij->nz = nz;
2490bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2491bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2492bef8e0ddSBarry Smith   }
2493bef8e0ddSBarry Smith 
2494bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2495bef8e0ddSBarry Smith }
2496fb2e594dSBarry Smith EXTERN_C_END
2497bef8e0ddSBarry Smith 
24984a2ae208SSatish Balay #undef __FUNCT__
24994a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2500bef8e0ddSBarry Smith /*@
2501bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2502bef8e0ddSBarry Smith        in the matrix.
2503bef8e0ddSBarry Smith 
2504bef8e0ddSBarry Smith   Input Parameters:
2505bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2506bef8e0ddSBarry Smith -  indices - the column indices
2507bef8e0ddSBarry Smith 
250815091d37SBarry Smith   Level: advanced
250915091d37SBarry Smith 
2510bef8e0ddSBarry Smith   Notes:
2511bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2512bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2513bef8e0ddSBarry Smith   of the MatSetValues() operation.
2514bef8e0ddSBarry Smith 
2515bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2516d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2517bef8e0ddSBarry Smith 
2518bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2519bef8e0ddSBarry Smith 
2520b9617806SBarry Smith     The indices should start with zero, not one.
2521b9617806SBarry Smith 
2522bef8e0ddSBarry Smith @*/
2523be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2524bef8e0ddSBarry Smith {
252597f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt *);
2526bef8e0ddSBarry Smith 
2527bef8e0ddSBarry Smith   PetscFunctionBegin;
25284482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
25294482741eSBarry Smith   PetscValidPointer(indices,2);
2530c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2531bef8e0ddSBarry Smith   if (f) {
2532bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2533bef8e0ddSBarry Smith   } else {
2534634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices");
2535bef8e0ddSBarry Smith   }
2536bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2537bef8e0ddSBarry Smith }
2538bef8e0ddSBarry Smith 
2539be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2540be6bf707SBarry Smith 
2541fb2e594dSBarry Smith EXTERN_C_BEGIN
25424a2ae208SSatish Balay #undef __FUNCT__
25434a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2544be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqAIJ(Mat mat)
2545be6bf707SBarry Smith {
2546be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
25476849ba73SBarry Smith   PetscErrorCode ierr;
2548899cda47SBarry Smith   size_t         nz = aij->i[mat->rmap.n];
2549be6bf707SBarry Smith 
2550be6bf707SBarry Smith   PetscFunctionBegin;
2551be6bf707SBarry Smith   if (aij->nonew != 1) {
2552*4e0d8c25SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);first");
2553be6bf707SBarry Smith   }
2554be6bf707SBarry Smith 
2555be6bf707SBarry Smith   /* allocate space for values if not already there */
2556be6bf707SBarry Smith   if (!aij->saved_values) {
255787828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
25589518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
2559be6bf707SBarry Smith   }
2560be6bf707SBarry Smith 
2561be6bf707SBarry Smith   /* copy values over */
256287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2563be6bf707SBarry Smith   PetscFunctionReturn(0);
2564be6bf707SBarry Smith }
2565fb2e594dSBarry Smith EXTERN_C_END
2566be6bf707SBarry Smith 
25674a2ae208SSatish Balay #undef __FUNCT__
2568b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2569be6bf707SBarry Smith /*@
2570be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2571be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2572be6bf707SBarry Smith        nonlinear portion.
2573be6bf707SBarry Smith 
2574be6bf707SBarry Smith    Collect on Mat
2575be6bf707SBarry Smith 
2576be6bf707SBarry Smith   Input Parameters:
25770e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2578be6bf707SBarry Smith 
257915091d37SBarry Smith   Level: advanced
258015091d37SBarry Smith 
2581be6bf707SBarry Smith   Common Usage, with SNESSolve():
2582be6bf707SBarry Smith $    Create Jacobian matrix
2583be6bf707SBarry Smith $    Set linear terms into matrix
2584be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2585be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2586be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2587*4e0d8c25SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);
2588be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2589be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2590be6bf707SBarry Smith $    In your Jacobian routine
2591be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2592be6bf707SBarry Smith $      Set nonlinear terms in matrix
2593be6bf707SBarry Smith 
2594be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2595be6bf707SBarry Smith $    // build linear portion of Jacobian
2596*4e0d8c25SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);
2597be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2598be6bf707SBarry Smith $    loop over nonlinear iterations
2599be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2600be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2601be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2602be6bf707SBarry Smith $       Solve linear system with Jacobian
2603be6bf707SBarry Smith $    endloop
2604be6bf707SBarry Smith 
2605be6bf707SBarry Smith   Notes:
2606be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2607*4e0d8c25SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE); before
2608be6bf707SBarry Smith     calling this routine.
2609be6bf707SBarry Smith 
26100c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
26110c468ba9SBarry Smith     and does not allocated additional space.
26120c468ba9SBarry Smith 
2613be6bf707SBarry Smith .seealso: MatRetrieveValues()
2614be6bf707SBarry Smith 
2615be6bf707SBarry Smith @*/
2616be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues(Mat mat)
2617be6bf707SBarry Smith {
2618dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2619be6bf707SBarry Smith 
2620be6bf707SBarry Smith   PetscFunctionBegin;
26214482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
262229bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
262329bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2624be6bf707SBarry Smith 
2625c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2626be6bf707SBarry Smith   if (f) {
2627be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2628be6bf707SBarry Smith   } else {
2629634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to store values");
2630be6bf707SBarry Smith   }
2631be6bf707SBarry Smith   PetscFunctionReturn(0);
2632be6bf707SBarry Smith }
2633be6bf707SBarry Smith 
2634fb2e594dSBarry Smith EXTERN_C_BEGIN
26354a2ae208SSatish Balay #undef __FUNCT__
26364a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2637be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqAIJ(Mat mat)
2638be6bf707SBarry Smith {
2639be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
26406849ba73SBarry Smith   PetscErrorCode ierr;
2641899cda47SBarry Smith   PetscInt       nz = aij->i[mat->rmap.n];
2642be6bf707SBarry Smith 
2643be6bf707SBarry Smith   PetscFunctionBegin;
2644be6bf707SBarry Smith   if (aij->nonew != 1) {
2645*4e0d8c25SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS,PETSC_TRUE);first");
2646be6bf707SBarry Smith   }
2647be6bf707SBarry Smith   if (!aij->saved_values) {
2648634064b4SBarry Smith     SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2649be6bf707SBarry Smith   }
2650be6bf707SBarry Smith   /* copy values over */
265187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2652be6bf707SBarry Smith   PetscFunctionReturn(0);
2653be6bf707SBarry Smith }
2654fb2e594dSBarry Smith EXTERN_C_END
2655be6bf707SBarry Smith 
26564a2ae208SSatish Balay #undef __FUNCT__
26574a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2658be6bf707SBarry Smith /*@
2659be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2660be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2661be6bf707SBarry Smith        nonlinear portion.
2662be6bf707SBarry Smith 
2663be6bf707SBarry Smith    Collect on Mat
2664be6bf707SBarry Smith 
2665be6bf707SBarry Smith   Input Parameters:
2666be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2667be6bf707SBarry Smith 
266815091d37SBarry Smith   Level: advanced
266915091d37SBarry Smith 
2670be6bf707SBarry Smith .seealso: MatStoreValues()
2671be6bf707SBarry Smith 
2672be6bf707SBarry Smith @*/
2673be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues(Mat mat)
2674be6bf707SBarry Smith {
2675dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(Mat);
2676be6bf707SBarry Smith 
2677be6bf707SBarry Smith   PetscFunctionBegin;
26784482741eSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
267929bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
268029bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2681be6bf707SBarry Smith 
2682c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2683be6bf707SBarry Smith   if (f) {
2684be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2685be6bf707SBarry Smith   } else {
2686634064b4SBarry Smith     SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to retrieve values");
2687be6bf707SBarry Smith   }
2688be6bf707SBarry Smith   PetscFunctionReturn(0);
2689be6bf707SBarry Smith }
2690be6bf707SBarry Smith 
2691f83d6046SBarry Smith 
2692be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
26934a2ae208SSatish Balay #undef __FUNCT__
26944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
269517ab2063SBarry Smith /*@C
2696682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
26970d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
26986e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
269951c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
27002bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
270117ab2063SBarry Smith 
2702db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2703db81eaa0SLois Curfman McInnes 
270417ab2063SBarry Smith    Input Parameters:
2705db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
270617ab2063SBarry Smith .  m - number of rows
270717ab2063SBarry Smith .  n - number of columns
270817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
270951c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
27102bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
271117ab2063SBarry Smith 
271217ab2063SBarry Smith    Output Parameter:
2713416022c9SBarry Smith .  A - the matrix
271417ab2063SBarry Smith 
2715b259b22eSLois Curfman McInnes    Notes:
271649a6f317SBarry Smith    If nnz is given then nz is ignored
271749a6f317SBarry Smith 
271817ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
271917ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
27200002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
272144cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
272217ab2063SBarry Smith 
272317ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2724a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
27253d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
27266da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
272717ab2063SBarry Smith 
2728682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
27294fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2730682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
27316c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
27326c7ebb05SLois Curfman McInnes 
27336c7ebb05SLois Curfman McInnes    Options Database Keys:
2734698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2735698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2736db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2737db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2738db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
273917ab2063SBarry Smith 
2740027ccd11SLois Curfman McInnes    Level: intermediate
2741027ccd11SLois Curfman McInnes 
274236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
274336db0b34SBarry Smith 
274417ab2063SBarry Smith @*/
2745be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
274617ab2063SBarry Smith {
2747dfbe8321SBarry Smith   PetscErrorCode ierr;
27486945ee14SBarry Smith 
27493a40ed3dSBarry Smith   PetscFunctionBegin;
2750f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2751f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2752273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2753ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,(PetscInt*)nnz);CHKERRQ(ierr);
2754273d9f13SBarry Smith   PetscFunctionReturn(0);
2755273d9f13SBarry Smith }
2756273d9f13SBarry Smith 
27574a2ae208SSatish Balay #undef __FUNCT__
27584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2759273d9f13SBarry Smith /*@C
2760273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2761273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2762273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2763273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2764273d9f13SBarry Smith 
2765273d9f13SBarry Smith    Collective on MPI_Comm
2766273d9f13SBarry Smith 
2767273d9f13SBarry Smith    Input Parameters:
276845bfc511SMatthew Knepley +  B - The matrix
2769273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2770273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2771273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2772273d9f13SBarry Smith 
2773273d9f13SBarry Smith    Notes:
277449a6f317SBarry Smith      If nnz is given then nz is ignored
277549a6f317SBarry Smith 
2776273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
2777273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2778273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2779273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2780273d9f13SBarry Smith 
2781273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2782273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2783273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2784273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2785273d9f13SBarry Smith 
2786a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
2787a96a251dSBarry Smith    entries or columns indices
2788a96a251dSBarry Smith 
2789273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2790273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2791273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2792273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2793273d9f13SBarry Smith 
2794273d9f13SBarry Smith    Options Database Keys:
2795698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
2796698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
2797273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2798273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2799273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2800273d9f13SBarry Smith 
2801273d9f13SBarry Smith    Level: intermediate
2802273d9f13SBarry Smith 
2803273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2804273d9f13SBarry Smith 
2805273d9f13SBarry Smith @*/
2806be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
2807273d9f13SBarry Smith {
280897f1f81fSBarry Smith   PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[]);
2809a23d5eceSKris Buschelman 
2810a23d5eceSKris Buschelman   PetscFunctionBegin;
2811a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2812a23d5eceSKris Buschelman   if (f) {
2813a23d5eceSKris Buschelman     ierr = (*f)(B,nz,nnz);CHKERRQ(ierr);
2814a23d5eceSKris Buschelman   }
2815a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2816a23d5eceSKris Buschelman }
2817a23d5eceSKris Buschelman 
2818a23d5eceSKris Buschelman EXTERN_C_BEGIN
2819a23d5eceSKris Buschelman #undef __FUNCT__
2820a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
2821be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,PetscInt *nnz)
2822a23d5eceSKris Buschelman {
2823273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2824a43ee2ecSKris Buschelman   PetscTruth     skipallocation = PETSC_FALSE;
28256849ba73SBarry Smith   PetscErrorCode ierr;
282697f1f81fSBarry Smith   PetscInt       i;
2827273d9f13SBarry Smith 
2828273d9f13SBarry Smith   PetscFunctionBegin;
2829d5d45c9bSBarry Smith 
2830a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
2831c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2832c461c341SBarry Smith     nz             = 0;
2833c461c341SBarry Smith   }
2834c461c341SBarry Smith 
2835899cda47SBarry Smith   B->rmap.bs = B->cmap.bs = 1;
28366148ca0dSBarry Smith   ierr = PetscMapSetUp(&B->rmap);CHKERRQ(ierr);
28376148ca0dSBarry Smith   ierr = PetscMapSetUp(&B->cmap);CHKERRQ(ierr);
2838899cda47SBarry Smith 
2839435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2840435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2841b73539f3SBarry Smith   if (nnz) {
2842899cda47SBarry Smith     for (i=0; i<B->rmap.n; i++) {
284329bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
2844899cda47SBarry Smith       if (nnz[i] > B->cmap.n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap.n);
2845b73539f3SBarry Smith     }
2846b73539f3SBarry Smith   }
2847b73539f3SBarry Smith 
2848273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2849273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2850273d9f13SBarry Smith 
2851ab93d7beSBarry Smith   if (!skipallocation) {
2852899cda47SBarry Smith     ierr = PetscMalloc2(B->rmap.n,PetscInt,&b->imax,B->rmap.n,PetscInt,&b->ilen);CHKERRQ(ierr);
28539518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(B,2*B->rmap.n*sizeof(PetscInt));CHKERRQ(ierr);
2854273d9f13SBarry Smith     if (!nnz) {
2855435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2856273d9f13SBarry Smith       else if (nz <= 0)        nz = 1;
2857899cda47SBarry Smith       for (i=0; i<B->rmap.n; i++) b->imax[i] = nz;
2858899cda47SBarry Smith       nz = nz*B->rmap.n;
2859273d9f13SBarry Smith     } else {
2860273d9f13SBarry Smith       nz = 0;
2861899cda47SBarry Smith       for (i=0; i<B->rmap.n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2862273d9f13SBarry Smith     }
2863273d9f13SBarry Smith 
2864ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
2865899cda47SBarry Smith     for (i=0; i<B->rmap.n; i++) { b->ilen[i] = 0;}
2866ab93d7beSBarry Smith 
2867273d9f13SBarry Smith     /* allocate the matrix space */
2868899cda47SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap.n+1,PetscInt,&b->i);CHKERRQ(ierr);
28699518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(B,(B->rmap.n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
2870bfeeae90SHong Zhang     b->i[0] = 0;
2871899cda47SBarry Smith     for (i=1; i<B->rmap.n+1; i++) {
28725da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
28735da197adSKris Buschelman     }
2874273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2875e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
2876e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
2877c461c341SBarry Smith   } else {
2878e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
2879e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
2880c461c341SBarry Smith   }
2881273d9f13SBarry Smith 
2882273d9f13SBarry Smith   b->nz                = 0;
2883273d9f13SBarry Smith   b->maxnz             = nz;
2884273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2885273d9f13SBarry Smith   PetscFunctionReturn(0);
2886273d9f13SBarry Smith }
2887a23d5eceSKris Buschelman EXTERN_C_END
2888273d9f13SBarry Smith 
2889a1661176SMatthew Knepley #undef  __FUNCT__
2890a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
2891a1661176SMatthew Knepley /*@C
2892a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
2893a1661176SMatthew Knepley 
2894a1661176SMatthew Knepley    Input Parameters:
2895a1661176SMatthew Knepley +  B - the matrix
2896a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
2897a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
2898a1661176SMatthew Knepley -  v - optional values in the matrix
2899a1661176SMatthew Knepley 
2900d58b2322SMatthew Knepley    Contributed by: Lisandro Dalchin
2901d58b2322SMatthew Knepley 
2902a1661176SMatthew Knepley    Level: developer
2903a1661176SMatthew Knepley 
2904a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
2905a1661176SMatthew Knepley 
2906a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
2907a1661176SMatthew Knepley @*/
2908a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
2909a1661176SMatthew Knepley {
2910a1661176SMatthew Knepley   PetscErrorCode (*f)(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]);
2911a1661176SMatthew Knepley   PetscErrorCode ierr;
2912a1661176SMatthew Knepley 
2913a1661176SMatthew Knepley   PetscFunctionBegin;
2914a1661176SMatthew Knepley   PetscValidHeaderSpecific(B,MAT_COOKIE,1);
2915a1661176SMatthew Knepley   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr);
2916a1661176SMatthew Knepley   if (f) {
2917a1661176SMatthew Knepley     ierr = (*f)(B,i,j,v);CHKERRQ(ierr);
2918a1661176SMatthew Knepley   }
2919a1661176SMatthew Knepley   PetscFunctionReturn(0);
2920a1661176SMatthew Knepley }
2921a1661176SMatthew Knepley 
2922a1661176SMatthew Knepley EXTERN_C_BEGIN
2923a1661176SMatthew Knepley #undef  __FUNCT__
2924a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
2925b7940d39SSatish Balay PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
2926a1661176SMatthew Knepley {
2927a1661176SMatthew Knepley   PetscInt       i;
2928a1661176SMatthew Knepley   PetscInt       m,n;
2929a1661176SMatthew Knepley   PetscInt       nz;
2930a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
2931a1661176SMatthew Knepley   PetscScalar    *values;
2932a1661176SMatthew Knepley   PetscErrorCode ierr;
2933a1661176SMatthew Knepley 
2934a1661176SMatthew Knepley   PetscFunctionBegin;
2935a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
2936a1661176SMatthew Knepley 
2937b7940d39SSatish Balay   if (Ii[0]) {
2938b7940d39SSatish Balay     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
2939a1661176SMatthew Knepley   }
2940a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
2941a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2942b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
2943a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
2944a1661176SMatthew Knepley     if (nz < 0) {
2945a1661176SMatthew Knepley       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
2946a1661176SMatthew Knepley     }
2947a1661176SMatthew Knepley     nnz[i] = nz;
2948a1661176SMatthew Knepley   }
2949a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
2950a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
2951a1661176SMatthew Knepley 
2952a1661176SMatthew Knepley   if (v) {
2953a1661176SMatthew Knepley     values = (PetscScalar*) v;
2954a1661176SMatthew Knepley   } else {
2955a1661176SMatthew Knepley     ierr = PetscMalloc((nz_max+1)*sizeof(PetscScalar), &values);CHKERRQ(ierr);
2956a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
2957a1661176SMatthew Knepley   }
2958a1661176SMatthew Knepley 
2959*4e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_COLUMNS_SORTED,PETSC_TRUE);CHKERRQ(ierr);
2960a1661176SMatthew Knepley 
2961a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
2962b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
2963b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
2964a1661176SMatthew Knepley   }
2965a1661176SMatthew Knepley 
2966a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2967a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2968*4e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_COLUMNS_SORTED,PETSC_FALSE);CHKERRQ(ierr);
2969a1661176SMatthew Knepley 
2970a1661176SMatthew Knepley   if (!v) {
2971a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
2972a1661176SMatthew Knepley   }
2973a1661176SMatthew Knepley   PetscFunctionReturn(0);
2974a1661176SMatthew Knepley }
2975a1661176SMatthew Knepley EXTERN_C_END
2976a1661176SMatthew Knepley 
29770bad9183SKris Buschelman /*MC
2978fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
29790bad9183SKris Buschelman    based on compressed sparse row format.
29800bad9183SKris Buschelman 
29810bad9183SKris Buschelman    Options Database Keys:
29820bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
29830bad9183SKris Buschelman 
29840bad9183SKris Buschelman   Level: beginner
29850bad9183SKris Buschelman 
2986f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
29870bad9183SKris Buschelman M*/
29880bad9183SKris Buschelman 
2989a6175056SHong Zhang EXTERN_C_BEGIN
299017667f90SBarry Smith extern PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_SeqCRL(Mat,MatType,MatReuse,Mat*);
299117667f90SBarry Smith EXTERN_C_END
299217667f90SBarry Smith 
299317667f90SBarry Smith EXTERN_C_BEGIN
29944a2ae208SSatish Balay #undef __FUNCT__
29954a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2996be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqAIJ(Mat B)
2997273d9f13SBarry Smith {
2998273d9f13SBarry Smith   Mat_SeqAIJ     *b;
2999dfbe8321SBarry Smith   PetscErrorCode ierr;
300038baddfdSBarry Smith   PetscMPIInt    size;
3001273d9f13SBarry Smith 
3002273d9f13SBarry Smith   PetscFunctionBegin;
3003273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
3004273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3005273d9f13SBarry Smith 
300638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3007b0a32e0cSBarry Smith   B->data             = (void*)b;
3008549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3009416022c9SBarry Smith   B->factor           = 0;
301090f02eecSBarry Smith   B->mapping          = 0;
3011416022c9SBarry Smith   b->row              = 0;
3012416022c9SBarry Smith   b->col              = 0;
301382bf6240SBarry Smith   b->icol             = 0;
3014b810aeb4SBarry Smith   b->reallocs         = 0;
3015f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
301636db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3017f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3018416022c9SBarry Smith   b->nonew             = 0;
3019416022c9SBarry Smith   b->diag              = 0;
3020416022c9SBarry Smith   b->solve_work        = 0;
30212a1b7f2aSHong Zhang   B->spptr             = 0;
3022be6bf707SBarry Smith   b->saved_values      = 0;
3023d7f994e1SBarry Smith   b->idiag             = 0;
3024d7f994e1SBarry Smith   b->ssor              = 0;
3025f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
3026a30b2313SHong Zhang   b->xtoy              = 0;
3027a30b2313SHong Zhang   b->XtoY              = 0;
302873e7a558SHong Zhang   b->compressedrow.use     = PETSC_FALSE;
3029899cda47SBarry Smith   b->compressedrow.nrows   = B->rmap.n;
3030d487561eSHong Zhang   b->compressedrow.i       = PETSC_NULL;
3031d487561eSHong Zhang   b->compressedrow.rindex  = PETSC_NULL;
3032d487561eSHong Zhang   b->compressedrow.checked = PETSC_FALSE;
303388e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
303417ab2063SBarry Smith 
303535d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3036f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
3037bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
3038bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3039f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
3040be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
3041bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3042f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
3043be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
3044bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3045a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",
3046a6175056SHong Zhang                                      "MatConvert_SeqAIJ_SeqSBAIJ",
3047a6175056SHong Zhang                                       MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
304885fc7724SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C",
304985fc7724SBarry Smith                                      "MatConvert_SeqAIJ_SeqBAIJ",
305085fc7724SBarry Smith                                       MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3051ba03775dSHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqcsrperm_C",
3052ba03775dSHong Zhang                                      "MatConvert_SeqAIJ_SeqCSRPERM",
3053ba03775dSHong Zhang                                       MatConvert_SeqAIJ_SeqCSRPERM);CHKERRQ(ierr);
305417667f90SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqcrl_C",
305517667f90SBarry Smith                                      "MatConvert_SeqAIJ_SeqCRL",
305617667f90SBarry Smith                                       MatConvert_SeqAIJ_SeqCRL);CHKERRQ(ierr);
30575fbd3699SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C",
30585fbd3699SBarry Smith                                      "MatIsTranspose_SeqAIJ",
30595fbd3699SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
30601cbb95d3SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C",
30611cbb95d3SBarry Smith                                      "MatIsHermitianTranspose_SeqAIJ",
30621cbb95d3SBarry Smith                                       MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3063a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C",
3064a23d5eceSKris Buschelman                                      "MatSeqAIJSetPreallocation_SeqAIJ",
3065a23d5eceSKris Buschelman                                       MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3066a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",
3067a1661176SMatthew Knepley 				     "MatSeqAIJSetPreallocationCSR_SeqAIJ",
3068a1661176SMatthew Knepley 				      MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
306905b94e36SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C",
307005b94e36SKris Buschelman                                      "MatReorderForNonzeroDiagonal_SeqAIJ",
307105b94e36SKris Buschelman                                       MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
30724846f1f5SKris Buschelman   ierr = MatCreate_Inode(B);CHKERRQ(ierr);
307317667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
30743a40ed3dSBarry Smith   PetscFunctionReturn(0);
307517ab2063SBarry Smith }
3076273d9f13SBarry Smith EXTERN_C_END
307717ab2063SBarry Smith 
30784a2ae208SSatish Balay #undef __FUNCT__
30794a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
3080dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
308117ab2063SBarry Smith {
3082416022c9SBarry Smith   Mat            C;
3083416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
30846849ba73SBarry Smith   PetscErrorCode ierr;
3085899cda47SBarry Smith   PetscInt       i,m = A->rmap.n;
308617ab2063SBarry Smith 
30873a40ed3dSBarry Smith   PetscFunctionBegin;
30884043dd9cSLois Curfman McInnes   *B = 0;
3089f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&C);CHKERRQ(ierr);
3090899cda47SBarry Smith   ierr = MatSetSizes(C,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
3091be5d1d56SKris Buschelman   ierr = MatSetType(C,A->type_name);CHKERRQ(ierr);
30921d5dac46SHong Zhang   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
30931d5dac46SHong Zhang 
3094899cda47SBarry Smith   ierr = PetscMapCopy(A->comm,&A->rmap,&C->rmap);CHKERRQ(ierr);
3095899cda47SBarry Smith   ierr = PetscMapCopy(A->comm,&A->cmap,&C->cmap);CHKERRQ(ierr);
3096899cda47SBarry Smith 
3097273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3098273d9f13SBarry Smith 
3099416022c9SBarry Smith   C->factor           = A->factor;
31006ad4291fSHong Zhang 
3101416022c9SBarry Smith   c->row            = 0;
3102416022c9SBarry Smith   c->col            = 0;
310382bf6240SBarry Smith   c->icol           = 0;
31046ad4291fSHong Zhang   c->reallocs       = 0;
310517ab2063SBarry Smith 
31066ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
310717ab2063SBarry Smith 
310833b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
31099518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
311017ab2063SBarry Smith   for (i=0; i<m; i++) {
3111416022c9SBarry Smith     c->imax[i] = a->imax[i];
3112416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
311317ab2063SBarry Smith   }
311417ab2063SBarry Smith 
311517ab2063SBarry Smith   /* allocate the matrix space */
3116a96a251dSBarry Smith   ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
31179518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3118f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
311997f1f81fSBarry Smith   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
312017ab2063SBarry Smith   if (m > 0) {
312197f1f81fSBarry Smith     ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3122be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
3123bfeeae90SHong Zhang       ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3124be6bf707SBarry Smith     } else {
3125bfeeae90SHong Zhang       ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
312617ab2063SBarry Smith     }
312708480c60SBarry Smith   }
312817ab2063SBarry Smith 
3129416022c9SBarry Smith   c->sorted            = a->sorted;
31306ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3131416022c9SBarry Smith   c->roworiented       = a->roworiented;
3132416022c9SBarry Smith   c->nonew             = a->nonew;
3133416022c9SBarry Smith   if (a->diag) {
313497f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
313552e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
313617ab2063SBarry Smith     for (i=0; i<m; i++) {
3137416022c9SBarry Smith       c->diag[i] = a->diag[i];
313817ab2063SBarry Smith     }
31393a40ed3dSBarry Smith   } else c->diag        = 0;
31406ad4291fSHong Zhang   c->solve_work         = 0;
31416ad4291fSHong Zhang   c->saved_values          = 0;
31426ad4291fSHong Zhang   c->idiag                 = 0;
31436ad4291fSHong Zhang   c->ssor                  = 0;
31446ad4291fSHong Zhang   c->keepzeroedrows        = a->keepzeroedrows;
3145e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3146e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
31476ad4291fSHong Zhang   c->xtoy                  = 0;
31486ad4291fSHong Zhang   c->XtoY                  = 0;
31496ad4291fSHong Zhang 
3150416022c9SBarry Smith   c->nz                 = a->nz;
3151416022c9SBarry Smith   c->maxnz              = a->maxnz;
3152273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3153754ec7b1SSatish Balay 
31546ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
31556ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
31566ad4291fSHong Zhang   c->compressedrow.checked = a->compressedrow.checked;
31576ad4291fSHong Zhang   if ( a->compressedrow.checked && a->compressedrow.use){
31586ad4291fSHong Zhang     i = a->compressedrow.nrows;
31596ad4291fSHong Zhang     ierr = PetscMalloc((2*i+1)*sizeof(PetscInt),&c->compressedrow.i);CHKERRQ(ierr);
31606ad4291fSHong Zhang     c->compressedrow.rindex = c->compressedrow.i + i + 1;
31616ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
31626ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
316327ea64f8SHong Zhang   } else {
316427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
316527ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
316627ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
31676ad4291fSHong Zhang   }
316888e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
31694846f1f5SKris Buschelman   ierr = MatDuplicate_Inode(A,cpvalues,&C);CHKERRQ(ierr);
31704846f1f5SKris Buschelman 
3171416022c9SBarry Smith   *B = C;
3172b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
31733a40ed3dSBarry Smith   PetscFunctionReturn(0);
317417ab2063SBarry Smith }
317517ab2063SBarry Smith 
31764a2ae208SSatish Balay #undef __FUNCT__
31774a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3178f69a0ea3SMatthew Knepley PetscErrorCode MatLoad_SeqAIJ(PetscViewer viewer, MatType type,Mat *A)
317917ab2063SBarry Smith {
3180416022c9SBarry Smith   Mat_SeqAIJ     *a;
3181416022c9SBarry Smith   Mat            B;
31826849ba73SBarry Smith   PetscErrorCode ierr;
31833c601197SSatish Balay   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N;
318438baddfdSBarry Smith   int            fd;
318538baddfdSBarry Smith   PetscMPIInt    size;
3186bcd2baecSBarry Smith   MPI_Comm       comm;
318717ab2063SBarry Smith 
31883a40ed3dSBarry Smith   PetscFunctionBegin;
3189e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3190d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
319129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
3192b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
31930752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3194552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
319517ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
319617ab2063SBarry Smith 
3197d64ed03dSBarry Smith   if (nz < 0) {
319829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3199d64ed03dSBarry Smith   }
3200d64ed03dSBarry Smith 
320117ab2063SBarry Smith   /* read in row lengths */
320297f1f81fSBarry Smith   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
32030752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
320417ab2063SBarry Smith 
32053c601197SSatish Balay   /* check if sum of rowlengths is same as nz */
32063c601197SSatish Balay   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
32073c601197SSatish Balay   if (sum != nz) SETERRQ2(PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
32083c601197SSatish Balay 
320917ab2063SBarry Smith   /* create our matrix */
3210f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,&B);CHKERRQ(ierr);
3211f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3212b3a1e11cSKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
3213ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(B,0,rowlengths);CHKERRQ(ierr);
3214416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
321517ab2063SBarry Smith 
32160752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
321717ab2063SBarry Smith 
321817ab2063SBarry Smith   /* read in nonzero values */
32190752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
322017ab2063SBarry Smith 
322117ab2063SBarry Smith   /* set matrix "i" values */
3222efb16452SHong Zhang   a->i[0] = 0;
322317ab2063SBarry Smith   for (i=1; i<= M; i++) {
3224416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3225416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
322617ab2063SBarry Smith   }
3227606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
322817ab2063SBarry Smith 
32296d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
32306d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3231b3a1e11cSKris Buschelman   *A = B;
32323a40ed3dSBarry Smith   PetscFunctionReturn(0);
323317ab2063SBarry Smith }
323417ab2063SBarry Smith 
32354a2ae208SSatish Balay #undef __FUNCT__
3236b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3237dfbe8321SBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
32387264ac53SSatish Balay {
32397264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3240dfbe8321SBarry Smith   PetscErrorCode ierr;
32417264ac53SSatish Balay 
32423a40ed3dSBarry Smith   PetscFunctionBegin;
3243bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3244899cda47SBarry Smith   if ((A->rmap.n != B->rmap.n) || (A->cmap.n != B->cmap.n) ||(a->nz != b->nz)) {
3245ca44d042SBarry Smith     *flg = PETSC_FALSE;
3246ca44d042SBarry Smith     PetscFunctionReturn(0);
3247bcd2baecSBarry Smith   }
32487264ac53SSatish Balay 
32497264ac53SSatish Balay   /* if the a->i are the same */
3250899cda47SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap.n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3251abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
32527264ac53SSatish Balay 
32537264ac53SSatish Balay   /* if a->j are the same */
325497f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3255abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3256bcd2baecSBarry Smith 
3257bcd2baecSBarry Smith   /* if a->a are the same */
325887828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
32590f5bd95cSBarry Smith 
32603a40ed3dSBarry Smith   PetscFunctionReturn(0);
32617264ac53SSatish Balay 
32627264ac53SSatish Balay }
326336db0b34SBarry Smith 
32644a2ae208SSatish Balay #undef __FUNCT__
32654a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
326605869f15SSatish Balay /*@
326736db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
326836db0b34SBarry Smith               provided by the user.
326936db0b34SBarry Smith 
3270c75a6043SHong Zhang       Collective on MPI_Comm
327136db0b34SBarry Smith 
327236db0b34SBarry Smith    Input Parameters:
327336db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
327436db0b34SBarry Smith .   m - number of rows
327536db0b34SBarry Smith .   n - number of columns
327636db0b34SBarry Smith .   i - row indices
327736db0b34SBarry Smith .   j - column indices
327836db0b34SBarry Smith -   a - matrix values
327936db0b34SBarry Smith 
328036db0b34SBarry Smith    Output Parameter:
328136db0b34SBarry Smith .   mat - the matrix
328236db0b34SBarry Smith 
328336db0b34SBarry Smith    Level: intermediate
328436db0b34SBarry Smith 
328536db0b34SBarry Smith    Notes:
32860551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
328736db0b34SBarry Smith     once the matrix is destroyed
328836db0b34SBarry Smith 
328936db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
329036db0b34SBarry Smith 
3291bfeeae90SHong Zhang        The i and j indices are 0 based
329236db0b34SBarry Smith 
3293a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
3294a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
3295a4552177SSatish Balay     as shown:
3296a4552177SSatish Balay 
3297a4552177SSatish Balay         1 0 0
3298a4552177SSatish Balay         2 0 3
3299a4552177SSatish Balay         4 5 6
3300a4552177SSatish Balay 
3301a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
3302a4552177SSatish Balay         j =  {0,0,2,0,1,2}  [size = nz = 6]
3303a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
3304a4552177SSatish Balay 
33052fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
330636db0b34SBarry Smith 
330736db0b34SBarry Smith @*/
3308be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
330936db0b34SBarry Smith {
3310dfbe8321SBarry Smith   PetscErrorCode ierr;
331197f1f81fSBarry Smith   PetscInt       ii;
331236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
331336db0b34SBarry Smith 
331436db0b34SBarry Smith   PetscFunctionBegin;
3315a96a251dSBarry Smith   if (i[0]) {
3316634064b4SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
331736db0b34SBarry Smith   }
3318f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3319f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3320ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3321ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3322ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3323ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3324ab93d7beSBarry Smith 
332536db0b34SBarry Smith   aij->i = i;
332636db0b34SBarry Smith   aij->j = j;
332736db0b34SBarry Smith   aij->a = a;
332836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
332936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
3330e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
3331e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
333236db0b34SBarry Smith 
333336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
333436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
33352515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
333679a5c55eSBarry 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]);
333736db0b34SBarry Smith #endif
333836db0b34SBarry Smith   }
33392515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
334036db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
334179a5c55eSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
334279a5c55eSBarry Smith     if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]);
334336db0b34SBarry Smith   }
334436db0b34SBarry Smith #endif
334536db0b34SBarry Smith 
3346b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3347b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
334836db0b34SBarry Smith   PetscFunctionReturn(0);
334936db0b34SBarry Smith }
335036db0b34SBarry Smith 
3351cc8ba8e1SBarry Smith #undef __FUNCT__
3352ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3353dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3354cc8ba8e1SBarry Smith {
3355dfbe8321SBarry Smith   PetscErrorCode ierr;
3356cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
335736db0b34SBarry Smith 
3358cc8ba8e1SBarry Smith   PetscFunctionBegin;
33598ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
3360cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3361cc8ba8e1SBarry Smith     a->coloring = coloring;
336212c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
336397f1f81fSBarry Smith     PetscInt             i,*larray;
336412c595b3SBarry Smith     ISColoring      ocoloring;
336508b6dcc0SBarry Smith     ISColoringValue *colors;
336612c595b3SBarry Smith 
336712c595b3SBarry Smith     /* set coloring for diagonal portion */
3368899cda47SBarry Smith     ierr = PetscMalloc((A->cmap.n+1)*sizeof(PetscInt),&larray);CHKERRQ(ierr);
3369899cda47SBarry Smith     for (i=0; i<A->cmap.n; i++) {
337012c595b3SBarry Smith       larray[i] = i;
337112c595b3SBarry Smith     }
3372899cda47SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->cmap.n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
3373899cda47SBarry Smith     ierr = PetscMalloc((A->cmap.n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
3374899cda47SBarry Smith     for (i=0; i<A->cmap.n; i++) {
337512c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
337612c595b3SBarry Smith     }
337712c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
337895a80f87SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap.n,colors,&ocoloring);CHKERRQ(ierr);
337912c595b3SBarry Smith     a->coloring = ocoloring;
338012c595b3SBarry Smith   }
3381cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3382cc8ba8e1SBarry Smith }
3383cc8ba8e1SBarry Smith 
3384dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3385ee4f033dSBarry Smith EXTERN_C_BEGIN
338629c1e371SBarry Smith #include "adic/ad_utils.h"
3387ee4f033dSBarry Smith EXTERN_C_END
3388cc8ba8e1SBarry Smith 
3389cc8ba8e1SBarry Smith #undef __FUNCT__
3390ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3391dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3392cc8ba8e1SBarry Smith {
3393cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3394899cda47SBarry Smith   PetscInt        m = A->rmap.n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
33954440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
339608b6dcc0SBarry Smith   ISColoringValue *color;
3397cc8ba8e1SBarry Smith 
3398cc8ba8e1SBarry Smith   PetscFunctionBegin;
3399e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
34004440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3401cc8ba8e1SBarry Smith   color = a->coloring->colors;
3402cc8ba8e1SBarry Smith   /* loop over rows */
3403cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3404cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3405cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3406cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3407cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3408cc8ba8e1SBarry Smith     }
34094440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3410ee4f033dSBarry Smith   }
3411ee4f033dSBarry Smith   PetscFunctionReturn(0);
3412ee4f033dSBarry Smith }
3413ee4f033dSBarry Smith #endif
3414ee4f033dSBarry Smith 
3415ee4f033dSBarry Smith #undef __FUNCT__
3416ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
341797f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3418ee4f033dSBarry Smith {
3419ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3420899cda47SBarry Smith   PetscInt             m = A->rmap.n,*ii = a->i,*jj = a->j,nz,i,j;
342187828ca2SBarry Smith   PetscScalar     *v = a->a,*values = (PetscScalar *)advalues;
342208b6dcc0SBarry Smith   ISColoringValue *color;
3423ee4f033dSBarry Smith 
3424ee4f033dSBarry Smith   PetscFunctionBegin;
3425e005ede5SBarry Smith   if (!a->coloring) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3426ee4f033dSBarry Smith   color = a->coloring->colors;
3427ee4f033dSBarry Smith   /* loop over rows */
3428ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3429ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3430ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3431ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3432ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3433ee4f033dSBarry Smith     }
3434ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3435cc8ba8e1SBarry Smith   }
3436cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3437cc8ba8e1SBarry Smith }
343836db0b34SBarry Smith 
343981824310SBarry Smith /*
344081824310SBarry Smith     Special version for direct calls from Fortran
344181824310SBarry Smith */
344281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
344381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
344481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
344581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
344681824310SBarry Smith #endif
344781824310SBarry Smith 
344881824310SBarry Smith /* Change these macros so can be used in void function */
344981824310SBarry Smith #undef CHKERRQ
345081824310SBarry Smith #define CHKERRQ(ierr) CHKERRABORT(A->comm,ierr)
345181824310SBarry Smith #undef SETERRQ2
345281824310SBarry Smith #define SETERRQ2(ierr,b,c,d) CHKERRABORT(A->comm,ierr)
345381824310SBarry Smith 
345481824310SBarry Smith EXTERN_C_BEGIN
345581824310SBarry Smith #undef __FUNCT__
345681824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
34571f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
345881824310SBarry Smith {
345981824310SBarry Smith   Mat            A = *AA;
346081824310SBarry Smith   PetscInt       m = *mm, n = *nn;
346181824310SBarry Smith   InsertMode     is = *isis;
346281824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
346381824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
346481824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
346581824310SBarry Smith   PetscErrorCode ierr;
346681824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
346781824310SBarry Smith   PetscScalar    *ap,value,*aa;
3468edb03aefSBarry Smith   PetscTruth     ignorezeroentries = a->ignorezeroentries;
346981824310SBarry Smith   PetscTruth     roworiented = a->roworiented;
347081824310SBarry Smith 
347181824310SBarry Smith   PetscFunctionBegin;
347281824310SBarry Smith   MatPreallocated(A);
347381824310SBarry Smith   imax = a->imax;
347481824310SBarry Smith   ai = a->i;
347581824310SBarry Smith   ailen = a->ilen;
347681824310SBarry Smith   aj = a->j;
347781824310SBarry Smith   aa = a->a;
347881824310SBarry Smith 
347981824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
348081824310SBarry Smith     row  = im[k];
348181824310SBarry Smith     if (row < 0) continue;
348281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3483899cda47SBarry Smith     if (row >= A->rmap.n) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
348481824310SBarry Smith #endif
348581824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
348681824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
348781824310SBarry Smith     low  = 0;
348881824310SBarry Smith     high = nrow;
348981824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
349081824310SBarry Smith       if (in[l] < 0) continue;
349181824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3492899cda47SBarry Smith       if (in[l] >= A->cmap.n) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
349381824310SBarry Smith #endif
349481824310SBarry Smith       col = in[l];
349581824310SBarry Smith       if (roworiented) {
349681824310SBarry Smith         value = v[l + k*n];
349781824310SBarry Smith       } else {
349881824310SBarry Smith         value = v[k + l*m];
349981824310SBarry Smith       }
350081824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
350181824310SBarry Smith 
350281824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
350381824310SBarry Smith       lastcol = col;
350481824310SBarry Smith       while (high-low > 5) {
350581824310SBarry Smith         t = (low+high)/2;
350681824310SBarry Smith         if (rp[t] > col) high = t;
350781824310SBarry Smith         else             low  = t;
350881824310SBarry Smith       }
350981824310SBarry Smith       for (i=low; i<high; i++) {
351081824310SBarry Smith         if (rp[i] > col) break;
351181824310SBarry Smith         if (rp[i] == col) {
351281824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
351381824310SBarry Smith           else                  ap[i] = value;
351481824310SBarry Smith           goto noinsert;
351581824310SBarry Smith         }
351681824310SBarry Smith       }
351781824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
351881824310SBarry Smith       if (nonew == 1) goto noinsert;
351981824310SBarry Smith       if (nonew == -1) SETERRABORT(A->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
3520421e10b8SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap.n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
352181824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
352281824310SBarry Smith       /* shift up all the later entries in this row */
352381824310SBarry Smith       for (ii=N; ii>=i; ii--) {
352481824310SBarry Smith         rp[ii+1] = rp[ii];
352581824310SBarry Smith         ap[ii+1] = ap[ii];
352681824310SBarry Smith       }
352781824310SBarry Smith       rp[i] = col;
352881824310SBarry Smith       ap[i] = value;
352981824310SBarry Smith       noinsert:;
353081824310SBarry Smith       low = i + 1;
353181824310SBarry Smith     }
353281824310SBarry Smith     ailen[row] = nrow;
353381824310SBarry Smith   }
353481824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
353581824310SBarry Smith   PetscFunctionReturnVoid();
353681824310SBarry Smith }
353781824310SBarry Smith EXTERN_C_END
3538