xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 51d315f7f51405b454a6b2ffbc3c7276a5e2a085)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
1117ab2063SBarry Smith 
120716a85fSBarry Smith 
130716a85fSBarry Smith #undef __FUNCT__
140716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
150716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
160716a85fSBarry Smith {
170716a85fSBarry Smith   PetscErrorCode ierr;
180716a85fSBarry Smith   PetscInt       i,m,n;
190716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
200716a85fSBarry Smith 
210716a85fSBarry Smith   PetscFunctionBegin;
220716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
230716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
240716a85fSBarry Smith   if (type == NORM_2) {
250716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
260716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
270716a85fSBarry Smith     }
280716a85fSBarry Smith   } else if (type == NORM_1) {
290716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
300716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
310716a85fSBarry Smith     }
320716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
330716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
340716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
350716a85fSBarry Smith     }
360716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
370716a85fSBarry Smith 
380716a85fSBarry Smith   if (type == NORM_2) {
390716a85fSBarry Smith     for (i=0; i<n; i++) norms[i] = sqrt(norms[i]);
400716a85fSBarry Smith   }
410716a85fSBarry Smith   PetscFunctionReturn(0);
420716a85fSBarry Smith }
430716a85fSBarry Smith 
444a2ae208SSatish Balay #undef __FUNCT__
456ce1633cSBarry Smith #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
466ce1633cSBarry Smith PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
476ce1633cSBarry Smith {
486ce1633cSBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
496ce1633cSBarry Smith   const MatScalar   *aa = a->a;
506ce1633cSBarry Smith   PetscInt          i,m=A->rmap->n,cnt = 0;
516ce1633cSBarry Smith   const PetscInt    *jj = a->j,*diag;
526ce1633cSBarry Smith   PetscInt          *rows;
536ce1633cSBarry Smith   PetscErrorCode    ierr;
546ce1633cSBarry Smith 
556ce1633cSBarry Smith   PetscFunctionBegin;
566ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
576ce1633cSBarry Smith   diag = a->diag;
586ce1633cSBarry Smith   for (i=0; i<m; i++) {
596ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
606ce1633cSBarry Smith       cnt++;
616ce1633cSBarry Smith     }
626ce1633cSBarry Smith   }
636ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr);
646ce1633cSBarry Smith   cnt  = 0;
656ce1633cSBarry Smith   for (i=0; i<m; i++) {
666ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
676ce1633cSBarry Smith       rows[cnt++] = i;
686ce1633cSBarry Smith     }
696ce1633cSBarry Smith   }
706ce1633cSBarry Smith   ierr = ISCreateGeneral(((PetscObject)A)->comm,cnt,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
716ce1633cSBarry Smith   PetscFunctionReturn(0);
726ce1633cSBarry Smith }
736ce1633cSBarry Smith 
746ce1633cSBarry Smith #undef __FUNCT__
75b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
76b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
77b3a44c85SBarry Smith {
78b3a44c85SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
79b3a44c85SBarry Smith   const MatScalar   *aa;
80b3a44c85SBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
81b3a44c85SBarry Smith   const PetscInt    *ii;
82b3a44c85SBarry Smith   PetscInt          n,i,j,*rows;
83b3a44c85SBarry Smith   PetscErrorCode    ierr;
84b3a44c85SBarry Smith 
85b3a44c85SBarry Smith   PetscFunctionBegin;
86b3a44c85SBarry Smith   *keptrows = 0;
87b3a44c85SBarry Smith   ii        = a->i;
88b3a44c85SBarry Smith   for (i=0; i<m; i++) {
89b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
90b3a44c85SBarry Smith     if (!n) {
91b3a44c85SBarry Smith       cnt++;
92b3a44c85SBarry Smith       goto ok1;
93b3a44c85SBarry Smith     }
94b3a44c85SBarry Smith     aa  = a->a + ii[i];
95b3a44c85SBarry Smith     for (j=0; j<n; j++) {
96b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
97b3a44c85SBarry Smith     }
98b3a44c85SBarry Smith     cnt++;
99b3a44c85SBarry Smith     ok1:;
100b3a44c85SBarry Smith   }
101b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
102b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
103b3a44c85SBarry Smith   cnt  = 0;
104b3a44c85SBarry Smith   for (i=0; i<m; i++) {
105b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
106b3a44c85SBarry Smith     if (!n) continue;
107b3a44c85SBarry Smith     aa  = a->a + ii[i];
108b3a44c85SBarry Smith     for (j=0; j<n; j++) {
109b3a44c85SBarry Smith       if (aa[j] != 0.0) {
110b3a44c85SBarry Smith         rows[cnt++] = i;
111b3a44c85SBarry Smith         break;
112b3a44c85SBarry Smith       }
113b3a44c85SBarry Smith     }
114b3a44c85SBarry Smith   }
115b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
116b3a44c85SBarry Smith   PetscFunctionReturn(0);
117b3a44c85SBarry Smith }
118b3a44c85SBarry Smith 
119b3a44c85SBarry Smith #undef __FUNCT__
12079299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1217087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
12279299369SBarry Smith {
12379299369SBarry Smith   PetscErrorCode ierr;
12479299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
125d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
12654f21887SBarry Smith   MatScalar      *aa = aij->a;
12754f21887SBarry Smith   PetscScalar    *v;
128ace3abfcSBarry Smith   PetscBool      missing;
12979299369SBarry Smith 
13079299369SBarry Smith   PetscFunctionBegin;
13109f38230SBarry Smith   if (Y->assembled) {
13209f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
13309f38230SBarry Smith     if (!missing) {
13479299369SBarry Smith       diag = aij->diag;
13579299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
13679299369SBarry Smith       if (is == INSERT_VALUES) {
13779299369SBarry Smith 	for (i=0; i<m; i++) {
13879299369SBarry Smith 	  aa[diag[i]] = v[i];
13979299369SBarry Smith 	}
14079299369SBarry Smith       } else {
14179299369SBarry Smith 	for (i=0; i<m; i++) {
14279299369SBarry Smith 	  aa[diag[i]] += v[i];
14379299369SBarry Smith 	}
14479299369SBarry Smith       }
14579299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
14679299369SBarry Smith       PetscFunctionReturn(0);
14779299369SBarry Smith     }
14809f38230SBarry Smith   }
14909f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
15009f38230SBarry Smith   PetscFunctionReturn(0);
15109f38230SBarry Smith }
15279299369SBarry Smith 
15379299369SBarry Smith #undef __FUNCT__
1544a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
155ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
15617ab2063SBarry Smith {
157416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
158dfbe8321SBarry Smith   PetscErrorCode ierr;
15997f1f81fSBarry Smith   PetscInt       i,ishift;
16017ab2063SBarry Smith 
1613a40ed3dSBarry Smith   PetscFunctionBegin;
162d0f46423SBarry Smith   *m     = A->rmap->n;
1633a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
164bfeeae90SHong Zhang   ishift = 0;
16553e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
166d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
167bfeeae90SHong Zhang   } else if (oshift == 1) {
168d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1693b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
170d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
171d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
172ecc77c7aSBarry Smith     if (ja) {
17397f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
1743b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
175ecc77c7aSBarry Smith     }
1766945ee14SBarry Smith   } else {
177ecc77c7aSBarry Smith     *ia = a->i;
178ecc77c7aSBarry Smith     if (ja) *ja = a->j;
179a2ce50c7SBarry Smith   }
1803a40ed3dSBarry Smith   PetscFunctionReturn(0);
181a2744918SBarry Smith }
182a2744918SBarry Smith 
1834a2ae208SSatish Balay #undef __FUNCT__
1844a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
185ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1866945ee14SBarry Smith {
187dfbe8321SBarry Smith   PetscErrorCode ierr;
1886945ee14SBarry Smith 
1893a40ed3dSBarry Smith   PetscFunctionBegin;
1903a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
191bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
192606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
193ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
194bcd2baecSBarry Smith   }
1953a40ed3dSBarry Smith   PetscFunctionReturn(0);
19617ab2063SBarry Smith }
19717ab2063SBarry Smith 
1984a2ae208SSatish Balay #undef __FUNCT__
1994a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
200ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2013b2fbd54SBarry Smith {
2023b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
203dfbe8321SBarry Smith   PetscErrorCode ierr;
204d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
20597f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2063b2fbd54SBarry Smith 
2073a40ed3dSBarry Smith   PetscFunctionBegin;
208899cda47SBarry Smith   *nn = n;
2093a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2103b2fbd54SBarry Smith   if (symmetric) {
211d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2123b2fbd54SBarry Smith   } else {
21397f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
21497f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
21597f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
21697f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
2173b2fbd54SBarry Smith     jj = a->j;
2183b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
219bfeeae90SHong Zhang       collengths[jj[i]]++;
2203b2fbd54SBarry Smith     }
2213b2fbd54SBarry Smith     cia[0] = oshift;
2223b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2233b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2243b2fbd54SBarry Smith     }
22597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2263b2fbd54SBarry Smith     jj   = a->j;
227a93ec695SBarry Smith     for (row=0; row<m; row++) {
228a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
229a93ec695SBarry Smith       for (i=0; i<mr; i++) {
230bfeeae90SHong Zhang         col = *jj++;
2313b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2323b2fbd54SBarry Smith       }
2333b2fbd54SBarry Smith     }
234606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2353b2fbd54SBarry Smith     *ia = cia; *ja = cja;
2363b2fbd54SBarry Smith   }
2373a40ed3dSBarry Smith   PetscFunctionReturn(0);
2383b2fbd54SBarry Smith }
2393b2fbd54SBarry Smith 
2404a2ae208SSatish Balay #undef __FUNCT__
2414a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
242ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2433b2fbd54SBarry Smith {
244dfbe8321SBarry Smith   PetscErrorCode ierr;
245606d414cSSatish Balay 
2463a40ed3dSBarry Smith   PetscFunctionBegin;
2473a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2483b2fbd54SBarry Smith 
249606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
250606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2513b2fbd54SBarry Smith 
2523a40ed3dSBarry Smith   PetscFunctionReturn(0);
2533b2fbd54SBarry Smith }
2543b2fbd54SBarry Smith 
25587d4246cSBarry Smith #undef __FUNCT__
25687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
25787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
25887d4246cSBarry Smith {
25987d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26087d4246cSBarry Smith   PetscInt       *ai = a->i;
26187d4246cSBarry Smith   PetscErrorCode ierr;
26287d4246cSBarry Smith 
26387d4246cSBarry Smith   PetscFunctionBegin;
26487d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
26587d4246cSBarry Smith   PetscFunctionReturn(0);
26687d4246cSBarry Smith }
26787d4246cSBarry Smith 
2684a2ae208SSatish Balay #undef __FUNCT__
2694a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
27097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
27117ab2063SBarry Smith {
272416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
273e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
27497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
2756849ba73SBarry Smith   PetscErrorCode ierr;
276e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
27754f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
278ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
279ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
28017ab2063SBarry Smith 
2813a40ed3dSBarry Smith   PetscFunctionBegin;
28271fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
28317ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
284416022c9SBarry Smith     row  = im[k];
2855ef9f2a5SBarry Smith     if (row < 0) continue;
2862515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
287e32f2f54SBarry 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);
2883b2fbd54SBarry Smith #endif
289bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
29017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
291416022c9SBarry Smith     low  = 0;
292c71e6ed7SBarry Smith     high = nrow;
29317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
2945ef9f2a5SBarry Smith       if (in[l] < 0) continue;
2952515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
296e32f2f54SBarry 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);
2973b2fbd54SBarry Smith #endif
298bfeeae90SHong Zhang       col = in[l];
29916371a99SBarry Smith       if (v) {
3004b0e389bSBarry Smith 	if (roworiented) {
3015ef9f2a5SBarry Smith 	  value = v[l + k*n];
302bef8e0ddSBarry Smith 	} else {
3034b0e389bSBarry Smith 	  value = v[k + l*m];
3044b0e389bSBarry Smith 	}
30516371a99SBarry Smith       } else {
30675567043SBarry Smith         value = 0.;
30716371a99SBarry Smith       }
308abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
30936db0b34SBarry Smith 
3107cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
311e2ee6c50SBarry Smith       lastcol = col;
312416022c9SBarry Smith       while (high-low > 5) {
313416022c9SBarry Smith         t = (low+high)/2;
314416022c9SBarry Smith         if (rp[t] > col) high = t;
315416022c9SBarry Smith         else             low  = t;
31617ab2063SBarry Smith       }
317416022c9SBarry Smith       for (i=low; i<high; i++) {
31817ab2063SBarry Smith         if (rp[i] > col) break;
31917ab2063SBarry Smith         if (rp[i] == col) {
320416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
32117ab2063SBarry Smith           else                  ap[i] = value;
322e44c0bd4SBarry Smith           low = i + 1;
32317ab2063SBarry Smith           goto noinsert;
32417ab2063SBarry Smith         }
32517ab2063SBarry Smith       }
326abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
327c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
328e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
329fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
330c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
331416022c9SBarry Smith       /* shift up all the later entries in this row */
332416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
33317ab2063SBarry Smith         rp[ii+1] = rp[ii];
33417ab2063SBarry Smith         ap[ii+1] = ap[ii];
33517ab2063SBarry Smith       }
33617ab2063SBarry Smith       rp[i] = col;
33717ab2063SBarry Smith       ap[i] = value;
338416022c9SBarry Smith       low   = i + 1;
339e44c0bd4SBarry Smith       noinsert:;
34017ab2063SBarry Smith     }
34117ab2063SBarry Smith     ailen[row] = nrow;
34217ab2063SBarry Smith   }
34388e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
3443a40ed3dSBarry Smith   PetscFunctionReturn(0);
34517ab2063SBarry Smith }
34617ab2063SBarry Smith 
34781824310SBarry Smith 
3484a2ae208SSatish Balay #undef __FUNCT__
3494a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
350a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
3517eb43aa7SLois Curfman McInnes {
3527eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
35397f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
35497f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
35554f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
3567eb43aa7SLois Curfman McInnes 
3573a40ed3dSBarry Smith   PetscFunctionBegin;
3587eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
3597eb43aa7SLois Curfman McInnes     row  = im[k];
360e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
361e32f2f54SBarry 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);
362bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
3637eb43aa7SLois Curfman McInnes     nrow = ailen[row];
3647eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
365e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
366e32f2f54SBarry 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);
367bfeeae90SHong Zhang       col = in[l] ;
3687eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
3697eb43aa7SLois Curfman McInnes       while (high-low > 5) {
3707eb43aa7SLois Curfman McInnes         t = (low+high)/2;
3717eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
3727eb43aa7SLois Curfman McInnes         else             low  = t;
3737eb43aa7SLois Curfman McInnes       }
3747eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
3757eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
3767eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
377b49de8d1SLois Curfman McInnes           *v++ = ap[i];
3787eb43aa7SLois Curfman McInnes           goto finished;
3797eb43aa7SLois Curfman McInnes         }
3807eb43aa7SLois Curfman McInnes       }
38197e567efSBarry Smith       *v++ = 0.0;
3827eb43aa7SLois Curfman McInnes       finished:;
3837eb43aa7SLois Curfman McInnes     }
3847eb43aa7SLois Curfman McInnes   }
3853a40ed3dSBarry Smith   PetscFunctionReturn(0);
3867eb43aa7SLois Curfman McInnes }
3877eb43aa7SLois Curfman McInnes 
38817ab2063SBarry Smith 
3894a2ae208SSatish Balay #undef __FUNCT__
3904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
391dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
39217ab2063SBarry Smith {
393416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3946849ba73SBarry Smith   PetscErrorCode ierr;
3956f69ff64SBarry Smith   PetscInt       i,*col_lens;
3966f69ff64SBarry Smith   int            fd;
39717ab2063SBarry Smith 
3983a40ed3dSBarry Smith   PetscFunctionBegin;
399b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
400d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4010700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
402d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
403d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
404416022c9SBarry Smith   col_lens[3] = a->nz;
405416022c9SBarry Smith 
406416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
407d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
408416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
40917ab2063SBarry Smith   }
410d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
411606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
412416022c9SBarry Smith 
413416022c9SBarry Smith   /* store column indices (zero start index) */
4146f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
415416022c9SBarry Smith 
416416022c9SBarry Smith   /* store nonzero values */
4176f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
4183a40ed3dSBarry Smith   PetscFunctionReturn(0);
41917ab2063SBarry Smith }
420416022c9SBarry Smith 
42109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
422cd155464SBarry Smith 
4234a2ae208SSatish Balay #undef __FUNCT__
4244a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
425dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
426416022c9SBarry Smith {
427416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
428dfbe8321SBarry Smith   PetscErrorCode    ierr;
429d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
430e060cb09SBarry Smith   const char        *name;
431f3ef73ceSBarry Smith   PetscViewerFormat format;
43217ab2063SBarry Smith 
4333a40ed3dSBarry Smith   PetscFunctionBegin;
434b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
43571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
43697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
437d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
438d00d2cf4SBarry Smith       nofinalvalue = 1;
439d00d2cf4SBarry Smith     }
440d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
441d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
44277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
44377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
444b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
44517ab2063SBarry Smith 
44617ab2063SBarry Smith     for (i=0; i<m; i++) {
447416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
448aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
44977431f27SBarry 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);
45017ab2063SBarry Smith #else
45177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
45217ab2063SBarry Smith #endif
45317ab2063SBarry Smith       }
45417ab2063SBarry Smith     }
455d00d2cf4SBarry Smith     if (nofinalvalue) {
456d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
457d00d2cf4SBarry Smith     }
458317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
459fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
460d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
46168369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
462cd155464SBarry Smith      PetscFunctionReturn(0);
463fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
464d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4657566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
46644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
46777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
46844cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
469aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
47036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
471a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
47236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
473a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
47436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
475a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
4766831982aSBarry Smith         }
47744cd7ae7SLois Curfman McInnes #else
478a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
47944cd7ae7SLois Curfman McInnes #endif
48044cd7ae7SLois Curfman McInnes       }
481b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
48244cd7ae7SLois Curfman McInnes     }
483d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
484fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
48597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
486d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4877566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
48897f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
489496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
490496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
491496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
492496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
493aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
495496be53dSLois Curfman McInnes #else
496496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
497496be53dSLois Curfman McInnes #endif
498496be53dSLois Curfman McInnes         }
499496be53dSLois Curfman McInnes       }
500496be53dSLois Curfman McInnes     }
5012e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
50277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5032e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
50477431f27SBarry 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);}
50577431f27SBarry 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);}
50677431f27SBarry 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);}
50777431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
50877431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
50977431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
510496be53dSLois Curfman McInnes     }
511b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
512606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
513496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
514496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
51577431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
516496be53dSLois Curfman McInnes       }
517b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
518496be53dSLois Curfman McInnes     }
519b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
520496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
521496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
522496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
523aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
52436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
525b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
5266831982aSBarry Smith           }
527496be53dSLois Curfman McInnes #else
528b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
529496be53dSLois Curfman McInnes #endif
530496be53dSLois Curfman McInnes         }
531496be53dSLois Curfman McInnes       }
532b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
533496be53dSLois Curfman McInnes     }
534d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
535fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
53697f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
53787828ca2SBarry Smith     PetscScalar value;
53802594712SBarry Smith 
539d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5407566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
54102594712SBarry Smith     for (i=0; i<m; i++) {
54202594712SBarry Smith       jcnt = 0;
543d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
544e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
54502594712SBarry Smith           value = a->a[cnt++];
546e24b481bSBarry Smith           jcnt++;
54702594712SBarry Smith         } else {
54802594712SBarry Smith           value = 0.0;
54902594712SBarry Smith         }
550aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
551b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
55202594712SBarry Smith #else
553b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
55402594712SBarry Smith #endif
55502594712SBarry Smith       }
556b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
55702594712SBarry Smith     }
558d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5593c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
560d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5617566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
5623c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5633c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
5643c215bfdSMatthew Knepley #else
5653c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
5663c215bfdSMatthew Knepley #endif
567d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
5683c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
5693c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5703c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5713c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
5723c215bfdSMatthew 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);
5733c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
5743c215bfdSMatthew 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);
5753c215bfdSMatthew Knepley         } else {
5763c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5773c215bfdSMatthew Knepley         }
5783c215bfdSMatthew Knepley #else
5793c215bfdSMatthew Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr);
5803c215bfdSMatthew Knepley #endif
5813c215bfdSMatthew Knepley       }
5823c215bfdSMatthew Knepley     }
583d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5843a40ed3dSBarry Smith   } else {
585d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5867566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
587d5f3da31SBarry Smith     if (A->factortype){
58816cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
58916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
59016cd7e1dSShri Abhyankar         /* L part */
59116cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
59216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
59316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
59416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
59616cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59716cd7e1dSShri Abhyankar           } else {
59816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
59916cd7e1dSShri Abhyankar           }
60016cd7e1dSShri Abhyankar #else
60116cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
60216cd7e1dSShri Abhyankar #endif
60316cd7e1dSShri Abhyankar         }
60416cd7e1dSShri Abhyankar 	/* diagonal */
60516cd7e1dSShri Abhyankar 	j = a->diag[i];
60616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
60716cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
60816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
60916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
61016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
61116cd7e1dSShri Abhyankar           } else {
61216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
61316cd7e1dSShri Abhyankar           }
61416cd7e1dSShri Abhyankar #else
61516cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
61616cd7e1dSShri Abhyankar #endif
61716cd7e1dSShri Abhyankar 
61816cd7e1dSShri Abhyankar 	/* U part */
61916cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
62016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
62116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
62216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
62416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62516cd7e1dSShri Abhyankar           } else {
62616cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
62716cd7e1dSShri Abhyankar           }
62816cd7e1dSShri Abhyankar #else
62916cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
63016cd7e1dSShri Abhyankar #endif
63116cd7e1dSShri Abhyankar }
63216cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
63316cd7e1dSShri Abhyankar         }
63416cd7e1dSShri Abhyankar     } else {
63517ab2063SBarry Smith       for (i=0; i<m; i++) {
63677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
637416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
638aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
63936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
640a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64136db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
642a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6433a40ed3dSBarry Smith           } else {
644a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
64517ab2063SBarry Smith           }
64617ab2063SBarry Smith #else
647a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
64817ab2063SBarry Smith #endif
64917ab2063SBarry Smith         }
650b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65117ab2063SBarry Smith       }
65216cd7e1dSShri Abhyankar     }
653d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
65417ab2063SBarry Smith   }
655b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6563a40ed3dSBarry Smith   PetscFunctionReturn(0);
657416022c9SBarry Smith }
658416022c9SBarry Smith 
6594a2ae208SSatish Balay #undef __FUNCT__
6604a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
661dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
662416022c9SBarry Smith {
663480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
664416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
665dfbe8321SBarry Smith   PetscErrorCode    ierr;
666d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
66736db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
668b0a32e0cSBarry Smith   PetscViewer       viewer;
669f3ef73ceSBarry Smith   PetscViewerFormat format;
670cddf8d76SBarry Smith 
6713a40ed3dSBarry Smith   PetscFunctionBegin;
672480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
673b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
67419bcc07fSBarry Smith 
675b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
676416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
6770513a670SBarry Smith 
678fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
6790513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
680b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
681416022c9SBarry Smith     for (i=0; i<m; i++) {
682cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
683bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
684bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
685aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
68636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
687cddf8d76SBarry Smith #else
688cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
689cddf8d76SBarry Smith #endif
690b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
691cddf8d76SBarry Smith       }
692cddf8d76SBarry Smith     }
693b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
694cddf8d76SBarry Smith     for (i=0; i<m; i++) {
695cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
696bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
697bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
698cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
699b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
700cddf8d76SBarry Smith       }
701cddf8d76SBarry Smith     }
702b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
703cddf8d76SBarry Smith     for (i=0; i<m; i++) {
704cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
705bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
706bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
707aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
709cddf8d76SBarry Smith #else
710cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
711cddf8d76SBarry Smith #endif
712b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
713416022c9SBarry Smith       }
714416022c9SBarry Smith     }
7150513a670SBarry Smith   } else {
7160513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
7170513a670SBarry Smith     /* first determine max of all nonzero values */
71897f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
719b0a32e0cSBarry Smith     PetscDraw   popup;
72036db0b34SBarry Smith     PetscReal scale;
7210513a670SBarry Smith 
7220513a670SBarry Smith     for (i=0; i<nz; i++) {
7230513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
7240513a670SBarry Smith     }
725b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
726b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
727b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
7280513a670SBarry Smith     count = 0;
7290513a670SBarry Smith     for (i=0; i<m; i++) {
7300513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
731bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
732bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
73397f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
734b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
7350513a670SBarry Smith         count++;
7360513a670SBarry Smith       }
7370513a670SBarry Smith     }
7380513a670SBarry Smith   }
739480ef9eaSBarry Smith   PetscFunctionReturn(0);
740480ef9eaSBarry Smith }
741cddf8d76SBarry Smith 
7424a2ae208SSatish Balay #undef __FUNCT__
7434a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
744dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
745480ef9eaSBarry Smith {
746dfbe8321SBarry Smith   PetscErrorCode ierr;
747b0a32e0cSBarry Smith   PetscDraw      draw;
74836db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
749ace3abfcSBarry Smith   PetscBool      isnull;
750480ef9eaSBarry Smith 
751480ef9eaSBarry Smith   PetscFunctionBegin;
752b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
753b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
754480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
755480ef9eaSBarry Smith 
756480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
757d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
758480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
759b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
760b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
761480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7623a40ed3dSBarry Smith   PetscFunctionReturn(0);
763416022c9SBarry Smith }
764416022c9SBarry Smith 
7654a2ae208SSatish Balay #undef __FUNCT__
7664a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
767dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
768416022c9SBarry Smith {
769dfbe8321SBarry Smith   PetscErrorCode ierr;
770ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
771416022c9SBarry Smith 
7723a40ed3dSBarry Smith   PetscFunctionBegin;
7732692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
7742692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
7752692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
776c45a1595SBarry Smith   if (iascii) {
7773a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7780f5bd95cSBarry Smith   } else if (isbinary) {
7793a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
7800f5bd95cSBarry Smith   } else if (isdraw) {
7813a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
7825cd90555SBarry Smith   } else {
783e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
78417ab2063SBarry Smith   }
7854108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
7863a40ed3dSBarry Smith   PetscFunctionReturn(0);
78717ab2063SBarry Smith }
78819bcc07fSBarry Smith 
7894a2ae208SSatish Balay #undef __FUNCT__
7904a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
791dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
79217ab2063SBarry Smith {
793416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7946849ba73SBarry Smith   PetscErrorCode ierr;
79597f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
796d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
79754f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
7983447b6efSHong Zhang   PetscReal      ratio=0.6;
79917ab2063SBarry Smith 
8003a40ed3dSBarry Smith   PetscFunctionBegin;
8013a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
80217ab2063SBarry Smith 
80343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
80417ab2063SBarry Smith   for (i=1; i<m; i++) {
805416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
80617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
80794a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
80817ab2063SBarry Smith     if (fshift) {
809bfeeae90SHong Zhang       ip = aj + ai[i] ;
810bfeeae90SHong Zhang       ap = aa + ai[i] ;
81117ab2063SBarry Smith       N  = ailen[i];
81217ab2063SBarry Smith       for (j=0; j<N; j++) {
81317ab2063SBarry Smith         ip[j-fshift] = ip[j];
81417ab2063SBarry Smith         ap[j-fshift] = ap[j];
81517ab2063SBarry Smith       }
81617ab2063SBarry Smith     }
81717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
81817ab2063SBarry Smith   }
81917ab2063SBarry Smith   if (m) {
82017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
82117ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
82217ab2063SBarry Smith   }
82317ab2063SBarry Smith   /* reset ilen and imax for each row */
82417ab2063SBarry Smith   for (i=0; i<m; i++) {
82517ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
82617ab2063SBarry Smith   }
827bfeeae90SHong Zhang   a->nz = ai[m];
82865e19b50SBarry 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);
82917ab2063SBarry Smith 
83009f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
831d0f46423SBarry 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);
832ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
833ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
8348e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
835dd5f02e7SSatish Balay   a->reallocs          = 0;
8364e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
83736db0b34SBarry Smith   a->rmax              = rmax;
8384e220ebcSLois Curfman McInnes 
839cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
84088e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
84171c2f376SKris Buschelman 
8424108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
84371f1c65dSBarry Smith 
84471f1c65dSBarry Smith   a->idiagvalid = PETSC_FALSE;
8453a40ed3dSBarry Smith   PetscFunctionReturn(0);
84617ab2063SBarry Smith }
84717ab2063SBarry Smith 
8484a2ae208SSatish Balay #undef __FUNCT__
84999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
85099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
85199cafbc1SBarry Smith {
85299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
85399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
85454f21887SBarry Smith   MatScalar      *aa = a->a;
85599cafbc1SBarry Smith 
85699cafbc1SBarry Smith   PetscFunctionBegin;
85799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
85899cafbc1SBarry Smith   PetscFunctionReturn(0);
85999cafbc1SBarry Smith }
86099cafbc1SBarry Smith 
86199cafbc1SBarry Smith #undef __FUNCT__
86299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
86399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
86499cafbc1SBarry Smith {
86599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
86699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
86754f21887SBarry Smith   MatScalar      *aa = a->a;
86899cafbc1SBarry Smith 
86999cafbc1SBarry Smith   PetscFunctionBegin;
87099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
87199cafbc1SBarry Smith   PetscFunctionReturn(0);
87299cafbc1SBarry Smith }
87399cafbc1SBarry Smith 
87499cafbc1SBarry Smith #undef __FUNCT__
8754a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
876dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
87717ab2063SBarry Smith {
878416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
879dfbe8321SBarry Smith   PetscErrorCode ierr;
8803a40ed3dSBarry Smith 
8813a40ed3dSBarry Smith   PetscFunctionBegin;
882d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
8833a40ed3dSBarry Smith   PetscFunctionReturn(0);
88417ab2063SBarry Smith }
885416022c9SBarry Smith 
8864a2ae208SSatish Balay #undef __FUNCT__
8874a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
888dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
88917ab2063SBarry Smith {
890416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
891dfbe8321SBarry Smith   PetscErrorCode ierr;
892d5d45c9bSBarry Smith 
8933a40ed3dSBarry Smith   PetscFunctionBegin;
894aa482453SBarry Smith #if defined(PETSC_USE_LOG)
895d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
89617ab2063SBarry Smith #endif
897e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
8986bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
8996bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
90005b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
90105b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
90271f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
90305b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
9046bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
90505b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
9066bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
90705b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
9086bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
909cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
910a30b2313SHong Zhang 
9114108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
912bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
913901853e0SKris Buschelman 
914dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
915901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
916901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
917901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
918901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
919901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
9205a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
921901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
922901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
923a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
924901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
9253a40ed3dSBarry Smith   PetscFunctionReturn(0);
92617ab2063SBarry Smith }
92717ab2063SBarry Smith 
9284a2ae208SSatish Balay #undef __FUNCT__
9294a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
930ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
93117ab2063SBarry Smith {
932416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9334846f1f5SKris Buschelman   PetscErrorCode ierr;
9343a40ed3dSBarry Smith 
9353a40ed3dSBarry Smith   PetscFunctionBegin;
936a65d3064SKris Buschelman   switch (op) {
937a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
9384e0d8c25SBarry Smith       a->roworiented       = flg;
939a65d3064SKris Buschelman       break;
940a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
941a9817697SBarry Smith       a->keepnonzeropattern    = flg;
942a65d3064SKris Buschelman       break;
943512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
944512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
945a65d3064SKris Buschelman       break;
946a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
9474e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
948a65d3064SKris Buschelman       break;
949a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
9504e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
951a65d3064SKris Buschelman       break;
95228b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
95328b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
95428b2fa4aSMatthew Knepley       break;
955a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
9564e0d8c25SBarry Smith       a->ignorezeroentries = flg;
9570df259c2SBarry Smith       break;
958cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
959cd6b891eSBarry Smith       a->compressedrow.check = flg;
960d487561eSHong Zhang       break;
9613d472b54SHong Zhang     case MAT_SPD:
9623d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
9633d472b54SHong Zhang       A->spd                             = flg;
9643d472b54SHong Zhang       if (flg) {
9653d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
9663d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
9673d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
9683d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
9693d472b54SHong Zhang       }
9703d472b54SHong Zhang       break;
971b1646e73SJed Brown     case MAT_SYMMETRIC:
972b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
973b1646e73SJed Brown     case MAT_HERMITIAN:
974b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
9754e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
976a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
977a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
978290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
979a65d3064SKris Buschelman       break;
980b87ac2d8SJed Brown     case MAT_USE_INODES:
981b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
982b87ac2d8SJed Brown       break;
983a65d3064SKris Buschelman     default:
984e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
985a65d3064SKris Buschelman   }
9864108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
9873a40ed3dSBarry Smith   PetscFunctionReturn(0);
98817ab2063SBarry Smith }
98917ab2063SBarry Smith 
9904a2ae208SSatish Balay #undef __FUNCT__
9914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
992dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
99317ab2063SBarry Smith {
994416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9956849ba73SBarry Smith   PetscErrorCode ierr;
996d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
99735e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
99817ab2063SBarry Smith 
9993a40ed3dSBarry Smith   PetscFunctionBegin;
1000d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1001e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
100235e7444dSHong Zhang 
1003d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
1004d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
100535e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
100635e7444dSHong Zhang     for (i=0; i<n; i++) x[i] = aa[diag[i]];
100735e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
100835e7444dSHong Zhang     PetscFunctionReturn(0);
100935e7444dSHong Zhang   }
101035e7444dSHong Zhang 
10112dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
10121ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
101335e7444dSHong Zhang   for (i=0; i<n; i++) {
101435e7444dSHong Zhang     nz = ai[i+1] - ai[i];
10152f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
101635e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
101735e7444dSHong Zhang       if (aj[j] == i) {
101835e7444dSHong Zhang         x[i] = aa[j];
101917ab2063SBarry Smith         break;
102017ab2063SBarry Smith       }
102117ab2063SBarry Smith     }
102217ab2063SBarry Smith   }
10231ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
10243a40ed3dSBarry Smith   PetscFunctionReturn(0);
102517ab2063SBarry Smith }
102617ab2063SBarry Smith 
1027c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10284a2ae208SSatish Balay #undef __FUNCT__
10294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1030dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
103117ab2063SBarry Smith {
1032416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
10335c897100SBarry Smith   PetscScalar       *x,*y;
1034dfbe8321SBarry Smith   PetscErrorCode    ierr;
1035d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
10365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1037a77337e4SBarry Smith   MatScalar         *v;
1038a77337e4SBarry Smith   PetscScalar       alpha;
103904fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
10403447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
1041ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
10425c897100SBarry Smith #endif
104317ab2063SBarry Smith 
10443a40ed3dSBarry Smith   PetscFunctionBegin;
10452e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
10461ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
10471ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10485c897100SBarry Smith 
10495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1050bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
10515c897100SBarry Smith #else
10523447b6efSHong Zhang   if (usecprow){
10533447b6efSHong Zhang     m    = cprow.nrows;
10543447b6efSHong Zhang     ii   = cprow.i;
10557b2bb3b9SHong Zhang     ridx = cprow.rindex;
10563447b6efSHong Zhang   } else {
10573447b6efSHong Zhang     ii = a->i;
10583447b6efSHong Zhang   }
105917ab2063SBarry Smith   for (i=0; i<m; i++) {
10603447b6efSHong Zhang     idx   = a->j + ii[i] ;
10613447b6efSHong Zhang     v     = a->a + ii[i] ;
10623447b6efSHong Zhang     n     = ii[i+1] - ii[i];
10633447b6efSHong Zhang     if (usecprow){
10647b2bb3b9SHong Zhang       alpha = x[ridx[i]];
10653447b6efSHong Zhang     } else {
106617ab2063SBarry Smith       alpha = x[i];
10673447b6efSHong Zhang     }
106804fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
106917ab2063SBarry Smith   }
10705c897100SBarry Smith #endif
1071dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
10721ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10731ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10743a40ed3dSBarry Smith   PetscFunctionReturn(0);
107517ab2063SBarry Smith }
107617ab2063SBarry Smith 
10774a2ae208SSatish Balay #undef __FUNCT__
10785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1079dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
10805c897100SBarry Smith {
1081dfbe8321SBarry Smith   PetscErrorCode ierr;
10825c897100SBarry Smith 
10835c897100SBarry Smith   PetscFunctionBegin;
1084170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
10855c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
10865c897100SBarry Smith   PetscFunctionReturn(0);
10875c897100SBarry Smith }
10885c897100SBarry Smith 
1089c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10905c897100SBarry Smith #undef __FUNCT__
10914a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1092dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
109317ab2063SBarry Smith {
1094416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1095d9fead3dSBarry Smith   PetscScalar       *y;
109654f21887SBarry Smith   const PetscScalar *x;
109754f21887SBarry Smith   const MatScalar   *aa;
1098dfbe8321SBarry Smith   PetscErrorCode    ierr;
1099003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1100003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
11018aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1102362ced78SSatish Balay   PetscScalar       sum;
1103ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
110417ab2063SBarry Smith 
1105b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
110697952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1107fee21e36SBarry Smith #endif
1108fee21e36SBarry Smith 
11093a40ed3dSBarry Smith   PetscFunctionBegin;
11103649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11111ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
111297952fefSHong Zhang   aj  = a->j;
111397952fefSHong Zhang   aa  = a->a;
1114416022c9SBarry Smith   ii  = a->i;
11154eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
111697952fefSHong Zhang     m    = a->compressedrow.nrows;
111797952fefSHong Zhang     ii   = a->compressedrow.i;
111897952fefSHong Zhang     ridx = a->compressedrow.rindex;
111997952fefSHong Zhang     for (i=0; i<m; i++){
112097952fefSHong Zhang       n   = ii[i+1] - ii[i];
112197952fefSHong Zhang       aj  = a->j + ii[i];
112297952fefSHong Zhang       aa  = a->a + ii[i];
112397952fefSHong Zhang       sum = 0.0;
1124a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1125003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1126003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
112797952fefSHong Zhang       y[*ridx++] = sum;
112897952fefSHong Zhang     }
112997952fefSHong Zhang   } else { /* do not use compressed row format */
1130b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1131b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1132b05257ddSBarry Smith #else
113317ab2063SBarry Smith     for (i=0; i<m; i++) {
1134003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1135003131ecSBarry Smith       aj  = a->j + ii[i];
1136003131ecSBarry Smith       aa  = a->a + ii[i];
113717ab2063SBarry Smith       sum  = 0.0;
1138a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1139003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
114017ab2063SBarry Smith       y[i] = sum;
114117ab2063SBarry Smith     }
11428d195f9aSBarry Smith #endif
1143b05257ddSBarry Smith   }
1144dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
11453649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11461ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11473a40ed3dSBarry Smith   PetscFunctionReturn(0);
114817ab2063SBarry Smith }
114917ab2063SBarry Smith 
11500ca81413SKerry Stevens //*******************
11510ca81413SKerry Stevens typedef struct {
11520ca81413SKerry Stevens   const MatScalar* matdata;
11530ca81413SKerry Stevens   const PetscScalar* vecdata;
11540ca81413SKerry Stevens   PetscScalar* vecout;
11550ca81413SKerry Stevens   const PetscInt* colindnz;
11560ca81413SKerry Stevens   const PetscInt* rownumnz;
11570ca81413SKerry Stevens   PetscInt numrows;
11580ca81413SKerry Stevens   const PetscInt* specidx;
11590ca81413SKerry Stevens   PetscInt nzr;
11600ca81413SKerry Stevens } MatMult_KernelData;
1161*51d315f7SKerry Stevens MatMult_KernelData* kerneldatap_MatMult = NULL;
1162*51d315f7SKerry Stevens MatMult_KernelData** pdata_MatMult = NULL;
11630ca81413SKerry Stevens 
11640ca81413SKerry Stevens void* MatMult_Kernel(void *arg)
11650ca81413SKerry Stevens {
11660ca81413SKerry Stevens   MatMult_KernelData *data = (MatMult_KernelData*)arg;
11670ca81413SKerry Stevens   PetscScalar       sum;
11680ca81413SKerry Stevens   const MatScalar   *aabase = data->matdata,*aa;
11690ca81413SKerry Stevens   const PetscScalar *x = data->vecdata;
11700ca81413SKerry Stevens   PetscScalar       *y = data->vecout;
11710ca81413SKerry Stevens   const PetscInt    *ajbase = data->colindnz,*aj;
11720ca81413SKerry Stevens   const PetscInt    *ii = data->rownumnz;
11730ca81413SKerry Stevens   PetscInt          m  = data->numrows;
11740ca81413SKerry Stevens   const PetscInt    *ridx = data->specidx;
11750ca81413SKerry Stevens   PetscInt          i,n,nonzerorow = 0;
11760ca81413SKerry Stevens 
11770ca81413SKerry Stevens   if(ridx!=NULL) {
11780ca81413SKerry Stevens     for (i=0; i<m; i++){
11790ca81413SKerry Stevens       n   = ii[i+1] - ii[i];
11800ca81413SKerry Stevens       aj  = ajbase + ii[i];
11810ca81413SKerry Stevens       aa  = aabase + ii[i];
11820ca81413SKerry Stevens       sum = 0.0;
1183*51d315f7SKerry Stevens       /*if(n>0) {
1184*51d315f7SKerry Stevens         PetscSparseDensePlusDot(sum,x,aa,aj,n);
1185*51d315f7SKerry Stevens         nonzerorow++;
1186*51d315f7SKerry Stevens       }*/
11870ca81413SKerry Stevens       nonzerorow += (n>0);
11880ca81413SKerry Stevens       PetscSparseDensePlusDot(sum,x,aa,aj,n);
11890ca81413SKerry Stevens       y[*ridx++] = sum;
11900ca81413SKerry Stevens     }
11910ca81413SKerry Stevens   }
11920ca81413SKerry Stevens   else {
1193*51d315f7SKerry Stevens     PetscInt ibase = data->nzr;
11940ca81413SKerry Stevens     for (i=0; i<m; i++) {
11950ca81413SKerry Stevens       n   = ii[i+1] - ii[i];
11960ca81413SKerry Stevens       aj  = ajbase + ii[i];
11970ca81413SKerry Stevens       aa  = aabase + ii[i];
11980ca81413SKerry Stevens       sum  = 0.0;
1199*51d315f7SKerry Stevens       /*if(n>0) {
1200*51d315f7SKerry Stevens         PetscSparseDensePlusDot(sum,x,aa,aj,n);
1201*51d315f7SKerry Stevens         nonzerorow++;
1202*51d315f7SKerry Stevens       }*/
12030ca81413SKerry Stevens       nonzerorow += (n>0);
12040ca81413SKerry Stevens       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1205*51d315f7SKerry Stevens       y[i+ibase] = sum;
12060ca81413SKerry Stevens     }
12070ca81413SKerry Stevens   }
12080ca81413SKerry Stevens   data->nzr = nonzerorow;
12090ca81413SKerry Stevens   return NULL;
12100ca81413SKerry Stevens }
12110ca81413SKerry Stevens 
12120ca81413SKerry Stevens extern PetscMPIInt PetscMaxThreads;
1213*51d315f7SKerry Stevens PetscErrorCode MainJob(void* (*pFunc)(void*),void**,PetscInt);
1214*51d315f7SKerry Stevens 
12150ca81413SKerry Stevens #undef __FUNCT__
1216*51d315f7SKerry Stevens #define __FUNCT__ "MatMult_SeqPThreadAIJ"
1217*51d315f7SKerry Stevens PetscErrorCode MatMult_SeqPThreadAIJ(Mat A,Vec xx,Vec yy)
12180ca81413SKerry Stevens {
12190ca81413SKerry Stevens   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
12200ca81413SKerry Stevens   PetscScalar       *y;
12210ca81413SKerry Stevens   const PetscScalar *x;
12220ca81413SKerry Stevens   PetscErrorCode    ierr;
12230ca81413SKerry Stevens   PetscInt          m=A->rmap->n,nonzerorow=0;
12240ca81413SKerry Stevens   PetscBool         usecprow=a->compressedrow.use;
12250ca81413SKerry Stevens 
12260ca81413SKerry Stevens #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
12270ca81413SKerry Stevens #pragma disjoint(*x,*y,*aa)
12280ca81413SKerry Stevens #endif
12290ca81413SKerry Stevens 
12300ca81413SKerry Stevens   PetscFunctionBegin;
12310ca81413SKerry Stevens   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12320ca81413SKerry Stevens   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12330ca81413SKerry Stevens 
12340ca81413SKerry Stevens   if(usecprow) {
12350ca81413SKerry Stevens     PetscInt          NumPerThread,iindex;
12360ca81413SKerry Stevens     const MatScalar   *aa = a->a;
12370ca81413SKerry Stevens     const PetscInt    *aj = a->j,*ii = a->compressedrow.i,*ridx=a->compressedrow.rindex;
12380ca81413SKerry Stevens     PetscInt          i,iStartVal,iEndVal,iStartIndex,iEndIndex;
12390ca81413SKerry Stevens     const PetscInt    iNumThreads = PetscMaxThreads;  //this number could be different
1240*51d315f7SKerry Stevens     //MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
1241*51d315f7SKerry Stevens     //MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
1242*51d315f7SKerry Stevens 
1243*51d315f7SKerry Stevens     if(kerneldatap_MatMult==NULL) {
1244*51d315f7SKerry Stevens       //only need to check 1 of them
1245*51d315f7SKerry Stevens       kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
1246*51d315f7SKerry Stevens       pdata_MatMult       = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
1247*51d315f7SKerry Stevens       for(i=0; i<iNumThreads; i++) {
1248*51d315f7SKerry Stevens         pdata_MatMult[i] = &kerneldatap_MatMult[i];
1249*51d315f7SKerry Stevens       }
1250*51d315f7SKerry Stevens     }
12510ca81413SKerry Stevens 
12520ca81413SKerry Stevens     m    = a->compressedrow.nrows;
12530ca81413SKerry Stevens     NumPerThread = ii[m]/iNumThreads;
12540ca81413SKerry Stevens     iindex = 0;
12550ca81413SKerry Stevens     for(i=0; i<iNumThreads;i++) {
12560ca81413SKerry Stevens       iStartIndex = iindex;
12570ca81413SKerry Stevens       iStartVal = ii[iStartIndex];
12580ca81413SKerry Stevens       iEndVal = iStartVal;
12590ca81413SKerry Stevens       //determine number of rows to process
12600ca81413SKerry Stevens       while(iEndVal-iStartVal<NumPerThread) {
12610ca81413SKerry Stevens 	iindex++;
12620ca81413SKerry Stevens 	iEndVal = ii[iindex];
12630ca81413SKerry Stevens       }
12640ca81413SKerry Stevens       //determine whether to go back 1
12650ca81413SKerry Stevens       if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) {
12660ca81413SKerry Stevens 	iindex--;
12670ca81413SKerry Stevens 	iEndVal = ii[iindex];
12680ca81413SKerry Stevens       }
12690ca81413SKerry Stevens       iEndIndex = iindex;
1270*51d315f7SKerry Stevens       /*kerneldatap[i].matdata  = aa;
12710ca81413SKerry Stevens       kerneldatap[i].vecdata  = x;
12720ca81413SKerry Stevens       kerneldatap[i].vecout   = y;
12730ca81413SKerry Stevens       kerneldatap[i].colindnz = aj;
12740ca81413SKerry Stevens       kerneldatap[i].rownumnz = ii + iStartIndex;
12750ca81413SKerry Stevens       kerneldatap[i].numrows  = iEndIndex - iStartIndex + 1;
12760ca81413SKerry Stevens       kerneldatap[i].specidx  = ridx + iStartVal;
12770ca81413SKerry Stevens       kerneldatap[i].nzr      = 0;
1278*51d315f7SKerry Stevens       pdata[i] = &kerneldatap[i];*/
1279*51d315f7SKerry Stevens       kerneldatap_MatMult[i].matdata  = aa;
1280*51d315f7SKerry Stevens       kerneldatap_MatMult[i].vecdata  = x;
1281*51d315f7SKerry Stevens       kerneldatap_MatMult[i].vecout   = y;
1282*51d315f7SKerry Stevens       kerneldatap_MatMult[i].colindnz = aj;
1283*51d315f7SKerry Stevens       kerneldatap_MatMult[i].rownumnz = ii + iStartIndex;
1284*51d315f7SKerry Stevens       kerneldatap_MatMult[i].numrows  = iEndIndex - iStartIndex + 1;
1285*51d315f7SKerry Stevens       kerneldatap_MatMult[i].specidx  = ridx + iStartVal;
1286*51d315f7SKerry Stevens       kerneldatap_MatMult[i].nzr      = 0;
12870ca81413SKerry Stevens       iindex++;
12880ca81413SKerry Stevens     }
1289*51d315f7SKerry Stevens     //ierr = MainJob(MatMult_Kernel,(void**)pdata,iNumThreads);
1290*51d315f7SKerry Stevens     ierr = MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads);
1291*51d315f7SKerry Stevens     //collect results
1292*51d315f7SKerry Stevens     for(i=0; i<iNumThreads; i++) {
1293*51d315f7SKerry Stevens       //nonzerorow += kerneldatap[i].nzr;
1294*51d315f7SKerry Stevens       nonzerorow += kerneldatap_MatMult[i].nzr;
1295*51d315f7SKerry Stevens     }
1296*51d315f7SKerry Stevens     //free(kerneldatap);
1297*51d315f7SKerry Stevens     //free(pdata);
1298*51d315f7SKerry Stevens   }
1299*51d315f7SKerry Stevens   else {
1300*51d315f7SKerry Stevens #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1301*51d315f7SKerry Stevens   fortranmultaij_(&m,x,a->i,a->j,a->a,y);
1302*51d315f7SKerry Stevens #else
1303*51d315f7SKerry Stevens   PetscInt            i,iindex;
1304*51d315f7SKerry Stevens     const MatScalar   *aa = a->a;
1305*51d315f7SKerry Stevens     const PetscInt    *aj = a->j,*ii = a->i;
1306*51d315f7SKerry Stevens     const PetscInt    iNumThreads = PetscMaxThreads;  //this number could be different
1307*51d315f7SKerry Stevens     PetscInt          Q = m/iNumThreads;
1308*51d315f7SKerry Stevens     PetscInt          R = m-Q*iNumThreads;
1309*51d315f7SKerry Stevens     PetscBool         S;
1310*51d315f7SKerry Stevens 
1311*51d315f7SKerry Stevens     MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
1312*51d315f7SKerry Stevens     MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
1313*51d315f7SKerry Stevens 
1314*51d315f7SKerry Stevens     iindex = 0;
1315*51d315f7SKerry Stevens     for(i=0; i<iNumThreads;i++) {
1316*51d315f7SKerry Stevens       S = i<R;
1317*51d315f7SKerry Stevens       kerneldatap[i].matdata  = aa;
1318*51d315f7SKerry Stevens       kerneldatap[i].vecdata  = x;
1319*51d315f7SKerry Stevens       kerneldatap[i].vecout   = y;
1320*51d315f7SKerry Stevens       kerneldatap[i].colindnz = aj;
1321*51d315f7SKerry Stevens       kerneldatap[i].rownumnz = ii + iindex;
1322*51d315f7SKerry Stevens       kerneldatap[i].numrows  = S?Q+1:Q;
1323*51d315f7SKerry Stevens       kerneldatap[i].specidx  = PETSC_NULL;
1324*51d315f7SKerry Stevens       kerneldatap[i].nzr      = iindex; //serves as the 'base' row (needed to access correctly into output vector y)
1325*51d315f7SKerry Stevens       pdata[i] = &kerneldatap[i];
1326*51d315f7SKerry Stevens       iindex += kerneldatap[i].numrows;
1327*51d315f7SKerry Stevens     }
13280ca81413SKerry Stevens     MainJob(MatMult_Kernel,(void**)pdata,iNumThreads);
13290ca81413SKerry Stevens     //collect results
13300ca81413SKerry Stevens     for(i=0; i<iNumThreads; i++) {
13310ca81413SKerry Stevens       nonzerorow += kerneldatap[i].nzr;
13320ca81413SKerry Stevens     }
1333*51d315f7SKerry Stevens     free(kerneldatap);
1334*51d315f7SKerry Stevens     free(pdata);
1335*51d315f7SKerry Stevens     /*if(kerneldatap_MatMult==NULL) {
1336*51d315f7SKerry Stevens       //only need to check 1 of them
1337*51d315f7SKerry Stevens       kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
1338*51d315f7SKerry Stevens       pdata_MatMult       = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
1339*51d315f7SKerry Stevens       for(i=0; i<iNumThreads; i++) {
1340*51d315f7SKerry Stevens         pdata_MatMult[i] = &kerneldatap_MatMult[i];
13410ca81413SKerry Stevens       }
1342*51d315f7SKerry Stevens     }
13430ca81413SKerry Stevens 
13440ca81413SKerry Stevens     NumPerThread = ii[m]/iNumThreads;
13450ca81413SKerry Stevens     iindex = 0;
13460ca81413SKerry Stevens     for(i=0; i<iNumThreads;i++) {
13470ca81413SKerry Stevens       iStartIndex = iindex;
13480ca81413SKerry Stevens       iStartVal = ii[iStartIndex];
13490ca81413SKerry Stevens       iEndVal = iStartVal;
13500ca81413SKerry Stevens       //determine number of rows to process
13510ca81413SKerry Stevens       while(iEndVal-iStartVal<NumPerThread) {
13520ca81413SKerry Stevens 	iindex++;
13530ca81413SKerry Stevens 	iEndVal = ii[iindex];
13540ca81413SKerry Stevens       }
13550ca81413SKerry Stevens       //determine whether to go back 1
13560ca81413SKerry Stevens       if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) {
13570ca81413SKerry Stevens 	iindex--;
13580ca81413SKerry Stevens 	iEndVal = ii[iindex];
13590ca81413SKerry Stevens       }
1360*51d315f7SKerry Stevens       iindex--; //needed b/c ii[k] gives # nonzero elements of rows 0 through k-1
13610ca81413SKerry Stevens       iEndIndex = iindex;
1362*51d315f7SKerry Stevens       kerneldatap_MatMult[i].matdata  = aa;
1363*51d315f7SKerry Stevens       kerneldatap_MatMult[i].vecdata  = x;
1364*51d315f7SKerry Stevens       kerneldatap_MatMult[i].vecout   = y;
1365*51d315f7SKerry Stevens       kerneldatap_MatMult[i].colindnz = aj;
1366*51d315f7SKerry Stevens       kerneldatap_MatMult[i].rownumnz = ii + iStartIndex;
1367*51d315f7SKerry Stevens       kerneldatap_MatMult[i].numrows  = iEndIndex - iStartIndex + 1;
1368*51d315f7SKerry Stevens       kerneldatap_MatMult[i].specidx  = PETSC_NULL;
1369*51d315f7SKerry Stevens       kerneldatap_MatMult[i].nzr      = iStartIndex;
13700ca81413SKerry Stevens       iindex++;
13710ca81413SKerry Stevens     }
1372*51d315f7SKerry Stevens     MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads);
13730ca81413SKerry Stevens     //collect results
13740ca81413SKerry Stevens     for(i=0; i<iNumThreads; i++) {
1375*51d315f7SKerry Stevens       nonzerorow += kerneldatap_MatMult[i].nzr;
1376*51d315f7SKerry Stevens     }*/
13770ca81413SKerry Stevens #endif
13780ca81413SKerry Stevens   }
13790ca81413SKerry Stevens 
13800ca81413SKerry Stevens   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
13810ca81413SKerry Stevens   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13820ca81413SKerry Stevens   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13830ca81413SKerry Stevens   PetscFunctionReturn(0);
13840ca81413SKerry Stevens }
13850ca81413SKerry Stevens //*******************
13860ca81413SKerry Stevens 
1387c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
13884a2ae208SSatish Balay #undef __FUNCT__
13894a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1390dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
139117ab2063SBarry Smith {
1392416022c9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
139354f21887SBarry Smith   PetscScalar     *x,*y,*z;
139454f21887SBarry Smith   const MatScalar *aa;
1395dfbe8321SBarry Smith   PetscErrorCode  ierr;
1396d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1397aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
139897952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1399362ced78SSatish Balay   PetscScalar     sum;
1400ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1401e36a17ebSSatish Balay #endif
14029ea0dfa2SSatish Balay 
14033a40ed3dSBarry Smith   PetscFunctionBegin;
14041ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
14051ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14062e8a6d31SBarry Smith   if (zz != yy) {
14071ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14082e8a6d31SBarry Smith   } else {
14092e8a6d31SBarry Smith     z = y;
14102e8a6d31SBarry Smith   }
1411bfeeae90SHong Zhang 
141297952fefSHong Zhang   aj  = a->j;
141397952fefSHong Zhang   aa  = a->a;
1414cddf8d76SBarry Smith   ii  = a->i;
1415aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
141697952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
141702ab625aSSatish Balay #else
14184eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
14194eb6d288SHong Zhang     if (zz != yy){
14204eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14214eb6d288SHong Zhang     }
142297952fefSHong Zhang     m    = a->compressedrow.nrows;
142397952fefSHong Zhang     ii   = a->compressedrow.i;
142497952fefSHong Zhang     ridx = a->compressedrow.rindex;
142597952fefSHong Zhang     for (i=0; i<m; i++){
142697952fefSHong Zhang       n  = ii[i+1] - ii[i];
142797952fefSHong Zhang       aj  = a->j + ii[i];
142897952fefSHong Zhang       aa  = a->a + ii[i];
142997952fefSHong Zhang       sum = y[*ridx];
143097952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
143197952fefSHong Zhang       z[*ridx++] = sum;
143297952fefSHong Zhang     }
143397952fefSHong Zhang   } else { /* do not use compressed row format */
143417ab2063SBarry Smith     for (i=0; i<m; i++) {
14359ea0dfa2SSatish Balay       jrow = ii[i];
14369ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
143717ab2063SBarry Smith       sum  = y[i];
14389ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
143997952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
14409ea0dfa2SSatish Balay       }
144117ab2063SBarry Smith       z[i] = sum;
144217ab2063SBarry Smith     }
144397952fefSHong Zhang   }
144402ab625aSSatish Balay #endif
1445dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
14461ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14471ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
14482e8a6d31SBarry Smith   if (zz != yy) {
14491ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
14502e8a6d31SBarry Smith   }
14518154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14526b375ea7SVictor Minden   /*
1453918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1454918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1455918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14566b375ea7SVictor Minden   */
1457918e98c3SVictor Minden #endif
14583a40ed3dSBarry Smith   PetscFunctionReturn(0);
145917ab2063SBarry Smith }
146017ab2063SBarry Smith 
146117ab2063SBarry Smith /*
146217ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
146317ab2063SBarry Smith */
14644a2ae208SSatish Balay #undef __FUNCT__
14654a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1466dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
146717ab2063SBarry Smith {
1468416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14696849ba73SBarry Smith   PetscErrorCode ierr;
1470d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
147117ab2063SBarry Smith 
14723a40ed3dSBarry Smith   PetscFunctionBegin;
147309f38230SBarry Smith   if (!a->diag) {
147409f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
14759518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
147609f38230SBarry Smith   }
1477d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
147809f38230SBarry Smith     a->diag[i] = a->i[i+1];
1479bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1480bfeeae90SHong Zhang       if (a->j[j] == i) {
148109f38230SBarry Smith         a->diag[i] = j;
148217ab2063SBarry Smith         break;
148317ab2063SBarry Smith       }
148417ab2063SBarry Smith     }
148517ab2063SBarry Smith   }
14863a40ed3dSBarry Smith   PetscFunctionReturn(0);
148717ab2063SBarry Smith }
148817ab2063SBarry Smith 
1489be5855fcSBarry Smith /*
1490be5855fcSBarry Smith      Checks for missing diagonals
1491be5855fcSBarry Smith */
14924a2ae208SSatish Balay #undef __FUNCT__
14934a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1494ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1495be5855fcSBarry Smith {
1496be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
149797f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1498be5855fcSBarry Smith 
1499be5855fcSBarry Smith   PetscFunctionBegin;
150009f38230SBarry Smith   *missing = PETSC_FALSE;
1501d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
150209f38230SBarry Smith     *missing  = PETSC_TRUE;
150309f38230SBarry Smith     if (d) *d = 0;
150409f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
150509f38230SBarry Smith   } else {
1506f1e2ffcdSBarry Smith     diag = a->diag;
1507d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1508bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
150909f38230SBarry Smith 	*missing = PETSC_TRUE;
151009f38230SBarry Smith 	if (d) *d = i;
151109f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
151209f38230SBarry Smith       }
1513be5855fcSBarry Smith     }
1514be5855fcSBarry Smith   }
1515be5855fcSBarry Smith   PetscFunctionReturn(0);
1516be5855fcSBarry Smith }
1517be5855fcSBarry Smith 
151871f1c65dSBarry Smith EXTERN_C_BEGIN
151971f1c65dSBarry Smith #undef __FUNCT__
152071f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
15217087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
152271f1c65dSBarry Smith {
152371f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
152471f1c65dSBarry Smith   PetscErrorCode ierr;
1525d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
152654f21887SBarry Smith   MatScalar      *v = a->a;
152754f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
152871f1c65dSBarry Smith 
152971f1c65dSBarry Smith   PetscFunctionBegin;
153071f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
153171f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
153271f1c65dSBarry Smith   diag = a->diag;
153371f1c65dSBarry Smith   if (!a->idiag) {
153471f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
153571f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
153671f1c65dSBarry Smith     v        = a->a;
153771f1c65dSBarry Smith   }
153871f1c65dSBarry Smith   mdiag = a->mdiag;
153971f1c65dSBarry Smith   idiag = a->idiag;
154071f1c65dSBarry Smith 
1541028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
154271f1c65dSBarry Smith     for (i=0; i<m; i++) {
154371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1544e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
154571f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
154671f1c65dSBarry Smith     }
154771f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
154871f1c65dSBarry Smith   } else {
154971f1c65dSBarry Smith     for (i=0; i<m; i++) {
155071f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
155171f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
155271f1c65dSBarry Smith     }
1553dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
155471f1c65dSBarry Smith   }
155571f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
155671f1c65dSBarry Smith   PetscFunctionReturn(0);
155771f1c65dSBarry Smith }
15585a9745a3SMatthew Knepley EXTERN_C_END
155971f1c65dSBarry Smith 
1560c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
15614a2ae208SSatish Balay #undef __FUNCT__
156241f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
156341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
156417ab2063SBarry Smith {
1565416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1566e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1567e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
156854f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1569dfbe8321SBarry Smith   PetscErrorCode     ierr;
1570d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
157197f1f81fSBarry Smith   const PetscInt     *idx,*diag;
157217ab2063SBarry Smith 
15733a40ed3dSBarry Smith   PetscFunctionBegin;
1574b965ef7fSBarry Smith   its = its*lits;
157591723122SBarry Smith 
157671f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
157771f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
157871f1c65dSBarry Smith   a->fshift = fshift;
157971f1c65dSBarry Smith   a->omega  = omega;
1580ed480e8bSBarry Smith 
158171f1c65dSBarry Smith   diag = a->diag;
158271f1c65dSBarry Smith   t     = a->ssor_work;
1583ed480e8bSBarry Smith   idiag = a->idiag;
158471f1c65dSBarry Smith   mdiag = a->mdiag;
1585ed480e8bSBarry Smith 
15861ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15873649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
158871f1c65dSBarry Smith   CHKMEMQ;
1589ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
159017ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
159117ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1592ed480e8bSBarry Smith     bs = b;
159317ab2063SBarry Smith     for (i=0; i<m; i++) {
159471f1c65dSBarry Smith         d    = fshift + mdiag[i];
1595416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1596ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1597ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
159817ab2063SBarry Smith         sum  = b[i]*d/omega;
1599003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
160017ab2063SBarry Smith         x[i] = sum;
160117ab2063SBarry Smith     }
16021ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16033649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1604efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16053a40ed3dSBarry Smith     PetscFunctionReturn(0);
160617ab2063SBarry Smith   }
1607c783ea89SBarry Smith 
160848af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1609e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16103a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
161117ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1612887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
161317ab2063SBarry Smith 
161417ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
161517ab2063SBarry Smith 
1616887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
161717ab2063SBarry Smith     */
161817ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
161917ab2063SBarry Smith 
162017ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
162117ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1622416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1623ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1624ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
162517ab2063SBarry Smith       sum  = b[i];
1626e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1627ed480e8bSBarry Smith       x[i] = sum*idiag[i];
162817ab2063SBarry Smith     }
162917ab2063SBarry Smith 
163017ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1631416022c9SBarry Smith     v = a->a;
1632ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
163317ab2063SBarry Smith 
163417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1635ed480e8bSBarry Smith     ts = t;
1636416022c9SBarry Smith     diag = a->diag;
163717ab2063SBarry Smith     for (i=0; i<m; i++) {
1638416022c9SBarry Smith       n    = diag[i] - a->i[i];
1639ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1640ed480e8bSBarry Smith       v    = a->a + a->i[i];
164117ab2063SBarry Smith       sum  = t[i];
1642003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1643ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1644733d66baSBarry Smith       /*  x = x + t */
1645733d66baSBarry Smith       x[i] += t[i];
164617ab2063SBarry Smith     }
164717ab2063SBarry Smith 
1648dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16491ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16503649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16513a40ed3dSBarry Smith     PetscFunctionReturn(0);
165217ab2063SBarry Smith   }
165317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
165417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
165517ab2063SBarry Smith       for (i=0; i<m; i++) {
1656416022c9SBarry Smith         n    = diag[i] - a->i[i];
1657ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1658ed480e8bSBarry Smith         v    = a->a + a->i[i];
165917ab2063SBarry Smith         sum  = b[i];
1660e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16615c99c7daSBarry Smith         t[i] = sum;
1662ed480e8bSBarry Smith         x[i] = sum*idiag[i];
166317ab2063SBarry Smith       }
16645c99c7daSBarry Smith       xb = t;
1665efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16663a40ed3dSBarry Smith     } else xb = b;
166717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
166817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1669416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1670ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1671ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
167217ab2063SBarry Smith         sum  = xb[i];
1673e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16745c99c7daSBarry Smith         if (xb == b) {
1675ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16765c99c7daSBarry Smith         } else {
16775c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
167817ab2063SBarry Smith         }
16795c99c7daSBarry Smith       }
1680efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
168117ab2063SBarry Smith     }
168217ab2063SBarry Smith     its--;
168317ab2063SBarry Smith   }
168417ab2063SBarry Smith   while (its--) {
168517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
168617ab2063SBarry Smith       for (i=0; i<m; i++) {
1687416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1688ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1689ed480e8bSBarry Smith         v    = a->a + a->i[i];
169017ab2063SBarry Smith         sum  = b[i];
1691e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1692ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
169317ab2063SBarry Smith       }
16949f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
169517ab2063SBarry Smith     }
169617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
169717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1698416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1699ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1700ed480e8bSBarry Smith         v    = a->a + a->i[i];
170117ab2063SBarry Smith         sum  = b[i];
1702e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1703ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
170417ab2063SBarry Smith       }
17059f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
170617ab2063SBarry Smith     }
170717ab2063SBarry Smith   }
17081ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17093649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
171071f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
171117ab2063SBarry Smith }
171217ab2063SBarry Smith 
17132af78befSBarry Smith 
17144a2ae208SSatish Balay #undef __FUNCT__
17154a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1716dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
171717ab2063SBarry Smith {
1718416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17194e220ebcSLois Curfman McInnes 
17203a40ed3dSBarry Smith   PetscFunctionBegin;
17214e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
17224e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
17234e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
17244e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
17254e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
17268e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
17277adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1728d5f3da31SBarry Smith   if (A->factortype) {
17294e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17304e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17314e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17324e220ebcSLois Curfman McInnes   } else {
17334e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17344e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17354e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17364e220ebcSLois Curfman McInnes   }
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
173817ab2063SBarry Smith }
173917ab2063SBarry Smith 
17404a2ae208SSatish Balay #undef __FUNCT__
17414a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
17422b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
174317ab2063SBarry Smith {
1744416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
17453b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
17466849ba73SBarry Smith   PetscErrorCode    ierr;
174797b48c8fSBarry Smith   const PetscScalar *xx;
174897b48c8fSBarry Smith   PetscScalar       *bb;
1749ace3abfcSBarry Smith   PetscBool         missing;
175017ab2063SBarry Smith 
17513a40ed3dSBarry Smith   PetscFunctionBegin;
175297b48c8fSBarry Smith   if (x && b) {
175397b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
175497b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
175597b48c8fSBarry Smith     for (i=0; i<N; i++) {
175697b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
175797b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
175897b48c8fSBarry Smith     }
175997b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
176097b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
176197b48c8fSBarry Smith   }
176297b48c8fSBarry Smith 
1763a9817697SBarry Smith   if (a->keepnonzeropattern) {
1764f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1765e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1766bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1767f1e2ffcdSBarry Smith     }
1768f4df32b1SMatthew Knepley     if (diag != 0.0) {
176909f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1770e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1771f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1772f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1773f1e2ffcdSBarry Smith       }
1774f1e2ffcdSBarry Smith     }
177588e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1776f1e2ffcdSBarry Smith   } else {
1777f4df32b1SMatthew Knepley     if (diag != 0.0) {
177817ab2063SBarry Smith       for (i=0; i<N; i++) {
1779e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17807ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1781416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1782f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1783bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
17847ae801bdSBarry Smith         } else { /* in case row was completely empty */
1785f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
178617ab2063SBarry Smith         }
178717ab2063SBarry Smith       }
17883a40ed3dSBarry Smith     } else {
178917ab2063SBarry Smith       for (i=0; i<N; i++) {
1790e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1791416022c9SBarry Smith         a->ilen[rows[i]] = 0;
179217ab2063SBarry Smith       }
179317ab2063SBarry Smith     }
179488e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1795f1e2ffcdSBarry Smith   }
179643a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17973a40ed3dSBarry Smith   PetscFunctionReturn(0);
179817ab2063SBarry Smith }
179917ab2063SBarry Smith 
18004a2ae208SSatish Balay #undef __FUNCT__
18016e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
18026e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18036e169961SBarry Smith {
18046e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18056e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18066e169961SBarry Smith   PetscErrorCode    ierr;
18072b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18086e169961SBarry Smith   const PetscScalar *xx;
18096e169961SBarry Smith   PetscScalar       *bb;
18106e169961SBarry Smith 
18116e169961SBarry Smith   PetscFunctionBegin;
18126e169961SBarry Smith   if (x && b) {
18136e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18146e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18152b40b63fSBarry Smith     vecs = PETSC_TRUE;
18166e169961SBarry Smith   }
18176e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
18186e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
18196e169961SBarry Smith   for (i=0; i<N; i++) {
18206e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18216e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18226e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18236e169961SBarry Smith   }
18246e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18256e169961SBarry Smith     if (!zeroed[i]) {
18266e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18276e169961SBarry Smith         if (zeroed[a->j[j]]) {
18282b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18296e169961SBarry Smith           a->a[j] = 0.0;
18306e169961SBarry Smith         }
18316e169961SBarry Smith       }
18322b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18336e169961SBarry Smith   }
18346e169961SBarry Smith   if (x && b) {
18356e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18366e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18376e169961SBarry Smith   }
18386e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18396e169961SBarry Smith   if (diag != 0.0) {
18406e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18416e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18426e169961SBarry Smith     for (i=0; i<N; i++) {
18436e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
18446e169961SBarry Smith     }
18456e169961SBarry Smith   }
18466e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
18476e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18486e169961SBarry Smith   PetscFunctionReturn(0);
18496e169961SBarry Smith }
18506e169961SBarry Smith 
18516e169961SBarry Smith #undef __FUNCT__
18524a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1853a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
185417ab2063SBarry Smith {
1855416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
185697f1f81fSBarry Smith   PetscInt   *itmp;
185717ab2063SBarry Smith 
18583a40ed3dSBarry Smith   PetscFunctionBegin;
1859e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
186017ab2063SBarry Smith 
1861416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1862bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
186317ab2063SBarry Smith   if (idx) {
1864bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1865bfeeae90SHong Zhang     if (*nz) {
18664e093b46SBarry Smith       *idx = itmp;
186717ab2063SBarry Smith     }
186817ab2063SBarry Smith     else *idx = 0;
186917ab2063SBarry Smith   }
18703a40ed3dSBarry Smith   PetscFunctionReturn(0);
187117ab2063SBarry Smith }
187217ab2063SBarry Smith 
1873bfeeae90SHong Zhang /* remove this function? */
18744a2ae208SSatish Balay #undef __FUNCT__
18754a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1876a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187717ab2063SBarry Smith {
18783a40ed3dSBarry Smith   PetscFunctionBegin;
18793a40ed3dSBarry Smith   PetscFunctionReturn(0);
188017ab2063SBarry Smith }
188117ab2063SBarry Smith 
18824a2ae208SSatish Balay #undef __FUNCT__
18834a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1884dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
188517ab2063SBarry Smith {
1886416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
188754f21887SBarry Smith   MatScalar      *v = a->a;
188836db0b34SBarry Smith   PetscReal      sum = 0.0;
18896849ba73SBarry Smith   PetscErrorCode ierr;
189097f1f81fSBarry Smith   PetscInt       i,j;
189117ab2063SBarry Smith 
18923a40ed3dSBarry Smith   PetscFunctionBegin;
189317ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1894416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1895aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
189636db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
189717ab2063SBarry Smith #else
189817ab2063SBarry Smith       sum += (*v)*(*v); v++;
189917ab2063SBarry Smith #endif
190017ab2063SBarry Smith     }
1901064f8208SBarry Smith     *nrm = sqrt(sum);
19023a40ed3dSBarry Smith   } else if (type == NORM_1) {
190336db0b34SBarry Smith     PetscReal *tmp;
190497f1f81fSBarry Smith     PetscInt    *jj = a->j;
1905d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1906d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1907064f8208SBarry Smith     *nrm = 0.0;
1908416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1909bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
191017ab2063SBarry Smith     }
1911d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1912064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
191317ab2063SBarry Smith     }
1914606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
19153a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1916064f8208SBarry Smith     *nrm = 0.0;
1917d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1918bfeeae90SHong Zhang       v = a->a + a->i[j];
191917ab2063SBarry Smith       sum = 0.0;
1920416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1921cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
192217ab2063SBarry Smith       }
1923064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
192417ab2063SBarry Smith     }
19253a40ed3dSBarry Smith   } else {
1926e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
192717ab2063SBarry Smith   }
19283a40ed3dSBarry Smith   PetscFunctionReturn(0);
192917ab2063SBarry Smith }
193017ab2063SBarry Smith 
19314a2ae208SSatish Balay #undef __FUNCT__
19324a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1933fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
193417ab2063SBarry Smith {
1935416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1936416022c9SBarry Smith   Mat            C;
19376849ba73SBarry Smith   PetscErrorCode ierr;
1938d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
193954f21887SBarry Smith   MatScalar      *array = a->a;
194017ab2063SBarry Smith 
19413a40ed3dSBarry Smith   PetscFunctionBegin;
1942e32f2f54SBarry 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");
1943fc4dec0aSBarry Smith 
1944fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1945d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1946d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1947bfeeae90SHong Zhang 
1948bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
19497adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1950d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
19517adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1952ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1953606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1954a541d17aSBarry Smith   } else {
1955a541d17aSBarry Smith     C = *B;
1956a541d17aSBarry Smith   }
1957a541d17aSBarry Smith 
195817ab2063SBarry Smith   for (i=0; i<m; i++) {
195917ab2063SBarry Smith     len    = ai[i+1]-ai[i];
196087d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1961b9b97703SBarry Smith     array += len;
1962b9b97703SBarry Smith     aj    += len;
196317ab2063SBarry Smith   }
19646d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19656d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
196617ab2063SBarry Smith 
1967815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1968416022c9SBarry Smith     *B = C;
196917ab2063SBarry Smith   } else {
1970eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
197117ab2063SBarry Smith   }
19723a40ed3dSBarry Smith   PetscFunctionReturn(0);
197317ab2063SBarry Smith }
197417ab2063SBarry Smith 
1975cd0d46ebSvictorle EXTERN_C_BEGIN
1976cd0d46ebSvictorle #undef __FUNCT__
19775fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
19787087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1979cd0d46ebSvictorle {
1980cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
198154f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
198254f21887SBarry Smith   MatScalar      *va,*vb;
19836849ba73SBarry Smith   PetscErrorCode ierr;
198497f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1985cd0d46ebSvictorle 
1986cd0d46ebSvictorle   PetscFunctionBegin;
1987cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1988cd0d46ebSvictorle 
1989cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1990cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
19915485867bSBarry Smith   if (ma!=nb || na!=mb){
19925485867bSBarry Smith     *f = PETSC_FALSE;
19935485867bSBarry Smith     PetscFunctionReturn(0);
19945485867bSBarry Smith   }
1995cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1996cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1997cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
199897f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
199997f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2000cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2001cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2002cd0d46ebSvictorle 
2003cd0d46ebSvictorle   *f = PETSC_TRUE;
2004cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2005cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
200697f1f81fSBarry Smith       PetscInt         idc,idr;
20075485867bSBarry Smith       PetscScalar vc,vr;
2008cd0d46ebSvictorle       /* column/row index/value */
20095485867bSBarry Smith       idc = adx[aptr[i]];
20105485867bSBarry Smith       idr = bdx[bptr[idc]];
20115485867bSBarry Smith       vc  = va[aptr[i]];
20125485867bSBarry Smith       vr  = vb[bptr[idc]];
20135485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20145485867bSBarry Smith         *f = PETSC_FALSE;
20155485867bSBarry Smith         goto done;
2016cd0d46ebSvictorle       } else {
20175485867bSBarry Smith         aptr[i]++;
20185485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2019cd0d46ebSvictorle       }
2020cd0d46ebSvictorle     }
2021cd0d46ebSvictorle   }
2022cd0d46ebSvictorle  done:
2023cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20243aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2025cd0d46ebSvictorle   PetscFunctionReturn(0);
2026cd0d46ebSvictorle }
2027cd0d46ebSvictorle EXTERN_C_END
2028cd0d46ebSvictorle 
20291cbb95d3SBarry Smith EXTERN_C_BEGIN
20301cbb95d3SBarry Smith #undef __FUNCT__
20311cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
20327087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20331cbb95d3SBarry Smith {
20341cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
203554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
203654f21887SBarry Smith   MatScalar      *va,*vb;
20371cbb95d3SBarry Smith   PetscErrorCode ierr;
20381cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20391cbb95d3SBarry Smith 
20401cbb95d3SBarry Smith   PetscFunctionBegin;
20411cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
20421cbb95d3SBarry Smith 
20431cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20441cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20451cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
20461cbb95d3SBarry Smith     *f = PETSC_FALSE;
20471cbb95d3SBarry Smith     PetscFunctionReturn(0);
20481cbb95d3SBarry Smith   }
20491cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
20501cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
20511cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
20521cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
20531cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
20541cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20551cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20561cbb95d3SBarry Smith 
20571cbb95d3SBarry Smith   *f = PETSC_TRUE;
20581cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20591cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
20601cbb95d3SBarry Smith       PetscInt         idc,idr;
20611cbb95d3SBarry Smith       PetscScalar vc,vr;
20621cbb95d3SBarry Smith       /* column/row index/value */
20631cbb95d3SBarry Smith       idc = adx[aptr[i]];
20641cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
20651cbb95d3SBarry Smith       vc  = va[aptr[i]];
20661cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
20671cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
20681cbb95d3SBarry Smith         *f = PETSC_FALSE;
20691cbb95d3SBarry Smith         goto done;
20701cbb95d3SBarry Smith       } else {
20711cbb95d3SBarry Smith         aptr[i]++;
20721cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
20731cbb95d3SBarry Smith       }
20741cbb95d3SBarry Smith     }
20751cbb95d3SBarry Smith   }
20761cbb95d3SBarry Smith  done:
20771cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
20781cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
20791cbb95d3SBarry Smith   PetscFunctionReturn(0);
20801cbb95d3SBarry Smith }
20811cbb95d3SBarry Smith EXTERN_C_END
20821cbb95d3SBarry Smith 
20839e29f15eSvictorle #undef __FUNCT__
20849e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2085ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20869e29f15eSvictorle {
2087dfbe8321SBarry Smith   PetscErrorCode ierr;
20889e29f15eSvictorle   PetscFunctionBegin;
20895485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
20909e29f15eSvictorle   PetscFunctionReturn(0);
20919e29f15eSvictorle }
20929e29f15eSvictorle 
20934a2ae208SSatish Balay #undef __FUNCT__
20941cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2095ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20961cbb95d3SBarry Smith {
20971cbb95d3SBarry Smith   PetscErrorCode ierr;
20981cbb95d3SBarry Smith   PetscFunctionBegin;
20991cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21001cbb95d3SBarry Smith   PetscFunctionReturn(0);
21011cbb95d3SBarry Smith }
21021cbb95d3SBarry Smith 
21031cbb95d3SBarry Smith #undef __FUNCT__
21044a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2105dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
210617ab2063SBarry Smith {
2107416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
210854f21887SBarry Smith   PetscScalar    *l,*r,x;
210954f21887SBarry Smith   MatScalar      *v;
2110dfbe8321SBarry Smith   PetscErrorCode ierr;
2111d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
211217ab2063SBarry Smith 
21133a40ed3dSBarry Smith   PetscFunctionBegin;
211417ab2063SBarry Smith   if (ll) {
21153ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21163ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2117e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2118e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21191ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2120416022c9SBarry Smith     v = a->a;
212117ab2063SBarry Smith     for (i=0; i<m; i++) {
212217ab2063SBarry Smith       x = l[i];
2123416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
212417ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
212517ab2063SBarry Smith     }
21261ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2127efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
212817ab2063SBarry Smith   }
212917ab2063SBarry Smith   if (rr) {
2130e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2131e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21321ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2133416022c9SBarry Smith     v = a->a; jj = a->j;
213417ab2063SBarry Smith     for (i=0; i<nz; i++) {
2135bfeeae90SHong Zhang       (*v++) *= r[*jj++];
213617ab2063SBarry Smith     }
21371ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2138efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
213917ab2063SBarry Smith   }
21403a40ed3dSBarry Smith   PetscFunctionReturn(0);
214117ab2063SBarry Smith }
214217ab2063SBarry Smith 
21434a2ae208SSatish Balay #undef __FUNCT__
21444a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
214597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
214617ab2063SBarry Smith {
2147db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21486849ba73SBarry Smith   PetscErrorCode ierr;
2149d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
215097f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21515d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21525d0c19d7SBarry Smith   PetscInt       nrows,ncols;
215397f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
215454f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2155416022c9SBarry Smith   Mat            C;
2156ace3abfcSBarry Smith   PetscBool      stride,sorted;
215717ab2063SBarry Smith 
21583a40ed3dSBarry Smith   PetscFunctionBegin;
215914ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2160e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
216114ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2162e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
216399141d43SSatish Balay 
216417ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2165b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2166b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
216717ab2063SBarry Smith 
2168fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
21690dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2170fee21e36SBarry Smith   if (stride && step == 1) {
217102834360SBarry Smith     /* special case of contiguous rows */
21720e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
217302834360SBarry Smith     /* loop over new rows determining lens and starting points */
217402834360SBarry Smith     for (i=0; i<nrows; i++) {
2175bfeeae90SHong Zhang       kstart  = ai[irow[i]];
2176a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
217702834360SBarry Smith       for (k=kstart; k<kend; k++) {
2178bfeeae90SHong Zhang         if (aj[k] >= first) {
217902834360SBarry Smith           starts[i] = k;
218002834360SBarry Smith           break;
218102834360SBarry Smith 	}
218202834360SBarry Smith       }
2183a2744918SBarry Smith       sum = 0;
218402834360SBarry Smith       while (k < kend) {
2185bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2186a2744918SBarry Smith         sum++;
218702834360SBarry Smith       }
2188a2744918SBarry Smith       lens[i] = sum;
218902834360SBarry Smith     }
219002834360SBarry Smith     /* create submatrix */
2191cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
219297f1f81fSBarry Smith       PetscInt n_cols,n_rows;
219308480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2194e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2195d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
219608480c60SBarry Smith       C = *B;
21973a40ed3dSBarry Smith     } else {
21987adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2199f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22007adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2201ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
220208480c60SBarry Smith     }
2203db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2204db02288aSLois Curfman McInnes 
220502834360SBarry Smith     /* loop over rows inserting into submatrix */
2206db02288aSLois Curfman McInnes     a_new    = c->a;
2207db02288aSLois Curfman McInnes     j_new    = c->j;
2208db02288aSLois Curfman McInnes     i_new    = c->i;
2209bfeeae90SHong Zhang 
221002834360SBarry Smith     for (i=0; i<nrows; i++) {
2211a2744918SBarry Smith       ii    = starts[i];
2212a2744918SBarry Smith       lensi = lens[i];
2213a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2214a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
221502834360SBarry Smith       }
221687828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2217a2744918SBarry Smith       a_new      += lensi;
2218a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
2219a2744918SBarry Smith       c->ilen[i]  = lensi;
222002834360SBarry Smith     }
22210e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22223a40ed3dSBarry Smith   } else {
222302834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22240e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
222597f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
22260e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
222717ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
222802834360SBarry Smith     /* determine lens of each row */
222902834360SBarry Smith     for (i=0; i<nrows; i++) {
2230bfeeae90SHong Zhang       kstart  = ai[irow[i]];
223102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
223202834360SBarry Smith       lens[i] = 0;
223302834360SBarry Smith       for (k=kstart; k<kend; k++) {
2234bfeeae90SHong Zhang         if (smap[aj[k]]) {
223502834360SBarry Smith           lens[i]++;
223602834360SBarry Smith         }
223702834360SBarry Smith       }
223802834360SBarry Smith     }
223917ab2063SBarry Smith     /* Create and fill new matrix */
2240a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2241ace3abfcSBarry Smith       PetscBool  equal;
22420f5bd95cSBarry Smith 
224399141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
2244e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2245d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
22460f5bd95cSBarry Smith       if (!equal) {
2247e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
224899141d43SSatish Balay       }
2249d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
225008480c60SBarry Smith       C = *B;
22513a40ed3dSBarry Smith     } else {
22527adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2253f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22547adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2255ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
225608480c60SBarry Smith     }
225799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
225817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
225999141d43SSatish Balay       row    = irow[i];
2260bfeeae90SHong Zhang       kstart = ai[row];
226199141d43SSatish Balay       kend   = kstart + a->ilen[row];
2262bfeeae90SHong Zhang       mat_i  = c->i[i];
226399141d43SSatish Balay       mat_j  = c->j + mat_i;
226499141d43SSatish Balay       mat_a  = c->a + mat_i;
226599141d43SSatish Balay       mat_ilen = c->ilen + i;
226617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2267bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2268ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
226999141d43SSatish Balay           *mat_a++ = a->a[k];
227099141d43SSatish Balay           (*mat_ilen)++;
227199141d43SSatish Balay 
227217ab2063SBarry Smith         }
227317ab2063SBarry Smith       }
227417ab2063SBarry Smith     }
227502834360SBarry Smith     /* Free work space */
227602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2277606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2278606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
227902834360SBarry Smith   }
22806d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22816d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228217ab2063SBarry Smith 
228317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2284416022c9SBarry Smith   *B = C;
22853a40ed3dSBarry Smith   PetscFunctionReturn(0);
228617ab2063SBarry Smith }
228717ab2063SBarry Smith 
22881df811f5SHong Zhang #undef __FUNCT__
228982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
229082d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
229182d44351SHong Zhang {
229282d44351SHong Zhang   PetscErrorCode ierr;
229382d44351SHong Zhang   Mat            B;
229482d44351SHong Zhang 
229582d44351SHong Zhang   PetscFunctionBegin;
229682d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
229782d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
229882d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
229982d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
230082d44351SHong Zhang   *subMat = B;
230182d44351SHong Zhang   PetscFunctionReturn(0);
230282d44351SHong Zhang }
230382d44351SHong Zhang 
230482d44351SHong Zhang #undef __FUNCT__
23054a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
23060481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2307a871dcd8SBarry Smith {
230863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2309dfbe8321SBarry Smith   PetscErrorCode ierr;
231063b91edcSBarry Smith   Mat            outA;
2311ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
231263b91edcSBarry Smith 
23133a40ed3dSBarry Smith   PetscFunctionBegin;
2314e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23151df811f5SHong Zhang 
2316b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2317b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2318a871dcd8SBarry Smith 
231963b91edcSBarry Smith   outA              = inA;
2320d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2321c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23226bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2323c3122656SLisandro Dalcin   a->row = row;
2324c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23256bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2326c3122656SLisandro Dalcin   a->col = col;
232763b91edcSBarry Smith 
232836db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23296bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23304c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
233152e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2332f0ec6fceSSatish Balay 
233394a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2334d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2335d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
233694a9d846SBarry Smith   }
233763b91edcSBarry Smith 
2338f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2339137fb511SHong Zhang   if (row_identity && col_identity) {
2340ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2341137fb511SHong Zhang   } else {
2342719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2343137fb511SHong Zhang   }
23443a40ed3dSBarry Smith   PetscFunctionReturn(0);
2345a871dcd8SBarry Smith }
2346a871dcd8SBarry Smith 
23474a2ae208SSatish Balay #undef __FUNCT__
23484a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2349f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2350f0b747eeSBarry Smith {
2351f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2352f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2353efee365bSSatish Balay   PetscErrorCode ierr;
23540805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
23553a40ed3dSBarry Smith 
23563a40ed3dSBarry Smith   PetscFunctionBegin;
2357f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2358efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
23593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2360f0b747eeSBarry Smith }
2361f0b747eeSBarry Smith 
23624a2ae208SSatish Balay #undef __FUNCT__
23634a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
236497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2365cddf8d76SBarry Smith {
2366dfbe8321SBarry Smith   PetscErrorCode ierr;
236797f1f81fSBarry Smith   PetscInt       i;
2368cddf8d76SBarry Smith 
23693a40ed3dSBarry Smith   PetscFunctionBegin;
2370cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2371b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2372cddf8d76SBarry Smith   }
2373cddf8d76SBarry Smith 
2374cddf8d76SBarry Smith   for (i=0; i<n; i++) {
23756a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2376cddf8d76SBarry Smith   }
23773a40ed3dSBarry Smith   PetscFunctionReturn(0);
2378cddf8d76SBarry Smith }
2379cddf8d76SBarry Smith 
23804a2ae208SSatish Balay #undef __FUNCT__
23814a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
238297f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
23834dcbc457SBarry Smith {
2384e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
23856849ba73SBarry Smith   PetscErrorCode ierr;
23865d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
23875d0c19d7SBarry Smith   const PetscInt *idx;
238897f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2389f1af5d2fSBarry Smith   PetscBT        table;
2390bbd702dbSSatish Balay 
23913a40ed3dSBarry Smith   PetscFunctionBegin;
2392d0f46423SBarry Smith   m     = A->rmap->n;
2393e4d965acSSatish Balay   ai    = a->i;
2394bfeeae90SHong Zhang   aj    = a->j;
23958a047759SSatish Balay 
2396e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
239706763907SSatish Balay 
239897f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
23996831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
240006763907SSatish Balay 
2401e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2402b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2403e4d965acSSatish Balay     isz  = 0;
24046831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2405e4d965acSSatish Balay 
2406e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
24074dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2408b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2409e4d965acSSatish Balay 
2410dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2411e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2412f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
24134dcbc457SBarry Smith     }
241406763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
24156bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2416e4d965acSSatish Balay 
241704a348a9SBarry Smith     k = 0;
241804a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
241904a348a9SBarry Smith       n = isz;
242006763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2421e4d965acSSatish Balay         row   = nidx[k];
2422e4d965acSSatish Balay         start = ai[row];
2423e4d965acSSatish Balay         end   = ai[row+1];
242404a348a9SBarry Smith         for (l = start; l<end ; l++){
2425efb16452SHong Zhang           val = aj[l] ;
2426f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2427e4d965acSSatish Balay         }
2428e4d965acSSatish Balay       }
2429e4d965acSSatish Balay     }
243070b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2431e4d965acSSatish Balay   }
24326831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2433606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
24343a40ed3dSBarry Smith   PetscFunctionReturn(0);
24354dcbc457SBarry Smith }
243617ab2063SBarry Smith 
24370513a670SBarry Smith /* -------------------------------------------------------------- */
24384a2ae208SSatish Balay #undef __FUNCT__
24394a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2440dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
24410513a670SBarry Smith {
24420513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24436849ba73SBarry Smith   PetscErrorCode ierr;
24443b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
24455d0c19d7SBarry Smith   const PetscInt *row,*col;
24465d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
244756cd22aeSBarry Smith   IS             icolp,irowp;
24483b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
24493b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
24500513a670SBarry Smith 
24513a40ed3dSBarry Smith   PetscFunctionBegin;
24524c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
245356cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
24544c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
245556cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
24560513a670SBarry Smith 
24570513a670SBarry Smith   /* determine lengths of permuted rows */
245897f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
24590513a670SBarry Smith   for (i=0; i<m; i++) {
24600513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
24610513a670SBarry Smith   }
24627adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2463f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
24647adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2465ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2466606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
24670513a670SBarry Smith 
246897f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
24690513a670SBarry Smith   for (i=0; i<m; i++) {
247032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24710513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2472cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
247332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24740513a670SBarry Smith   }
2475606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
24763c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
24770513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24780513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
247956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
248056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
24816bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
24826bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
24833a40ed3dSBarry Smith   PetscFunctionReturn(0);
24840513a670SBarry Smith }
24850513a670SBarry Smith 
24864a2ae208SSatish Balay #undef __FUNCT__
24874a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2488dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2489cb5b572fSBarry Smith {
2490dfbe8321SBarry Smith   PetscErrorCode ierr;
2491cb5b572fSBarry Smith 
2492cb5b572fSBarry Smith   PetscFunctionBegin;
249333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
249433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2495be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2496be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2497be6bf707SBarry Smith 
2498700c5bfcSBarry 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");
2499d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2500cb5b572fSBarry Smith   } else {
2501cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2502cb5b572fSBarry Smith   }
2503cb5b572fSBarry Smith   PetscFunctionReturn(0);
2504cb5b572fSBarry Smith }
2505cb5b572fSBarry Smith 
25064a2ae208SSatish Balay #undef __FUNCT__
25074a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2508dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2509273d9f13SBarry Smith {
2510dfbe8321SBarry Smith   PetscErrorCode ierr;
2511273d9f13SBarry Smith 
2512273d9f13SBarry Smith   PetscFunctionBegin;
2513ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2514273d9f13SBarry Smith   PetscFunctionReturn(0);
2515273d9f13SBarry Smith }
2516273d9f13SBarry Smith 
25174a2ae208SSatish Balay #undef __FUNCT__
25184a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2519a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
25206c0721eeSBarry Smith {
25216c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
25226c0721eeSBarry Smith   PetscFunctionBegin;
25236c0721eeSBarry Smith   *array = a->a;
25246c0721eeSBarry Smith   PetscFunctionReturn(0);
25256c0721eeSBarry Smith }
25266c0721eeSBarry Smith 
25274a2ae208SSatish Balay #undef __FUNCT__
25284a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2529dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
25306c0721eeSBarry Smith {
25316c0721eeSBarry Smith   PetscFunctionBegin;
25326c0721eeSBarry Smith   PetscFunctionReturn(0);
25336c0721eeSBarry Smith }
2534273d9f13SBarry Smith 
2535ee4f033dSBarry Smith #undef __FUNCT__
2536ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2537dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2538ee4f033dSBarry Smith {
25396849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
25406849ba73SBarry Smith   PetscErrorCode ierr;
254197f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2542efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
254387828ca2SBarry Smith   PetscScalar    *vscale_array;
2544ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2545ee4f033dSBarry Smith   Vec            w1,w2,w3;
2546ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2547ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2548ee4f033dSBarry Smith 
2549ee4f033dSBarry Smith   PetscFunctionBegin;
2550ee4f033dSBarry Smith   if (!coloring->w1) {
2551ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
255252e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2553ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
255452e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2555ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
255652e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2557ee4f033dSBarry Smith   }
2558ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2559ee4f033dSBarry Smith 
2560ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2561acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2562ee4f033dSBarry Smith   if (flg) {
2563ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2564ee4f033dSBarry Smith   } else {
2565ace3abfcSBarry Smith     PetscBool  assembled;
25660b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
25670b9b6f31SBarry Smith     if (assembled) {
2568ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2569ee4f033dSBarry Smith     }
25700b9b6f31SBarry Smith   }
2571ee4f033dSBarry Smith 
2572ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2573ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2574ee4f033dSBarry Smith 
2575ee4f033dSBarry Smith   /*
2576ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2577ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2578ee4f033dSBarry Smith   */
2579ee4f033dSBarry Smith   if (coloring->F) {
2580ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2581ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2582ee4f033dSBarry Smith     if (m1 != m2) {
2583ee4f033dSBarry Smith       coloring->F = 0;
2584ee4f033dSBarry Smith     }
2585ee4f033dSBarry Smith   }
2586ee4f033dSBarry Smith 
2587ee4f033dSBarry Smith   if (coloring->F) {
2588ee4f033dSBarry Smith     w1          = coloring->F;
2589ee4f033dSBarry Smith     coloring->F = 0;
2590ee4f033dSBarry Smith   } else {
259166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2592ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
259366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2594ee4f033dSBarry Smith   }
2595ee4f033dSBarry Smith 
2596ee4f033dSBarry Smith   /*
2597ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2598ee4f033dSBarry Smith   */
25991ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
26001ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2601ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2602ee4f033dSBarry Smith     /*
2603ee4f033dSBarry Smith        Loop over each column associated with color adding the
2604ee4f033dSBarry Smith        perturbation to the vector w3.
2605ee4f033dSBarry Smith     */
2606ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2607ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2608ee4f033dSBarry Smith       dx  = xx[col];
2609ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2610ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2611ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2612ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2613ee4f033dSBarry Smith #else
2614ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2615ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2616ee4f033dSBarry Smith #endif
2617ee4f033dSBarry Smith       dx                *= epsilon;
2618ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2619ee4f033dSBarry Smith     }
2620ee4f033dSBarry Smith   }
26211ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2622ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2623ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2624ee4f033dSBarry Smith 
2625ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2626ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2627ee4f033dSBarry Smith 
2628ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2629ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2630ee4f033dSBarry Smith 
26311ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2632ee4f033dSBarry Smith   /*
2633ee4f033dSBarry Smith       Loop over each color
2634ee4f033dSBarry Smith   */
2635ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
263649b058dcSBarry Smith     coloring->currentcolor = k;
2637ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
26381ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2639ee4f033dSBarry Smith     /*
2640ee4f033dSBarry Smith        Loop over each column associated with color adding the
2641ee4f033dSBarry Smith        perturbation to the vector w3.
2642ee4f033dSBarry Smith     */
2643ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2644ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2645ee4f033dSBarry Smith       dx  = xx[col];
26465b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2647ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2648ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2649ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2650ee4f033dSBarry Smith #else
2651ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2652ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2653ee4f033dSBarry Smith #endif
2654ee4f033dSBarry Smith       dx            *= epsilon;
2655e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2656ee4f033dSBarry Smith       w3_array[col] += dx;
2657ee4f033dSBarry Smith     }
26581ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2659ee4f033dSBarry Smith 
2660ee4f033dSBarry Smith     /*
2661ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2662ee4f033dSBarry Smith     */
2663ee4f033dSBarry Smith 
266466f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2665ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
266666f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2667efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2668ee4f033dSBarry Smith 
2669ee4f033dSBarry Smith     /*
2670ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2671ee4f033dSBarry Smith     */
26721ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2673ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2674ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2675ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2676ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2677ee4f033dSBarry Smith       srow   = row + start;
2678ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2679ee4f033dSBarry Smith     }
26801ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2681ee4f033dSBarry Smith   }
268249b058dcSBarry Smith   coloring->currentcolor = k;
26831ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
26841ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2685ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2686ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2687ee4f033dSBarry Smith   PetscFunctionReturn(0);
2688ee4f033dSBarry Smith }
2689ee4f033dSBarry Smith 
26908229c054SShri Abhyankar /*
26918229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26928229c054SShri Abhyankar    have different nonzero structure.
26938229c054SShri Abhyankar */
2694ac90fabeSBarry Smith #undef __FUNCT__
26958229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
26968229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2697ec7775f6SShri Abhyankar {
26988229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2699ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2700ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2701ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2702ec7775f6SShri Abhyankar 
2703ec7775f6SShri Abhyankar   PetscFunctionBegin;
2704ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2705ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
27068af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27078af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27088af7cee1SJed Brown     nnz[i] = 0;
27098af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27108af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27118af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27128af7cee1SJed Brown       nnz[i]++;
27138af7cee1SJed Brown     }
27148af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2715ec7775f6SShri Abhyankar   }
2716ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2717ec7775f6SShri Abhyankar }
2718ec7775f6SShri Abhyankar 
2719ec7775f6SShri Abhyankar #undef __FUNCT__
2720ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2721f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2722ac90fabeSBarry Smith {
2723dfbe8321SBarry Smith   PetscErrorCode ierr;
272497f1f81fSBarry Smith   PetscInt       i;
2725ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
27260805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2727ac90fabeSBarry Smith 
2728ac90fabeSBarry Smith   PetscFunctionBegin;
2729ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2730f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2731f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2732c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2733a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2734a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27356bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2736a30b2313SHong Zhang     }
2737a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2738d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2739a30b2313SHong Zhang       y->XtoY = X;
2740407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2741c537a176SHong Zhang     }
2742f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
27431e2582c4SBarry 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);
2744ac90fabeSBarry Smith   } else {
27458229c054SShri Abhyankar     Mat      B;
27468229c054SShri Abhyankar     PetscInt *nnz;
274716b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2748ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2749bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27504aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2751ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
27528229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
27538229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2754ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2755ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27568229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2757ac90fabeSBarry Smith   }
2758ac90fabeSBarry Smith   PetscFunctionReturn(0);
2759ac90fabeSBarry Smith }
2760ac90fabeSBarry Smith 
2761521d7252SBarry Smith #undef __FUNCT__
2762521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2763521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2764521d7252SBarry Smith {
276541c166b1SJed Brown   PetscErrorCode ierr;
276641c166b1SJed Brown 
2767521d7252SBarry Smith   PetscFunctionBegin;
276841c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
276941c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2770521d7252SBarry Smith   PetscFunctionReturn(0);
2771521d7252SBarry Smith }
2772521d7252SBarry Smith 
2773354c94deSBarry Smith #undef __FUNCT__
2774354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27757087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2776354c94deSBarry Smith {
2777354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2778354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2779354c94deSBarry Smith   PetscInt    i,nz;
2780354c94deSBarry Smith   PetscScalar *a;
2781354c94deSBarry Smith 
2782354c94deSBarry Smith   PetscFunctionBegin;
2783354c94deSBarry Smith   nz = aij->nz;
2784354c94deSBarry Smith   a  = aij->a;
2785354c94deSBarry Smith   for (i=0; i<nz; i++) {
2786354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2787354c94deSBarry Smith   }
2788354c94deSBarry Smith #else
2789354c94deSBarry Smith   PetscFunctionBegin;
2790354c94deSBarry Smith #endif
2791354c94deSBarry Smith   PetscFunctionReturn(0);
2792354c94deSBarry Smith }
2793354c94deSBarry Smith 
2794e34fafa9SBarry Smith #undef __FUNCT__
2795985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2796985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2797e34fafa9SBarry Smith {
2798e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2799e34fafa9SBarry Smith   PetscErrorCode ierr;
2800d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2801e34fafa9SBarry Smith   PetscReal      atmp;
2802985db425SBarry Smith   PetscScalar    *x;
2803e34fafa9SBarry Smith   MatScalar      *aa;
2804e34fafa9SBarry Smith 
2805e34fafa9SBarry Smith   PetscFunctionBegin;
2806e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2807e34fafa9SBarry Smith   aa   = a->a;
2808e34fafa9SBarry Smith   ai   = a->i;
2809e34fafa9SBarry Smith   aj   = a->j;
2810e34fafa9SBarry Smith 
2811985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2812e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2813e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2814e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2815e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2816e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28179189402eSHong Zhang     x[i] = 0.0;
2818e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2819985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2820985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2821985db425SBarry Smith       aa++; aj++;
2822985db425SBarry Smith     }
2823985db425SBarry Smith   }
2824985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2825985db425SBarry Smith   PetscFunctionReturn(0);
2826985db425SBarry Smith }
2827985db425SBarry Smith 
2828985db425SBarry Smith #undef __FUNCT__
2829985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2830985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2831985db425SBarry Smith {
2832985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2833985db425SBarry Smith   PetscErrorCode ierr;
2834d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2835985db425SBarry Smith   PetscScalar    *x;
2836985db425SBarry Smith   MatScalar      *aa;
2837985db425SBarry Smith 
2838985db425SBarry Smith   PetscFunctionBegin;
2839e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2840985db425SBarry Smith   aa   = a->a;
2841985db425SBarry Smith   ai   = a->i;
2842985db425SBarry Smith   aj   = a->j;
2843985db425SBarry Smith 
2844985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2845985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2846985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2847e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2848985db425SBarry Smith   for (i=0; i<m; i++) {
2849985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2850d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2851985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2852985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2853985db425SBarry Smith       x[i] = 0.0;
2854985db425SBarry Smith       if (idx) {
2855985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2856985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2857985db425SBarry Smith           if (aj[j] > j) {
2858985db425SBarry Smith             idx[i] = j;
2859985db425SBarry Smith             break;
2860985db425SBarry Smith           }
2861985db425SBarry Smith         }
2862985db425SBarry Smith       }
2863985db425SBarry Smith     }
2864985db425SBarry Smith     for (j=0; j<ncols; j++){
2865985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2866985db425SBarry Smith       aa++; aj++;
2867985db425SBarry Smith     }
2868985db425SBarry Smith   }
2869985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2870985db425SBarry Smith   PetscFunctionReturn(0);
2871985db425SBarry Smith }
2872985db425SBarry Smith 
2873985db425SBarry Smith #undef __FUNCT__
2874c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2875c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2876c87e5d42SMatthew Knepley {
2877c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2878c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2879c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2880c87e5d42SMatthew Knepley   PetscReal      atmp;
2881c87e5d42SMatthew Knepley   PetscScalar    *x;
2882c87e5d42SMatthew Knepley   MatScalar      *aa;
2883c87e5d42SMatthew Knepley 
2884c87e5d42SMatthew Knepley   PetscFunctionBegin;
2885e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2886c87e5d42SMatthew Knepley   aa   = a->a;
2887c87e5d42SMatthew Knepley   ai   = a->i;
2888c87e5d42SMatthew Knepley   aj   = a->j;
2889c87e5d42SMatthew Knepley 
2890c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2891c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2892c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2893e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2894c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2895c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2896289a08f5SMatthew Knepley     if (ncols) {
2897289a08f5SMatthew Knepley       /* Get first nonzero */
2898289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2899289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2900289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2901289a08f5SMatthew Knepley       }
2902289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2903289a08f5SMatthew Knepley     } else {
2904289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2905289a08f5SMatthew Knepley     }
2906c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2907c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2908289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2909c87e5d42SMatthew Knepley       aa++; aj++;
2910c87e5d42SMatthew Knepley     }
2911c87e5d42SMatthew Knepley   }
2912c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2913c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2914c87e5d42SMatthew Knepley }
2915c87e5d42SMatthew Knepley 
2916c87e5d42SMatthew Knepley #undef __FUNCT__
2917985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2918985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2919985db425SBarry Smith {
2920985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2921985db425SBarry Smith   PetscErrorCode ierr;
2922d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2923985db425SBarry Smith   PetscScalar    *x;
2924985db425SBarry Smith   MatScalar      *aa;
2925985db425SBarry Smith 
2926985db425SBarry Smith   PetscFunctionBegin;
2927e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2928985db425SBarry Smith   aa   = a->a;
2929985db425SBarry Smith   ai   = a->i;
2930985db425SBarry Smith   aj   = a->j;
2931985db425SBarry Smith 
2932985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2933985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2934985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2935e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2936985db425SBarry Smith   for (i=0; i<m; i++) {
2937985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2938d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2939985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2940985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2941985db425SBarry Smith       x[i] = 0.0;
2942985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2943985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2944985db425SBarry Smith         for (j=0;j<ncols;j++) {
2945985db425SBarry Smith           if (aj[j] > j) {
2946985db425SBarry Smith             idx[i] = j;
2947985db425SBarry Smith             break;
2948985db425SBarry Smith           }
2949985db425SBarry Smith         }
2950985db425SBarry Smith       }
2951985db425SBarry Smith     }
2952985db425SBarry Smith     for (j=0; j<ncols; j++){
2953985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2954985db425SBarry Smith       aa++; aj++;
2955e34fafa9SBarry Smith     }
2956e34fafa9SBarry Smith   }
2957e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2958e34fafa9SBarry Smith   PetscFunctionReturn(0);
2959e34fafa9SBarry Smith }
29607087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2961682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
29620a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2963cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2964cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2965cb5b572fSBarry Smith        MatMult_SeqAIJ,
296697304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
29677c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
29687c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2969db4efbfdSBarry Smith        0,
2970db4efbfdSBarry Smith        0,
2971db4efbfdSBarry Smith        0,
2972db4efbfdSBarry Smith /*10*/ 0,
2973cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2974cb5b572fSBarry Smith        0,
297541f059aeSBarry Smith        MatSOR_SeqAIJ,
297617ab2063SBarry Smith        MatTranspose_SeqAIJ,
297797304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2978cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2979cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2980cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2981cb5b572fSBarry Smith        MatNorm_SeqAIJ,
298297304618SKris Buschelman /*20*/ 0,
2983cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2984cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2985cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2986d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2987db4efbfdSBarry Smith        0,
2988db4efbfdSBarry Smith        0,
2989db4efbfdSBarry Smith        0,
2990db4efbfdSBarry Smith        0,
2991d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2992db4efbfdSBarry Smith        0,
2993db4efbfdSBarry Smith        0,
29946c0721eeSBarry Smith        MatGetArray_SeqAIJ,
29956c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2996d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2997cb5b572fSBarry Smith        0,
2998cb5b572fSBarry Smith        0,
2999cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
3000cb5b572fSBarry Smith        0,
3001d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
3002cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
3003cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
3004cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
3005cb5b572fSBarry Smith        MatCopy_SeqAIJ,
3006d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
3007cb5b572fSBarry Smith        MatScale_SeqAIJ,
3008cb5b572fSBarry Smith        0,
300979299369SBarry Smith        MatDiagonalSet_SeqAIJ,
30106e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
3011d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
30123b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
30133b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
30143b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
3015a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
3016d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
3017b9617806SBarry Smith        0,
30180513a670SBarry Smith        0,
3019cda55fadSBarry Smith        MatPermute_SeqAIJ,
3020cda55fadSBarry Smith        0,
3021d519adbfSMatthew Knepley /*59*/ 0,
3022b9b97703SBarry Smith        MatDestroy_SeqAIJ,
3023b9b97703SBarry Smith        MatView_SeqAIJ,
3024357abbc8SBarry Smith        0,
3025ee4f033dSBarry Smith        0,
3026d519adbfSMatthew Knepley /*64*/ 0,
3027ee4f033dSBarry Smith        0,
3028ee4f033dSBarry Smith        0,
3029ee4f033dSBarry Smith        0,
3030ee4f033dSBarry Smith        0,
3031d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
3032c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
3033ee4f033dSBarry Smith        0,
3034ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
3035dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3036ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
3037dcf5cc72SBarry Smith #else
3038dcf5cc72SBarry Smith        0,
3039dcf5cc72SBarry Smith #endif
3040d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
30413acb8795SBarry Smith        MatFDColoringApply_AIJ,
304297304618SKris Buschelman        0,
304397304618SKris Buschelman        0,
304497304618SKris Buschelman        0,
30456ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
304697304618SKris Buschelman        0,
304797304618SKris Buschelman        0,
304897304618SKris Buschelman        0,
3049bc011b1eSHong Zhang        MatLoad_SeqAIJ,
3050d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
30511cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
30526284ec50SHong Zhang        0,
30536284ec50SHong Zhang        0,
3054bc011b1eSHong Zhang        0,
3055d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
305626be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
305726be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
3058d439da42SKris Buschelman        MatPtAP_Basic,
30597ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
3060d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
3061bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
3062bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
3063bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
30647ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
3065d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
3066609c6c4dSKris Buschelman        0,
3067609c6c4dSKris Buschelman        0,
306887d4246cSBarry Smith        MatConjugate_SeqAIJ,
306987d4246cSBarry Smith        0,
3070d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
307199cafbc1SBarry Smith        MatRealPart_SeqAIJ,
3072f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
3073f5edf698SHong Zhang        0,
30742bebee5dSHong Zhang        0,
3075cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
3076985db425SBarry Smith        0,
30772af78befSBarry Smith        MatGetRowMin_SeqAIJ,
30782af78befSBarry Smith        0,
3079599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
3080d519adbfSMatthew Knepley /*114*/0,
3081599ef60dSHong Zhang        0,
30823c2a7987SHong Zhang        0,
3083fe97e370SBarry Smith        0,
3084fbdbba38SShri Abhyankar        0,
3085fbdbba38SShri Abhyankar /*119*/0,
3086fbdbba38SShri Abhyankar        0,
3087fbdbba38SShri Abhyankar        0,
308882d44351SHong Zhang        0,
3089b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
30900716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ,
30910716a85fSBarry Smith        MatGetColumnNorms_SeqAIJ
30929e29f15eSvictorle };
309317ab2063SBarry Smith 
3094fb2e594dSBarry Smith EXTERN_C_BEGIN
30954a2ae208SSatish Balay #undef __FUNCT__
30964a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
30977087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3098bef8e0ddSBarry Smith {
3099bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
310097f1f81fSBarry Smith   PetscInt   i,nz,n;
3101bef8e0ddSBarry Smith 
3102bef8e0ddSBarry Smith   PetscFunctionBegin;
3103bef8e0ddSBarry Smith 
3104bef8e0ddSBarry Smith   nz = aij->maxnz;
3105d0f46423SBarry Smith   n  = mat->rmap->n;
3106bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3107bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3108bef8e0ddSBarry Smith   }
3109bef8e0ddSBarry Smith   aij->nz = nz;
3110bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3111bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3112bef8e0ddSBarry Smith   }
3113bef8e0ddSBarry Smith 
3114bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3115bef8e0ddSBarry Smith }
3116fb2e594dSBarry Smith EXTERN_C_END
3117bef8e0ddSBarry Smith 
31184a2ae208SSatish Balay #undef __FUNCT__
31194a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3120bef8e0ddSBarry Smith /*@
3121bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3122bef8e0ddSBarry Smith        in the matrix.
3123bef8e0ddSBarry Smith 
3124bef8e0ddSBarry Smith   Input Parameters:
3125bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3126bef8e0ddSBarry Smith -  indices - the column indices
3127bef8e0ddSBarry Smith 
312815091d37SBarry Smith   Level: advanced
312915091d37SBarry Smith 
3130bef8e0ddSBarry Smith   Notes:
3131bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3132bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3133bef8e0ddSBarry Smith   of the MatSetValues() operation.
3134bef8e0ddSBarry Smith 
3135bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3136d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3137bef8e0ddSBarry Smith 
3138bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3139bef8e0ddSBarry Smith 
3140b9617806SBarry Smith     The indices should start with zero, not one.
3141b9617806SBarry Smith 
3142bef8e0ddSBarry Smith @*/
31437087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3144bef8e0ddSBarry Smith {
31454ac538c5SBarry Smith   PetscErrorCode ierr;
3146bef8e0ddSBarry Smith 
3147bef8e0ddSBarry Smith   PetscFunctionBegin;
31480700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
31494482741eSBarry Smith   PetscValidPointer(indices,2);
31504ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
3151bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3152bef8e0ddSBarry Smith }
3153bef8e0ddSBarry Smith 
3154be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3155be6bf707SBarry Smith 
3156fb2e594dSBarry Smith EXTERN_C_BEGIN
31574a2ae208SSatish Balay #undef __FUNCT__
31584a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
31597087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3160be6bf707SBarry Smith {
3161be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
31626849ba73SBarry Smith   PetscErrorCode ierr;
3163d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3164be6bf707SBarry Smith 
3165be6bf707SBarry Smith   PetscFunctionBegin;
3166be6bf707SBarry Smith   if (aij->nonew != 1) {
3167e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3168be6bf707SBarry Smith   }
3169be6bf707SBarry Smith 
3170be6bf707SBarry Smith   /* allocate space for values if not already there */
3171be6bf707SBarry Smith   if (!aij->saved_values) {
317287828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
31739518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3174be6bf707SBarry Smith   }
3175be6bf707SBarry Smith 
3176be6bf707SBarry Smith   /* copy values over */
317787828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3178be6bf707SBarry Smith   PetscFunctionReturn(0);
3179be6bf707SBarry Smith }
3180fb2e594dSBarry Smith EXTERN_C_END
3181be6bf707SBarry Smith 
31824a2ae208SSatish Balay #undef __FUNCT__
3183b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3184be6bf707SBarry Smith /*@
3185be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3186be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3187be6bf707SBarry Smith        nonlinear portion.
3188be6bf707SBarry Smith 
3189be6bf707SBarry Smith    Collect on Mat
3190be6bf707SBarry Smith 
3191be6bf707SBarry Smith   Input Parameters:
31920e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3193be6bf707SBarry Smith 
319415091d37SBarry Smith   Level: advanced
319515091d37SBarry Smith 
3196be6bf707SBarry Smith   Common Usage, with SNESSolve():
3197be6bf707SBarry Smith $    Create Jacobian matrix
3198be6bf707SBarry Smith $    Set linear terms into matrix
3199be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3200be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3201be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3202512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3203be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3204be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3205be6bf707SBarry Smith $    In your Jacobian routine
3206be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3207be6bf707SBarry Smith $      Set nonlinear terms in matrix
3208be6bf707SBarry Smith 
3209be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3210be6bf707SBarry Smith $    // build linear portion of Jacobian
3211512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3212be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3213be6bf707SBarry Smith $    loop over nonlinear iterations
3214be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3215be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3216be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3217be6bf707SBarry Smith $       Solve linear system with Jacobian
3218be6bf707SBarry Smith $    endloop
3219be6bf707SBarry Smith 
3220be6bf707SBarry Smith   Notes:
3221be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3222512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3223be6bf707SBarry Smith     calling this routine.
3224be6bf707SBarry Smith 
32250c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
32260c468ba9SBarry Smith     and does not allocated additional space.
32270c468ba9SBarry Smith 
3228be6bf707SBarry Smith .seealso: MatRetrieveValues()
3229be6bf707SBarry Smith 
3230be6bf707SBarry Smith @*/
32317087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3232be6bf707SBarry Smith {
32334ac538c5SBarry Smith   PetscErrorCode ierr;
3234be6bf707SBarry Smith 
3235be6bf707SBarry Smith   PetscFunctionBegin;
32360700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3237e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3238e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32394ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3240be6bf707SBarry Smith   PetscFunctionReturn(0);
3241be6bf707SBarry Smith }
3242be6bf707SBarry Smith 
3243fb2e594dSBarry Smith EXTERN_C_BEGIN
32444a2ae208SSatish Balay #undef __FUNCT__
32454a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
32467087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3247be6bf707SBarry Smith {
3248be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
32496849ba73SBarry Smith   PetscErrorCode ierr;
3250d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3251be6bf707SBarry Smith 
3252be6bf707SBarry Smith   PetscFunctionBegin;
3253be6bf707SBarry Smith   if (aij->nonew != 1) {
3254e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3255be6bf707SBarry Smith   }
3256be6bf707SBarry Smith   if (!aij->saved_values) {
3257e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3258be6bf707SBarry Smith   }
3259be6bf707SBarry Smith   /* copy values over */
326087828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3261be6bf707SBarry Smith   PetscFunctionReturn(0);
3262be6bf707SBarry Smith }
3263fb2e594dSBarry Smith EXTERN_C_END
3264be6bf707SBarry Smith 
32654a2ae208SSatish Balay #undef __FUNCT__
32664a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3267be6bf707SBarry Smith /*@
3268be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3269be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3270be6bf707SBarry Smith        nonlinear portion.
3271be6bf707SBarry Smith 
3272be6bf707SBarry Smith    Collect on Mat
3273be6bf707SBarry Smith 
3274be6bf707SBarry Smith   Input Parameters:
3275be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3276be6bf707SBarry Smith 
327715091d37SBarry Smith   Level: advanced
327815091d37SBarry Smith 
3279be6bf707SBarry Smith .seealso: MatStoreValues()
3280be6bf707SBarry Smith 
3281be6bf707SBarry Smith @*/
32827087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3283be6bf707SBarry Smith {
32844ac538c5SBarry Smith   PetscErrorCode ierr;
3285be6bf707SBarry Smith 
3286be6bf707SBarry Smith   PetscFunctionBegin;
32870700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3288e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3289e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32904ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3291be6bf707SBarry Smith   PetscFunctionReturn(0);
3292be6bf707SBarry Smith }
3293be6bf707SBarry Smith 
3294f83d6046SBarry Smith 
3295be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
32964a2ae208SSatish Balay #undef __FUNCT__
32974a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
329817ab2063SBarry Smith /*@C
3299682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33000d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33016e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
330251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33032bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
330417ab2063SBarry Smith 
3305db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3306db81eaa0SLois Curfman McInnes 
330717ab2063SBarry Smith    Input Parameters:
3308db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
330917ab2063SBarry Smith .  m - number of rows
331017ab2063SBarry Smith .  n - number of columns
331117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
331251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33132bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
331417ab2063SBarry Smith 
331517ab2063SBarry Smith    Output Parameter:
3316416022c9SBarry Smith .  A - the matrix
331717ab2063SBarry Smith 
3318175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3319ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3320175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3321175b88e8SBarry Smith 
3322b259b22eSLois Curfman McInnes    Notes:
332349a6f317SBarry Smith    If nnz is given then nz is ignored
332449a6f317SBarry Smith 
332517ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
332617ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
33270002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
332844cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
332917ab2063SBarry Smith 
333017ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3331a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
33323d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
33336da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
333417ab2063SBarry Smith 
3335682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
33364fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3337682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
33386c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
33396c7ebb05SLois Curfman McInnes 
33406c7ebb05SLois Curfman McInnes    Options Database Keys:
3341698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
33429db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
334317ab2063SBarry Smith 
3344027ccd11SLois Curfman McInnes    Level: intermediate
3345027ccd11SLois Curfman McInnes 
334636db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
334736db0b34SBarry Smith 
334817ab2063SBarry Smith @*/
33497087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
335017ab2063SBarry Smith {
3351dfbe8321SBarry Smith   PetscErrorCode ierr;
33526945ee14SBarry Smith 
33533a40ed3dSBarry Smith   PetscFunctionBegin;
3354f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3355117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3356c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3357d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3358273d9f13SBarry Smith   PetscFunctionReturn(0);
3359273d9f13SBarry Smith }
3360273d9f13SBarry Smith 
33614a2ae208SSatish Balay #undef __FUNCT__
33624a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3363273d9f13SBarry Smith /*@C
3364273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3365273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3366273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3367273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3368273d9f13SBarry Smith 
3369273d9f13SBarry Smith    Collective on MPI_Comm
3370273d9f13SBarry Smith 
3371273d9f13SBarry Smith    Input Parameters:
3372117016b1SBarry Smith +  B - The matrix-free
3373273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3374273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3375273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3376273d9f13SBarry Smith 
3377273d9f13SBarry Smith    Notes:
337849a6f317SBarry Smith      If nnz is given then nz is ignored
337949a6f317SBarry Smith 
3380273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3381273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3382273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3383273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3384273d9f13SBarry Smith 
3385273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3386273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3387273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3388273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3389273d9f13SBarry Smith 
3390aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3391aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3392aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3393aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3394aa95bbe8SBarry Smith 
3395a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3396a96a251dSBarry Smith    entries or columns indices
3397a96a251dSBarry Smith 
3398273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3399273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3400273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3401273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3402273d9f13SBarry Smith 
3403273d9f13SBarry Smith    Options Database Keys:
3404698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3405698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3406273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3407273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3408273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3409273d9f13SBarry Smith 
3410273d9f13SBarry Smith    Level: intermediate
3411273d9f13SBarry Smith 
3412aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3413273d9f13SBarry Smith 
3414273d9f13SBarry Smith @*/
34157087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3416273d9f13SBarry Smith {
34174ac538c5SBarry Smith   PetscErrorCode ierr;
3418a23d5eceSKris Buschelman 
3419a23d5eceSKris Buschelman   PetscFunctionBegin;
34204ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3421a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3422a23d5eceSKris Buschelman }
3423a23d5eceSKris Buschelman 
3424a23d5eceSKris Buschelman EXTERN_C_BEGIN
3425a23d5eceSKris Buschelman #undef __FUNCT__
3426a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
34277087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3428a23d5eceSKris Buschelman {
3429273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3430ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
34316849ba73SBarry Smith   PetscErrorCode ierr;
343297f1f81fSBarry Smith   PetscInt       i;
3433273d9f13SBarry Smith 
3434273d9f13SBarry Smith   PetscFunctionBegin;
3435d5d45c9bSBarry Smith 
3436a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3437c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3438c461c341SBarry Smith     nz             = 0;
3439c461c341SBarry Smith   }
3440c461c341SBarry Smith 
344126283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
344226283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
344326283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
344426283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3445899cda47SBarry Smith 
3446435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3447e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3448b73539f3SBarry Smith   if (nnz) {
3449d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3450e32f2f54SBarry 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]);
3451e32f2f54SBarry 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);
3452b73539f3SBarry Smith     }
3453b73539f3SBarry Smith   }
3454b73539f3SBarry Smith 
3455273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3456273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3457273d9f13SBarry Smith 
3458ab93d7beSBarry Smith   if (!skipallocation) {
34592ee49352SLisandro Dalcin     if (!b->imax) {
3460d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3461d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
34622ee49352SLisandro Dalcin     }
3463273d9f13SBarry Smith     if (!nnz) {
3464435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3465c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3466d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3467d0f46423SBarry Smith       nz = nz*B->rmap->n;
3468273d9f13SBarry Smith     } else {
3469273d9f13SBarry Smith       nz = 0;
3470d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3471273d9f13SBarry Smith     }
3472ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3473d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3474ab93d7beSBarry Smith 
3475273d9f13SBarry Smith     /* allocate the matrix space */
34762ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3477d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3478d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3479bfeeae90SHong Zhang     b->i[0] = 0;
3480d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
34815da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
34825da197adSKris Buschelman     }
3483273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3484e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3485e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3486c461c341SBarry Smith   } else {
3487e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3488e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3489c461c341SBarry Smith   }
3490273d9f13SBarry Smith 
3491273d9f13SBarry Smith   b->nz                = 0;
3492273d9f13SBarry Smith   b->maxnz             = nz;
3493273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3494273d9f13SBarry Smith   PetscFunctionReturn(0);
3495273d9f13SBarry Smith }
3496a23d5eceSKris Buschelman EXTERN_C_END
3497273d9f13SBarry Smith 
3498a1661176SMatthew Knepley #undef  __FUNCT__
3499a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
350058d36128SBarry Smith /*@
3501a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3502a1661176SMatthew Knepley 
3503a1661176SMatthew Knepley    Input Parameters:
3504a1661176SMatthew Knepley +  B - the matrix
3505a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3506a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3507a1661176SMatthew Knepley -  v - optional values in the matrix
3508a1661176SMatthew Knepley 
3509a1661176SMatthew Knepley    Level: developer
3510a1661176SMatthew Knepley 
351158d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
351258d36128SBarry Smith 
3513a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3514a1661176SMatthew Knepley 
3515a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3516a1661176SMatthew Knepley @*/
3517a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3518a1661176SMatthew Knepley {
3519a1661176SMatthew Knepley   PetscErrorCode ierr;
3520a1661176SMatthew Knepley 
3521a1661176SMatthew Knepley   PetscFunctionBegin;
35220700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35234ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3524a1661176SMatthew Knepley   PetscFunctionReturn(0);
3525a1661176SMatthew Knepley }
3526a1661176SMatthew Knepley 
3527a1661176SMatthew Knepley EXTERN_C_BEGIN
3528a1661176SMatthew Knepley #undef  __FUNCT__
3529a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
35307087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3531a1661176SMatthew Knepley {
3532a1661176SMatthew Knepley   PetscInt       i;
3533a1661176SMatthew Knepley   PetscInt       m,n;
3534a1661176SMatthew Knepley   PetscInt       nz;
3535a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3536a1661176SMatthew Knepley   PetscScalar    *values;
3537a1661176SMatthew Knepley   PetscErrorCode ierr;
3538a1661176SMatthew Knepley 
3539a1661176SMatthew Knepley   PetscFunctionBegin;
3540a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3541a1661176SMatthew Knepley 
354265e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3543a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3544a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3545b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3546a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
354765e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3548a1661176SMatthew Knepley     nnz[i] = nz;
3549a1661176SMatthew Knepley   }
3550a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3551a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3552a1661176SMatthew Knepley 
3553a1661176SMatthew Knepley   if (v) {
3554a1661176SMatthew Knepley     values = (PetscScalar*) v;
3555a1661176SMatthew Knepley   } else {
35560e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3557a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3558a1661176SMatthew Knepley   }
3559a1661176SMatthew Knepley 
3560a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3561b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3562b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3563a1661176SMatthew Knepley   }
3564a1661176SMatthew Knepley 
3565a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3566a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3567a1661176SMatthew Knepley 
3568a1661176SMatthew Knepley   if (!v) {
3569a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3570a1661176SMatthew Knepley   }
3571a1661176SMatthew Knepley   PetscFunctionReturn(0);
3572a1661176SMatthew Knepley }
3573a1661176SMatthew Knepley EXTERN_C_END
3574a1661176SMatthew Knepley 
3575c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3576c6db04a5SJed Brown #include <private/petscaxpy.h>
3577170fe5c8SBarry Smith 
3578170fe5c8SBarry Smith #undef __FUNCT__
3579170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3580170fe5c8SBarry Smith /*
3581170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3582170fe5c8SBarry Smith 
3583170fe5c8SBarry Smith                n                       p                          p
3584170fe5c8SBarry Smith         (              )       (              )         (                  )
3585170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3586170fe5c8SBarry Smith         (              )       (              )         (                  )
3587170fe5c8SBarry Smith 
3588170fe5c8SBarry Smith */
3589170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3590170fe5c8SBarry Smith {
3591170fe5c8SBarry Smith   PetscErrorCode     ierr;
3592170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3593170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3594170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
35951de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3596170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3597170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3598170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3599170fe5c8SBarry Smith 
3600170fe5c8SBarry Smith   PetscFunctionBegin;
3601d0f46423SBarry Smith   m = A->rmap->n;
3602d0f46423SBarry Smith   n = A->cmap->n;
3603d0f46423SBarry Smith   p = B->cmap->n;
3604170fe5c8SBarry Smith   a = sub_a->v;
3605170fe5c8SBarry Smith   b = sub_b->a;
3606170fe5c8SBarry Smith   c = sub_c->v;
3607170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3608170fe5c8SBarry Smith 
3609170fe5c8SBarry Smith   ii  = sub_b->i;
3610170fe5c8SBarry Smith   idx = sub_b->j;
3611170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3612170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3613170fe5c8SBarry Smith     while (q-->0) {
3614170fe5c8SBarry Smith       c_q = c + m*(*idx);
3615170fe5c8SBarry Smith       a_q = a + m*i;
3616be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3617170fe5c8SBarry Smith       idx++;
3618170fe5c8SBarry Smith       b++;
3619170fe5c8SBarry Smith     }
3620170fe5c8SBarry Smith   }
3621170fe5c8SBarry Smith   PetscFunctionReturn(0);
3622170fe5c8SBarry Smith }
3623170fe5c8SBarry Smith 
3624170fe5c8SBarry Smith #undef __FUNCT__
3625170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3626170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3627170fe5c8SBarry Smith {
3628170fe5c8SBarry Smith   PetscErrorCode ierr;
3629d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3630170fe5c8SBarry Smith   Mat            Cmat;
3631170fe5c8SBarry Smith 
3632170fe5c8SBarry Smith   PetscFunctionBegin;
3633e32f2f54SBarry 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);
363439804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3635170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3636170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3637170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3638170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3639170fe5c8SBarry Smith   *C = Cmat;
3640170fe5c8SBarry Smith   PetscFunctionReturn(0);
3641170fe5c8SBarry Smith }
3642170fe5c8SBarry Smith 
3643170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3644170fe5c8SBarry Smith #undef __FUNCT__
3645170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3646170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3647170fe5c8SBarry Smith {
3648170fe5c8SBarry Smith   PetscErrorCode ierr;
3649170fe5c8SBarry Smith 
3650170fe5c8SBarry Smith   PetscFunctionBegin;
3651170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3652170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3653170fe5c8SBarry Smith   }
3654170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3655170fe5c8SBarry Smith   PetscFunctionReturn(0);
3656170fe5c8SBarry Smith }
3657170fe5c8SBarry Smith 
3658170fe5c8SBarry Smith 
36590bad9183SKris Buschelman /*MC
3660fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
36610bad9183SKris Buschelman    based on compressed sparse row format.
36620bad9183SKris Buschelman 
36630bad9183SKris Buschelman    Options Database Keys:
36640bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
36650bad9183SKris Buschelman 
36660bad9183SKris Buschelman   Level: beginner
36670bad9183SKris Buschelman 
3668f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
36690bad9183SKris Buschelman M*/
36700bad9183SKris Buschelman 
3671a6175056SHong Zhang EXTERN_C_BEGIN
3672b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3673b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3674b5e56a35SBarry Smith #endif
3675ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3676af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3677af1023dbSSatish Balay #endif
36787087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
36797087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
36807087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
36817087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3682611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
36837087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3684611f576cSBarry Smith #endif
3685611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
36867087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3687611f576cSBarry Smith #endif
3688f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3689f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3690f3c0ef26SHong Zhang #endif
3691611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
36927087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3693611f576cSBarry Smith #endif
3694eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
36957087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3696eb3b5408SSatish Balay #endif
3697586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
36987087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3699586621ddSJed Brown #endif
3700719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
37017087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3702719d5645SBarry Smith #endif
3703b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
37047087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
37057087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
37067087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3707b3866ffcSBarry Smith #endif
370817667f90SBarry Smith EXTERN_C_END
370917667f90SBarry Smith 
371017667f90SBarry Smith EXTERN_C_BEGIN
37114a2ae208SSatish Balay #undef __FUNCT__
37124a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
37137087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3714273d9f13SBarry Smith {
3715273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3716dfbe8321SBarry Smith   PetscErrorCode ierr;
371738baddfdSBarry Smith   PetscMPIInt    size;
3718273d9f13SBarry Smith 
3719273d9f13SBarry Smith   PetscFunctionBegin;
37207adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3721e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3722273d9f13SBarry Smith 
372338f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3724b0a32e0cSBarry Smith   B->data             = (void*)b;
3725549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3726416022c9SBarry Smith   b->row              = 0;
3727416022c9SBarry Smith   b->col              = 0;
372882bf6240SBarry Smith   b->icol             = 0;
3729b810aeb4SBarry Smith   b->reallocs         = 0;
373036db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3731f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3732416022c9SBarry Smith   b->nonew             = 0;
3733416022c9SBarry Smith   b->diag              = 0;
3734416022c9SBarry Smith   b->solve_work        = 0;
37352a1b7f2aSHong Zhang   B->spptr             = 0;
3736be6bf707SBarry Smith   b->saved_values      = 0;
3737d7f994e1SBarry Smith   b->idiag             = 0;
373871f1c65dSBarry Smith   b->mdiag             = 0;
373971f1c65dSBarry Smith   b->ssor_work         = 0;
374071f1c65dSBarry Smith   b->omega             = 1.0;
374171f1c65dSBarry Smith   b->fshift            = 0.0;
374271f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3743a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3744a30b2313SHong Zhang   b->xtoy              = 0;
3745a30b2313SHong Zhang   b->XtoY              = 0;
374688e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
374717ab2063SBarry Smith 
374835d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3749b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3750700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3751b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3752b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3753b3866ffcSBarry Smith #endif
3754b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3755700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3756b5e56a35SBarry Smith #endif
3757ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3758700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3759719d5645SBarry Smith #endif
3760611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3761700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3762611f576cSBarry Smith #endif
3763f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3764700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3765f3c0ef26SHong Zhang #endif
3766611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3767700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3768611f576cSBarry Smith #endif
3769611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3770700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3771611f576cSBarry Smith #endif
3772eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3773700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3774eb3b5408SSatish Balay #endif
3775586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3776700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3777586621ddSJed Brown #endif
3778719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3779700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3780719d5645SBarry Smith #endif
3781700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3782700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3783700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3784700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3785700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3786700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3787700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3788700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3789700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3790700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3791700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3792700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3793700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3794700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3795700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3796700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3797700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3798700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
37994108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
380017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
38013a40ed3dSBarry Smith   PetscFunctionReturn(0);
380217ab2063SBarry Smith }
3803273d9f13SBarry Smith EXTERN_C_END
380417ab2063SBarry Smith 
3805*51d315f7SKerry Stevens EXTERN_C_BEGIN
3806*51d315f7SKerry Stevens #undef __FUNCT__
3807*51d315f7SKerry Stevens #define __FUNCT__ "MatCreate_SeqPThreadAIJ"
3808*51d315f7SKerry Stevens PetscErrorCode  MatCreate_SeqPThreadAIJ(Mat B)
3809*51d315f7SKerry Stevens {
3810*51d315f7SKerry Stevens   PetscErrorCode ierr;
3811*51d315f7SKerry Stevens 
3812*51d315f7SKerry Stevens   PetscFunctionBegin;
3813*51d315f7SKerry Stevens   ierr = MatCreate_SeqAIJ(B);
3814*51d315f7SKerry Stevens   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3815*51d315f7SKerry Stevens   B->ops->mult = MatMult_SeqPThreadAIJ;
3816*51d315f7SKerry Stevens   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQPTHREADAIJ);CHKERRQ(ierr);
3817*51d315f7SKerry Stevens   PetscFunctionReturn(0);
3818*51d315f7SKerry Stevens }
3819*51d315f7SKerry Stevens EXTERN_C_END
3820*51d315f7SKerry Stevens 
38214a2ae208SSatish Balay #undef __FUNCT__
3822b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3823b24902e0SBarry Smith /*
3824b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3825b24902e0SBarry Smith */
3826ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
382717ab2063SBarry Smith {
3828416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
38296849ba73SBarry Smith   PetscErrorCode ierr;
3830d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
383117ab2063SBarry Smith 
38323a40ed3dSBarry Smith   PetscFunctionBegin;
3833273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3834273d9f13SBarry Smith 
3835d5f3da31SBarry Smith   C->factortype     = A->factortype;
3836416022c9SBarry Smith   c->row            = 0;
3837416022c9SBarry Smith   c->col            = 0;
383882bf6240SBarry Smith   c->icol           = 0;
38396ad4291fSHong Zhang   c->reallocs       = 0;
384017ab2063SBarry Smith 
38416ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
384217ab2063SBarry Smith 
3843aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3844aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3845eec197d1SBarry Smith 
384633b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
38479518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
384817ab2063SBarry Smith   for (i=0; i<m; i++) {
3849416022c9SBarry Smith     c->imax[i] = a->imax[i];
3850416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
385117ab2063SBarry Smith   }
385217ab2063SBarry Smith 
385317ab2063SBarry Smith   /* allocate the matrix space */
3854f77e22a1SHong Zhang   if (mallocmatspace){
3855a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
38569518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3857f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
385897f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
385917ab2063SBarry Smith     if (m > 0) {
386097f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3861be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3862bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3863be6bf707SBarry Smith       } else {
3864bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
386517ab2063SBarry Smith       }
386608480c60SBarry Smith     }
3867f77e22a1SHong Zhang   }
386817ab2063SBarry Smith 
38696ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3870416022c9SBarry Smith   c->roworiented       = a->roworiented;
3871416022c9SBarry Smith   c->nonew             = a->nonew;
3872416022c9SBarry Smith   if (a->diag) {
387397f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
387452e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
387517ab2063SBarry Smith     for (i=0; i<m; i++) {
3876416022c9SBarry Smith       c->diag[i] = a->diag[i];
387717ab2063SBarry Smith     }
38783a40ed3dSBarry Smith   } else c->diag           = 0;
38796ad4291fSHong Zhang   c->solve_work            = 0;
38806ad4291fSHong Zhang   c->saved_values          = 0;
38816ad4291fSHong Zhang   c->idiag                 = 0;
388271f1c65dSBarry Smith   c->ssor_work             = 0;
3883a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3884e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3885e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
38866ad4291fSHong Zhang   c->xtoy                  = 0;
38876ad4291fSHong Zhang   c->XtoY                  = 0;
38886ad4291fSHong Zhang 
3889416022c9SBarry Smith   c->nz                 = a->nz;
38908ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3891273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3892754ec7b1SSatish Balay 
38936ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
38946ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3895cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3896cd6b891eSBarry Smith   if (a->compressedrow.use){
38976ad4291fSHong Zhang     i = a->compressedrow.nrows;
38980e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
38996ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
39006ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
390127ea64f8SHong Zhang   } else {
390227ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
390327ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
390427ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
39056ad4291fSHong Zhang   }
390688e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
39074108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
39084846f1f5SKris Buschelman 
39097adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
39103a40ed3dSBarry Smith   PetscFunctionReturn(0);
391117ab2063SBarry Smith }
391217ab2063SBarry Smith 
39134a2ae208SSatish Balay #undef __FUNCT__
3914b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3915b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3916b24902e0SBarry Smith {
3917b24902e0SBarry Smith   PetscErrorCode ierr;
3918b24902e0SBarry Smith 
3919b24902e0SBarry Smith   PetscFunctionBegin;
3920b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
39214b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3922b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3923f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3924b24902e0SBarry Smith   PetscFunctionReturn(0);
3925b24902e0SBarry Smith }
3926b24902e0SBarry Smith 
3927b24902e0SBarry Smith #undef __FUNCT__
39284a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3929112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3930fbdbba38SShri Abhyankar {
3931fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3932fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3933fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3934fbdbba38SShri Abhyankar   int            fd;
3935fbdbba38SShri Abhyankar   PetscMPIInt    size;
3936fbdbba38SShri Abhyankar   MPI_Comm       comm;
3937fbdbba38SShri Abhyankar 
3938fbdbba38SShri Abhyankar   PetscFunctionBegin;
3939fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3940fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3941fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3942fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3943fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3944fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3945fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3946fbdbba38SShri Abhyankar 
3947fbdbba38SShri Abhyankar   if (nz < 0) {
3948fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3949fbdbba38SShri Abhyankar   }
3950fbdbba38SShri Abhyankar 
3951fbdbba38SShri Abhyankar   /* read in row lengths */
3952fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3953fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3954fbdbba38SShri Abhyankar 
3955fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3956fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3957fbdbba38SShri 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);
3958fbdbba38SShri Abhyankar 
3959fbdbba38SShri Abhyankar   /* set global size if not set already*/
3960f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3961fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3962aabbc4fbSShri Abhyankar   } else {
3963fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3964fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3965f501eaabSShri 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);
3966aabbc4fbSShri Abhyankar   }
3967fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3968fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3969fbdbba38SShri Abhyankar 
3970fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3971fbdbba38SShri Abhyankar 
3972fbdbba38SShri Abhyankar   /* read in nonzero values */
3973fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3974fbdbba38SShri Abhyankar 
3975fbdbba38SShri Abhyankar   /* set matrix "i" values */
3976fbdbba38SShri Abhyankar   a->i[0] = 0;
3977fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3978fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3979fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3980fbdbba38SShri Abhyankar   }
3981fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3982fbdbba38SShri Abhyankar 
3983fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3984fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3985fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3986fbdbba38SShri Abhyankar }
3987fbdbba38SShri Abhyankar 
3988fbdbba38SShri Abhyankar #undef __FUNCT__
3989b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3990ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
39917264ac53SSatish Balay {
39927264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3993dfbe8321SBarry Smith   PetscErrorCode ierr;
3994eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3995eeffb40dSHong Zhang   PetscInt k;
3996eeffb40dSHong Zhang #endif
39977264ac53SSatish Balay 
39983a40ed3dSBarry Smith   PetscFunctionBegin;
3999bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4000d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4001ca44d042SBarry Smith     *flg = PETSC_FALSE;
4002ca44d042SBarry Smith     PetscFunctionReturn(0);
4003bcd2baecSBarry Smith   }
40047264ac53SSatish Balay 
40057264ac53SSatish Balay   /* if the a->i are the same */
4006d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4007abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
40087264ac53SSatish Balay 
40097264ac53SSatish Balay   /* if a->j are the same */
401097f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4011abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4012bcd2baecSBarry Smith 
4013bcd2baecSBarry Smith   /* if a->a are the same */
4014eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4015eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
4016eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
4017eeffb40dSHong Zhang       *flg = PETSC_FALSE;
40183a40ed3dSBarry Smith       PetscFunctionReturn(0);
4019eeffb40dSHong Zhang     }
4020eeffb40dSHong Zhang   }
4021eeffb40dSHong Zhang #else
4022eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4023eeffb40dSHong Zhang #endif
4024eeffb40dSHong Zhang   PetscFunctionReturn(0);
40257264ac53SSatish Balay }
402636db0b34SBarry Smith 
40274a2ae208SSatish Balay #undef __FUNCT__
40284a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
402905869f15SSatish Balay /*@
403036db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
403136db0b34SBarry Smith               provided by the user.
403236db0b34SBarry Smith 
4033c75a6043SHong Zhang       Collective on MPI_Comm
403436db0b34SBarry Smith 
403536db0b34SBarry Smith    Input Parameters:
403636db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
403736db0b34SBarry Smith .   m - number of rows
403836db0b34SBarry Smith .   n - number of columns
403936db0b34SBarry Smith .   i - row indices
404036db0b34SBarry Smith .   j - column indices
404136db0b34SBarry Smith -   a - matrix values
404236db0b34SBarry Smith 
404336db0b34SBarry Smith    Output Parameter:
404436db0b34SBarry Smith .   mat - the matrix
404536db0b34SBarry Smith 
404636db0b34SBarry Smith    Level: intermediate
404736db0b34SBarry Smith 
404836db0b34SBarry Smith    Notes:
40490551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4050292fb18eSBarry Smith     once the matrix is destroyed and not before
405136db0b34SBarry Smith 
405236db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
405336db0b34SBarry Smith 
4054bfeeae90SHong Zhang        The i and j indices are 0 based
405536db0b34SBarry Smith 
4056a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4057a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4058a4552177SSatish Balay     as shown:
4059a4552177SSatish Balay 
4060a4552177SSatish Balay         1 0 0
4061a4552177SSatish Balay         2 0 3
4062a4552177SSatish Balay         4 5 6
4063a4552177SSatish Balay 
4064a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
40659985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4066a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4067a4552177SSatish Balay 
40689985e31cSBarry Smith 
40692fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
407036db0b34SBarry Smith 
407136db0b34SBarry Smith @*/
40727087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
407336db0b34SBarry Smith {
4074dfbe8321SBarry Smith   PetscErrorCode ierr;
4075cbcfb4deSHong Zhang   PetscInt       ii;
407636db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4077cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4078cbcfb4deSHong Zhang   PetscInt       jj;
4079cbcfb4deSHong Zhang #endif
408036db0b34SBarry Smith 
408136db0b34SBarry Smith   PetscFunctionBegin;
4082a96a251dSBarry Smith   if (i[0]) {
4083e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
408436db0b34SBarry Smith   }
4085f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4086f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4087ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4088ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4089ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4090ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4091ab93d7beSBarry Smith 
409236db0b34SBarry Smith   aij->i = i;
409336db0b34SBarry Smith   aij->j = j;
409436db0b34SBarry Smith   aij->a = a;
409536db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
409636db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4097e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4098e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
409936db0b34SBarry Smith 
410036db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
410136db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
41022515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4103e32f2f54SBarry 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]);
41049985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4105e32f2f54SBarry 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);
4106e32f2f54SBarry 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);
41079985e31cSBarry Smith     }
410836db0b34SBarry Smith #endif
410936db0b34SBarry Smith   }
41102515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
411136db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4112e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4113e32f2f54SBarry 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]);
411436db0b34SBarry Smith   }
411536db0b34SBarry Smith #endif
411636db0b34SBarry Smith 
4117b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4118b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
411936db0b34SBarry Smith   PetscFunctionReturn(0);
412036db0b34SBarry Smith }
412136db0b34SBarry Smith 
4122cc8ba8e1SBarry Smith #undef __FUNCT__
4123ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4124dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4125cc8ba8e1SBarry Smith {
4126dfbe8321SBarry Smith   PetscErrorCode ierr;
4127cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
412836db0b34SBarry Smith 
4129cc8ba8e1SBarry Smith   PetscFunctionBegin;
41308ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4131cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4132cc8ba8e1SBarry Smith     a->coloring = coloring;
413312c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
413497f1f81fSBarry Smith     PetscInt             i,*larray;
413512c595b3SBarry Smith     ISColoring      ocoloring;
413608b6dcc0SBarry Smith     ISColoringValue *colors;
413712c595b3SBarry Smith 
413812c595b3SBarry Smith     /* set coloring for diagonal portion */
41390e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
4140d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
414112c595b3SBarry Smith       larray[i] = i;
414212c595b3SBarry Smith     }
4143992144d0SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
41440e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
4145d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
414612c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
414712c595b3SBarry Smith     }
414812c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
4149d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
415012c595b3SBarry Smith     a->coloring = ocoloring;
415112c595b3SBarry Smith   }
4152cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4153cc8ba8e1SBarry Smith }
4154cc8ba8e1SBarry Smith 
4155dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
4156ee4f033dSBarry Smith EXTERN_C_BEGIN
4157c6db04a5SJed Brown #include <adic/ad_utils.h>
4158ee4f033dSBarry Smith EXTERN_C_END
4159cc8ba8e1SBarry Smith 
4160cc8ba8e1SBarry Smith #undef __FUNCT__
4161ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
4162dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
4163cc8ba8e1SBarry Smith {
4164cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4165d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
41664440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
416708b6dcc0SBarry Smith   ISColoringValue *color;
4168cc8ba8e1SBarry Smith 
4169cc8ba8e1SBarry Smith   PetscFunctionBegin;
4170e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
41714440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
4172cc8ba8e1SBarry Smith   color = a->coloring->colors;
4173cc8ba8e1SBarry Smith   /* loop over rows */
4174cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
4175cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
4176cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
4177cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
4178cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
4179cc8ba8e1SBarry Smith     }
41804440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
4181ee4f033dSBarry Smith   }
4182ee4f033dSBarry Smith   PetscFunctionReturn(0);
4183ee4f033dSBarry Smith }
4184ee4f033dSBarry Smith #endif
4185ee4f033dSBarry Smith 
4186ee4f033dSBarry Smith #undef __FUNCT__
4187ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
418897f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4189ee4f033dSBarry Smith {
4190ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4191d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
419254f21887SBarry Smith   MatScalar       *v = a->a;
419354f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
419408b6dcc0SBarry Smith   ISColoringValue *color;
4195ee4f033dSBarry Smith 
4196ee4f033dSBarry Smith   PetscFunctionBegin;
4197e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4198ee4f033dSBarry Smith   color = a->coloring->colors;
4199ee4f033dSBarry Smith   /* loop over rows */
4200ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4201ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4202ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
4203ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
4204ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
4205ee4f033dSBarry Smith     }
4206ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4207cc8ba8e1SBarry Smith   }
4208cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4209cc8ba8e1SBarry Smith }
421036db0b34SBarry Smith 
421181824310SBarry Smith /*
421281824310SBarry Smith     Special version for direct calls from Fortran
421381824310SBarry Smith */
4214c6db04a5SJed Brown #include <private/fortranimpl.h>
421581824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
421681824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
421781824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
421881824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
421981824310SBarry Smith #endif
422081824310SBarry Smith 
422181824310SBarry Smith /* Change these macros so can be used in void function */
422281824310SBarry Smith #undef CHKERRQ
42237adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
422481824310SBarry Smith #undef SETERRQ2
4225e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
422681824310SBarry Smith 
422781824310SBarry Smith EXTERN_C_BEGIN
422881824310SBarry Smith #undef __FUNCT__
422981824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
42301f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
423181824310SBarry Smith {
423281824310SBarry Smith   Mat            A = *AA;
423381824310SBarry Smith   PetscInt       m = *mm, n = *nn;
423481824310SBarry Smith   InsertMode     is = *isis;
423581824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
423681824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
423781824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
423881824310SBarry Smith   PetscErrorCode ierr;
423981824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
424054f21887SBarry Smith   MatScalar      *ap,value,*aa;
4241ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4242ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
424381824310SBarry Smith 
424481824310SBarry Smith   PetscFunctionBegin;
4245d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
424681824310SBarry Smith   imax = a->imax;
424781824310SBarry Smith   ai = a->i;
424881824310SBarry Smith   ailen = a->ilen;
424981824310SBarry Smith   aj = a->j;
425081824310SBarry Smith   aa = a->a;
425181824310SBarry Smith 
425281824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
425381824310SBarry Smith     row  = im[k];
425481824310SBarry Smith     if (row < 0) continue;
425581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4256d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
425781824310SBarry Smith #endif
425881824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
425981824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
426081824310SBarry Smith     low  = 0;
426181824310SBarry Smith     high = nrow;
426281824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
426381824310SBarry Smith       if (in[l] < 0) continue;
426481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4265d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
426681824310SBarry Smith #endif
426781824310SBarry Smith       col = in[l];
426881824310SBarry Smith       if (roworiented) {
426981824310SBarry Smith         value = v[l + k*n];
427081824310SBarry Smith       } else {
427181824310SBarry Smith         value = v[k + l*m];
427281824310SBarry Smith       }
427381824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
427481824310SBarry Smith 
427581824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
427681824310SBarry Smith       lastcol = col;
427781824310SBarry Smith       while (high-low > 5) {
427881824310SBarry Smith         t = (low+high)/2;
427981824310SBarry Smith         if (rp[t] > col) high = t;
428081824310SBarry Smith         else             low  = t;
428181824310SBarry Smith       }
428281824310SBarry Smith       for (i=low; i<high; i++) {
428381824310SBarry Smith         if (rp[i] > col) break;
428481824310SBarry Smith         if (rp[i] == col) {
428581824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
428681824310SBarry Smith           else                  ap[i] = value;
428781824310SBarry Smith           goto noinsert;
428881824310SBarry Smith         }
428981824310SBarry Smith       }
429081824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
429181824310SBarry Smith       if (nonew == 1) goto noinsert;
42927adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4293fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
429481824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
429581824310SBarry Smith       /* shift up all the later entries in this row */
429681824310SBarry Smith       for (ii=N; ii>=i; ii--) {
429781824310SBarry Smith         rp[ii+1] = rp[ii];
429881824310SBarry Smith         ap[ii+1] = ap[ii];
429981824310SBarry Smith       }
430081824310SBarry Smith       rp[i] = col;
430181824310SBarry Smith       ap[i] = value;
430281824310SBarry Smith       noinsert:;
430381824310SBarry Smith       low = i + 1;
430481824310SBarry Smith     }
430581824310SBarry Smith     ailen[row] = nrow;
430681824310SBarry Smith   }
430781824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
430881824310SBarry Smith   PetscFunctionReturnVoid();
430981824310SBarry Smith }
431081824310SBarry Smith EXTERN_C_END
431162298a1eSBarry Smith 
4312