xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 62298a1ea7c914f3baa83cf2ea73d8d50564269a)
1992c00aaSSatish Balay #define PETSCMAT_DLL
2b3cc6726SBarry Smith 
3b377110cSBarry Smith 
4d5d45c9bSBarry Smith /*
53369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
6d5d45c9bSBarry Smith   matrix storage format.
7d5d45c9bSBarry Smith */
83369ce9aSBarry Smith 
97c4f633dSBarry Smith 
107c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
11f3da1532SBarry Smith #include "petscblaslapack.h"
120a835dfdSSatish Balay #include "petscbt.h"
1317ab2063SBarry Smith 
144a2ae208SSatish Balay #undef __FUNCT__
1579299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
167087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
1779299369SBarry Smith {
1879299369SBarry Smith   PetscErrorCode ierr;
1979299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
20d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
2154f21887SBarry Smith   MatScalar      *aa = aij->a;
2254f21887SBarry Smith   PetscScalar    *v;
23ace3abfcSBarry Smith   PetscBool      missing;
2479299369SBarry Smith 
2579299369SBarry Smith   PetscFunctionBegin;
2609f38230SBarry Smith   if (Y->assembled) {
2709f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
2809f38230SBarry Smith     if (!missing) {
2979299369SBarry Smith       diag = aij->diag;
3079299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
3179299369SBarry Smith       if (is == INSERT_VALUES) {
3279299369SBarry Smith 	for (i=0; i<m; i++) {
3379299369SBarry Smith 	  aa[diag[i]] = v[i];
3479299369SBarry Smith 	}
3579299369SBarry Smith       } else {
3679299369SBarry Smith 	for (i=0; i<m; i++) {
3779299369SBarry Smith 	  aa[diag[i]] += v[i];
3879299369SBarry Smith 	}
3979299369SBarry Smith       }
4079299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
4179299369SBarry Smith       PetscFunctionReturn(0);
4279299369SBarry Smith     }
4309f38230SBarry Smith   }
4409f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
4509f38230SBarry Smith   PetscFunctionReturn(0);
4609f38230SBarry Smith }
4779299369SBarry Smith 
4879299369SBarry Smith #undef __FUNCT__
494a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
50ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
5117ab2063SBarry Smith {
52416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
53dfbe8321SBarry Smith   PetscErrorCode ierr;
5497f1f81fSBarry Smith   PetscInt       i,ishift;
5517ab2063SBarry Smith 
563a40ed3dSBarry Smith   PetscFunctionBegin;
57d0f46423SBarry Smith   *m     = A->rmap->n;
583a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
59bfeeae90SHong Zhang   ishift = 0;
6053e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
61d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
62bfeeae90SHong Zhang   } else if (oshift == 1) {
63d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
643b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
65d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
66d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
67ecc77c7aSBarry Smith     if (ja) {
6897f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
693b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
70ecc77c7aSBarry Smith     }
716945ee14SBarry Smith   } else {
72ecc77c7aSBarry Smith     *ia = a->i;
73ecc77c7aSBarry Smith     if (ja) *ja = a->j;
74a2ce50c7SBarry Smith   }
753a40ed3dSBarry Smith   PetscFunctionReturn(0);
76a2744918SBarry Smith }
77a2744918SBarry Smith 
784a2ae208SSatish Balay #undef __FUNCT__
794a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
80ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
816945ee14SBarry Smith {
82dfbe8321SBarry Smith   PetscErrorCode ierr;
836945ee14SBarry Smith 
843a40ed3dSBarry Smith   PetscFunctionBegin;
853a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
86bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
87606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
88ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
89bcd2baecSBarry Smith   }
903a40ed3dSBarry Smith   PetscFunctionReturn(0);
9117ab2063SBarry Smith }
9217ab2063SBarry Smith 
934a2ae208SSatish Balay #undef __FUNCT__
944a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
95ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
963b2fbd54SBarry Smith {
973b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98dfbe8321SBarry Smith   PetscErrorCode ierr;
99d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
10097f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
1013b2fbd54SBarry Smith 
1023a40ed3dSBarry Smith   PetscFunctionBegin;
103899cda47SBarry Smith   *nn = n;
1043a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1053b2fbd54SBarry Smith   if (symmetric) {
106d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
1073b2fbd54SBarry Smith   } else {
10897f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
10997f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
11097f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
11197f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
1123b2fbd54SBarry Smith     jj = a->j;
1133b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
114bfeeae90SHong Zhang       collengths[jj[i]]++;
1153b2fbd54SBarry Smith     }
1163b2fbd54SBarry Smith     cia[0] = oshift;
1173b2fbd54SBarry Smith     for (i=0; i<n; i++) {
1183b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1193b2fbd54SBarry Smith     }
12097f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
1213b2fbd54SBarry Smith     jj   = a->j;
122a93ec695SBarry Smith     for (row=0; row<m; row++) {
123a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
124a93ec695SBarry Smith       for (i=0; i<mr; i++) {
125bfeeae90SHong Zhang         col = *jj++;
1263b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1273b2fbd54SBarry Smith       }
1283b2fbd54SBarry Smith     }
129606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1303b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1313b2fbd54SBarry Smith   }
1323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1333b2fbd54SBarry Smith }
1343b2fbd54SBarry Smith 
1354a2ae208SSatish Balay #undef __FUNCT__
1364a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
137ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1383b2fbd54SBarry Smith {
139dfbe8321SBarry Smith   PetscErrorCode ierr;
140606d414cSSatish Balay 
1413a40ed3dSBarry Smith   PetscFunctionBegin;
1423a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1433b2fbd54SBarry Smith 
144606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
145606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1463b2fbd54SBarry Smith 
1473a40ed3dSBarry Smith   PetscFunctionReturn(0);
1483b2fbd54SBarry Smith }
1493b2fbd54SBarry Smith 
15087d4246cSBarry Smith #undef __FUNCT__
15187d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
15287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
15387d4246cSBarry Smith {
15487d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15587d4246cSBarry Smith   PetscInt       *ai = a->i;
15687d4246cSBarry Smith   PetscErrorCode ierr;
15787d4246cSBarry Smith 
15887d4246cSBarry Smith   PetscFunctionBegin;
15987d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
16087d4246cSBarry Smith   PetscFunctionReturn(0);
16187d4246cSBarry Smith }
16287d4246cSBarry Smith 
1634a2ae208SSatish Balay #undef __FUNCT__
1644a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
16597f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
16617ab2063SBarry Smith {
167416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
168e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
16997f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
1706849ba73SBarry Smith   PetscErrorCode ierr;
171e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
17254f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
173ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
174ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
17517ab2063SBarry Smith 
1763a40ed3dSBarry Smith   PetscFunctionBegin;
17771fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
17817ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
179416022c9SBarry Smith     row  = im[k];
1805ef9f2a5SBarry Smith     if (row < 0) continue;
1812515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
182e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
1833b2fbd54SBarry Smith #endif
184bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
18517ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
186416022c9SBarry Smith     low  = 0;
187c71e6ed7SBarry Smith     high = nrow;
18817ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1895ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1902515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
191e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
1923b2fbd54SBarry Smith #endif
193bfeeae90SHong Zhang       col = in[l];
19416371a99SBarry Smith       if (v) {
1954b0e389bSBarry Smith 	if (roworiented) {
1965ef9f2a5SBarry Smith 	  value = v[l + k*n];
197bef8e0ddSBarry Smith 	} else {
1984b0e389bSBarry Smith 	  value = v[k + l*m];
1994b0e389bSBarry Smith 	}
20016371a99SBarry Smith       } else {
20175567043SBarry Smith         value = 0.;
20216371a99SBarry Smith       }
203abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
20436db0b34SBarry Smith 
2057cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
206e2ee6c50SBarry Smith       lastcol = col;
207416022c9SBarry Smith       while (high-low > 5) {
208416022c9SBarry Smith         t = (low+high)/2;
209416022c9SBarry Smith         if (rp[t] > col) high = t;
210416022c9SBarry Smith         else             low  = t;
21117ab2063SBarry Smith       }
212416022c9SBarry Smith       for (i=low; i<high; i++) {
21317ab2063SBarry Smith         if (rp[i] > col) break;
21417ab2063SBarry Smith         if (rp[i] == col) {
215416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
21617ab2063SBarry Smith           else                  ap[i] = value;
217e44c0bd4SBarry Smith           low = i + 1;
21817ab2063SBarry Smith           goto noinsert;
21917ab2063SBarry Smith         }
22017ab2063SBarry Smith       }
221abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
222c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
223e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
224fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
225c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
226416022c9SBarry Smith       /* shift up all the later entries in this row */
227416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
22817ab2063SBarry Smith         rp[ii+1] = rp[ii];
22917ab2063SBarry Smith         ap[ii+1] = ap[ii];
23017ab2063SBarry Smith       }
23117ab2063SBarry Smith       rp[i] = col;
23217ab2063SBarry Smith       ap[i] = value;
233416022c9SBarry Smith       low   = i + 1;
234e44c0bd4SBarry Smith       noinsert:;
23517ab2063SBarry Smith     }
23617ab2063SBarry Smith     ailen[row] = nrow;
23717ab2063SBarry Smith   }
23888e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
2393a40ed3dSBarry Smith   PetscFunctionReturn(0);
24017ab2063SBarry Smith }
24117ab2063SBarry Smith 
24281824310SBarry Smith 
2434a2ae208SSatish Balay #undef __FUNCT__
2444a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
245a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
2467eb43aa7SLois Curfman McInnes {
2477eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
24897f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
24997f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
25054f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
2517eb43aa7SLois Curfman McInnes 
2523a40ed3dSBarry Smith   PetscFunctionBegin;
2537eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2547eb43aa7SLois Curfman McInnes     row  = im[k];
255e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
256e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
257bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
2587eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2597eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
260e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
261e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
262bfeeae90SHong Zhang       col = in[l] ;
2637eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2647eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2657eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2667eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2677eb43aa7SLois Curfman McInnes         else             low  = t;
2687eb43aa7SLois Curfman McInnes       }
2697eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2707eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2717eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
272b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2737eb43aa7SLois Curfman McInnes           goto finished;
2747eb43aa7SLois Curfman McInnes         }
2757eb43aa7SLois Curfman McInnes       }
27697e567efSBarry Smith       *v++ = 0.0;
2777eb43aa7SLois Curfman McInnes       finished:;
2787eb43aa7SLois Curfman McInnes     }
2797eb43aa7SLois Curfman McInnes   }
2803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2817eb43aa7SLois Curfman McInnes }
2827eb43aa7SLois Curfman McInnes 
28317ab2063SBarry Smith 
2844a2ae208SSatish Balay #undef __FUNCT__
2854a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
286dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
28717ab2063SBarry Smith {
288416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2896849ba73SBarry Smith   PetscErrorCode ierr;
2906f69ff64SBarry Smith   PetscInt       i,*col_lens;
2916f69ff64SBarry Smith   int            fd;
29217ab2063SBarry Smith 
2933a40ed3dSBarry Smith   PetscFunctionBegin;
294b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
295d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
2960700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
297d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
298d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
299416022c9SBarry Smith   col_lens[3] = a->nz;
300416022c9SBarry Smith 
301416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
302d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
303416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
30417ab2063SBarry Smith   }
305d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
306606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
307416022c9SBarry Smith 
308416022c9SBarry Smith   /* store column indices (zero start index) */
3096f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
310416022c9SBarry Smith 
311416022c9SBarry Smith   /* store nonzero values */
3126f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
3133a40ed3dSBarry Smith   PetscFunctionReturn(0);
31417ab2063SBarry Smith }
315416022c9SBarry Smith 
31609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
317cd155464SBarry Smith 
3184a2ae208SSatish Balay #undef __FUNCT__
3194a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
320dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
321416022c9SBarry Smith {
322416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
323dfbe8321SBarry Smith   PetscErrorCode    ierr;
324d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
325e060cb09SBarry Smith   const char        *name;
326f3ef73ceSBarry Smith   PetscViewerFormat format;
32717ab2063SBarry Smith 
3283a40ed3dSBarry Smith   PetscFunctionBegin;
329b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
33071c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
33197f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
332d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
333d00d2cf4SBarry Smith       nofinalvalue = 1;
334d00d2cf4SBarry Smith     }
335d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
336d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
33777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
33877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
339b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
34017ab2063SBarry Smith 
34117ab2063SBarry Smith     for (i=0; i<m; i++) {
342416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
343aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
34477431f27SBarry 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);
34517ab2063SBarry Smith #else
34677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
34717ab2063SBarry Smith #endif
34817ab2063SBarry Smith       }
34917ab2063SBarry Smith     }
350d00d2cf4SBarry Smith     if (nofinalvalue) {
351d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
352d00d2cf4SBarry Smith     }
353317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
354fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
355d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
35668369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
357cd155464SBarry Smith      PetscFunctionReturn(0);
358fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
359d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
3607566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
36144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
36277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
36344cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
364aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
36536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
366a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
36736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
368a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
36936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
370a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3716831982aSBarry Smith         }
37244cd7ae7SLois Curfman McInnes #else
373a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
37444cd7ae7SLois Curfman McInnes #endif
37544cd7ae7SLois Curfman McInnes       }
376b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
37744cd7ae7SLois Curfman McInnes     }
378d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
379fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
38097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
381d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
3827566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
38397f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
384496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
385496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
386496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
387496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
388aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
38936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
390496be53dSLois Curfman McInnes #else
391496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
392496be53dSLois Curfman McInnes #endif
393496be53dSLois Curfman McInnes         }
394496be53dSLois Curfman McInnes       }
395496be53dSLois Curfman McInnes     }
3962e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
39777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
3982e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
39977431f27SBarry 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);}
40077431f27SBarry 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);}
40177431f27SBarry 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);}
40277431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
40377431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
40477431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
405496be53dSLois Curfman McInnes     }
406b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
407606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
408496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
409496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
41077431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
411496be53dSLois Curfman McInnes       }
412b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
413496be53dSLois Curfman McInnes     }
414b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
415496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
416496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
417496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
418aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
41936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
420b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4216831982aSBarry Smith           }
422496be53dSLois Curfman McInnes #else
423b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
424496be53dSLois Curfman McInnes #endif
425496be53dSLois Curfman McInnes         }
426496be53dSLois Curfman McInnes       }
427b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
428496be53dSLois Curfman McInnes     }
429d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
430fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
43197f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
43287828ca2SBarry Smith     PetscScalar value;
43302594712SBarry Smith 
434d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4357566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
43602594712SBarry Smith     for (i=0; i<m; i++) {
43702594712SBarry Smith       jcnt = 0;
438d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
439e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44002594712SBarry Smith           value = a->a[cnt++];
441e24b481bSBarry Smith           jcnt++;
44202594712SBarry Smith         } else {
44302594712SBarry Smith           value = 0.0;
44402594712SBarry Smith         }
445aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
446b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
44702594712SBarry Smith #else
448b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
44902594712SBarry Smith #endif
45002594712SBarry Smith       }
451b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45202594712SBarry Smith     }
453d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
4543c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
455d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4567566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
4573c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
4583c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
4593c215bfdSMatthew Knepley #else
4603c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
4613c215bfdSMatthew Knepley #endif
462d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
4633c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
4643c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
4653c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
4663c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
4673c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4683c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
4693c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G -%G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4703c215bfdSMatthew Knepley         } else {
4713c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
4723c215bfdSMatthew Knepley         }
4733c215bfdSMatthew Knepley #else
4743c215bfdSMatthew Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr);
4753c215bfdSMatthew Knepley #endif
4763c215bfdSMatthew Knepley       }
4773c215bfdSMatthew Knepley     }
478d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
4793a40ed3dSBarry Smith   } else {
480d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4817566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
482d5f3da31SBarry Smith     if (A->factortype){
48316cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
48416cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
48516cd7e1dSShri Abhyankar         /* L part */
48616cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
48716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
48816cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
48916cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
49016cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
49116cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
49216cd7e1dSShri Abhyankar           } else {
49316cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
49416cd7e1dSShri Abhyankar           }
49516cd7e1dSShri Abhyankar #else
49616cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
49716cd7e1dSShri Abhyankar #endif
49816cd7e1dSShri Abhyankar         }
49916cd7e1dSShri Abhyankar 	/* diagonal */
50016cd7e1dSShri Abhyankar 	j = a->diag[i];
50116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
50216cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
50316cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
50416cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
50516cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
50616cd7e1dSShri Abhyankar           } else {
50716cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
50816cd7e1dSShri Abhyankar           }
50916cd7e1dSShri Abhyankar #else
51016cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
51116cd7e1dSShri Abhyankar #endif
51216cd7e1dSShri Abhyankar 
51316cd7e1dSShri Abhyankar 	/* U part */
51416cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
51516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
51616cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
51716cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
51816cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
51916cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
52016cd7e1dSShri Abhyankar           } else {
52116cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
52216cd7e1dSShri Abhyankar           }
52316cd7e1dSShri Abhyankar #else
52416cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
52516cd7e1dSShri Abhyankar #endif
52616cd7e1dSShri Abhyankar }
52716cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
52816cd7e1dSShri Abhyankar         }
52916cd7e1dSShri Abhyankar     } else {
53017ab2063SBarry Smith       for (i=0; i<m; i++) {
53177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
532416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
533aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
53436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
535a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
53636db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
537a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
5383a40ed3dSBarry Smith           } else {
539a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
54017ab2063SBarry Smith           }
54117ab2063SBarry Smith #else
542a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
54317ab2063SBarry Smith #endif
54417ab2063SBarry Smith         }
545b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
54617ab2063SBarry Smith       }
54716cd7e1dSShri Abhyankar     }
548d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
54917ab2063SBarry Smith   }
550b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
5513a40ed3dSBarry Smith   PetscFunctionReturn(0);
552416022c9SBarry Smith }
553416022c9SBarry Smith 
5544a2ae208SSatish Balay #undef __FUNCT__
5554a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
556dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
557416022c9SBarry Smith {
558480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
559416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
560dfbe8321SBarry Smith   PetscErrorCode    ierr;
561d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
56236db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
563b0a32e0cSBarry Smith   PetscViewer       viewer;
564f3ef73ceSBarry Smith   PetscViewerFormat format;
565cddf8d76SBarry Smith 
5663a40ed3dSBarry Smith   PetscFunctionBegin;
567480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
568b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
56919bcc07fSBarry Smith 
570b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
571416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5720513a670SBarry Smith 
573fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
5740513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
575b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
576416022c9SBarry Smith     for (i=0; i<m; i++) {
577cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
578bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
579bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
580aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58136db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
582cddf8d76SBarry Smith #else
583cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
584cddf8d76SBarry Smith #endif
585b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
586cddf8d76SBarry Smith       }
587cddf8d76SBarry Smith     }
588b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
589cddf8d76SBarry Smith     for (i=0; i<m; i++) {
590cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
591bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
592bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
593cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
594b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
595cddf8d76SBarry Smith       }
596cddf8d76SBarry Smith     }
597b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
598cddf8d76SBarry Smith     for (i=0; i<m; i++) {
599cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
600bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
601bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
602aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
60336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
604cddf8d76SBarry Smith #else
605cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
606cddf8d76SBarry Smith #endif
607b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
608416022c9SBarry Smith       }
609416022c9SBarry Smith     }
6100513a670SBarry Smith   } else {
6110513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
6120513a670SBarry Smith     /* first determine max of all nonzero values */
61397f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
614b0a32e0cSBarry Smith     PetscDraw   popup;
61536db0b34SBarry Smith     PetscReal scale;
6160513a670SBarry Smith 
6170513a670SBarry Smith     for (i=0; i<nz; i++) {
6180513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
6190513a670SBarry Smith     }
620b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
621b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
622b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
6230513a670SBarry Smith     count = 0;
6240513a670SBarry Smith     for (i=0; i<m; i++) {
6250513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
626bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
627bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
62897f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
629b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
6300513a670SBarry Smith         count++;
6310513a670SBarry Smith       }
6320513a670SBarry Smith     }
6330513a670SBarry Smith   }
634480ef9eaSBarry Smith   PetscFunctionReturn(0);
635480ef9eaSBarry Smith }
636cddf8d76SBarry Smith 
6374a2ae208SSatish Balay #undef __FUNCT__
6384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
639dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
640480ef9eaSBarry Smith {
641dfbe8321SBarry Smith   PetscErrorCode ierr;
642b0a32e0cSBarry Smith   PetscDraw      draw;
64336db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
644ace3abfcSBarry Smith   PetscBool      isnull;
645480ef9eaSBarry Smith 
646480ef9eaSBarry Smith   PetscFunctionBegin;
647b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
648b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
649480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
650480ef9eaSBarry Smith 
651480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
652d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
653480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
654b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
655b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
656480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
6573a40ed3dSBarry Smith   PetscFunctionReturn(0);
658416022c9SBarry Smith }
659416022c9SBarry Smith 
6604a2ae208SSatish Balay #undef __FUNCT__
6614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
662dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
663416022c9SBarry Smith {
664dfbe8321SBarry Smith   PetscErrorCode ierr;
665ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
666416022c9SBarry Smith 
6673a40ed3dSBarry Smith   PetscFunctionBegin;
6682692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
6692692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
6702692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
671c45a1595SBarry Smith   if (iascii) {
6723a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6730f5bd95cSBarry Smith   } else if (isbinary) {
6743a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6750f5bd95cSBarry Smith   } else if (isdraw) {
6763a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6775cd90555SBarry Smith   } else {
678e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
67917ab2063SBarry Smith   }
6804108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
6813a40ed3dSBarry Smith   PetscFunctionReturn(0);
68217ab2063SBarry Smith }
68319bcc07fSBarry Smith 
6844a2ae208SSatish Balay #undef __FUNCT__
6854a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
686dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
68717ab2063SBarry Smith {
688416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
6896849ba73SBarry Smith   PetscErrorCode ierr;
69097f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
691d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
69254f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
6933447b6efSHong Zhang   PetscReal      ratio=0.6;
69417ab2063SBarry Smith 
6953a40ed3dSBarry Smith   PetscFunctionBegin;
6963a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
69717ab2063SBarry Smith 
69843ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
69917ab2063SBarry Smith   for (i=1; i<m; i++) {
700416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
70117ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
70294a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
70317ab2063SBarry Smith     if (fshift) {
704bfeeae90SHong Zhang       ip = aj + ai[i] ;
705bfeeae90SHong Zhang       ap = aa + ai[i] ;
70617ab2063SBarry Smith       N  = ailen[i];
70717ab2063SBarry Smith       for (j=0; j<N; j++) {
70817ab2063SBarry Smith         ip[j-fshift] = ip[j];
70917ab2063SBarry Smith         ap[j-fshift] = ap[j];
71017ab2063SBarry Smith       }
71117ab2063SBarry Smith     }
71217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
71317ab2063SBarry Smith   }
71417ab2063SBarry Smith   if (m) {
71517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
71617ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
71717ab2063SBarry Smith   }
71817ab2063SBarry Smith   /* reset ilen and imax for each row */
71917ab2063SBarry Smith   for (i=0; i<m; i++) {
72017ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
72117ab2063SBarry Smith   }
722bfeeae90SHong Zhang   a->nz = ai[m];
72365e19b50SBarry Smith   if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift);
72417ab2063SBarry Smith 
72509f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
726d0f46423SBarry 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);
727ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
728ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
7298e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
730dd5f02e7SSatish Balay   a->reallocs          = 0;
7314e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
73236db0b34SBarry Smith   a->rmax              = rmax;
7334e220ebcSLois Curfman McInnes 
734cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
73588e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
73671c2f376SKris Buschelman 
7374108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
73871f1c65dSBarry Smith 
73971f1c65dSBarry Smith   a->idiagvalid = PETSC_FALSE;
7403a40ed3dSBarry Smith   PetscFunctionReturn(0);
74117ab2063SBarry Smith }
74217ab2063SBarry Smith 
7434a2ae208SSatish Balay #undef __FUNCT__
74499cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
74599cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
74699cafbc1SBarry Smith {
74799cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
74899cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
74954f21887SBarry Smith   MatScalar      *aa = a->a;
75099cafbc1SBarry Smith 
75199cafbc1SBarry Smith   PetscFunctionBegin;
75299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
75399cafbc1SBarry Smith   PetscFunctionReturn(0);
75499cafbc1SBarry Smith }
75599cafbc1SBarry Smith 
75699cafbc1SBarry Smith #undef __FUNCT__
75799cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
75899cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
75999cafbc1SBarry Smith {
76099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
76199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
76254f21887SBarry Smith   MatScalar      *aa = a->a;
76399cafbc1SBarry Smith 
76499cafbc1SBarry Smith   PetscFunctionBegin;
76599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
76699cafbc1SBarry Smith   PetscFunctionReturn(0);
76799cafbc1SBarry Smith }
76899cafbc1SBarry Smith 
76999cafbc1SBarry Smith #undef __FUNCT__
7704a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
771dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
77217ab2063SBarry Smith {
773416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
774dfbe8321SBarry Smith   PetscErrorCode ierr;
7753a40ed3dSBarry Smith 
7763a40ed3dSBarry Smith   PetscFunctionBegin;
777d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
7783a40ed3dSBarry Smith   PetscFunctionReturn(0);
77917ab2063SBarry Smith }
780416022c9SBarry Smith 
7814a2ae208SSatish Balay #undef __FUNCT__
7824a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
783dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
78417ab2063SBarry Smith {
785416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
786dfbe8321SBarry Smith   PetscErrorCode ierr;
787d5d45c9bSBarry Smith 
7883a40ed3dSBarry Smith   PetscFunctionBegin;
789aa482453SBarry Smith #if defined(PETSC_USE_LOG)
790d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
79117ab2063SBarry Smith #endif
792e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
793c38d4ed2SBarry Smith   if (a->row) {
794c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
795c38d4ed2SBarry Smith   }
796c38d4ed2SBarry Smith   if (a->col) {
797c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
798c38d4ed2SBarry Smith   }
79905b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
80005b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
80171f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
80205b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
80382bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
80405b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
805cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
80605b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
807407f6b05SHong Zhang   if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);}
808cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
809a30b2313SHong Zhang 
8104108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
8114846f1f5SKris Buschelman 
812606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
813901853e0SKris Buschelman 
814dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
815901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
816901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
817901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
818901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
819901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
8205a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
821901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
822901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
823a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
824901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
8253a40ed3dSBarry Smith   PetscFunctionReturn(0);
82617ab2063SBarry Smith }
82717ab2063SBarry Smith 
8284a2ae208SSatish Balay #undef __FUNCT__
8294a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
830ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
83117ab2063SBarry Smith {
832416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8334846f1f5SKris Buschelman   PetscErrorCode ierr;
8343a40ed3dSBarry Smith 
8353a40ed3dSBarry Smith   PetscFunctionBegin;
836a65d3064SKris Buschelman   switch (op) {
837a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
8384e0d8c25SBarry Smith       a->roworiented       = flg;
839a65d3064SKris Buschelman       break;
840a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
841a9817697SBarry Smith       a->keepnonzeropattern    = flg;
842a65d3064SKris Buschelman       break;
843512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
844512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
845a65d3064SKris Buschelman       break;
846a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
8474e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
848a65d3064SKris Buschelman       break;
849a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
8504e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
851a65d3064SKris Buschelman       break;
85228b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
85328b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
85428b2fa4aSMatthew Knepley       break;
855a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
8564e0d8c25SBarry Smith       a->ignorezeroentries = flg;
8570df259c2SBarry Smith       break;
858cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
859cd6b891eSBarry Smith       a->compressedrow.check = flg;
860d487561eSHong Zhang       break;
8613d472b54SHong Zhang     case MAT_SPD:
8623d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
8633d472b54SHong Zhang       A->spd                             = flg;
8643d472b54SHong Zhang       if (flg) {
8653d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
8663d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
8673d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
8683d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
8693d472b54SHong Zhang       }
8703d472b54SHong Zhang       break;
871b1646e73SJed Brown     case MAT_SYMMETRIC:
872b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
873b1646e73SJed Brown     case MAT_HERMITIAN:
874b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
8754e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
876a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
877a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
878290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
879a65d3064SKris Buschelman       break;
880b87ac2d8SJed Brown     case MAT_USE_INODES:
881b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
882b87ac2d8SJed Brown       break;
883a65d3064SKris Buschelman     default:
884e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
885a65d3064SKris Buschelman   }
8864108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
8873a40ed3dSBarry Smith   PetscFunctionReturn(0);
88817ab2063SBarry Smith }
88917ab2063SBarry Smith 
8904a2ae208SSatish Balay #undef __FUNCT__
8914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
892dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
89317ab2063SBarry Smith {
894416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8956849ba73SBarry Smith   PetscErrorCode ierr;
896d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
89735e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
89817ab2063SBarry Smith 
8993a40ed3dSBarry Smith   PetscFunctionBegin;
900d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
901e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
90235e7444dSHong Zhang 
903d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
904d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
90535e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
90635e7444dSHong Zhang     for (i=0; i<n; i++) x[i] = aa[diag[i]];
90735e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
90835e7444dSHong Zhang     PetscFunctionReturn(0);
90935e7444dSHong Zhang   }
91035e7444dSHong Zhang 
9112dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
9121ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
91335e7444dSHong Zhang   for (i=0; i<n; i++) {
91435e7444dSHong Zhang     nz = ai[i+1] - ai[i];
9152f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
91635e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
91735e7444dSHong Zhang       if (aj[j] == i) {
91835e7444dSHong Zhang         x[i] = aa[j];
91917ab2063SBarry Smith         break;
92017ab2063SBarry Smith       }
92117ab2063SBarry Smith     }
92217ab2063SBarry Smith   }
9231ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
9243a40ed3dSBarry Smith   PetscFunctionReturn(0);
92517ab2063SBarry Smith }
92617ab2063SBarry Smith 
927b377110cSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h"
9284a2ae208SSatish Balay #undef __FUNCT__
9294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
930dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
93117ab2063SBarry Smith {
932416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
9335c897100SBarry Smith   PetscScalar       *x,*y;
934dfbe8321SBarry Smith   PetscErrorCode    ierr;
935d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
9365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
937a77337e4SBarry Smith   MatScalar         *v;
938a77337e4SBarry Smith   PetscScalar       alpha;
93904fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
9403447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
941ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
9425c897100SBarry Smith #endif
94317ab2063SBarry Smith 
9443a40ed3dSBarry Smith   PetscFunctionBegin;
9452e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
9461ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9471ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9485c897100SBarry Smith 
9495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
950bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
9515c897100SBarry Smith #else
9523447b6efSHong Zhang   if (usecprow){
9533447b6efSHong Zhang     m    = cprow.nrows;
9543447b6efSHong Zhang     ii   = cprow.i;
9557b2bb3b9SHong Zhang     ridx = cprow.rindex;
9563447b6efSHong Zhang   } else {
9573447b6efSHong Zhang     ii = a->i;
9583447b6efSHong Zhang   }
95917ab2063SBarry Smith   for (i=0; i<m; i++) {
9603447b6efSHong Zhang     idx   = a->j + ii[i] ;
9613447b6efSHong Zhang     v     = a->a + ii[i] ;
9623447b6efSHong Zhang     n     = ii[i+1] - ii[i];
9633447b6efSHong Zhang     if (usecprow){
9647b2bb3b9SHong Zhang       alpha = x[ridx[i]];
9653447b6efSHong Zhang     } else {
96617ab2063SBarry Smith       alpha = x[i];
9673447b6efSHong Zhang     }
96804fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
96917ab2063SBarry Smith   }
9705c897100SBarry Smith #endif
971dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
9721ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9731ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9743a40ed3dSBarry Smith   PetscFunctionReturn(0);
97517ab2063SBarry Smith }
97617ab2063SBarry Smith 
9774a2ae208SSatish Balay #undef __FUNCT__
9785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
979dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
9805c897100SBarry Smith {
981dfbe8321SBarry Smith   PetscErrorCode ierr;
9825c897100SBarry Smith 
9835c897100SBarry Smith   PetscFunctionBegin;
984170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
9855c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
9865c897100SBarry Smith   PetscFunctionReturn(0);
9875c897100SBarry Smith }
9885c897100SBarry Smith 
989a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h"
9905c897100SBarry Smith #undef __FUNCT__
9914a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
992dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
99317ab2063SBarry Smith {
994416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
995d9fead3dSBarry Smith   PetscScalar       *y;
99654f21887SBarry Smith   const PetscScalar *x;
99754f21887SBarry Smith   const MatScalar   *aa;
998dfbe8321SBarry Smith   PetscErrorCode    ierr;
999003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1000003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
10018aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1002362ced78SSatish Balay   PetscScalar       sum;
1003ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
100417ab2063SBarry Smith 
1005b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
100697952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1007fee21e36SBarry Smith #endif
1008fee21e36SBarry Smith 
10093a40ed3dSBarry Smith   PetscFunctionBegin;
10103649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10111ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
101297952fefSHong Zhang   aj  = a->j;
101397952fefSHong Zhang   aa  = a->a;
1014416022c9SBarry Smith   ii  = a->i;
10154eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
101697952fefSHong Zhang     m    = a->compressedrow.nrows;
101797952fefSHong Zhang     ii   = a->compressedrow.i;
101897952fefSHong Zhang     ridx = a->compressedrow.rindex;
101997952fefSHong Zhang     for (i=0; i<m; i++){
102097952fefSHong Zhang       n   = ii[i+1] - ii[i];
102197952fefSHong Zhang       aj  = a->j + ii[i];
102297952fefSHong Zhang       aa  = a->a + ii[i];
102397952fefSHong Zhang       sum = 0.0;
1024a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1025003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1026003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
102797952fefSHong Zhang       y[*ridx++] = sum;
102897952fefSHong Zhang     }
102997952fefSHong Zhang   } else { /* do not use compressed row format */
1030b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1031b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1032b05257ddSBarry Smith #else
103317ab2063SBarry Smith     for (i=0; i<m; i++) {
1034003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1035003131ecSBarry Smith       aj  = a->j + ii[i];
1036003131ecSBarry Smith       aa  = a->a + ii[i];
103717ab2063SBarry Smith       sum  = 0.0;
1038a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1039003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
104017ab2063SBarry Smith       y[i] = sum;
104117ab2063SBarry Smith     }
10428d195f9aSBarry Smith #endif
1043b05257ddSBarry Smith   }
1044dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
10453649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
10461ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10473a40ed3dSBarry Smith   PetscFunctionReturn(0);
104817ab2063SBarry Smith }
104917ab2063SBarry Smith 
1050a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h"
10514a2ae208SSatish Balay #undef __FUNCT__
10524a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1053dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
105417ab2063SBarry Smith {
1055416022c9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
105654f21887SBarry Smith   PetscScalar     *x,*y,*z;
105754f21887SBarry Smith   const MatScalar *aa;
1058dfbe8321SBarry Smith   PetscErrorCode  ierr;
1059d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1060aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
106197952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1062362ced78SSatish Balay   PetscScalar     sum;
1063ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1064e36a17ebSSatish Balay #endif
10659ea0dfa2SSatish Balay 
10663a40ed3dSBarry Smith   PetscFunctionBegin;
10671ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
10681ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10692e8a6d31SBarry Smith   if (zz != yy) {
10701ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
10712e8a6d31SBarry Smith   } else {
10722e8a6d31SBarry Smith     z = y;
10732e8a6d31SBarry Smith   }
1074bfeeae90SHong Zhang 
107597952fefSHong Zhang   aj  = a->j;
107697952fefSHong Zhang   aa  = a->a;
1077cddf8d76SBarry Smith   ii  = a->i;
1078aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
107997952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
108002ab625aSSatish Balay #else
10814eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
10824eb6d288SHong Zhang     if (zz != yy){
10834eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
10844eb6d288SHong Zhang     }
108597952fefSHong Zhang     m    = a->compressedrow.nrows;
108697952fefSHong Zhang     ii   = a->compressedrow.i;
108797952fefSHong Zhang     ridx = a->compressedrow.rindex;
108897952fefSHong Zhang     for (i=0; i<m; i++){
108997952fefSHong Zhang       n  = ii[i+1] - ii[i];
109097952fefSHong Zhang       aj  = a->j + ii[i];
109197952fefSHong Zhang       aa  = a->a + ii[i];
109297952fefSHong Zhang       sum = y[*ridx];
109397952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
109497952fefSHong Zhang       z[*ridx++] = sum;
109597952fefSHong Zhang     }
109697952fefSHong Zhang   } else { /* do not use compressed row format */
109717ab2063SBarry Smith     for (i=0; i<m; i++) {
10989ea0dfa2SSatish Balay       jrow = ii[i];
10999ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
110017ab2063SBarry Smith       sum  = y[i];
11019ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
110297952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
11039ea0dfa2SSatish Balay       }
110417ab2063SBarry Smith       z[i] = sum;
110517ab2063SBarry Smith     }
110697952fefSHong Zhang   }
110702ab625aSSatish Balay #endif
1108dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11091ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11101ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11112e8a6d31SBarry Smith   if (zz != yy) {
11121ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
11132e8a6d31SBarry Smith   }
1114918e98c3SVictor Minden #if defined(PETSC_HAVE_CUDA)
11156b375ea7SVictor Minden   /*
1116918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1117918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1118918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
11196b375ea7SVictor Minden   */
1120918e98c3SVictor Minden #endif
11213a40ed3dSBarry Smith   PetscFunctionReturn(0);
112217ab2063SBarry Smith }
112317ab2063SBarry Smith 
112417ab2063SBarry Smith /*
112517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
112617ab2063SBarry Smith */
11274a2ae208SSatish Balay #undef __FUNCT__
11284a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1129dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
113017ab2063SBarry Smith {
1131416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11326849ba73SBarry Smith   PetscErrorCode ierr;
1133d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
113417ab2063SBarry Smith 
11353a40ed3dSBarry Smith   PetscFunctionBegin;
113609f38230SBarry Smith   if (!a->diag) {
113709f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
11389518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
113909f38230SBarry Smith   }
1140d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
114109f38230SBarry Smith     a->diag[i] = a->i[i+1];
1142bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1143bfeeae90SHong Zhang       if (a->j[j] == i) {
114409f38230SBarry Smith         a->diag[i] = j;
114517ab2063SBarry Smith         break;
114617ab2063SBarry Smith       }
114717ab2063SBarry Smith     }
114817ab2063SBarry Smith   }
11493a40ed3dSBarry Smith   PetscFunctionReturn(0);
115017ab2063SBarry Smith }
115117ab2063SBarry Smith 
1152be5855fcSBarry Smith /*
1153be5855fcSBarry Smith      Checks for missing diagonals
1154be5855fcSBarry Smith */
11554a2ae208SSatish Balay #undef __FUNCT__
11564a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1157ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1158be5855fcSBarry Smith {
1159be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
116097f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1161be5855fcSBarry Smith 
1162be5855fcSBarry Smith   PetscFunctionBegin;
116309f38230SBarry Smith   *missing = PETSC_FALSE;
1164d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
116509f38230SBarry Smith     *missing  = PETSC_TRUE;
116609f38230SBarry Smith     if (d) *d = 0;
116709f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
116809f38230SBarry Smith   } else {
1169f1e2ffcdSBarry Smith     diag = a->diag;
1170d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1171bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
117209f38230SBarry Smith 	*missing = PETSC_TRUE;
117309f38230SBarry Smith 	if (d) *d = i;
117409f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
117509f38230SBarry Smith       }
1176be5855fcSBarry Smith     }
1177be5855fcSBarry Smith   }
1178be5855fcSBarry Smith   PetscFunctionReturn(0);
1179be5855fcSBarry Smith }
1180be5855fcSBarry Smith 
118171f1c65dSBarry Smith EXTERN_C_BEGIN
118271f1c65dSBarry Smith #undef __FUNCT__
118371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
11847087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
118571f1c65dSBarry Smith {
118671f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
118771f1c65dSBarry Smith   PetscErrorCode ierr;
1188d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
118954f21887SBarry Smith   MatScalar      *v = a->a;
119054f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
119171f1c65dSBarry Smith 
119271f1c65dSBarry Smith   PetscFunctionBegin;
119371f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
119471f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
119571f1c65dSBarry Smith   diag = a->diag;
119671f1c65dSBarry Smith   if (!a->idiag) {
119771f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
119871f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
119971f1c65dSBarry Smith     v        = a->a;
120071f1c65dSBarry Smith   }
120171f1c65dSBarry Smith   mdiag = a->mdiag;
120271f1c65dSBarry Smith   idiag = a->idiag;
120371f1c65dSBarry Smith 
1204028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
120571f1c65dSBarry Smith     for (i=0; i<m; i++) {
120671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1207e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
120871f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
120971f1c65dSBarry Smith     }
121071f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
121171f1c65dSBarry Smith   } else {
121271f1c65dSBarry Smith     for (i=0; i<m; i++) {
121371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
121471f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
121571f1c65dSBarry Smith     }
1216dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
121771f1c65dSBarry Smith   }
121871f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
121971f1c65dSBarry Smith   PetscFunctionReturn(0);
122071f1c65dSBarry Smith }
12215a9745a3SMatthew Knepley EXTERN_C_END
122271f1c65dSBarry Smith 
1223a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/frelax.h"
12244a2ae208SSatish Balay #undef __FUNCT__
122541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
122641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
122717ab2063SBarry Smith {
1228416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1229e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1230e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
123154f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1232dfbe8321SBarry Smith   PetscErrorCode     ierr;
1233d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
123497f1f81fSBarry Smith   const PetscInt     *idx,*diag;
123517ab2063SBarry Smith 
12363a40ed3dSBarry Smith   PetscFunctionBegin;
1237b965ef7fSBarry Smith   its = its*lits;
123891723122SBarry Smith 
123971f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
124071f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
124171f1c65dSBarry Smith   a->fshift = fshift;
124271f1c65dSBarry Smith   a->omega  = omega;
1243ed480e8bSBarry Smith 
124471f1c65dSBarry Smith   diag = a->diag;
124571f1c65dSBarry Smith   t     = a->ssor_work;
1246ed480e8bSBarry Smith   idiag = a->idiag;
124771f1c65dSBarry Smith   mdiag = a->mdiag;
1248ed480e8bSBarry Smith 
12491ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
12503649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
125171f1c65dSBarry Smith   CHKMEMQ;
1252ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
125317ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
125417ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1255ed480e8bSBarry Smith     bs = b;
125617ab2063SBarry Smith     for (i=0; i<m; i++) {
125771f1c65dSBarry Smith         d    = fshift + mdiag[i];
1258416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1259ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1260ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
126117ab2063SBarry Smith         sum  = b[i]*d/omega;
1262003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
126317ab2063SBarry Smith         x[i] = sum;
126417ab2063SBarry Smith     }
12651ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12663649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1267efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
12683a40ed3dSBarry Smith     PetscFunctionReturn(0);
126917ab2063SBarry Smith   }
1270c783ea89SBarry Smith 
127148af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1272e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
12733a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
127417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1275887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
127617ab2063SBarry Smith 
127717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
127817ab2063SBarry Smith 
1279887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
128017ab2063SBarry Smith     */
128117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
128217ab2063SBarry Smith 
128317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
128417ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1285416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1286ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1287ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
128817ab2063SBarry Smith       sum  = b[i];
1289e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1290ed480e8bSBarry Smith       x[i] = sum*idiag[i];
129117ab2063SBarry Smith     }
129217ab2063SBarry Smith 
129317ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1294416022c9SBarry Smith     v = a->a;
1295ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
129617ab2063SBarry Smith 
129717ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1298ed480e8bSBarry Smith     ts = t;
1299416022c9SBarry Smith     diag = a->diag;
130017ab2063SBarry Smith     for (i=0; i<m; i++) {
1301416022c9SBarry Smith       n    = diag[i] - a->i[i];
1302ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1303ed480e8bSBarry Smith       v    = a->a + a->i[i];
130417ab2063SBarry Smith       sum  = t[i];
1305003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1306ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1307733d66baSBarry Smith       /*  x = x + t */
1308733d66baSBarry Smith       x[i] += t[i];
130917ab2063SBarry Smith     }
131017ab2063SBarry Smith 
1311dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
13121ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13133649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
13143a40ed3dSBarry Smith     PetscFunctionReturn(0);
131517ab2063SBarry Smith   }
131617ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
131717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
131817ab2063SBarry Smith       for (i=0; i<m; i++) {
1319416022c9SBarry Smith         n    = diag[i] - a->i[i];
1320ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1321ed480e8bSBarry Smith         v    = a->a + a->i[i];
132217ab2063SBarry Smith         sum  = b[i];
1323e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13245c99c7daSBarry Smith         t[i] = sum;
1325ed480e8bSBarry Smith         x[i] = sum*idiag[i];
132617ab2063SBarry Smith       }
13275c99c7daSBarry Smith       xb = t;
1328efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13293a40ed3dSBarry Smith     } else xb = b;
133017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
133117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1332416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1333ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1334ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
133517ab2063SBarry Smith         sum  = xb[i];
1336e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13375c99c7daSBarry Smith         if (xb == b) {
1338ed480e8bSBarry Smith           x[i] = sum*idiag[i];
13395c99c7daSBarry Smith         } else {
13405c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
134117ab2063SBarry Smith         }
13425c99c7daSBarry Smith       }
1343efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
134417ab2063SBarry Smith     }
134517ab2063SBarry Smith     its--;
134617ab2063SBarry Smith   }
134717ab2063SBarry Smith   while (its--) {
134817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
134917ab2063SBarry Smith       for (i=0; i<m; i++) {
1350416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1351ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1352ed480e8bSBarry Smith         v    = a->a + a->i[i];
135317ab2063SBarry Smith         sum  = b[i];
1354e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1355ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
135617ab2063SBarry Smith       }
13579f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
135817ab2063SBarry Smith     }
135917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
136017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1361416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1362ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1363ed480e8bSBarry Smith         v    = a->a + a->i[i];
136417ab2063SBarry Smith         sum  = b[i];
1365e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1366ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
136717ab2063SBarry Smith       }
13689f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
136917ab2063SBarry Smith     }
137017ab2063SBarry Smith   }
13711ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13723649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
137371f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
137417ab2063SBarry Smith }
137517ab2063SBarry Smith 
13762af78befSBarry Smith 
13774a2ae208SSatish Balay #undef __FUNCT__
13784a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1379dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
138017ab2063SBarry Smith {
1381416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
13824e220ebcSLois Curfman McInnes 
13833a40ed3dSBarry Smith   PetscFunctionBegin;
13844e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
13854e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
13864e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
13874e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
13884e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
13898e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
13907adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1391d5f3da31SBarry Smith   if (A->factortype) {
13924e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
13934e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
13944e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
13954e220ebcSLois Curfman McInnes   } else {
13964e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
13974e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
13984e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
13994e220ebcSLois Curfman McInnes   }
14003a40ed3dSBarry Smith   PetscFunctionReturn(0);
140117ab2063SBarry Smith }
140217ab2063SBarry Smith 
14034a2ae208SSatish Balay #undef __FUNCT__
14044a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
14052b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
140617ab2063SBarry Smith {
1407416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14083b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
14096849ba73SBarry Smith   PetscErrorCode    ierr;
141097b48c8fSBarry Smith   const PetscScalar *xx;
141197b48c8fSBarry Smith   PetscScalar       *bb;
1412ace3abfcSBarry Smith   PetscBool         missing;
141317ab2063SBarry Smith 
14143a40ed3dSBarry Smith   PetscFunctionBegin;
141597b48c8fSBarry Smith   if (x && b) {
141697b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
141797b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
141897b48c8fSBarry Smith     for (i=0; i<N; i++) {
141997b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
142097b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
142197b48c8fSBarry Smith     }
142297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
142397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
142497b48c8fSBarry Smith   }
142597b48c8fSBarry Smith 
1426a9817697SBarry Smith   if (a->keepnonzeropattern) {
1427f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1428e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1429bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1430f1e2ffcdSBarry Smith     }
1431f4df32b1SMatthew Knepley     if (diag != 0.0) {
143209f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1433e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1434f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1435f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1436f1e2ffcdSBarry Smith       }
1437f1e2ffcdSBarry Smith     }
143888e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1439f1e2ffcdSBarry Smith   } else {
1440f4df32b1SMatthew Knepley     if (diag != 0.0) {
144117ab2063SBarry Smith       for (i=0; i<N; i++) {
1442e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
14437ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1444416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1445f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1446bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
14477ae801bdSBarry Smith         } else { /* in case row was completely empty */
1448f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
144917ab2063SBarry Smith         }
145017ab2063SBarry Smith       }
14513a40ed3dSBarry Smith     } else {
145217ab2063SBarry Smith       for (i=0; i<N; i++) {
1453e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1454416022c9SBarry Smith         a->ilen[rows[i]] = 0;
145517ab2063SBarry Smith       }
145617ab2063SBarry Smith     }
145788e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1458f1e2ffcdSBarry Smith   }
145943a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14603a40ed3dSBarry Smith   PetscFunctionReturn(0);
146117ab2063SBarry Smith }
146217ab2063SBarry Smith 
14634a2ae208SSatish Balay #undef __FUNCT__
14646e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
14656e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
14666e169961SBarry Smith {
14676e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14686e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
14696e169961SBarry Smith   PetscErrorCode    ierr;
14702b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
14716e169961SBarry Smith   const PetscScalar *xx;
14726e169961SBarry Smith   PetscScalar       *bb;
14736e169961SBarry Smith 
14746e169961SBarry Smith   PetscFunctionBegin;
14756e169961SBarry Smith   if (x && b) {
14766e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
14776e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
14782b40b63fSBarry Smith     vecs = PETSC_TRUE;
14796e169961SBarry Smith   }
14806e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
14816e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
14826e169961SBarry Smith   for (i=0; i<N; i++) {
14836e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
14846e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
14856e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
14866e169961SBarry Smith   }
14876e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
14886e169961SBarry Smith     if (!zeroed[i]) {
14896e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
14906e169961SBarry Smith         if (zeroed[a->j[j]]) {
14912b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
14926e169961SBarry Smith           a->a[j] = 0.0;
14936e169961SBarry Smith         }
14946e169961SBarry Smith       }
14952b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
14966e169961SBarry Smith   }
14976e169961SBarry Smith   if (x && b) {
14986e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
14996e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
15006e169961SBarry Smith   }
15016e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
15026e169961SBarry Smith   if (diag != 0.0) {
15036e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
15046e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
15056e169961SBarry Smith     for (i=0; i<N; i++) {
15066e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
15076e169961SBarry Smith     }
15086e169961SBarry Smith   }
15096e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
15106e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15116e169961SBarry Smith   PetscFunctionReturn(0);
15126e169961SBarry Smith }
15136e169961SBarry Smith 
15146e169961SBarry Smith #undef __FUNCT__
15154a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1516a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
151717ab2063SBarry Smith {
1518416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
151997f1f81fSBarry Smith   PetscInt   *itmp;
152017ab2063SBarry Smith 
15213a40ed3dSBarry Smith   PetscFunctionBegin;
1522e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
152317ab2063SBarry Smith 
1524416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1525bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
152617ab2063SBarry Smith   if (idx) {
1527bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1528bfeeae90SHong Zhang     if (*nz) {
15294e093b46SBarry Smith       *idx = itmp;
153017ab2063SBarry Smith     }
153117ab2063SBarry Smith     else *idx = 0;
153217ab2063SBarry Smith   }
15333a40ed3dSBarry Smith   PetscFunctionReturn(0);
153417ab2063SBarry Smith }
153517ab2063SBarry Smith 
1536bfeeae90SHong Zhang /* remove this function? */
15374a2ae208SSatish Balay #undef __FUNCT__
15384a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1539a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
154017ab2063SBarry Smith {
15413a40ed3dSBarry Smith   PetscFunctionBegin;
15423a40ed3dSBarry Smith   PetscFunctionReturn(0);
154317ab2063SBarry Smith }
154417ab2063SBarry Smith 
15454a2ae208SSatish Balay #undef __FUNCT__
15464a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1547dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
154817ab2063SBarry Smith {
1549416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
155054f21887SBarry Smith   MatScalar      *v = a->a;
155136db0b34SBarry Smith   PetscReal      sum = 0.0;
15526849ba73SBarry Smith   PetscErrorCode ierr;
155397f1f81fSBarry Smith   PetscInt       i,j;
155417ab2063SBarry Smith 
15553a40ed3dSBarry Smith   PetscFunctionBegin;
155617ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1557416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1558aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
155936db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
156017ab2063SBarry Smith #else
156117ab2063SBarry Smith       sum += (*v)*(*v); v++;
156217ab2063SBarry Smith #endif
156317ab2063SBarry Smith     }
1564064f8208SBarry Smith     *nrm = sqrt(sum);
15653a40ed3dSBarry Smith   } else if (type == NORM_1) {
156636db0b34SBarry Smith     PetscReal *tmp;
156797f1f81fSBarry Smith     PetscInt    *jj = a->j;
1568d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1569d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1570064f8208SBarry Smith     *nrm = 0.0;
1571416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1572bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
157317ab2063SBarry Smith     }
1574d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1575064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
157617ab2063SBarry Smith     }
1577606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
15783a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1579064f8208SBarry Smith     *nrm = 0.0;
1580d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1581bfeeae90SHong Zhang       v = a->a + a->i[j];
158217ab2063SBarry Smith       sum = 0.0;
1583416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1584cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
158517ab2063SBarry Smith       }
1586064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
158717ab2063SBarry Smith     }
15883a40ed3dSBarry Smith   } else {
1589e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
159017ab2063SBarry Smith   }
15913a40ed3dSBarry Smith   PetscFunctionReturn(0);
159217ab2063SBarry Smith }
159317ab2063SBarry Smith 
15944a2ae208SSatish Balay #undef __FUNCT__
15954a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1596fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
159717ab2063SBarry Smith {
1598416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1599416022c9SBarry Smith   Mat            C;
16006849ba73SBarry Smith   PetscErrorCode ierr;
1601d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
160254f21887SBarry Smith   MatScalar      *array = a->a;
160317ab2063SBarry Smith 
16043a40ed3dSBarry Smith   PetscFunctionBegin;
1605e32f2f54SBarry Smith   if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1606fc4dec0aSBarry Smith 
1607fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1608d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1609d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1610bfeeae90SHong Zhang 
1611bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
16127adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1613d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
16147adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1615ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1616606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1617a541d17aSBarry Smith   } else {
1618a541d17aSBarry Smith     C = *B;
1619a541d17aSBarry Smith   }
1620a541d17aSBarry Smith 
162117ab2063SBarry Smith   for (i=0; i<m; i++) {
162217ab2063SBarry Smith     len    = ai[i+1]-ai[i];
162387d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1624b9b97703SBarry Smith     array += len;
1625b9b97703SBarry Smith     aj    += len;
162617ab2063SBarry Smith   }
16276d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16286d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
162917ab2063SBarry Smith 
1630815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1631416022c9SBarry Smith     *B = C;
163217ab2063SBarry Smith   } else {
1633eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
163417ab2063SBarry Smith   }
16353a40ed3dSBarry Smith   PetscFunctionReturn(0);
163617ab2063SBarry Smith }
163717ab2063SBarry Smith 
1638cd0d46ebSvictorle EXTERN_C_BEGIN
1639cd0d46ebSvictorle #undef __FUNCT__
16405fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
16417087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1642cd0d46ebSvictorle {
1643cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
164454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
164554f21887SBarry Smith   MatScalar      *va,*vb;
16466849ba73SBarry Smith   PetscErrorCode ierr;
164797f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1648cd0d46ebSvictorle 
1649cd0d46ebSvictorle   PetscFunctionBegin;
1650cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1651cd0d46ebSvictorle 
1652cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1653cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
16545485867bSBarry Smith   if (ma!=nb || na!=mb){
16555485867bSBarry Smith     *f = PETSC_FALSE;
16565485867bSBarry Smith     PetscFunctionReturn(0);
16575485867bSBarry Smith   }
1658cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1659cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1660cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
166197f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
166297f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1663cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1664cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1665cd0d46ebSvictorle 
1666cd0d46ebSvictorle   *f = PETSC_TRUE;
1667cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1668cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
166997f1f81fSBarry Smith       PetscInt         idc,idr;
16705485867bSBarry Smith       PetscScalar vc,vr;
1671cd0d46ebSvictorle       /* column/row index/value */
16725485867bSBarry Smith       idc = adx[aptr[i]];
16735485867bSBarry Smith       idr = bdx[bptr[idc]];
16745485867bSBarry Smith       vc  = va[aptr[i]];
16755485867bSBarry Smith       vr  = vb[bptr[idc]];
16765485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
16775485867bSBarry Smith 	*f = PETSC_FALSE;
16785485867bSBarry Smith         goto done;
1679cd0d46ebSvictorle       } else {
16805485867bSBarry Smith 	aptr[i]++;
16815485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1682cd0d46ebSvictorle       }
1683cd0d46ebSvictorle     }
1684cd0d46ebSvictorle   }
1685cd0d46ebSvictorle  done:
1686cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
16873aeef889SHong Zhang   if (B) {
16883aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
16893aeef889SHong Zhang   }
1690cd0d46ebSvictorle   PetscFunctionReturn(0);
1691cd0d46ebSvictorle }
1692cd0d46ebSvictorle EXTERN_C_END
1693cd0d46ebSvictorle 
16941cbb95d3SBarry Smith EXTERN_C_BEGIN
16951cbb95d3SBarry Smith #undef __FUNCT__
16961cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
16977087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
16981cbb95d3SBarry Smith {
16991cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
170054f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
170154f21887SBarry Smith   MatScalar      *va,*vb;
17021cbb95d3SBarry Smith   PetscErrorCode ierr;
17031cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
17041cbb95d3SBarry Smith 
17051cbb95d3SBarry Smith   PetscFunctionBegin;
17061cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
17071cbb95d3SBarry Smith 
17081cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
17091cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17101cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
17111cbb95d3SBarry Smith     *f = PETSC_FALSE;
17121cbb95d3SBarry Smith     PetscFunctionReturn(0);
17131cbb95d3SBarry Smith   }
17141cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
17151cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
17161cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
17171cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
17181cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
17191cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
17201cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
17211cbb95d3SBarry Smith 
17221cbb95d3SBarry Smith   *f = PETSC_TRUE;
17231cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
17241cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
17251cbb95d3SBarry Smith       PetscInt         idc,idr;
17261cbb95d3SBarry Smith       PetscScalar vc,vr;
17271cbb95d3SBarry Smith       /* column/row index/value */
17281cbb95d3SBarry Smith       idc = adx[aptr[i]];
17291cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
17301cbb95d3SBarry Smith       vc  = va[aptr[i]];
17311cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
17321cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
17331cbb95d3SBarry Smith 	*f = PETSC_FALSE;
17341cbb95d3SBarry Smith         goto done;
17351cbb95d3SBarry Smith       } else {
17361cbb95d3SBarry Smith 	aptr[i]++;
17371cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
17381cbb95d3SBarry Smith       }
17391cbb95d3SBarry Smith     }
17401cbb95d3SBarry Smith   }
17411cbb95d3SBarry Smith  done:
17421cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
17431cbb95d3SBarry Smith   if (B) {
17441cbb95d3SBarry Smith     ierr = PetscFree(bptr);CHKERRQ(ierr);
17451cbb95d3SBarry Smith   }
17461cbb95d3SBarry Smith   PetscFunctionReturn(0);
17471cbb95d3SBarry Smith }
17481cbb95d3SBarry Smith EXTERN_C_END
17491cbb95d3SBarry Smith 
17509e29f15eSvictorle #undef __FUNCT__
17519e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1752ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
17539e29f15eSvictorle {
1754dfbe8321SBarry Smith   PetscErrorCode ierr;
17559e29f15eSvictorle   PetscFunctionBegin;
17565485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
17579e29f15eSvictorle   PetscFunctionReturn(0);
17589e29f15eSvictorle }
17599e29f15eSvictorle 
17604a2ae208SSatish Balay #undef __FUNCT__
17611cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
1762ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
17631cbb95d3SBarry Smith {
17641cbb95d3SBarry Smith   PetscErrorCode ierr;
17651cbb95d3SBarry Smith   PetscFunctionBegin;
17661cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
17671cbb95d3SBarry Smith   PetscFunctionReturn(0);
17681cbb95d3SBarry Smith }
17691cbb95d3SBarry Smith 
17701cbb95d3SBarry Smith #undef __FUNCT__
17714a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1772dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
177317ab2063SBarry Smith {
1774416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
177554f21887SBarry Smith   PetscScalar    *l,*r,x;
177654f21887SBarry Smith   MatScalar      *v;
1777dfbe8321SBarry Smith   PetscErrorCode ierr;
1778d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
177917ab2063SBarry Smith 
17803a40ed3dSBarry Smith   PetscFunctionBegin;
178117ab2063SBarry Smith   if (ll) {
17823ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
17833ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1784e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1785e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
17861ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1787416022c9SBarry Smith     v = a->a;
178817ab2063SBarry Smith     for (i=0; i<m; i++) {
178917ab2063SBarry Smith       x = l[i];
1790416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
179117ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
179217ab2063SBarry Smith     }
17931ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1794efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
179517ab2063SBarry Smith   }
179617ab2063SBarry Smith   if (rr) {
1797e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1798e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
17991ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1800416022c9SBarry Smith     v = a->a; jj = a->j;
180117ab2063SBarry Smith     for (i=0; i<nz; i++) {
1802bfeeae90SHong Zhang       (*v++) *= r[*jj++];
180317ab2063SBarry Smith     }
18041ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1805efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
180617ab2063SBarry Smith   }
18073a40ed3dSBarry Smith   PetscFunctionReturn(0);
180817ab2063SBarry Smith }
180917ab2063SBarry Smith 
18104a2ae208SSatish Balay #undef __FUNCT__
18114a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
181297f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
181317ab2063SBarry Smith {
1814db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
18156849ba73SBarry Smith   PetscErrorCode ierr;
1816d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
181797f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
18185d0c19d7SBarry Smith   const PetscInt *irow,*icol;
18195d0c19d7SBarry Smith   PetscInt       nrows,ncols;
182097f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
182154f21887SBarry Smith   MatScalar      *a_new,*mat_a;
1822416022c9SBarry Smith   Mat            C;
1823ace3abfcSBarry Smith   PetscBool      stride,sorted;
182417ab2063SBarry Smith 
18253a40ed3dSBarry Smith   PetscFunctionBegin;
182614ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
1827e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
182814ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
1829e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
183099141d43SSatish Balay 
183117ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1832b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1833b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
183417ab2063SBarry Smith 
1835fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
18360dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
1837fee21e36SBarry Smith   if (stride && step == 1) {
183802834360SBarry Smith     /* special case of contiguous rows */
18390e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
184002834360SBarry Smith     /* loop over new rows determining lens and starting points */
184102834360SBarry Smith     for (i=0; i<nrows; i++) {
1842bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1843a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
184402834360SBarry Smith       for (k=kstart; k<kend; k++) {
1845bfeeae90SHong Zhang         if (aj[k] >= first) {
184602834360SBarry Smith           starts[i] = k;
184702834360SBarry Smith           break;
184802834360SBarry Smith 	}
184902834360SBarry Smith       }
1850a2744918SBarry Smith       sum = 0;
185102834360SBarry Smith       while (k < kend) {
1852bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1853a2744918SBarry Smith         sum++;
185402834360SBarry Smith       }
1855a2744918SBarry Smith       lens[i] = sum;
185602834360SBarry Smith     }
185702834360SBarry Smith     /* create submatrix */
1858cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
185997f1f81fSBarry Smith       PetscInt n_cols,n_rows;
186008480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1861e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1862d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
186308480c60SBarry Smith       C = *B;
18643a40ed3dSBarry Smith     } else {
18657adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1866f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
18677adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1868ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
186908480c60SBarry Smith     }
1870db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1871db02288aSLois Curfman McInnes 
187202834360SBarry Smith     /* loop over rows inserting into submatrix */
1873db02288aSLois Curfman McInnes     a_new    = c->a;
1874db02288aSLois Curfman McInnes     j_new    = c->j;
1875db02288aSLois Curfman McInnes     i_new    = c->i;
1876bfeeae90SHong Zhang 
187702834360SBarry Smith     for (i=0; i<nrows; i++) {
1878a2744918SBarry Smith       ii    = starts[i];
1879a2744918SBarry Smith       lensi = lens[i];
1880a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1881a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
188202834360SBarry Smith       }
188387828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1884a2744918SBarry Smith       a_new      += lensi;
1885a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1886a2744918SBarry Smith       c->ilen[i]  = lensi;
188702834360SBarry Smith     }
18880e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
18893a40ed3dSBarry Smith   } else {
189002834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
18910e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
189297f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
18930e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
189417ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
189502834360SBarry Smith     /* determine lens of each row */
189602834360SBarry Smith     for (i=0; i<nrows; i++) {
1897bfeeae90SHong Zhang       kstart  = ai[irow[i]];
189802834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
189902834360SBarry Smith       lens[i] = 0;
190002834360SBarry Smith       for (k=kstart; k<kend; k++) {
1901bfeeae90SHong Zhang         if (smap[aj[k]]) {
190202834360SBarry Smith           lens[i]++;
190302834360SBarry Smith         }
190402834360SBarry Smith       }
190502834360SBarry Smith     }
190617ab2063SBarry Smith     /* Create and fill new matrix */
1907a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1908ace3abfcSBarry Smith       PetscBool  equal;
19090f5bd95cSBarry Smith 
191099141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1911e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1912d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
19130f5bd95cSBarry Smith       if (!equal) {
1914e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
191599141d43SSatish Balay       }
1916d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
191708480c60SBarry Smith       C = *B;
19183a40ed3dSBarry Smith     } else {
19197adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1920f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19217adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1922ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
192308480c60SBarry Smith     }
192499141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
192517ab2063SBarry Smith     for (i=0; i<nrows; i++) {
192699141d43SSatish Balay       row    = irow[i];
1927bfeeae90SHong Zhang       kstart = ai[row];
192899141d43SSatish Balay       kend   = kstart + a->ilen[row];
1929bfeeae90SHong Zhang       mat_i  = c->i[i];
193099141d43SSatish Balay       mat_j  = c->j + mat_i;
193199141d43SSatish Balay       mat_a  = c->a + mat_i;
193299141d43SSatish Balay       mat_ilen = c->ilen + i;
193317ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1934bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1935ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
193699141d43SSatish Balay           *mat_a++ = a->a[k];
193799141d43SSatish Balay           (*mat_ilen)++;
193899141d43SSatish Balay 
193917ab2063SBarry Smith         }
194017ab2063SBarry Smith       }
194117ab2063SBarry Smith     }
194202834360SBarry Smith     /* Free work space */
194302834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1944606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1945606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
194602834360SBarry Smith   }
19476d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19486d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
194917ab2063SBarry Smith 
195017ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1951416022c9SBarry Smith   *B = C;
19523a40ed3dSBarry Smith   PetscFunctionReturn(0);
195317ab2063SBarry Smith }
195417ab2063SBarry Smith 
19551df811f5SHong Zhang #undef __FUNCT__
195682d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
195782d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
195882d44351SHong Zhang {
195982d44351SHong Zhang   PetscErrorCode ierr;
196082d44351SHong Zhang   Mat            B;
196182d44351SHong Zhang 
196282d44351SHong Zhang   PetscFunctionBegin;
196382d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
196482d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
196582d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
196682d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
196782d44351SHong Zhang   *subMat = B;
196882d44351SHong Zhang   PetscFunctionReturn(0);
196982d44351SHong Zhang }
197082d44351SHong Zhang 
197182d44351SHong Zhang #undef __FUNCT__
19724a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
19730481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
1974a871dcd8SBarry Smith {
197563b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
1976dfbe8321SBarry Smith   PetscErrorCode ierr;
197763b91edcSBarry Smith   Mat            outA;
1978ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
197963b91edcSBarry Smith 
19803a40ed3dSBarry Smith   PetscFunctionBegin;
1981e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
19821df811f5SHong Zhang 
1983b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1984b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1985a871dcd8SBarry Smith 
198663b91edcSBarry Smith   outA              = inA;
1987d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
1988c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1989c3122656SLisandro Dalcin   if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr);}
1990c3122656SLisandro Dalcin   a->row = row;
1991c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1992c3122656SLisandro Dalcin   if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr);}
1993c3122656SLisandro Dalcin   a->col = col;
199463b91edcSBarry Smith 
199536db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1996b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
19974c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
199852e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
1999f0ec6fceSSatish Balay 
200094a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2001d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2002d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
200394a9d846SBarry Smith   }
200463b91edcSBarry Smith 
2005f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2006137fb511SHong Zhang   if (row_identity && col_identity) {
2007ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2008137fb511SHong Zhang   } else {
2009719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2010137fb511SHong Zhang   }
20113a40ed3dSBarry Smith   PetscFunctionReturn(0);
2012a871dcd8SBarry Smith }
2013a871dcd8SBarry Smith 
20144a2ae208SSatish Balay #undef __FUNCT__
20154a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2016f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2017f0b747eeSBarry Smith {
2018f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2019f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2020efee365bSSatish Balay   PetscErrorCode ierr;
20210805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
20223a40ed3dSBarry Smith 
20233a40ed3dSBarry Smith   PetscFunctionBegin;
2024f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2025efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20263a40ed3dSBarry Smith   PetscFunctionReturn(0);
2027f0b747eeSBarry Smith }
2028f0b747eeSBarry Smith 
20294a2ae208SSatish Balay #undef __FUNCT__
20304a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
203197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2032cddf8d76SBarry Smith {
2033dfbe8321SBarry Smith   PetscErrorCode ierr;
203497f1f81fSBarry Smith   PetscInt       i;
2035cddf8d76SBarry Smith 
20363a40ed3dSBarry Smith   PetscFunctionBegin;
2037cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2038b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2039cddf8d76SBarry Smith   }
2040cddf8d76SBarry Smith 
2041cddf8d76SBarry Smith   for (i=0; i<n; i++) {
20426a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2043cddf8d76SBarry Smith   }
20443a40ed3dSBarry Smith   PetscFunctionReturn(0);
2045cddf8d76SBarry Smith }
2046cddf8d76SBarry Smith 
20474a2ae208SSatish Balay #undef __FUNCT__
20484a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
204997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
20504dcbc457SBarry Smith {
2051e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
20526849ba73SBarry Smith   PetscErrorCode ierr;
20535d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
20545d0c19d7SBarry Smith   const PetscInt *idx;
205597f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2056f1af5d2fSBarry Smith   PetscBT        table;
2057bbd702dbSSatish Balay 
20583a40ed3dSBarry Smith   PetscFunctionBegin;
2059d0f46423SBarry Smith   m     = A->rmap->n;
2060e4d965acSSatish Balay   ai    = a->i;
2061bfeeae90SHong Zhang   aj    = a->j;
20628a047759SSatish Balay 
2063e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
206406763907SSatish Balay 
206597f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
20666831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
206706763907SSatish Balay 
2068e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2069b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2070e4d965acSSatish Balay     isz  = 0;
20716831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2072e4d965acSSatish Balay 
2073e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
20744dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2075b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2076e4d965acSSatish Balay 
2077dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2078e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2079f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
20804dcbc457SBarry Smith     }
208106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
208206763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
2083e4d965acSSatish Balay 
208404a348a9SBarry Smith     k = 0;
208504a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
208604a348a9SBarry Smith       n = isz;
208706763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2088e4d965acSSatish Balay         row   = nidx[k];
2089e4d965acSSatish Balay         start = ai[row];
2090e4d965acSSatish Balay         end   = ai[row+1];
209104a348a9SBarry Smith         for (l = start; l<end ; l++){
2092efb16452SHong Zhang           val = aj[l] ;
2093f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2094e4d965acSSatish Balay         }
2095e4d965acSSatish Balay       }
2096e4d965acSSatish Balay     }
209770b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2098e4d965acSSatish Balay   }
20996831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2100606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
21013a40ed3dSBarry Smith   PetscFunctionReturn(0);
21024dcbc457SBarry Smith }
210317ab2063SBarry Smith 
21040513a670SBarry Smith /* -------------------------------------------------------------- */
21054a2ae208SSatish Balay #undef __FUNCT__
21064a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2107dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
21080513a670SBarry Smith {
21090513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21106849ba73SBarry Smith   PetscErrorCode ierr;
21113b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
21125d0c19d7SBarry Smith   const PetscInt *row,*col;
21135d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
211456cd22aeSBarry Smith   IS             icolp,irowp;
21153b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
21163b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
21170513a670SBarry Smith 
21183a40ed3dSBarry Smith   PetscFunctionBegin;
21194c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
212056cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
21214c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
212256cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
21230513a670SBarry Smith 
21240513a670SBarry Smith   /* determine lengths of permuted rows */
212597f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
21260513a670SBarry Smith   for (i=0; i<m; i++) {
21270513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
21280513a670SBarry Smith   }
21297adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2130f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
21317adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2132ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2133606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
21340513a670SBarry Smith 
213597f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
21360513a670SBarry Smith   for (i=0; i<m; i++) {
213732ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
21380513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2139cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
214032ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
21410513a670SBarry Smith   }
2142606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
21433c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
21440513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21450513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
214656cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
214756cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
214856cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
214956cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
21503a40ed3dSBarry Smith   PetscFunctionReturn(0);
21510513a670SBarry Smith }
21520513a670SBarry Smith 
21534a2ae208SSatish Balay #undef __FUNCT__
21544a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2155dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2156cb5b572fSBarry Smith {
2157dfbe8321SBarry Smith   PetscErrorCode ierr;
2158cb5b572fSBarry Smith 
2159cb5b572fSBarry Smith   PetscFunctionBegin;
216033f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
216133f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2162be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2163be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2164be6bf707SBarry Smith 
2165700c5bfcSBarry Smith     if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different");
2166d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2167cb5b572fSBarry Smith   } else {
2168cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2169cb5b572fSBarry Smith   }
2170cb5b572fSBarry Smith   PetscFunctionReturn(0);
2171cb5b572fSBarry Smith }
2172cb5b572fSBarry Smith 
21734a2ae208SSatish Balay #undef __FUNCT__
21744a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2175dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2176273d9f13SBarry Smith {
2177dfbe8321SBarry Smith   PetscErrorCode ierr;
2178273d9f13SBarry Smith 
2179273d9f13SBarry Smith   PetscFunctionBegin;
2180ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2181273d9f13SBarry Smith   PetscFunctionReturn(0);
2182273d9f13SBarry Smith }
2183273d9f13SBarry Smith 
21844a2ae208SSatish Balay #undef __FUNCT__
21854a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2186a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
21876c0721eeSBarry Smith {
21886c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
21896c0721eeSBarry Smith   PetscFunctionBegin;
21906c0721eeSBarry Smith   *array = a->a;
21916c0721eeSBarry Smith   PetscFunctionReturn(0);
21926c0721eeSBarry Smith }
21936c0721eeSBarry Smith 
21944a2ae208SSatish Balay #undef __FUNCT__
21954a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2196dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
21976c0721eeSBarry Smith {
21986c0721eeSBarry Smith   PetscFunctionBegin;
21996c0721eeSBarry Smith   PetscFunctionReturn(0);
22006c0721eeSBarry Smith }
2201273d9f13SBarry Smith 
2202ee4f033dSBarry Smith #undef __FUNCT__
2203ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2204dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2205ee4f033dSBarry Smith {
22066849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
22076849ba73SBarry Smith   PetscErrorCode ierr;
220897f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2209efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
221087828ca2SBarry Smith   PetscScalar    *vscale_array;
2211ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2212ee4f033dSBarry Smith   Vec            w1,w2,w3;
2213ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2214ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2215ee4f033dSBarry Smith 
2216ee4f033dSBarry Smith   PetscFunctionBegin;
2217ee4f033dSBarry Smith   if (!coloring->w1) {
2218ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
221952e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2220ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
222152e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2222ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
222352e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2224ee4f033dSBarry Smith   }
2225ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2226ee4f033dSBarry Smith 
2227ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2228acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2229ee4f033dSBarry Smith   if (flg) {
2230ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2231ee4f033dSBarry Smith   } else {
2232ace3abfcSBarry Smith     PetscBool  assembled;
22330b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
22340b9b6f31SBarry Smith     if (assembled) {
2235ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2236ee4f033dSBarry Smith     }
22370b9b6f31SBarry Smith   }
2238ee4f033dSBarry Smith 
2239ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2240ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2241ee4f033dSBarry Smith 
2242ee4f033dSBarry Smith   /*
2243ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2244ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2245ee4f033dSBarry Smith   */
2246ee4f033dSBarry Smith   if (coloring->F) {
2247ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2248ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2249ee4f033dSBarry Smith     if (m1 != m2) {
2250ee4f033dSBarry Smith       coloring->F = 0;
2251ee4f033dSBarry Smith     }
2252ee4f033dSBarry Smith   }
2253ee4f033dSBarry Smith 
2254ee4f033dSBarry Smith   if (coloring->F) {
2255ee4f033dSBarry Smith     w1          = coloring->F;
2256ee4f033dSBarry Smith     coloring->F = 0;
2257ee4f033dSBarry Smith   } else {
225866f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2259ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
226066f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2261ee4f033dSBarry Smith   }
2262ee4f033dSBarry Smith 
2263ee4f033dSBarry Smith   /*
2264ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2265ee4f033dSBarry Smith   */
22661ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
22671ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2268ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2269ee4f033dSBarry Smith     /*
2270ee4f033dSBarry Smith        Loop over each column associated with color adding the
2271ee4f033dSBarry Smith        perturbation to the vector w3.
2272ee4f033dSBarry Smith     */
2273ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2274ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2275ee4f033dSBarry Smith       dx  = xx[col];
2276ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2277ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2278ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2279ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2280ee4f033dSBarry Smith #else
2281ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2282ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2283ee4f033dSBarry Smith #endif
2284ee4f033dSBarry Smith       dx                *= epsilon;
2285ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2286ee4f033dSBarry Smith     }
2287ee4f033dSBarry Smith   }
22881ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2289ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2290ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2291ee4f033dSBarry Smith 
2292ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2293ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2294ee4f033dSBarry Smith 
2295ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2296ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2297ee4f033dSBarry Smith 
22981ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2299ee4f033dSBarry Smith   /*
2300ee4f033dSBarry Smith       Loop over each color
2301ee4f033dSBarry Smith   */
2302ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
230349b058dcSBarry Smith     coloring->currentcolor = k;
2304ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
23051ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2306ee4f033dSBarry Smith     /*
2307ee4f033dSBarry Smith        Loop over each column associated with color adding the
2308ee4f033dSBarry Smith        perturbation to the vector w3.
2309ee4f033dSBarry Smith     */
2310ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2311ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2312ee4f033dSBarry Smith       dx  = xx[col];
23135b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2314ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2315ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2316ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2317ee4f033dSBarry Smith #else
2318ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2319ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2320ee4f033dSBarry Smith #endif
2321ee4f033dSBarry Smith       dx            *= epsilon;
2322e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2323ee4f033dSBarry Smith       w3_array[col] += dx;
2324ee4f033dSBarry Smith     }
23251ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2326ee4f033dSBarry Smith 
2327ee4f033dSBarry Smith     /*
2328ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2329ee4f033dSBarry Smith     */
2330ee4f033dSBarry Smith 
233166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2332ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
233366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2334efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2335ee4f033dSBarry Smith 
2336ee4f033dSBarry Smith     /*
2337ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2338ee4f033dSBarry Smith     */
23391ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2340ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2341ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2342ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2343ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2344ee4f033dSBarry Smith       srow   = row + start;
2345ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2346ee4f033dSBarry Smith     }
23471ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2348ee4f033dSBarry Smith   }
234949b058dcSBarry Smith   coloring->currentcolor = k;
23501ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
23511ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2352ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2353ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2354ee4f033dSBarry Smith   PetscFunctionReturn(0);
2355ee4f033dSBarry Smith }
2356ee4f033dSBarry Smith 
23578229c054SShri Abhyankar /*
23588229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
23598229c054SShri Abhyankar    have different nonzero structure.
23608229c054SShri Abhyankar */
2361ac90fabeSBarry Smith #undef __FUNCT__
23628229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
23638229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2364ec7775f6SShri Abhyankar {
23658229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2366ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2367ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2368ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2369ec7775f6SShri Abhyankar 
2370ec7775f6SShri Abhyankar   PetscFunctionBegin;
2371ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2372ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
23738af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
23748af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
23758af7cee1SJed Brown     nnz[i] = 0;
23768af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
23778af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
23788af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
23798af7cee1SJed Brown       nnz[i]++;
23808af7cee1SJed Brown     }
23818af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2382ec7775f6SShri Abhyankar   }
2383ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2384ec7775f6SShri Abhyankar }
2385ec7775f6SShri Abhyankar 
2386ec7775f6SShri Abhyankar #undef __FUNCT__
2387ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2388f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2389ac90fabeSBarry Smith {
2390dfbe8321SBarry Smith   PetscErrorCode ierr;
239197f1f81fSBarry Smith   PetscInt       i;
2392ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
23930805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2394ac90fabeSBarry Smith 
2395ac90fabeSBarry Smith   PetscFunctionBegin;
2396ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2397f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2398f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2399c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2400a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2401a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2402a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2403a30b2313SHong Zhang     }
2404a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2405d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2406a30b2313SHong Zhang       y->XtoY = X;
2407407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2408c537a176SHong Zhang     }
2409f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
24101e2582c4SBarry Smith     ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);CHKERRQ(ierr);
2411ac90fabeSBarry Smith   } else {
24128229c054SShri Abhyankar     Mat      B;
24138229c054SShri Abhyankar     PetscInt *nnz;
241416b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2415ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2416bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
24174aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2418ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
24198229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
24208229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2421ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2422ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
24238229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2424ac90fabeSBarry Smith   }
2425ac90fabeSBarry Smith   PetscFunctionReturn(0);
2426ac90fabeSBarry Smith }
2427ac90fabeSBarry Smith 
2428521d7252SBarry Smith #undef __FUNCT__
2429521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2430521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2431521d7252SBarry Smith {
243241c166b1SJed Brown   PetscErrorCode ierr;
243341c166b1SJed Brown 
2434521d7252SBarry Smith   PetscFunctionBegin;
243541c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
243641c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2437521d7252SBarry Smith   PetscFunctionReturn(0);
2438521d7252SBarry Smith }
2439521d7252SBarry Smith 
2440354c94deSBarry Smith #undef __FUNCT__
2441354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
24427087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2443354c94deSBarry Smith {
2444354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2445354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2446354c94deSBarry Smith   PetscInt    i,nz;
2447354c94deSBarry Smith   PetscScalar *a;
2448354c94deSBarry Smith 
2449354c94deSBarry Smith   PetscFunctionBegin;
2450354c94deSBarry Smith   nz = aij->nz;
2451354c94deSBarry Smith   a  = aij->a;
2452354c94deSBarry Smith   for (i=0; i<nz; i++) {
2453354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2454354c94deSBarry Smith   }
2455354c94deSBarry Smith #else
2456354c94deSBarry Smith   PetscFunctionBegin;
2457354c94deSBarry Smith #endif
2458354c94deSBarry Smith   PetscFunctionReturn(0);
2459354c94deSBarry Smith }
2460354c94deSBarry Smith 
2461e34fafa9SBarry Smith #undef __FUNCT__
2462985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2463985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2464e34fafa9SBarry Smith {
2465e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2466e34fafa9SBarry Smith   PetscErrorCode ierr;
2467d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2468e34fafa9SBarry Smith   PetscReal      atmp;
2469985db425SBarry Smith   PetscScalar    *x;
2470e34fafa9SBarry Smith   MatScalar      *aa;
2471e34fafa9SBarry Smith 
2472e34fafa9SBarry Smith   PetscFunctionBegin;
2473e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2474e34fafa9SBarry Smith   aa   = a->a;
2475e34fafa9SBarry Smith   ai   = a->i;
2476e34fafa9SBarry Smith   aj   = a->j;
2477e34fafa9SBarry Smith 
2478985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2479e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2480e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2481e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2482e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2483e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
24849189402eSHong Zhang     x[i] = 0.0;
2485e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2486985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2487985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2488985db425SBarry Smith       aa++; aj++;
2489985db425SBarry Smith     }
2490985db425SBarry Smith   }
2491985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2492985db425SBarry Smith   PetscFunctionReturn(0);
2493985db425SBarry Smith }
2494985db425SBarry Smith 
2495985db425SBarry Smith #undef __FUNCT__
2496985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2497985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2498985db425SBarry Smith {
2499985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2500985db425SBarry Smith   PetscErrorCode ierr;
2501d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2502985db425SBarry Smith   PetscScalar    *x;
2503985db425SBarry Smith   MatScalar      *aa;
2504985db425SBarry Smith 
2505985db425SBarry Smith   PetscFunctionBegin;
2506e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2507985db425SBarry Smith   aa   = a->a;
2508985db425SBarry Smith   ai   = a->i;
2509985db425SBarry Smith   aj   = a->j;
2510985db425SBarry Smith 
2511985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2512985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2513985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2514e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2515985db425SBarry Smith   for (i=0; i<m; i++) {
2516985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2517d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2518985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2519985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2520985db425SBarry Smith       x[i] = 0.0;
2521985db425SBarry Smith       if (idx) {
2522985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2523985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2524985db425SBarry Smith           if (aj[j] > j) {
2525985db425SBarry Smith             idx[i] = j;
2526985db425SBarry Smith             break;
2527985db425SBarry Smith           }
2528985db425SBarry Smith         }
2529985db425SBarry Smith       }
2530985db425SBarry Smith     }
2531985db425SBarry Smith     for (j=0; j<ncols; j++){
2532985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2533985db425SBarry Smith       aa++; aj++;
2534985db425SBarry Smith     }
2535985db425SBarry Smith   }
2536985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2537985db425SBarry Smith   PetscFunctionReturn(0);
2538985db425SBarry Smith }
2539985db425SBarry Smith 
2540985db425SBarry Smith #undef __FUNCT__
2541c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2542c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2543c87e5d42SMatthew Knepley {
2544c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2545c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2546c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2547c87e5d42SMatthew Knepley   PetscReal      atmp;
2548c87e5d42SMatthew Knepley   PetscScalar    *x;
2549c87e5d42SMatthew Knepley   MatScalar      *aa;
2550c87e5d42SMatthew Knepley 
2551c87e5d42SMatthew Knepley   PetscFunctionBegin;
2552e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2553c87e5d42SMatthew Knepley   aa   = a->a;
2554c87e5d42SMatthew Knepley   ai   = a->i;
2555c87e5d42SMatthew Knepley   aj   = a->j;
2556c87e5d42SMatthew Knepley 
2557c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2558c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2559c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2560e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2561c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2562c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2563289a08f5SMatthew Knepley     if (ncols) {
2564289a08f5SMatthew Knepley       /* Get first nonzero */
2565289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2566289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2567289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2568289a08f5SMatthew Knepley       }
2569289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2570289a08f5SMatthew Knepley     } else {
2571289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2572289a08f5SMatthew Knepley     }
2573c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2574c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2575289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2576c87e5d42SMatthew Knepley       aa++; aj++;
2577c87e5d42SMatthew Knepley     }
2578c87e5d42SMatthew Knepley   }
2579c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2580c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2581c87e5d42SMatthew Knepley }
2582c87e5d42SMatthew Knepley 
2583c87e5d42SMatthew Knepley #undef __FUNCT__
2584985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2585985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2586985db425SBarry Smith {
2587985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2588985db425SBarry Smith   PetscErrorCode ierr;
2589d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2590985db425SBarry Smith   PetscScalar    *x;
2591985db425SBarry Smith   MatScalar      *aa;
2592985db425SBarry Smith 
2593985db425SBarry Smith   PetscFunctionBegin;
2594e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2595985db425SBarry Smith   aa   = a->a;
2596985db425SBarry Smith   ai   = a->i;
2597985db425SBarry Smith   aj   = a->j;
2598985db425SBarry Smith 
2599985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2600985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2601985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2602e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2603985db425SBarry Smith   for (i=0; i<m; i++) {
2604985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2605d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2606985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2607985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2608985db425SBarry Smith       x[i] = 0.0;
2609985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2610985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2611985db425SBarry Smith         for (j=0;j<ncols;j++) {
2612985db425SBarry Smith           if (aj[j] > j) {
2613985db425SBarry Smith             idx[i] = j;
2614985db425SBarry Smith             break;
2615985db425SBarry Smith           }
2616985db425SBarry Smith         }
2617985db425SBarry Smith       }
2618985db425SBarry Smith     }
2619985db425SBarry Smith     for (j=0; j<ncols; j++){
2620985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2621985db425SBarry Smith       aa++; aj++;
2622e34fafa9SBarry Smith     }
2623e34fafa9SBarry Smith   }
2624e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2625e34fafa9SBarry Smith   PetscFunctionReturn(0);
2626e34fafa9SBarry Smith }
26277087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2628682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
26290a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2630cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2631cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2632cb5b572fSBarry Smith        MatMult_SeqAIJ,
263397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
26347c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
26357c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2636db4efbfdSBarry Smith        0,
2637db4efbfdSBarry Smith        0,
2638db4efbfdSBarry Smith        0,
2639db4efbfdSBarry Smith /*10*/ 0,
2640cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2641cb5b572fSBarry Smith        0,
264241f059aeSBarry Smith        MatSOR_SeqAIJ,
264317ab2063SBarry Smith        MatTranspose_SeqAIJ,
264497304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2645cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2646cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2647cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2648cb5b572fSBarry Smith        MatNorm_SeqAIJ,
264997304618SKris Buschelman /*20*/ 0,
2650cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2651cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2652cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2653d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2654db4efbfdSBarry Smith        0,
2655db4efbfdSBarry Smith        0,
2656db4efbfdSBarry Smith        0,
2657db4efbfdSBarry Smith        0,
2658d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2659db4efbfdSBarry Smith        0,
2660db4efbfdSBarry Smith        0,
26616c0721eeSBarry Smith        MatGetArray_SeqAIJ,
26626c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2663d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2664cb5b572fSBarry Smith        0,
2665cb5b572fSBarry Smith        0,
2666cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2667cb5b572fSBarry Smith        0,
2668d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
2669cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2670cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2671cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2672cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2673d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
2674cb5b572fSBarry Smith        MatScale_SeqAIJ,
2675cb5b572fSBarry Smith        0,
267679299369SBarry Smith        MatDiagonalSet_SeqAIJ,
26776e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
2678d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
26793b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
26803b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
26813b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2682a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2683d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
2684b9617806SBarry Smith        0,
26850513a670SBarry Smith        0,
2686cda55fadSBarry Smith        MatPermute_SeqAIJ,
2687cda55fadSBarry Smith        0,
2688d519adbfSMatthew Knepley /*59*/ 0,
2689b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2690b9b97703SBarry Smith        MatView_SeqAIJ,
2691357abbc8SBarry Smith        0,
2692ee4f033dSBarry Smith        0,
2693d519adbfSMatthew Knepley /*64*/ 0,
2694ee4f033dSBarry Smith        0,
2695ee4f033dSBarry Smith        0,
2696ee4f033dSBarry Smith        0,
2697ee4f033dSBarry Smith        0,
2698d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
2699c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
2700ee4f033dSBarry Smith        0,
2701ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2702dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2703ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2704dcf5cc72SBarry Smith #else
2705dcf5cc72SBarry Smith        0,
2706dcf5cc72SBarry Smith #endif
2707d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
27083acb8795SBarry Smith        MatFDColoringApply_AIJ,
270997304618SKris Buschelman        0,
271097304618SKris Buschelman        0,
271197304618SKris Buschelman        0,
2712d519adbfSMatthew Knepley /*79*/ 0,
271397304618SKris Buschelman        0,
271497304618SKris Buschelman        0,
271597304618SKris Buschelman        0,
2716bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2717d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
27181cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
27196284ec50SHong Zhang        0,
27206284ec50SHong Zhang        0,
2721bc011b1eSHong Zhang        0,
2722d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
272326be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
272426be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2725d439da42SKris Buschelman        MatPtAP_Basic,
27267ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
2727d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
2728bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2729bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2730bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
27317ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
2732d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
2733609c6c4dSKris Buschelman        0,
2734609c6c4dSKris Buschelman        0,
273587d4246cSBarry Smith        MatConjugate_SeqAIJ,
273687d4246cSBarry Smith        0,
2737d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
273899cafbc1SBarry Smith        MatRealPart_SeqAIJ,
2739f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
2740f5edf698SHong Zhang        0,
27412bebee5dSHong Zhang        0,
2742d519adbfSMatthew Knepley /*109*/0,
2743985db425SBarry Smith        0,
27442af78befSBarry Smith        MatGetRowMin_SeqAIJ,
27452af78befSBarry Smith        0,
2746599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
2747d519adbfSMatthew Knepley /*114*/0,
2748599ef60dSHong Zhang        0,
27493c2a7987SHong Zhang        0,
2750fe97e370SBarry Smith        0,
2751fbdbba38SShri Abhyankar        0,
2752fbdbba38SShri Abhyankar /*119*/0,
2753fbdbba38SShri Abhyankar        0,
2754fbdbba38SShri Abhyankar        0,
275582d44351SHong Zhang        0,
275682d44351SHong Zhang        MatGetMultiProcBlock_SeqAIJ
27579e29f15eSvictorle };
275817ab2063SBarry Smith 
2759fb2e594dSBarry Smith EXTERN_C_BEGIN
27604a2ae208SSatish Balay #undef __FUNCT__
27614a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
27627087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2763bef8e0ddSBarry Smith {
2764bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
276597f1f81fSBarry Smith   PetscInt   i,nz,n;
2766bef8e0ddSBarry Smith 
2767bef8e0ddSBarry Smith   PetscFunctionBegin;
2768bef8e0ddSBarry Smith 
2769bef8e0ddSBarry Smith   nz = aij->maxnz;
2770d0f46423SBarry Smith   n  = mat->rmap->n;
2771bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2772bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2773bef8e0ddSBarry Smith   }
2774bef8e0ddSBarry Smith   aij->nz = nz;
2775bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2776bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2777bef8e0ddSBarry Smith   }
2778bef8e0ddSBarry Smith 
2779bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2780bef8e0ddSBarry Smith }
2781fb2e594dSBarry Smith EXTERN_C_END
2782bef8e0ddSBarry Smith 
27834a2ae208SSatish Balay #undef __FUNCT__
27844a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2785bef8e0ddSBarry Smith /*@
2786bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2787bef8e0ddSBarry Smith        in the matrix.
2788bef8e0ddSBarry Smith 
2789bef8e0ddSBarry Smith   Input Parameters:
2790bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2791bef8e0ddSBarry Smith -  indices - the column indices
2792bef8e0ddSBarry Smith 
279315091d37SBarry Smith   Level: advanced
279415091d37SBarry Smith 
2795bef8e0ddSBarry Smith   Notes:
2796bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2797bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2798bef8e0ddSBarry Smith   of the MatSetValues() operation.
2799bef8e0ddSBarry Smith 
2800bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2801d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2802bef8e0ddSBarry Smith 
2803bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2804bef8e0ddSBarry Smith 
2805b9617806SBarry Smith     The indices should start with zero, not one.
2806b9617806SBarry Smith 
2807bef8e0ddSBarry Smith @*/
28087087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2809bef8e0ddSBarry Smith {
28104ac538c5SBarry Smith   PetscErrorCode ierr;
2811bef8e0ddSBarry Smith 
2812bef8e0ddSBarry Smith   PetscFunctionBegin;
28130700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
28144482741eSBarry Smith   PetscValidPointer(indices,2);
28154ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
2816bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2817bef8e0ddSBarry Smith }
2818bef8e0ddSBarry Smith 
2819be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2820be6bf707SBarry Smith 
2821fb2e594dSBarry Smith EXTERN_C_BEGIN
28224a2ae208SSatish Balay #undef __FUNCT__
28234a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
28247087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
2825be6bf707SBarry Smith {
2826be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
28276849ba73SBarry Smith   PetscErrorCode ierr;
2828d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
2829be6bf707SBarry Smith 
2830be6bf707SBarry Smith   PetscFunctionBegin;
2831be6bf707SBarry Smith   if (aij->nonew != 1) {
2832e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2833be6bf707SBarry Smith   }
2834be6bf707SBarry Smith 
2835be6bf707SBarry Smith   /* allocate space for values if not already there */
2836be6bf707SBarry Smith   if (!aij->saved_values) {
283787828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
28389518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
2839be6bf707SBarry Smith   }
2840be6bf707SBarry Smith 
2841be6bf707SBarry Smith   /* copy values over */
284287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2843be6bf707SBarry Smith   PetscFunctionReturn(0);
2844be6bf707SBarry Smith }
2845fb2e594dSBarry Smith EXTERN_C_END
2846be6bf707SBarry Smith 
28474a2ae208SSatish Balay #undef __FUNCT__
2848b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2849be6bf707SBarry Smith /*@
2850be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2851be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2852be6bf707SBarry Smith        nonlinear portion.
2853be6bf707SBarry Smith 
2854be6bf707SBarry Smith    Collect on Mat
2855be6bf707SBarry Smith 
2856be6bf707SBarry Smith   Input Parameters:
28570e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2858be6bf707SBarry Smith 
285915091d37SBarry Smith   Level: advanced
286015091d37SBarry Smith 
2861be6bf707SBarry Smith   Common Usage, with SNESSolve():
2862be6bf707SBarry Smith $    Create Jacobian matrix
2863be6bf707SBarry Smith $    Set linear terms into matrix
2864be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2865be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2866be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2867512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2868be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2869be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2870be6bf707SBarry Smith $    In your Jacobian routine
2871be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2872be6bf707SBarry Smith $      Set nonlinear terms in matrix
2873be6bf707SBarry Smith 
2874be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2875be6bf707SBarry Smith $    // build linear portion of Jacobian
2876512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2877be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2878be6bf707SBarry Smith $    loop over nonlinear iterations
2879be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2880be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2881be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2882be6bf707SBarry Smith $       Solve linear system with Jacobian
2883be6bf707SBarry Smith $    endloop
2884be6bf707SBarry Smith 
2885be6bf707SBarry Smith   Notes:
2886be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2887512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
2888be6bf707SBarry Smith     calling this routine.
2889be6bf707SBarry Smith 
28900c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
28910c468ba9SBarry Smith     and does not allocated additional space.
28920c468ba9SBarry Smith 
2893be6bf707SBarry Smith .seealso: MatRetrieveValues()
2894be6bf707SBarry Smith 
2895be6bf707SBarry Smith @*/
28967087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
2897be6bf707SBarry Smith {
28984ac538c5SBarry Smith   PetscErrorCode ierr;
2899be6bf707SBarry Smith 
2900be6bf707SBarry Smith   PetscFunctionBegin;
29010700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2902e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2903e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
29044ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
2905be6bf707SBarry Smith   PetscFunctionReturn(0);
2906be6bf707SBarry Smith }
2907be6bf707SBarry Smith 
2908fb2e594dSBarry Smith EXTERN_C_BEGIN
29094a2ae208SSatish Balay #undef __FUNCT__
29104a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
29117087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
2912be6bf707SBarry Smith {
2913be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
29146849ba73SBarry Smith   PetscErrorCode ierr;
2915d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
2916be6bf707SBarry Smith 
2917be6bf707SBarry Smith   PetscFunctionBegin;
2918be6bf707SBarry Smith   if (aij->nonew != 1) {
2919e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2920be6bf707SBarry Smith   }
2921be6bf707SBarry Smith   if (!aij->saved_values) {
2922e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2923be6bf707SBarry Smith   }
2924be6bf707SBarry Smith   /* copy values over */
292587828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2926be6bf707SBarry Smith   PetscFunctionReturn(0);
2927be6bf707SBarry Smith }
2928fb2e594dSBarry Smith EXTERN_C_END
2929be6bf707SBarry Smith 
29304a2ae208SSatish Balay #undef __FUNCT__
29314a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2932be6bf707SBarry Smith /*@
2933be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2934be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2935be6bf707SBarry Smith        nonlinear portion.
2936be6bf707SBarry Smith 
2937be6bf707SBarry Smith    Collect on Mat
2938be6bf707SBarry Smith 
2939be6bf707SBarry Smith   Input Parameters:
2940be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2941be6bf707SBarry Smith 
294215091d37SBarry Smith   Level: advanced
294315091d37SBarry Smith 
2944be6bf707SBarry Smith .seealso: MatStoreValues()
2945be6bf707SBarry Smith 
2946be6bf707SBarry Smith @*/
29477087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
2948be6bf707SBarry Smith {
29494ac538c5SBarry Smith   PetscErrorCode ierr;
2950be6bf707SBarry Smith 
2951be6bf707SBarry Smith   PetscFunctionBegin;
29520700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2953e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2954e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
29554ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
2956be6bf707SBarry Smith   PetscFunctionReturn(0);
2957be6bf707SBarry Smith }
2958be6bf707SBarry Smith 
2959f83d6046SBarry Smith 
2960be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
29614a2ae208SSatish Balay #undef __FUNCT__
29624a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
296317ab2063SBarry Smith /*@C
2964682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
29650d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
29666e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
296751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
29682bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
296917ab2063SBarry Smith 
2970db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2971db81eaa0SLois Curfman McInnes 
297217ab2063SBarry Smith    Input Parameters:
2973db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
297417ab2063SBarry Smith .  m - number of rows
297517ab2063SBarry Smith .  n - number of columns
297617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
297751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
29782bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
297917ab2063SBarry Smith 
298017ab2063SBarry Smith    Output Parameter:
2981416022c9SBarry Smith .  A - the matrix
298217ab2063SBarry Smith 
2983175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
2984ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
2985175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
2986175b88e8SBarry Smith 
2987b259b22eSLois Curfman McInnes    Notes:
298849a6f317SBarry Smith    If nnz is given then nz is ignored
298949a6f317SBarry Smith 
299017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
299117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
29920002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
299344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
299417ab2063SBarry Smith 
299517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2996a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
29973d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
29986da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
299917ab2063SBarry Smith 
3000682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
30014fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3002682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
30036c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
30046c7ebb05SLois Curfman McInnes 
30056c7ebb05SLois Curfman McInnes    Options Database Keys:
3006698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
30079db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
300817ab2063SBarry Smith 
3009027ccd11SLois Curfman McInnes    Level: intermediate
3010027ccd11SLois Curfman McInnes 
301136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
301236db0b34SBarry Smith 
301317ab2063SBarry Smith @*/
30147087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
301517ab2063SBarry Smith {
3016dfbe8321SBarry Smith   PetscErrorCode ierr;
30176945ee14SBarry Smith 
30183a40ed3dSBarry Smith   PetscFunctionBegin;
3019f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3020117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3021c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3022d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3023273d9f13SBarry Smith   PetscFunctionReturn(0);
3024273d9f13SBarry Smith }
3025273d9f13SBarry Smith 
30264a2ae208SSatish Balay #undef __FUNCT__
30274a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3028273d9f13SBarry Smith /*@C
3029273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3030273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3031273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3032273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3033273d9f13SBarry Smith 
3034273d9f13SBarry Smith    Collective on MPI_Comm
3035273d9f13SBarry Smith 
3036273d9f13SBarry Smith    Input Parameters:
3037117016b1SBarry Smith +  B - The matrix-free
3038273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3039273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3040273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3041273d9f13SBarry Smith 
3042273d9f13SBarry Smith    Notes:
304349a6f317SBarry Smith      If nnz is given then nz is ignored
304449a6f317SBarry Smith 
3045273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3046273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3047273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3048273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3049273d9f13SBarry Smith 
3050273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3051273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3052273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3053273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3054273d9f13SBarry Smith 
3055aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3056aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3057aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3058aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3059aa95bbe8SBarry Smith 
3060a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3061a96a251dSBarry Smith    entries or columns indices
3062a96a251dSBarry Smith 
3063273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3064273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3065273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3066273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3067273d9f13SBarry Smith 
3068273d9f13SBarry Smith    Options Database Keys:
3069698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3070698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3071273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3072273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3073273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3074273d9f13SBarry Smith 
3075273d9f13SBarry Smith    Level: intermediate
3076273d9f13SBarry Smith 
3077aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3078273d9f13SBarry Smith 
3079273d9f13SBarry Smith @*/
30807087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3081273d9f13SBarry Smith {
30824ac538c5SBarry Smith   PetscErrorCode ierr;
3083a23d5eceSKris Buschelman 
3084a23d5eceSKris Buschelman   PetscFunctionBegin;
30854ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3086a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3087a23d5eceSKris Buschelman }
3088a23d5eceSKris Buschelman 
3089a23d5eceSKris Buschelman EXTERN_C_BEGIN
3090a23d5eceSKris Buschelman #undef __FUNCT__
3091a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
30927087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3093a23d5eceSKris Buschelman {
3094273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3095ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
30966849ba73SBarry Smith   PetscErrorCode ierr;
309797f1f81fSBarry Smith   PetscInt       i;
3098273d9f13SBarry Smith 
3099273d9f13SBarry Smith   PetscFunctionBegin;
3100d5d45c9bSBarry Smith 
3101a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3102c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3103c461c341SBarry Smith     nz             = 0;
3104c461c341SBarry Smith   }
3105c461c341SBarry Smith 
310626283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
310726283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
310826283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
310926283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3110899cda47SBarry Smith 
3111435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3112e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3113b73539f3SBarry Smith   if (nnz) {
3114d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3115e32f2f54SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
3116e32f2f54SBarry Smith       if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap->n);
3117b73539f3SBarry Smith     }
3118b73539f3SBarry Smith   }
3119b73539f3SBarry Smith 
3120273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3121273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3122273d9f13SBarry Smith 
3123ab93d7beSBarry Smith   if (!skipallocation) {
31242ee49352SLisandro Dalcin     if (!b->imax) {
3125d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3126d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
31272ee49352SLisandro Dalcin     }
3128273d9f13SBarry Smith     if (!nnz) {
3129435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3130c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3131d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3132d0f46423SBarry Smith       nz = nz*B->rmap->n;
3133273d9f13SBarry Smith     } else {
3134273d9f13SBarry Smith       nz = 0;
3135d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3136273d9f13SBarry Smith     }
3137ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3138d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3139ab93d7beSBarry Smith 
3140273d9f13SBarry Smith     /* allocate the matrix space */
31412ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3142d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3143d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3144bfeeae90SHong Zhang     b->i[0] = 0;
3145d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
31465da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
31475da197adSKris Buschelman     }
3148273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3149e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3150e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3151c461c341SBarry Smith   } else {
3152e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3153e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3154c461c341SBarry Smith   }
3155273d9f13SBarry Smith 
3156273d9f13SBarry Smith   b->nz                = 0;
3157273d9f13SBarry Smith   b->maxnz             = nz;
3158273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3159273d9f13SBarry Smith   PetscFunctionReturn(0);
3160273d9f13SBarry Smith }
3161a23d5eceSKris Buschelman EXTERN_C_END
3162273d9f13SBarry Smith 
3163a1661176SMatthew Knepley #undef  __FUNCT__
3164a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
316558d36128SBarry Smith /*@
3166a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3167a1661176SMatthew Knepley 
3168a1661176SMatthew Knepley    Input Parameters:
3169a1661176SMatthew Knepley +  B - the matrix
3170a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3171a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3172a1661176SMatthew Knepley -  v - optional values in the matrix
3173a1661176SMatthew Knepley 
3174a1661176SMatthew Knepley    Level: developer
3175a1661176SMatthew Knepley 
317658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
317758d36128SBarry Smith 
3178a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3179a1661176SMatthew Knepley 
3180a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3181a1661176SMatthew Knepley @*/
3182a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3183a1661176SMatthew Knepley {
3184a1661176SMatthew Knepley   PetscErrorCode ierr;
3185a1661176SMatthew Knepley 
3186a1661176SMatthew Knepley   PetscFunctionBegin;
31870700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
31884ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3189a1661176SMatthew Knepley   PetscFunctionReturn(0);
3190a1661176SMatthew Knepley }
3191a1661176SMatthew Knepley 
3192a1661176SMatthew Knepley EXTERN_C_BEGIN
3193a1661176SMatthew Knepley #undef  __FUNCT__
3194a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
31957087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3196a1661176SMatthew Knepley {
3197a1661176SMatthew Knepley   PetscInt       i;
3198a1661176SMatthew Knepley   PetscInt       m,n;
3199a1661176SMatthew Knepley   PetscInt       nz;
3200a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3201a1661176SMatthew Knepley   PetscScalar    *values;
3202a1661176SMatthew Knepley   PetscErrorCode ierr;
3203a1661176SMatthew Knepley 
3204a1661176SMatthew Knepley   PetscFunctionBegin;
3205a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3206a1661176SMatthew Knepley 
320765e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3208a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3209a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3210b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3211a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
321265e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3213a1661176SMatthew Knepley     nnz[i] = nz;
3214a1661176SMatthew Knepley   }
3215a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3216a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3217a1661176SMatthew Knepley 
3218a1661176SMatthew Knepley   if (v) {
3219a1661176SMatthew Knepley     values = (PetscScalar*) v;
3220a1661176SMatthew Knepley   } else {
32210e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3222a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3223a1661176SMatthew Knepley   }
3224a1661176SMatthew Knepley 
3225a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3226b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3227b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3228a1661176SMatthew Knepley   }
3229a1661176SMatthew Knepley 
3230a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3231a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3232a1661176SMatthew Knepley 
3233a1661176SMatthew Knepley   if (!v) {
3234a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3235a1661176SMatthew Knepley   }
3236a1661176SMatthew Knepley   PetscFunctionReturn(0);
3237a1661176SMatthew Knepley }
3238a1661176SMatthew Knepley EXTERN_C_END
3239a1661176SMatthew Knepley 
32407c4f633dSBarry Smith #include "../src/mat/impls/dense/seq/dense.h"
3241be7314b0SBarry Smith #include "private/petscaxpy.h"
3242170fe5c8SBarry Smith 
3243170fe5c8SBarry Smith #undef __FUNCT__
3244170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3245170fe5c8SBarry Smith /*
3246170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3247170fe5c8SBarry Smith 
3248170fe5c8SBarry Smith                n                       p                          p
3249170fe5c8SBarry Smith         (              )       (              )         (                  )
3250170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3251170fe5c8SBarry Smith         (              )       (              )         (                  )
3252170fe5c8SBarry Smith 
3253170fe5c8SBarry Smith */
3254170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3255170fe5c8SBarry Smith {
3256170fe5c8SBarry Smith   PetscErrorCode     ierr;
3257170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3258170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3259170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
32601de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3261170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3262170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3263170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3264170fe5c8SBarry Smith 
3265170fe5c8SBarry Smith   PetscFunctionBegin;
3266d0f46423SBarry Smith   m = A->rmap->n;
3267d0f46423SBarry Smith   n = A->cmap->n;
3268d0f46423SBarry Smith   p = B->cmap->n;
3269170fe5c8SBarry Smith   a = sub_a->v;
3270170fe5c8SBarry Smith   b = sub_b->a;
3271170fe5c8SBarry Smith   c = sub_c->v;
3272170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3273170fe5c8SBarry Smith 
3274170fe5c8SBarry Smith   ii  = sub_b->i;
3275170fe5c8SBarry Smith   idx = sub_b->j;
3276170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3277170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3278170fe5c8SBarry Smith     while (q-->0) {
3279170fe5c8SBarry Smith       c_q = c + m*(*idx);
3280170fe5c8SBarry Smith       a_q = a + m*i;
3281be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3282170fe5c8SBarry Smith       idx++;
3283170fe5c8SBarry Smith       b++;
3284170fe5c8SBarry Smith     }
3285170fe5c8SBarry Smith   }
3286170fe5c8SBarry Smith   PetscFunctionReturn(0);
3287170fe5c8SBarry Smith }
3288170fe5c8SBarry Smith 
3289170fe5c8SBarry Smith #undef __FUNCT__
3290170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3291170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3292170fe5c8SBarry Smith {
3293170fe5c8SBarry Smith   PetscErrorCode ierr;
3294d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3295170fe5c8SBarry Smith   Mat            Cmat;
3296170fe5c8SBarry Smith 
3297170fe5c8SBarry Smith   PetscFunctionBegin;
3298e32f2f54SBarry Smith   if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n);
329939804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3300170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3301170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3302170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3303170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3304170fe5c8SBarry Smith   *C = Cmat;
3305170fe5c8SBarry Smith   PetscFunctionReturn(0);
3306170fe5c8SBarry Smith }
3307170fe5c8SBarry Smith 
3308170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3309170fe5c8SBarry Smith #undef __FUNCT__
3310170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3311170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3312170fe5c8SBarry Smith {
3313170fe5c8SBarry Smith   PetscErrorCode ierr;
3314170fe5c8SBarry Smith 
3315170fe5c8SBarry Smith   PetscFunctionBegin;
3316170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3317170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3318170fe5c8SBarry Smith   }
3319170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3320170fe5c8SBarry Smith   PetscFunctionReturn(0);
3321170fe5c8SBarry Smith }
3322170fe5c8SBarry Smith 
3323170fe5c8SBarry Smith 
33240bad9183SKris Buschelman /*MC
3325fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
33260bad9183SKris Buschelman    based on compressed sparse row format.
33270bad9183SKris Buschelman 
33280bad9183SKris Buschelman    Options Database Keys:
33290bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
33300bad9183SKris Buschelman 
33310bad9183SKris Buschelman   Level: beginner
33320bad9183SKris Buschelman 
3333f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
33340bad9183SKris Buschelman M*/
33350bad9183SKris Buschelman 
3336a6175056SHong Zhang EXTERN_C_BEGIN
3337b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3338b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3339b5e56a35SBarry Smith #endif
334065460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE)
3341af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3342af1023dbSSatish Balay #endif
33437087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
33447087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
33457087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
33467087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3347611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
33487087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3349611f576cSBarry Smith #endif
3350611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
33517087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3352611f576cSBarry Smith #endif
3353f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3354f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3355f3c0ef26SHong Zhang #endif
3356611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
33577087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3358611f576cSBarry Smith #endif
3359eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
33607087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3361eb3b5408SSatish Balay #endif
3362586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
33637087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3364586621ddSJed Brown #endif
3365719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
33667087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3367719d5645SBarry Smith #endif
3368b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
33697087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
33707087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
33717087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3372b3866ffcSBarry Smith #endif
337317667f90SBarry Smith EXTERN_C_END
337417667f90SBarry Smith 
3375b24902e0SBarry Smith 
337617667f90SBarry Smith EXTERN_C_BEGIN
33774a2ae208SSatish Balay #undef __FUNCT__
33784a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
33797087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3380273d9f13SBarry Smith {
3381273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3382dfbe8321SBarry Smith   PetscErrorCode ierr;
338338baddfdSBarry Smith   PetscMPIInt    size;
3384273d9f13SBarry Smith 
3385273d9f13SBarry Smith   PetscFunctionBegin;
33867adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3387e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3388273d9f13SBarry Smith 
338938f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3390b0a32e0cSBarry Smith   B->data             = (void*)b;
3391549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3392416022c9SBarry Smith   b->row              = 0;
3393416022c9SBarry Smith   b->col              = 0;
339482bf6240SBarry Smith   b->icol             = 0;
3395b810aeb4SBarry Smith   b->reallocs         = 0;
339636db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3397f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3398416022c9SBarry Smith   b->nonew             = 0;
3399416022c9SBarry Smith   b->diag              = 0;
3400416022c9SBarry Smith   b->solve_work        = 0;
34012a1b7f2aSHong Zhang   B->spptr             = 0;
3402be6bf707SBarry Smith   b->saved_values      = 0;
3403d7f994e1SBarry Smith   b->idiag             = 0;
340471f1c65dSBarry Smith   b->mdiag             = 0;
340571f1c65dSBarry Smith   b->ssor_work         = 0;
340671f1c65dSBarry Smith   b->omega             = 1.0;
340771f1c65dSBarry Smith   b->fshift            = 0.0;
340871f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3409a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3410a30b2313SHong Zhang   b->xtoy              = 0;
3411a30b2313SHong Zhang   b->XtoY              = 0;
341288e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
341317ab2063SBarry Smith 
341435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3415b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3416700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3417b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3418b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3419b3866ffcSBarry Smith #endif
3420b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3421700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3422b5e56a35SBarry Smith #endif
342365460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE)
3424700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3425719d5645SBarry Smith #endif
3426611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3427700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3428611f576cSBarry Smith #endif
3429f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3430700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3431f3c0ef26SHong Zhang #endif
3432611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3433700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3434611f576cSBarry Smith #endif
3435611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3436700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3437611f576cSBarry Smith #endif
3438eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3439700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3440eb3b5408SSatish Balay #endif
3441586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3442700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3443586621ddSJed Brown #endif
3444719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3445700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3446719d5645SBarry Smith #endif
3447700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3448700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3449700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3450700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3451700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3452700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3453700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3454700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3455700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3456700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3457700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3458700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3459700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3460700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3461700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3462700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3463700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3464700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
34654108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
346617667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
34673a40ed3dSBarry Smith   PetscFunctionReturn(0);
346817ab2063SBarry Smith }
3469273d9f13SBarry Smith EXTERN_C_END
347017ab2063SBarry Smith 
34714a2ae208SSatish Balay #undef __FUNCT__
3472b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3473b24902e0SBarry Smith /*
3474b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3475b24902e0SBarry Smith */
3476ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
347717ab2063SBarry Smith {
3478416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
34796849ba73SBarry Smith   PetscErrorCode ierr;
3480d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
348117ab2063SBarry Smith 
34823a40ed3dSBarry Smith   PetscFunctionBegin;
3483273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3484273d9f13SBarry Smith 
3485d5f3da31SBarry Smith   C->factortype     = A->factortype;
3486416022c9SBarry Smith   c->row            = 0;
3487416022c9SBarry Smith   c->col            = 0;
348882bf6240SBarry Smith   c->icol           = 0;
34896ad4291fSHong Zhang   c->reallocs       = 0;
349017ab2063SBarry Smith 
34916ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
349217ab2063SBarry Smith 
349326283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->rmap,1);CHKERRQ(ierr);
349426283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->cmap,1);CHKERRQ(ierr);
349526283091SBarry Smith   ierr = PetscLayoutSetUp(C->rmap);CHKERRQ(ierr);
349626283091SBarry Smith   ierr = PetscLayoutSetUp(C->cmap);CHKERRQ(ierr);
3497eec197d1SBarry Smith 
349833b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
34999518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
350017ab2063SBarry Smith   for (i=0; i<m; i++) {
3501416022c9SBarry Smith     c->imax[i] = a->imax[i];
3502416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
350317ab2063SBarry Smith   }
350417ab2063SBarry Smith 
350517ab2063SBarry Smith   /* allocate the matrix space */
3506f77e22a1SHong Zhang   if (mallocmatspace){
3507a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
35089518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3509f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
351097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
351117ab2063SBarry Smith     if (m > 0) {
351297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3513be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3514bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3515be6bf707SBarry Smith       } else {
3516bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
351717ab2063SBarry Smith       }
351808480c60SBarry Smith     }
3519f77e22a1SHong Zhang   }
352017ab2063SBarry Smith 
35216ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3522416022c9SBarry Smith   c->roworiented       = a->roworiented;
3523416022c9SBarry Smith   c->nonew             = a->nonew;
3524416022c9SBarry Smith   if (a->diag) {
352597f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
352652e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
352717ab2063SBarry Smith     for (i=0; i<m; i++) {
3528416022c9SBarry Smith       c->diag[i] = a->diag[i];
352917ab2063SBarry Smith     }
35303a40ed3dSBarry Smith   } else c->diag           = 0;
35316ad4291fSHong Zhang   c->solve_work            = 0;
35326ad4291fSHong Zhang   c->saved_values          = 0;
35336ad4291fSHong Zhang   c->idiag                 = 0;
353471f1c65dSBarry Smith   c->ssor_work             = 0;
3535a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3536e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3537e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
35386ad4291fSHong Zhang   c->xtoy                  = 0;
35396ad4291fSHong Zhang   c->XtoY                  = 0;
35406ad4291fSHong Zhang 
3541416022c9SBarry Smith   c->nz                 = a->nz;
35428ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3543273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3544754ec7b1SSatish Balay 
35456ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
35466ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3547cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3548cd6b891eSBarry Smith   if (a->compressedrow.use){
35496ad4291fSHong Zhang     i = a->compressedrow.nrows;
35500e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
35516ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
35526ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
355327ea64f8SHong Zhang   } else {
355427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
355527ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
355627ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
35576ad4291fSHong Zhang   }
355888e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
35594108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
35604846f1f5SKris Buschelman 
35617adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
35623a40ed3dSBarry Smith   PetscFunctionReturn(0);
356317ab2063SBarry Smith }
356417ab2063SBarry Smith 
35654a2ae208SSatish Balay #undef __FUNCT__
3566b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3567b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3568b24902e0SBarry Smith {
3569b24902e0SBarry Smith   PetscErrorCode ierr;
3570b24902e0SBarry Smith 
3571b24902e0SBarry Smith   PetscFunctionBegin;
3572b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
35734b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3574b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3575f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3576b24902e0SBarry Smith   PetscFunctionReturn(0);
3577b24902e0SBarry Smith }
3578b24902e0SBarry Smith 
3579b24902e0SBarry Smith #undef __FUNCT__
35804a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3581112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3582fbdbba38SShri Abhyankar {
3583fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3584fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3585fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3586fbdbba38SShri Abhyankar   int            fd;
3587fbdbba38SShri Abhyankar   PetscMPIInt    size;
3588fbdbba38SShri Abhyankar   MPI_Comm       comm;
3589fbdbba38SShri Abhyankar 
3590fbdbba38SShri Abhyankar   PetscFunctionBegin;
3591fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3592fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3593fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3594fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3595fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3596fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3597fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3598fbdbba38SShri Abhyankar 
3599fbdbba38SShri Abhyankar   if (nz < 0) {
3600fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3601fbdbba38SShri Abhyankar   }
3602fbdbba38SShri Abhyankar 
3603fbdbba38SShri Abhyankar   /* read in row lengths */
3604fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3605fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3606fbdbba38SShri Abhyankar 
3607fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3608fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3609fbdbba38SShri Abhyankar   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
3610fbdbba38SShri Abhyankar 
3611fbdbba38SShri Abhyankar   /* set global size if not set already*/
3612f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3613fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3614aabbc4fbSShri Abhyankar   } else {
3615fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3616fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3617f501eaabSShri Abhyankar     if (M != rows ||  N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
3618aabbc4fbSShri Abhyankar   }
3619fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3620fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3621fbdbba38SShri Abhyankar 
3622fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3623fbdbba38SShri Abhyankar 
3624fbdbba38SShri Abhyankar   /* read in nonzero values */
3625fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3626fbdbba38SShri Abhyankar 
3627fbdbba38SShri Abhyankar   /* set matrix "i" values */
3628fbdbba38SShri Abhyankar   a->i[0] = 0;
3629fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3630fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3631fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3632fbdbba38SShri Abhyankar   }
3633fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3634fbdbba38SShri Abhyankar 
3635fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3636fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3637fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3638fbdbba38SShri Abhyankar }
3639fbdbba38SShri Abhyankar 
3640fbdbba38SShri Abhyankar #undef __FUNCT__
3641b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3642ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
36437264ac53SSatish Balay {
36447264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3645dfbe8321SBarry Smith   PetscErrorCode ierr;
3646eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3647eeffb40dSHong Zhang   PetscInt k;
3648eeffb40dSHong Zhang #endif
36497264ac53SSatish Balay 
36503a40ed3dSBarry Smith   PetscFunctionBegin;
3651bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3652d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
3653ca44d042SBarry Smith     *flg = PETSC_FALSE;
3654ca44d042SBarry Smith     PetscFunctionReturn(0);
3655bcd2baecSBarry Smith   }
36567264ac53SSatish Balay 
36577264ac53SSatish Balay   /* if the a->i are the same */
3658d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3659abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
36607264ac53SSatish Balay 
36617264ac53SSatish Balay   /* if a->j are the same */
366297f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3663abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3664bcd2baecSBarry Smith 
3665bcd2baecSBarry Smith   /* if a->a are the same */
3666eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3667eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
3668eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
3669eeffb40dSHong Zhang       *flg = PETSC_FALSE;
36703a40ed3dSBarry Smith       PetscFunctionReturn(0);
3671eeffb40dSHong Zhang     }
3672eeffb40dSHong Zhang   }
3673eeffb40dSHong Zhang #else
3674eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
3675eeffb40dSHong Zhang #endif
3676eeffb40dSHong Zhang   PetscFunctionReturn(0);
36777264ac53SSatish Balay }
367836db0b34SBarry Smith 
36794a2ae208SSatish Balay #undef __FUNCT__
36804a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
368105869f15SSatish Balay /*@
368236db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
368336db0b34SBarry Smith               provided by the user.
368436db0b34SBarry Smith 
3685c75a6043SHong Zhang       Collective on MPI_Comm
368636db0b34SBarry Smith 
368736db0b34SBarry Smith    Input Parameters:
368836db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
368936db0b34SBarry Smith .   m - number of rows
369036db0b34SBarry Smith .   n - number of columns
369136db0b34SBarry Smith .   i - row indices
369236db0b34SBarry Smith .   j - column indices
369336db0b34SBarry Smith -   a - matrix values
369436db0b34SBarry Smith 
369536db0b34SBarry Smith    Output Parameter:
369636db0b34SBarry Smith .   mat - the matrix
369736db0b34SBarry Smith 
369836db0b34SBarry Smith    Level: intermediate
369936db0b34SBarry Smith 
370036db0b34SBarry Smith    Notes:
37010551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
370236db0b34SBarry Smith     once the matrix is destroyed
370336db0b34SBarry Smith 
370436db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
370536db0b34SBarry Smith 
3706bfeeae90SHong Zhang        The i and j indices are 0 based
370736db0b34SBarry Smith 
3708a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
3709a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
3710a4552177SSatish Balay     as shown:
3711a4552177SSatish Balay 
3712a4552177SSatish Balay         1 0 0
3713a4552177SSatish Balay         2 0 3
3714a4552177SSatish Balay         4 5 6
3715a4552177SSatish Balay 
3716a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
37179985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
3718a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
3719a4552177SSatish Balay 
37209985e31cSBarry Smith 
37212fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
372236db0b34SBarry Smith 
372336db0b34SBarry Smith @*/
37247087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
372536db0b34SBarry Smith {
3726dfbe8321SBarry Smith   PetscErrorCode ierr;
3727cbcfb4deSHong Zhang   PetscInt       ii;
372836db0b34SBarry Smith   Mat_SeqAIJ     *aij;
3729cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
3730cbcfb4deSHong Zhang   PetscInt       jj;
3731cbcfb4deSHong Zhang #endif
373236db0b34SBarry Smith 
373336db0b34SBarry Smith   PetscFunctionBegin;
3734a96a251dSBarry Smith   if (i[0]) {
3735e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
373636db0b34SBarry Smith   }
3737f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3738f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3739ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3740ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3741ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3742ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3743ab93d7beSBarry Smith 
374436db0b34SBarry Smith   aij->i = i;
374536db0b34SBarry Smith   aij->j = j;
374636db0b34SBarry Smith   aij->a = a;
374736db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
374836db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
3749e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
3750e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
375136db0b34SBarry Smith 
375236db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
375336db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
37542515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
3755e32f2f54SBarry Smith     if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]);
37569985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
3757e32f2f54SBarry Smith       if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii);
3758e32f2f54SBarry Smith       if (j[jj] == j[jj]-1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii);
37599985e31cSBarry Smith     }
376036db0b34SBarry Smith #endif
376136db0b34SBarry Smith   }
37622515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
376336db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
3764e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
3765e32f2f54SBarry Smith     if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]);
376636db0b34SBarry Smith   }
376736db0b34SBarry Smith #endif
376836db0b34SBarry Smith 
3769b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3770b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
377136db0b34SBarry Smith   PetscFunctionReturn(0);
377236db0b34SBarry Smith }
377336db0b34SBarry Smith 
3774cc8ba8e1SBarry Smith #undef __FUNCT__
3775ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3776dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3777cc8ba8e1SBarry Smith {
3778dfbe8321SBarry Smith   PetscErrorCode ierr;
3779cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
378036db0b34SBarry Smith 
3781cc8ba8e1SBarry Smith   PetscFunctionBegin;
37828ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
3783cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3784cc8ba8e1SBarry Smith     a->coloring = coloring;
378512c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
378697f1f81fSBarry Smith     PetscInt             i,*larray;
378712c595b3SBarry Smith     ISColoring      ocoloring;
378808b6dcc0SBarry Smith     ISColoringValue *colors;
378912c595b3SBarry Smith 
379012c595b3SBarry Smith     /* set coloring for diagonal portion */
37910e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
3792d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
379312c595b3SBarry Smith       larray[i] = i;
379412c595b3SBarry Smith     }
3795784ac674SJed Brown     ierr = ISGlobalToLocalMappingApply(A->cmapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
37960e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
3797d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
379812c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
379912c595b3SBarry Smith     }
380012c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
3801d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
380212c595b3SBarry Smith     a->coloring = ocoloring;
380312c595b3SBarry Smith   }
3804cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3805cc8ba8e1SBarry Smith }
3806cc8ba8e1SBarry Smith 
3807dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3808ee4f033dSBarry Smith EXTERN_C_BEGIN
380929c1e371SBarry Smith #include "adic/ad_utils.h"
3810ee4f033dSBarry Smith EXTERN_C_END
3811cc8ba8e1SBarry Smith 
3812cc8ba8e1SBarry Smith #undef __FUNCT__
3813ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3814dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3815cc8ba8e1SBarry Smith {
3816cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3817d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
38184440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
381908b6dcc0SBarry Smith   ISColoringValue *color;
3820cc8ba8e1SBarry Smith 
3821cc8ba8e1SBarry Smith   PetscFunctionBegin;
3822e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
38234440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3824cc8ba8e1SBarry Smith   color = a->coloring->colors;
3825cc8ba8e1SBarry Smith   /* loop over rows */
3826cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3827cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3828cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3829cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3830cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3831cc8ba8e1SBarry Smith     }
38324440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3833ee4f033dSBarry Smith   }
3834ee4f033dSBarry Smith   PetscFunctionReturn(0);
3835ee4f033dSBarry Smith }
3836ee4f033dSBarry Smith #endif
3837ee4f033dSBarry Smith 
3838ee4f033dSBarry Smith #undef __FUNCT__
3839ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
384097f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3841ee4f033dSBarry Smith {
3842ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3843d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
384454f21887SBarry Smith   MatScalar       *v = a->a;
384554f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
384608b6dcc0SBarry Smith   ISColoringValue *color;
3847ee4f033dSBarry Smith 
3848ee4f033dSBarry Smith   PetscFunctionBegin;
3849e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3850ee4f033dSBarry Smith   color = a->coloring->colors;
3851ee4f033dSBarry Smith   /* loop over rows */
3852ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3853ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3854ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3855ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3856ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3857ee4f033dSBarry Smith     }
3858ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3859cc8ba8e1SBarry Smith   }
3860cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3861cc8ba8e1SBarry Smith }
386236db0b34SBarry Smith 
386381824310SBarry Smith /*
386481824310SBarry Smith     Special version for direct calls from Fortran
386581824310SBarry Smith */
38667087cfbeSBarry Smith #include "private/fortranimpl.h"
386781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
386881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
386981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
387081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
387181824310SBarry Smith #endif
387281824310SBarry Smith 
387381824310SBarry Smith /* Change these macros so can be used in void function */
387481824310SBarry Smith #undef CHKERRQ
38757adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
387681824310SBarry Smith #undef SETERRQ2
3877e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
387881824310SBarry Smith 
387981824310SBarry Smith EXTERN_C_BEGIN
388081824310SBarry Smith #undef __FUNCT__
388181824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
38821f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
388381824310SBarry Smith {
388481824310SBarry Smith   Mat            A = *AA;
388581824310SBarry Smith   PetscInt       m = *mm, n = *nn;
388681824310SBarry Smith   InsertMode     is = *isis;
388781824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
388881824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
388981824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
389081824310SBarry Smith   PetscErrorCode ierr;
389181824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
389254f21887SBarry Smith   MatScalar      *ap,value,*aa;
3893ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
3894ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
389581824310SBarry Smith 
389681824310SBarry Smith   PetscFunctionBegin;
3897d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
389881824310SBarry Smith   imax = a->imax;
389981824310SBarry Smith   ai = a->i;
390081824310SBarry Smith   ailen = a->ilen;
390181824310SBarry Smith   aj = a->j;
390281824310SBarry Smith   aa = a->a;
390381824310SBarry Smith 
390481824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
390581824310SBarry Smith     row  = im[k];
390681824310SBarry Smith     if (row < 0) continue;
390781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3908d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
390981824310SBarry Smith #endif
391081824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
391181824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
391281824310SBarry Smith     low  = 0;
391381824310SBarry Smith     high = nrow;
391481824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
391581824310SBarry Smith       if (in[l] < 0) continue;
391681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3917d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
391881824310SBarry Smith #endif
391981824310SBarry Smith       col = in[l];
392081824310SBarry Smith       if (roworiented) {
392181824310SBarry Smith         value = v[l + k*n];
392281824310SBarry Smith       } else {
392381824310SBarry Smith         value = v[k + l*m];
392481824310SBarry Smith       }
392581824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
392681824310SBarry Smith 
392781824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
392881824310SBarry Smith       lastcol = col;
392981824310SBarry Smith       while (high-low > 5) {
393081824310SBarry Smith         t = (low+high)/2;
393181824310SBarry Smith         if (rp[t] > col) high = t;
393281824310SBarry Smith         else             low  = t;
393381824310SBarry Smith       }
393481824310SBarry Smith       for (i=low; i<high; i++) {
393581824310SBarry Smith         if (rp[i] > col) break;
393681824310SBarry Smith         if (rp[i] == col) {
393781824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
393881824310SBarry Smith           else                  ap[i] = value;
393981824310SBarry Smith           goto noinsert;
394081824310SBarry Smith         }
394181824310SBarry Smith       }
394281824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
394381824310SBarry Smith       if (nonew == 1) goto noinsert;
39447adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
3945fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
394681824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
394781824310SBarry Smith       /* shift up all the later entries in this row */
394881824310SBarry Smith       for (ii=N; ii>=i; ii--) {
394981824310SBarry Smith         rp[ii+1] = rp[ii];
395081824310SBarry Smith         ap[ii+1] = ap[ii];
395181824310SBarry Smith       }
395281824310SBarry Smith       rp[i] = col;
395381824310SBarry Smith       ap[i] = value;
395481824310SBarry Smith       noinsert:;
395581824310SBarry Smith       low = i + 1;
395681824310SBarry Smith     }
395781824310SBarry Smith     ailen[row] = nrow;
395881824310SBarry Smith   }
395981824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
396081824310SBarry Smith   PetscFunctionReturnVoid();
396181824310SBarry Smith }
396281824310SBarry Smith EXTERN_C_END
3963*62298a1eSBarry Smith 
3964*62298a1eSBarry Smith #undef __FUNCT__
3965*62298a1eSBarry Smith #define __FUNCT__ "MatSeqAIJFindZeroRows"
3966*62298a1eSBarry Smith /*@C
3967*62298a1eSBarry Smith       MatSeqAIJFindZeroRows - Locate all rows that are not completely zero in the matrix
3968*62298a1eSBarry Smith 
3969*62298a1eSBarry Smith   Input Parameter:
3970*62298a1eSBarry Smith .    A  - the matrix
3971*62298a1eSBarry Smith 
3972*62298a1eSBarry Smith   Output Parameter:
3973*62298a1eSBarry Smith .    keptrows - the rows that are not completely zero
3974*62298a1eSBarry Smith 
3975*62298a1eSBarry Smith  @*/
3976*62298a1eSBarry Smith PetscErrorCode MatSeqAIJFindZeroRows(Mat A,IS *keptrows)
3977*62298a1eSBarry Smith {
3978*62298a1eSBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
3979*62298a1eSBarry Smith   const MatScalar   *aa;
3980*62298a1eSBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
3981*62298a1eSBarry Smith   const PetscInt    *ii;
3982*62298a1eSBarry Smith   PetscInt          n,i,j,*rows;
3983*62298a1eSBarry Smith   PetscErrorCode    ierr;
3984*62298a1eSBarry Smith 
3985*62298a1eSBarry Smith   PetscFunctionBegin;
3986*62298a1eSBarry Smith   *keptrows = 0;
3987*62298a1eSBarry Smith   ii        = a->i;
3988*62298a1eSBarry Smith   for (i=0; i<m; i++) {
3989*62298a1eSBarry Smith     n   = ii[i+1] - ii[i];
3990*62298a1eSBarry Smith     if (!n) {
3991*62298a1eSBarry Smith       cnt++;
3992*62298a1eSBarry Smith       goto ok1;
3993*62298a1eSBarry Smith     }
3994*62298a1eSBarry Smith     aa  = a->a + ii[i];
3995*62298a1eSBarry Smith     for (j=0; j<n; j++) {
3996*62298a1eSBarry Smith       if (aa[j] != 0.0) goto ok1;
3997*62298a1eSBarry Smith     }
3998*62298a1eSBarry Smith     cnt++;
3999*62298a1eSBarry Smith     ok1:;
4000*62298a1eSBarry Smith   }
4001*62298a1eSBarry Smith   if (!cnt) PetscFunctionReturn(0);
4002*62298a1eSBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
4003*62298a1eSBarry Smith   cnt  = 0;
4004*62298a1eSBarry Smith   for (i=0; i<m; i++) {
4005*62298a1eSBarry Smith     n   = ii[i+1] - ii[i];
4006*62298a1eSBarry Smith     if (!n) continue;
4007*62298a1eSBarry Smith     aa  = a->a + ii[i];
4008*62298a1eSBarry Smith     for (j=0; j<n; j++) {
4009*62298a1eSBarry Smith       if (aa[j] != 0.0) {
4010*62298a1eSBarry Smith         rows[cnt++] = i;
4011*62298a1eSBarry Smith         break;
4012*62298a1eSBarry Smith       }
4013*62298a1eSBarry Smith     }
4014*62298a1eSBarry Smith   }
4015*62298a1eSBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
4016*62298a1eSBarry Smith   PetscFunctionReturn(0);
4017*62298a1eSBarry Smith }
4018