xref: /petsc/src/mat/impls/aij/seq/aij.c (revision ff34cdc8f286383efa9ea24b8a1730ec7fd5ed01)
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;
116151d315f7SKerry Stevens MatMult_KernelData* kerneldatap_MatMult = NULL;
116251d315f7SKerry 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;
118351d315f7SKerry Stevens       /*if(n>0) {
118451d315f7SKerry Stevens         PetscSparseDensePlusDot(sum,x,aa,aj,n);
118551d315f7SKerry Stevens         nonzerorow++;
118651d315f7SKerry 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 {
119351d315f7SKerry 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;
119951d315f7SKerry Stevens       /*if(n>0) {
120051d315f7SKerry Stevens         PetscSparseDensePlusDot(sum,x,aa,aj,n);
120151d315f7SKerry Stevens         nonzerorow++;
120251d315f7SKerry Stevens       }*/
12030ca81413SKerry Stevens       nonzerorow += (n>0);
12040ca81413SKerry Stevens       PetscSparseDensePlusDot(sum,x,aa,aj,n);
120551d315f7SKerry Stevens       y[i+ibase] = sum;
12060ca81413SKerry Stevens     }
12070ca81413SKerry Stevens   }
12080ca81413SKerry Stevens   data->nzr = nonzerorow;
12090ca81413SKerry Stevens   return NULL;
12100ca81413SKerry Stevens }
12110ca81413SKerry Stevens 
1212*ff34cdc8SBarry Smith #if defined(PETSC_HAVE_PTHREADCLASSES)
12130ca81413SKerry Stevens extern PetscMPIInt PetscMaxThreads;
12149e800a48SKerry Stevens PetscErrorCode (*MainJob)(void* (*pFunc)(void*),void**,PetscInt);
121551d315f7SKerry Stevens 
12160ca81413SKerry Stevens #undef __FUNCT__
121751d315f7SKerry Stevens #define __FUNCT__ "MatMult_SeqPThreadAIJ"
121851d315f7SKerry Stevens PetscErrorCode MatMult_SeqPThreadAIJ(Mat A,Vec xx,Vec yy)
12190ca81413SKerry Stevens {
12200ca81413SKerry Stevens   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
12210ca81413SKerry Stevens   PetscScalar       *y;
12220ca81413SKerry Stevens   const PetscScalar *x;
12230ca81413SKerry Stevens   PetscErrorCode    ierr;
12240ca81413SKerry Stevens   PetscInt          m=A->rmap->n,nonzerorow=0;
12250ca81413SKerry Stevens   PetscBool         usecprow=a->compressedrow.use;
12260ca81413SKerry Stevens 
12270ca81413SKerry Stevens #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
12280ca81413SKerry Stevens #pragma disjoint(*x,*y,*aa)
12290ca81413SKerry Stevens #endif
12300ca81413SKerry Stevens 
12310ca81413SKerry Stevens   PetscFunctionBegin;
12320ca81413SKerry Stevens   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12330ca81413SKerry Stevens   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12340ca81413SKerry Stevens 
12350ca81413SKerry Stevens   if(usecprow) {
12360ca81413SKerry Stevens     PetscInt          NumPerThread,iindex;
12370ca81413SKerry Stevens     const MatScalar   *aa = a->a;
12380ca81413SKerry Stevens     const PetscInt    *aj = a->j,*ii = a->compressedrow.i,*ridx=a->compressedrow.rindex;
12390ca81413SKerry Stevens     PetscInt          i,iStartVal,iEndVal,iStartIndex,iEndIndex;
12400ca81413SKerry Stevens     const PetscInt    iNumThreads = PetscMaxThreads;  //this number could be different
124151d315f7SKerry Stevens     //MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
124251d315f7SKerry Stevens     //MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
124351d315f7SKerry Stevens 
124451d315f7SKerry Stevens     if(kerneldatap_MatMult==NULL) {
124551d315f7SKerry Stevens       //only need to check 1 of them
124651d315f7SKerry Stevens       kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
124751d315f7SKerry Stevens       pdata_MatMult       = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
124851d315f7SKerry Stevens       for(i=0; i<iNumThreads; i++) {
124951d315f7SKerry Stevens         pdata_MatMult[i] = &kerneldatap_MatMult[i];
125051d315f7SKerry Stevens       }
125151d315f7SKerry Stevens     }
12520ca81413SKerry Stevens 
12530ca81413SKerry Stevens     m    = a->compressedrow.nrows;
12540ca81413SKerry Stevens     NumPerThread = ii[m]/iNumThreads;
12550ca81413SKerry Stevens     iindex = 0;
12560ca81413SKerry Stevens     for(i=0; i<iNumThreads;i++) {
12570ca81413SKerry Stevens       iStartIndex = iindex;
12580ca81413SKerry Stevens       iStartVal = ii[iStartIndex];
12590ca81413SKerry Stevens       iEndVal = iStartVal;
12600ca81413SKerry Stevens       //determine number of rows to process
12610ca81413SKerry Stevens       while(iEndVal-iStartVal<NumPerThread) {
12620ca81413SKerry Stevens 	iindex++;
12630ca81413SKerry Stevens 	iEndVal = ii[iindex];
12640ca81413SKerry Stevens       }
12650ca81413SKerry Stevens       //determine whether to go back 1
12660ca81413SKerry Stevens       if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) {
12670ca81413SKerry Stevens 	iindex--;
12680ca81413SKerry Stevens 	iEndVal = ii[iindex];
12690ca81413SKerry Stevens       }
12700ca81413SKerry Stevens       iEndIndex = iindex;
127151d315f7SKerry Stevens       /*kerneldatap[i].matdata  = aa;
12720ca81413SKerry Stevens       kerneldatap[i].vecdata  = x;
12730ca81413SKerry Stevens       kerneldatap[i].vecout   = y;
12740ca81413SKerry Stevens       kerneldatap[i].colindnz = aj;
12750ca81413SKerry Stevens       kerneldatap[i].rownumnz = ii + iStartIndex;
12760ca81413SKerry Stevens       kerneldatap[i].numrows  = iEndIndex - iStartIndex + 1;
12770ca81413SKerry Stevens       kerneldatap[i].specidx  = ridx + iStartVal;
12780ca81413SKerry Stevens       kerneldatap[i].nzr      = 0;
127951d315f7SKerry Stevens       pdata[i] = &kerneldatap[i];*/
128051d315f7SKerry Stevens       kerneldatap_MatMult[i].matdata  = aa;
128151d315f7SKerry Stevens       kerneldatap_MatMult[i].vecdata  = x;
128251d315f7SKerry Stevens       kerneldatap_MatMult[i].vecout   = y;
128351d315f7SKerry Stevens       kerneldatap_MatMult[i].colindnz = aj;
128451d315f7SKerry Stevens       kerneldatap_MatMult[i].rownumnz = ii + iStartIndex;
128551d315f7SKerry Stevens       kerneldatap_MatMult[i].numrows  = iEndIndex - iStartIndex + 1;
128651d315f7SKerry Stevens       kerneldatap_MatMult[i].specidx  = ridx + iStartVal;
128751d315f7SKerry Stevens       kerneldatap_MatMult[i].nzr      = 0;
12880ca81413SKerry Stevens       iindex++;
12890ca81413SKerry Stevens     }
129051d315f7SKerry Stevens     //ierr = MainJob(MatMult_Kernel,(void**)pdata,iNumThreads);
129151d315f7SKerry Stevens     ierr = MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads);
129251d315f7SKerry Stevens     //collect results
129351d315f7SKerry Stevens     for(i=0; i<iNumThreads; i++) {
129451d315f7SKerry Stevens       //nonzerorow += kerneldatap[i].nzr;
129551d315f7SKerry Stevens       nonzerorow += kerneldatap_MatMult[i].nzr;
129651d315f7SKerry Stevens     }
129751d315f7SKerry Stevens     //free(kerneldatap);
129851d315f7SKerry Stevens     //free(pdata);
129951d315f7SKerry Stevens   }
130051d315f7SKerry Stevens   else {
130151d315f7SKerry Stevens #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
130251d315f7SKerry Stevens   fortranmultaij_(&m,x,a->i,a->j,a->a,y);
130351d315f7SKerry Stevens #else
130451d315f7SKerry Stevens   PetscInt            i,iindex;
130551d315f7SKerry Stevens     const MatScalar   *aa = a->a;
130651d315f7SKerry Stevens     const PetscInt    *aj = a->j,*ii = a->i;
130751d315f7SKerry Stevens     const PetscInt    iNumThreads = PetscMaxThreads;  //this number could be different
130851d315f7SKerry Stevens     PetscInt          Q = m/iNumThreads;
130951d315f7SKerry Stevens     PetscInt          R = m-Q*iNumThreads;
131051d315f7SKerry Stevens     PetscBool         S;
131151d315f7SKerry Stevens 
131251d315f7SKerry Stevens     MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
131351d315f7SKerry Stevens     MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
131451d315f7SKerry Stevens 
131551d315f7SKerry Stevens     iindex = 0;
131651d315f7SKerry Stevens     for(i=0; i<iNumThreads;i++) {
131751d315f7SKerry Stevens       S = i<R;
131851d315f7SKerry Stevens       kerneldatap[i].matdata  = aa;
131951d315f7SKerry Stevens       kerneldatap[i].vecdata  = x;
132051d315f7SKerry Stevens       kerneldatap[i].vecout   = y;
132151d315f7SKerry Stevens       kerneldatap[i].colindnz = aj;
132251d315f7SKerry Stevens       kerneldatap[i].rownumnz = ii + iindex;
132351d315f7SKerry Stevens       kerneldatap[i].numrows  = S?Q+1:Q;
132451d315f7SKerry Stevens       kerneldatap[i].specidx  = PETSC_NULL;
132551d315f7SKerry Stevens       kerneldatap[i].nzr      = iindex; //serves as the 'base' row (needed to access correctly into output vector y)
132651d315f7SKerry Stevens       pdata[i] = &kerneldatap[i];
132751d315f7SKerry Stevens       iindex += kerneldatap[i].numrows;
132851d315f7SKerry Stevens     }
13290ca81413SKerry Stevens     MainJob(MatMult_Kernel,(void**)pdata,iNumThreads);
13300ca81413SKerry Stevens     //collect results
13310ca81413SKerry Stevens     for(i=0; i<iNumThreads; i++) {
13320ca81413SKerry Stevens       nonzerorow += kerneldatap[i].nzr;
13330ca81413SKerry Stevens     }
133451d315f7SKerry Stevens     free(kerneldatap);
133551d315f7SKerry Stevens     free(pdata);
133651d315f7SKerry Stevens     /*if(kerneldatap_MatMult==NULL) {
133751d315f7SKerry Stevens       //only need to check 1 of them
133851d315f7SKerry Stevens       kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData));
133951d315f7SKerry Stevens       pdata_MatMult       = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*));
134051d315f7SKerry Stevens       for(i=0; i<iNumThreads; i++) {
134151d315f7SKerry Stevens         pdata_MatMult[i] = &kerneldatap_MatMult[i];
13420ca81413SKerry Stevens       }
134351d315f7SKerry Stevens     }
13440ca81413SKerry Stevens 
13450ca81413SKerry Stevens     NumPerThread = ii[m]/iNumThreads;
13460ca81413SKerry Stevens     iindex = 0;
13470ca81413SKerry Stevens     for(i=0; i<iNumThreads;i++) {
13480ca81413SKerry Stevens       iStartIndex = iindex;
13490ca81413SKerry Stevens       iStartVal = ii[iStartIndex];
13500ca81413SKerry Stevens       iEndVal = iStartVal;
13510ca81413SKerry Stevens       //determine number of rows to process
13520ca81413SKerry Stevens       while(iEndVal-iStartVal<NumPerThread) {
13530ca81413SKerry Stevens 	iindex++;
13540ca81413SKerry Stevens 	iEndVal = ii[iindex];
13550ca81413SKerry Stevens       }
13560ca81413SKerry Stevens       //determine whether to go back 1
13570ca81413SKerry Stevens       if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) {
13580ca81413SKerry Stevens 	iindex--;
13590ca81413SKerry Stevens 	iEndVal = ii[iindex];
13600ca81413SKerry Stevens       }
136151d315f7SKerry Stevens       iindex--; //needed b/c ii[k] gives # nonzero elements of rows 0 through k-1
13620ca81413SKerry Stevens       iEndIndex = iindex;
136351d315f7SKerry Stevens       kerneldatap_MatMult[i].matdata  = aa;
136451d315f7SKerry Stevens       kerneldatap_MatMult[i].vecdata  = x;
136551d315f7SKerry Stevens       kerneldatap_MatMult[i].vecout   = y;
136651d315f7SKerry Stevens       kerneldatap_MatMult[i].colindnz = aj;
136751d315f7SKerry Stevens       kerneldatap_MatMult[i].rownumnz = ii + iStartIndex;
136851d315f7SKerry Stevens       kerneldatap_MatMult[i].numrows  = iEndIndex - iStartIndex + 1;
136951d315f7SKerry Stevens       kerneldatap_MatMult[i].specidx  = PETSC_NULL;
137051d315f7SKerry Stevens       kerneldatap_MatMult[i].nzr      = iStartIndex;
13710ca81413SKerry Stevens       iindex++;
13720ca81413SKerry Stevens     }
137351d315f7SKerry Stevens     MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads);
13740ca81413SKerry Stevens     //collect results
13750ca81413SKerry Stevens     for(i=0; i<iNumThreads; i++) {
137651d315f7SKerry Stevens       nonzerorow += kerneldatap_MatMult[i].nzr;
137751d315f7SKerry Stevens     }*/
13780ca81413SKerry Stevens #endif
13790ca81413SKerry Stevens   }
13800ca81413SKerry Stevens 
13810ca81413SKerry Stevens   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
13820ca81413SKerry Stevens   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13830ca81413SKerry Stevens   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13840ca81413SKerry Stevens   PetscFunctionReturn(0);
13850ca81413SKerry Stevens }
13860ca81413SKerry Stevens //*******************
1387ba61063dSBarry Smith #endif
13880ca81413SKerry Stevens 
1389c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
13904a2ae208SSatish Balay #undef __FUNCT__
13914a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1392dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
139317ab2063SBarry Smith {
1394416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1395f15663dcSBarry Smith   PetscScalar       *y,*z;
1396f15663dcSBarry Smith   const PetscScalar *x;
139754f21887SBarry Smith   const MatScalar   *aa;
1398dfbe8321SBarry Smith   PetscErrorCode    ierr;
1399d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
1400f15663dcSBarry Smith   PetscInt          n,i,*ridx=PETSC_NULL;
1401362ced78SSatish Balay   PetscScalar       sum;
1402ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14039ea0dfa2SSatish Balay 
14043a40ed3dSBarry Smith   PetscFunctionBegin;
1405f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14061ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14072e8a6d31SBarry Smith   if (zz != yy) {
14081ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14092e8a6d31SBarry Smith   } else {
14102e8a6d31SBarry Smith     z = y;
14112e8a6d31SBarry Smith   }
1412bfeeae90SHong Zhang 
141397952fefSHong Zhang   aj  = a->j;
141497952fefSHong Zhang   aa  = a->a;
1415cddf8d76SBarry Smith   ii  = a->i;
14164eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
14174eb6d288SHong Zhang     if (zz != yy){
14184eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14194eb6d288SHong Zhang     }
142097952fefSHong Zhang     m    = a->compressedrow.nrows;
142197952fefSHong Zhang     ii   = a->compressedrow.i;
142297952fefSHong Zhang     ridx = a->compressedrow.rindex;
142397952fefSHong Zhang     for (i=0; i<m; i++){
142497952fefSHong Zhang       n  = ii[i+1] - ii[i];
142597952fefSHong Zhang       aj  = a->j + ii[i];
142697952fefSHong Zhang       aa  = a->a + ii[i];
142797952fefSHong Zhang       sum = y[*ridx];
1428f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142997952fefSHong Zhang       z[*ridx++] = sum;
143097952fefSHong Zhang     }
143197952fefSHong Zhang   } else { /* do not use compressed row format */
1432f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1433f15663dcSBarry Smith   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1434f15663dcSBarry Smith #else
143517ab2063SBarry Smith     for (i=0; i<m; i++) {
1436f15663dcSBarry Smith       n    = ii[i+1] - ii[i];
1437f15663dcSBarry Smith       aj  = a->j + ii[i];
1438f15663dcSBarry Smith       aa  = a->a + ii[i];
143917ab2063SBarry Smith       sum  = y[i];
1440f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
144117ab2063SBarry Smith       z[i] = sum;
144217ab2063SBarry Smith     }
144302ab625aSSatish Balay #endif
1444f15663dcSBarry Smith   }
1445dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1446f15663dcSBarry Smith   ierr = VecRestoreArrayRead(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);
22274dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22284dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22294dcab191SBarry Smith       if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols);
22304dcab191SBarry Smith #endif
22314dcab191SBarry Smith       smap[icol[i]] = i+1;
22324dcab191SBarry Smith     }
22334dcab191SBarry Smith 
223402834360SBarry Smith     /* determine lens of each row */
223502834360SBarry Smith     for (i=0; i<nrows; i++) {
2236bfeeae90SHong Zhang       kstart  = ai[irow[i]];
223702834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
223802834360SBarry Smith       lens[i] = 0;
223902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2240bfeeae90SHong Zhang         if (smap[aj[k]]) {
224102834360SBarry Smith           lens[i]++;
224202834360SBarry Smith         }
224302834360SBarry Smith       }
224402834360SBarry Smith     }
224517ab2063SBarry Smith     /* Create and fill new matrix */
2246a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2247ace3abfcSBarry Smith       PetscBool  equal;
22480f5bd95cSBarry Smith 
224999141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
2250e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2251d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
22520f5bd95cSBarry Smith       if (!equal) {
2253e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
225499141d43SSatish Balay       }
2255d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
225608480c60SBarry Smith       C = *B;
22573a40ed3dSBarry Smith     } else {
22587adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2259f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22607adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2261ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
226208480c60SBarry Smith     }
226399141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
226417ab2063SBarry Smith     for (i=0; i<nrows; i++) {
226599141d43SSatish Balay       row    = irow[i];
2266bfeeae90SHong Zhang       kstart = ai[row];
226799141d43SSatish Balay       kend   = kstart + a->ilen[row];
2268bfeeae90SHong Zhang       mat_i  = c->i[i];
226999141d43SSatish Balay       mat_j  = c->j + mat_i;
227099141d43SSatish Balay       mat_a  = c->a + mat_i;
227199141d43SSatish Balay       mat_ilen = c->ilen + i;
227217ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2273bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2274ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
227599141d43SSatish Balay           *mat_a++ = a->a[k];
227699141d43SSatish Balay           (*mat_ilen)++;
227799141d43SSatish Balay 
227817ab2063SBarry Smith         }
227917ab2063SBarry Smith       }
228017ab2063SBarry Smith     }
228102834360SBarry Smith     /* Free work space */
228202834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2283606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2284606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
228502834360SBarry Smith   }
22866d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22876d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228817ab2063SBarry Smith 
228917ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2290416022c9SBarry Smith   *B = C;
22913a40ed3dSBarry Smith   PetscFunctionReturn(0);
229217ab2063SBarry Smith }
229317ab2063SBarry Smith 
22941df811f5SHong Zhang #undef __FUNCT__
229582d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
229682d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
229782d44351SHong Zhang {
229882d44351SHong Zhang   PetscErrorCode ierr;
229982d44351SHong Zhang   Mat            B;
230082d44351SHong Zhang 
230182d44351SHong Zhang   PetscFunctionBegin;
230282d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
230382d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
230482d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
230582d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
230682d44351SHong Zhang   *subMat = B;
230782d44351SHong Zhang   PetscFunctionReturn(0);
230882d44351SHong Zhang }
230982d44351SHong Zhang 
231082d44351SHong Zhang #undef __FUNCT__
23114a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
23120481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2313a871dcd8SBarry Smith {
231463b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2315dfbe8321SBarry Smith   PetscErrorCode ierr;
231663b91edcSBarry Smith   Mat            outA;
2317ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
231863b91edcSBarry Smith 
23193a40ed3dSBarry Smith   PetscFunctionBegin;
2320e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23211df811f5SHong Zhang 
2322b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2323b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2324a871dcd8SBarry Smith 
232563b91edcSBarry Smith   outA              = inA;
2326d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2327c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23286bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2329c3122656SLisandro Dalcin   a->row = row;
2330c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23316bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2332c3122656SLisandro Dalcin   a->col = col;
233363b91edcSBarry Smith 
233436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23356bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23364c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
233752e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2338f0ec6fceSSatish Balay 
233994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2340d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2341d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
234294a9d846SBarry Smith   }
234363b91edcSBarry Smith 
2344f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2345137fb511SHong Zhang   if (row_identity && col_identity) {
2346ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2347137fb511SHong Zhang   } else {
2348719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2349137fb511SHong Zhang   }
23503a40ed3dSBarry Smith   PetscFunctionReturn(0);
2351a871dcd8SBarry Smith }
2352a871dcd8SBarry Smith 
23534a2ae208SSatish Balay #undef __FUNCT__
23544a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2355f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2356f0b747eeSBarry Smith {
2357f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2358f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2359efee365bSSatish Balay   PetscErrorCode ierr;
23600805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
23613a40ed3dSBarry Smith 
23623a40ed3dSBarry Smith   PetscFunctionBegin;
2363f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2364efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
23653a40ed3dSBarry Smith   PetscFunctionReturn(0);
2366f0b747eeSBarry Smith }
2367f0b747eeSBarry Smith 
23684a2ae208SSatish Balay #undef __FUNCT__
23694a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
237097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2371cddf8d76SBarry Smith {
2372dfbe8321SBarry Smith   PetscErrorCode ierr;
237397f1f81fSBarry Smith   PetscInt       i;
2374cddf8d76SBarry Smith 
23753a40ed3dSBarry Smith   PetscFunctionBegin;
2376cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2377b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2378cddf8d76SBarry Smith   }
2379cddf8d76SBarry Smith 
2380cddf8d76SBarry Smith   for (i=0; i<n; i++) {
23816a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2382cddf8d76SBarry Smith   }
23833a40ed3dSBarry Smith   PetscFunctionReturn(0);
2384cddf8d76SBarry Smith }
2385cddf8d76SBarry Smith 
23864a2ae208SSatish Balay #undef __FUNCT__
23874a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
238897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
23894dcbc457SBarry Smith {
2390e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
23916849ba73SBarry Smith   PetscErrorCode ierr;
23925d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
23935d0c19d7SBarry Smith   const PetscInt *idx;
239497f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2395f1af5d2fSBarry Smith   PetscBT        table;
2396bbd702dbSSatish Balay 
23973a40ed3dSBarry Smith   PetscFunctionBegin;
2398d0f46423SBarry Smith   m     = A->rmap->n;
2399e4d965acSSatish Balay   ai    = a->i;
2400bfeeae90SHong Zhang   aj    = a->j;
24018a047759SSatish Balay 
2402e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
240306763907SSatish Balay 
240497f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
24056831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
240606763907SSatish Balay 
2407e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2408b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2409e4d965acSSatish Balay     isz  = 0;
24106831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2411e4d965acSSatish Balay 
2412e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
24134dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2414b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2415e4d965acSSatish Balay 
2416dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2417e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2418f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
24194dcbc457SBarry Smith     }
242006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
24216bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2422e4d965acSSatish Balay 
242304a348a9SBarry Smith     k = 0;
242404a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
242504a348a9SBarry Smith       n = isz;
242606763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2427e4d965acSSatish Balay         row   = nidx[k];
2428e4d965acSSatish Balay         start = ai[row];
2429e4d965acSSatish Balay         end   = ai[row+1];
243004a348a9SBarry Smith         for (l = start; l<end ; l++){
2431efb16452SHong Zhang           val = aj[l] ;
2432f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2433e4d965acSSatish Balay         }
2434e4d965acSSatish Balay       }
2435e4d965acSSatish Balay     }
243670b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2437e4d965acSSatish Balay   }
24386831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2439606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
24403a40ed3dSBarry Smith   PetscFunctionReturn(0);
24414dcbc457SBarry Smith }
244217ab2063SBarry Smith 
24430513a670SBarry Smith /* -------------------------------------------------------------- */
24444a2ae208SSatish Balay #undef __FUNCT__
24454a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2446dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
24470513a670SBarry Smith {
24480513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24496849ba73SBarry Smith   PetscErrorCode ierr;
24503b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
24515d0c19d7SBarry Smith   const PetscInt *row,*col;
24525d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
245356cd22aeSBarry Smith   IS             icolp,irowp;
24543b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
24553b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
24560513a670SBarry Smith 
24573a40ed3dSBarry Smith   PetscFunctionBegin;
24584c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
245956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
24604c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
246156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
24620513a670SBarry Smith 
24630513a670SBarry Smith   /* determine lengths of permuted rows */
246497f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
24650513a670SBarry Smith   for (i=0; i<m; i++) {
24660513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
24670513a670SBarry Smith   }
24687adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2469f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
24707adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2471ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2472606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
24730513a670SBarry Smith 
247497f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
24750513a670SBarry Smith   for (i=0; i<m; i++) {
247632ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24770513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2478cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
247932ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24800513a670SBarry Smith   }
2481606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
24823c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
24830513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24840513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
248556cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
248656cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
24876bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
24886bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
24893a40ed3dSBarry Smith   PetscFunctionReturn(0);
24900513a670SBarry Smith }
24910513a670SBarry Smith 
24924a2ae208SSatish Balay #undef __FUNCT__
24934a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2494dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2495cb5b572fSBarry Smith {
2496dfbe8321SBarry Smith   PetscErrorCode ierr;
2497cb5b572fSBarry Smith 
2498cb5b572fSBarry Smith   PetscFunctionBegin;
249933f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
250033f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2501be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2502be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2503be6bf707SBarry Smith 
2504700c5bfcSBarry 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");
2505d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2506cb5b572fSBarry Smith   } else {
2507cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2508cb5b572fSBarry Smith   }
2509cb5b572fSBarry Smith   PetscFunctionReturn(0);
2510cb5b572fSBarry Smith }
2511cb5b572fSBarry Smith 
25124a2ae208SSatish Balay #undef __FUNCT__
25134a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2514dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2515273d9f13SBarry Smith {
2516dfbe8321SBarry Smith   PetscErrorCode ierr;
2517273d9f13SBarry Smith 
2518273d9f13SBarry Smith   PetscFunctionBegin;
2519ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2520273d9f13SBarry Smith   PetscFunctionReturn(0);
2521273d9f13SBarry Smith }
2522273d9f13SBarry Smith 
25234a2ae208SSatish Balay #undef __FUNCT__
25244a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2525a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
25266c0721eeSBarry Smith {
25276c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
25286c0721eeSBarry Smith   PetscFunctionBegin;
25296c0721eeSBarry Smith   *array = a->a;
25306c0721eeSBarry Smith   PetscFunctionReturn(0);
25316c0721eeSBarry Smith }
25326c0721eeSBarry Smith 
25334a2ae208SSatish Balay #undef __FUNCT__
25344a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2535dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
25366c0721eeSBarry Smith {
25376c0721eeSBarry Smith   PetscFunctionBegin;
25386c0721eeSBarry Smith   PetscFunctionReturn(0);
25396c0721eeSBarry Smith }
2540273d9f13SBarry Smith 
2541ee4f033dSBarry Smith #undef __FUNCT__
2542ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2543dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2544ee4f033dSBarry Smith {
25456849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
25466849ba73SBarry Smith   PetscErrorCode ierr;
254797f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2548efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
254987828ca2SBarry Smith   PetscScalar    *vscale_array;
2550ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2551ee4f033dSBarry Smith   Vec            w1,w2,w3;
2552ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2553ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2554ee4f033dSBarry Smith 
2555ee4f033dSBarry Smith   PetscFunctionBegin;
2556ee4f033dSBarry Smith   if (!coloring->w1) {
2557ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
255852e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2559ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
256052e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2561ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
256252e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2563ee4f033dSBarry Smith   }
2564ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2565ee4f033dSBarry Smith 
2566ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2567acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2568ee4f033dSBarry Smith   if (flg) {
2569ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2570ee4f033dSBarry Smith   } else {
2571ace3abfcSBarry Smith     PetscBool  assembled;
25720b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
25730b9b6f31SBarry Smith     if (assembled) {
2574ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2575ee4f033dSBarry Smith     }
25760b9b6f31SBarry Smith   }
2577ee4f033dSBarry Smith 
2578ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2579ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2580ee4f033dSBarry Smith 
2581ee4f033dSBarry Smith   /*
2582ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2583ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2584ee4f033dSBarry Smith   */
2585ee4f033dSBarry Smith   if (coloring->F) {
2586ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2587ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2588ee4f033dSBarry Smith     if (m1 != m2) {
2589ee4f033dSBarry Smith       coloring->F = 0;
2590ee4f033dSBarry Smith     }
2591ee4f033dSBarry Smith   }
2592ee4f033dSBarry Smith 
2593ee4f033dSBarry Smith   if (coloring->F) {
2594ee4f033dSBarry Smith     w1          = coloring->F;
2595ee4f033dSBarry Smith     coloring->F = 0;
2596ee4f033dSBarry Smith   } else {
259766f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2598ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
259966f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2600ee4f033dSBarry Smith   }
2601ee4f033dSBarry Smith 
2602ee4f033dSBarry Smith   /*
2603ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2604ee4f033dSBarry Smith   */
26051ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
26061ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2607ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2608ee4f033dSBarry Smith     /*
2609ee4f033dSBarry Smith        Loop over each column associated with color adding the
2610ee4f033dSBarry Smith        perturbation to the vector w3.
2611ee4f033dSBarry Smith     */
2612ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2613ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2614ee4f033dSBarry Smith       dx  = xx[col];
2615ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2616ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2617ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2618ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2619ee4f033dSBarry Smith #else
2620ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2621ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2622ee4f033dSBarry Smith #endif
2623ee4f033dSBarry Smith       dx                *= epsilon;
2624ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2625ee4f033dSBarry Smith     }
2626ee4f033dSBarry Smith   }
26271ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2628ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2629ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2630ee4f033dSBarry Smith 
2631ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2632ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2633ee4f033dSBarry Smith 
2634ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2635ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2636ee4f033dSBarry Smith 
26371ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2638ee4f033dSBarry Smith   /*
2639ee4f033dSBarry Smith       Loop over each color
2640ee4f033dSBarry Smith   */
2641ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
264249b058dcSBarry Smith     coloring->currentcolor = k;
2643ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
26441ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2645ee4f033dSBarry Smith     /*
2646ee4f033dSBarry Smith        Loop over each column associated with color adding the
2647ee4f033dSBarry Smith        perturbation to the vector w3.
2648ee4f033dSBarry Smith     */
2649ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2650ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2651ee4f033dSBarry Smith       dx  = xx[col];
26525b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2653ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2654ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2655ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2656ee4f033dSBarry Smith #else
2657ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2658ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2659ee4f033dSBarry Smith #endif
2660ee4f033dSBarry Smith       dx            *= epsilon;
2661e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2662ee4f033dSBarry Smith       w3_array[col] += dx;
2663ee4f033dSBarry Smith     }
26641ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2665ee4f033dSBarry Smith 
2666ee4f033dSBarry Smith     /*
2667ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2668ee4f033dSBarry Smith     */
2669ee4f033dSBarry Smith 
267066f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2671ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
267266f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2673efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2674ee4f033dSBarry Smith 
2675ee4f033dSBarry Smith     /*
2676ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2677ee4f033dSBarry Smith     */
26781ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2679ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2680ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2681ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2682ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2683ee4f033dSBarry Smith       srow   = row + start;
2684ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2685ee4f033dSBarry Smith     }
26861ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2687ee4f033dSBarry Smith   }
268849b058dcSBarry Smith   coloring->currentcolor = k;
26891ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
26901ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2691ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2692ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2693ee4f033dSBarry Smith   PetscFunctionReturn(0);
2694ee4f033dSBarry Smith }
2695ee4f033dSBarry Smith 
26968229c054SShri Abhyankar /*
26978229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26988229c054SShri Abhyankar    have different nonzero structure.
26998229c054SShri Abhyankar */
2700ac90fabeSBarry Smith #undef __FUNCT__
27018229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27028229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2703ec7775f6SShri Abhyankar {
27048229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2705ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2706ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2707ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2708ec7775f6SShri Abhyankar 
2709ec7775f6SShri Abhyankar   PetscFunctionBegin;
2710ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2711ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
27128af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27138af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27148af7cee1SJed Brown     nnz[i] = 0;
27158af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27168af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27178af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27188af7cee1SJed Brown       nnz[i]++;
27198af7cee1SJed Brown     }
27208af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2721ec7775f6SShri Abhyankar   }
2722ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2723ec7775f6SShri Abhyankar }
2724ec7775f6SShri Abhyankar 
2725ec7775f6SShri Abhyankar #undef __FUNCT__
2726ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2727f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2728ac90fabeSBarry Smith {
2729dfbe8321SBarry Smith   PetscErrorCode ierr;
273097f1f81fSBarry Smith   PetscInt       i;
2731ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
27320805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2733ac90fabeSBarry Smith 
2734ac90fabeSBarry Smith   PetscFunctionBegin;
2735ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2736f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2737f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2738c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2739a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2740a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27416bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2742a30b2313SHong Zhang     }
2743a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2744d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2745a30b2313SHong Zhang       y->XtoY = X;
2746407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2747c537a176SHong Zhang     }
2748f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
27491e2582c4SBarry 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);
2750ac90fabeSBarry Smith   } else {
27518229c054SShri Abhyankar     Mat      B;
27528229c054SShri Abhyankar     PetscInt *nnz;
275316b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2754ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2755bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27564aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2757ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
27588229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
27598229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2760ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2761ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27628229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2763ac90fabeSBarry Smith   }
2764ac90fabeSBarry Smith   PetscFunctionReturn(0);
2765ac90fabeSBarry Smith }
2766ac90fabeSBarry Smith 
2767521d7252SBarry Smith #undef __FUNCT__
2768521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2769521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2770521d7252SBarry Smith {
277141c166b1SJed Brown   PetscErrorCode ierr;
277241c166b1SJed Brown 
2773521d7252SBarry Smith   PetscFunctionBegin;
277441c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
277541c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2776521d7252SBarry Smith   PetscFunctionReturn(0);
2777521d7252SBarry Smith }
2778521d7252SBarry Smith 
2779354c94deSBarry Smith #undef __FUNCT__
2780354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27817087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2782354c94deSBarry Smith {
2783354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2784354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2785354c94deSBarry Smith   PetscInt    i,nz;
2786354c94deSBarry Smith   PetscScalar *a;
2787354c94deSBarry Smith 
2788354c94deSBarry Smith   PetscFunctionBegin;
2789354c94deSBarry Smith   nz = aij->nz;
2790354c94deSBarry Smith   a  = aij->a;
2791354c94deSBarry Smith   for (i=0; i<nz; i++) {
2792354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2793354c94deSBarry Smith   }
2794354c94deSBarry Smith #else
2795354c94deSBarry Smith   PetscFunctionBegin;
2796354c94deSBarry Smith #endif
2797354c94deSBarry Smith   PetscFunctionReturn(0);
2798354c94deSBarry Smith }
2799354c94deSBarry Smith 
2800e34fafa9SBarry Smith #undef __FUNCT__
2801985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2802985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2803e34fafa9SBarry Smith {
2804e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2805e34fafa9SBarry Smith   PetscErrorCode ierr;
2806d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2807e34fafa9SBarry Smith   PetscReal      atmp;
2808985db425SBarry Smith   PetscScalar    *x;
2809e34fafa9SBarry Smith   MatScalar      *aa;
2810e34fafa9SBarry Smith 
2811e34fafa9SBarry Smith   PetscFunctionBegin;
2812e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2813e34fafa9SBarry Smith   aa   = a->a;
2814e34fafa9SBarry Smith   ai   = a->i;
2815e34fafa9SBarry Smith   aj   = a->j;
2816e34fafa9SBarry Smith 
2817985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2818e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2819e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2820e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2821e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2822e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28239189402eSHong Zhang     x[i] = 0.0;
2824e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2825985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2826985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2827985db425SBarry Smith       aa++; aj++;
2828985db425SBarry Smith     }
2829985db425SBarry Smith   }
2830985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2831985db425SBarry Smith   PetscFunctionReturn(0);
2832985db425SBarry Smith }
2833985db425SBarry Smith 
2834985db425SBarry Smith #undef __FUNCT__
2835985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2836985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2837985db425SBarry Smith {
2838985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2839985db425SBarry Smith   PetscErrorCode ierr;
2840d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2841985db425SBarry Smith   PetscScalar    *x;
2842985db425SBarry Smith   MatScalar      *aa;
2843985db425SBarry Smith 
2844985db425SBarry Smith   PetscFunctionBegin;
2845e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2846985db425SBarry Smith   aa   = a->a;
2847985db425SBarry Smith   ai   = a->i;
2848985db425SBarry Smith   aj   = a->j;
2849985db425SBarry Smith 
2850985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2851985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2852985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2853e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2854985db425SBarry Smith   for (i=0; i<m; i++) {
2855985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2856d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2857985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2858985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2859985db425SBarry Smith       x[i] = 0.0;
2860985db425SBarry Smith       if (idx) {
2861985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2862985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2863985db425SBarry Smith           if (aj[j] > j) {
2864985db425SBarry Smith             idx[i] = j;
2865985db425SBarry Smith             break;
2866985db425SBarry Smith           }
2867985db425SBarry Smith         }
2868985db425SBarry Smith       }
2869985db425SBarry Smith     }
2870985db425SBarry Smith     for (j=0; j<ncols; j++){
2871985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2872985db425SBarry Smith       aa++; aj++;
2873985db425SBarry Smith     }
2874985db425SBarry Smith   }
2875985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2876985db425SBarry Smith   PetscFunctionReturn(0);
2877985db425SBarry Smith }
2878985db425SBarry Smith 
2879985db425SBarry Smith #undef __FUNCT__
2880c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2881c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2882c87e5d42SMatthew Knepley {
2883c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2884c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2885c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2886c87e5d42SMatthew Knepley   PetscReal      atmp;
2887c87e5d42SMatthew Knepley   PetscScalar    *x;
2888c87e5d42SMatthew Knepley   MatScalar      *aa;
2889c87e5d42SMatthew Knepley 
2890c87e5d42SMatthew Knepley   PetscFunctionBegin;
2891e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2892c87e5d42SMatthew Knepley   aa   = a->a;
2893c87e5d42SMatthew Knepley   ai   = a->i;
2894c87e5d42SMatthew Knepley   aj   = a->j;
2895c87e5d42SMatthew Knepley 
2896c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2897c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2898c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2899e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2900c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2901c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2902289a08f5SMatthew Knepley     if (ncols) {
2903289a08f5SMatthew Knepley       /* Get first nonzero */
2904289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2905289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2906289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2907289a08f5SMatthew Knepley       }
2908289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2909289a08f5SMatthew Knepley     } else {
2910289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2911289a08f5SMatthew Knepley     }
2912c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2913c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2914289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2915c87e5d42SMatthew Knepley       aa++; aj++;
2916c87e5d42SMatthew Knepley     }
2917c87e5d42SMatthew Knepley   }
2918c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2919c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2920c87e5d42SMatthew Knepley }
2921c87e5d42SMatthew Knepley 
2922c87e5d42SMatthew Knepley #undef __FUNCT__
2923985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2924985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2925985db425SBarry Smith {
2926985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2927985db425SBarry Smith   PetscErrorCode ierr;
2928d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2929985db425SBarry Smith   PetscScalar    *x;
2930985db425SBarry Smith   MatScalar      *aa;
2931985db425SBarry Smith 
2932985db425SBarry Smith   PetscFunctionBegin;
2933e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2934985db425SBarry Smith   aa   = a->a;
2935985db425SBarry Smith   ai   = a->i;
2936985db425SBarry Smith   aj   = a->j;
2937985db425SBarry Smith 
2938985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2939985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2940985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2941e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2942985db425SBarry Smith   for (i=0; i<m; i++) {
2943985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2944d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2945985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2946985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2947985db425SBarry Smith       x[i] = 0.0;
2948985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2949985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2950985db425SBarry Smith         for (j=0;j<ncols;j++) {
2951985db425SBarry Smith           if (aj[j] > j) {
2952985db425SBarry Smith             idx[i] = j;
2953985db425SBarry Smith             break;
2954985db425SBarry Smith           }
2955985db425SBarry Smith         }
2956985db425SBarry Smith       }
2957985db425SBarry Smith     }
2958985db425SBarry Smith     for (j=0; j<ncols; j++){
2959985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2960985db425SBarry Smith       aa++; aj++;
2961e34fafa9SBarry Smith     }
2962e34fafa9SBarry Smith   }
2963e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2964e34fafa9SBarry Smith   PetscFunctionReturn(0);
2965e34fafa9SBarry Smith }
29667087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2967682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
29680a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2969cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2970cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2971cb5b572fSBarry Smith        MatMult_SeqAIJ,
297297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
29737c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
29747c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2975db4efbfdSBarry Smith        0,
2976db4efbfdSBarry Smith        0,
2977db4efbfdSBarry Smith        0,
2978db4efbfdSBarry Smith /*10*/ 0,
2979cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2980cb5b572fSBarry Smith        0,
298141f059aeSBarry Smith        MatSOR_SeqAIJ,
298217ab2063SBarry Smith        MatTranspose_SeqAIJ,
298397304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2984cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2985cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2986cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2987cb5b572fSBarry Smith        MatNorm_SeqAIJ,
298897304618SKris Buschelman /*20*/ 0,
2989cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2990cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2991cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2992d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2993db4efbfdSBarry Smith        0,
2994db4efbfdSBarry Smith        0,
2995db4efbfdSBarry Smith        0,
2996db4efbfdSBarry Smith        0,
2997d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2998db4efbfdSBarry Smith        0,
2999db4efbfdSBarry Smith        0,
30006c0721eeSBarry Smith        MatGetArray_SeqAIJ,
30016c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
3002d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
3003cb5b572fSBarry Smith        0,
3004cb5b572fSBarry Smith        0,
3005cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
3006cb5b572fSBarry Smith        0,
3007d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
3008cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
3009cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
3010cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
3011cb5b572fSBarry Smith        MatCopy_SeqAIJ,
3012d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
3013cb5b572fSBarry Smith        MatScale_SeqAIJ,
3014cb5b572fSBarry Smith        0,
301579299369SBarry Smith        MatDiagonalSet_SeqAIJ,
30166e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
3017d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
30183b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
30193b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
30203b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
3021a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
3022d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
3023b9617806SBarry Smith        0,
30240513a670SBarry Smith        0,
3025cda55fadSBarry Smith        MatPermute_SeqAIJ,
3026cda55fadSBarry Smith        0,
3027d519adbfSMatthew Knepley /*59*/ 0,
3028b9b97703SBarry Smith        MatDestroy_SeqAIJ,
3029b9b97703SBarry Smith        MatView_SeqAIJ,
3030357abbc8SBarry Smith        0,
3031ee4f033dSBarry Smith        0,
3032d519adbfSMatthew Knepley /*64*/ 0,
3033ee4f033dSBarry Smith        0,
3034ee4f033dSBarry Smith        0,
3035ee4f033dSBarry Smith        0,
3036ee4f033dSBarry Smith        0,
3037d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
3038c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
3039ee4f033dSBarry Smith        0,
3040ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
3041dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3042ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
3043dcf5cc72SBarry Smith #else
3044dcf5cc72SBarry Smith        0,
3045dcf5cc72SBarry Smith #endif
3046d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
30473acb8795SBarry Smith        MatFDColoringApply_AIJ,
304897304618SKris Buschelman        0,
304997304618SKris Buschelman        0,
305097304618SKris Buschelman        0,
30516ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
305297304618SKris Buschelman        0,
305397304618SKris Buschelman        0,
305497304618SKris Buschelman        0,
3055bc011b1eSHong Zhang        MatLoad_SeqAIJ,
3056d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
30571cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
30586284ec50SHong Zhang        0,
30596284ec50SHong Zhang        0,
3060bc011b1eSHong Zhang        0,
3061d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
306226be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
306326be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
3064d439da42SKris Buschelman        MatPtAP_Basic,
30657ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
3066d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
3067bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
3068bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
3069bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
30707ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
3071d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
3072609c6c4dSKris Buschelman        0,
3073609c6c4dSKris Buschelman        0,
307487d4246cSBarry Smith        MatConjugate_SeqAIJ,
307587d4246cSBarry Smith        0,
3076d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
307799cafbc1SBarry Smith        MatRealPart_SeqAIJ,
3078f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
3079f5edf698SHong Zhang        0,
30802bebee5dSHong Zhang        0,
3081cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
3082985db425SBarry Smith        0,
30832af78befSBarry Smith        MatGetRowMin_SeqAIJ,
30842af78befSBarry Smith        0,
3085599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
3086d519adbfSMatthew Knepley /*114*/0,
3087599ef60dSHong Zhang        0,
30883c2a7987SHong Zhang        0,
3089fe97e370SBarry Smith        0,
3090fbdbba38SShri Abhyankar        0,
3091fbdbba38SShri Abhyankar /*119*/0,
3092fbdbba38SShri Abhyankar        0,
3093fbdbba38SShri Abhyankar        0,
309482d44351SHong Zhang        0,
3095b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
30960716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ,
30970716a85fSBarry Smith        MatGetColumnNorms_SeqAIJ
30989e29f15eSvictorle };
309917ab2063SBarry Smith 
3100fb2e594dSBarry Smith EXTERN_C_BEGIN
31014a2ae208SSatish Balay #undef __FUNCT__
31024a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
31037087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3104bef8e0ddSBarry Smith {
3105bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
310697f1f81fSBarry Smith   PetscInt   i,nz,n;
3107bef8e0ddSBarry Smith 
3108bef8e0ddSBarry Smith   PetscFunctionBegin;
3109bef8e0ddSBarry Smith 
3110bef8e0ddSBarry Smith   nz = aij->maxnz;
3111d0f46423SBarry Smith   n  = mat->rmap->n;
3112bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3113bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3114bef8e0ddSBarry Smith   }
3115bef8e0ddSBarry Smith   aij->nz = nz;
3116bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3117bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3118bef8e0ddSBarry Smith   }
3119bef8e0ddSBarry Smith 
3120bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3121bef8e0ddSBarry Smith }
3122fb2e594dSBarry Smith EXTERN_C_END
3123bef8e0ddSBarry Smith 
31244a2ae208SSatish Balay #undef __FUNCT__
31254a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3126bef8e0ddSBarry Smith /*@
3127bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3128bef8e0ddSBarry Smith        in the matrix.
3129bef8e0ddSBarry Smith 
3130bef8e0ddSBarry Smith   Input Parameters:
3131bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3132bef8e0ddSBarry Smith -  indices - the column indices
3133bef8e0ddSBarry Smith 
313415091d37SBarry Smith   Level: advanced
313515091d37SBarry Smith 
3136bef8e0ddSBarry Smith   Notes:
3137bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3138bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3139bef8e0ddSBarry Smith   of the MatSetValues() operation.
3140bef8e0ddSBarry Smith 
3141bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3142d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3143bef8e0ddSBarry Smith 
3144bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3145bef8e0ddSBarry Smith 
3146b9617806SBarry Smith     The indices should start with zero, not one.
3147b9617806SBarry Smith 
3148bef8e0ddSBarry Smith @*/
31497087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3150bef8e0ddSBarry Smith {
31514ac538c5SBarry Smith   PetscErrorCode ierr;
3152bef8e0ddSBarry Smith 
3153bef8e0ddSBarry Smith   PetscFunctionBegin;
31540700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
31554482741eSBarry Smith   PetscValidPointer(indices,2);
31564ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
3157bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3158bef8e0ddSBarry Smith }
3159bef8e0ddSBarry Smith 
3160be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3161be6bf707SBarry Smith 
3162fb2e594dSBarry Smith EXTERN_C_BEGIN
31634a2ae208SSatish Balay #undef __FUNCT__
31644a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
31657087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3166be6bf707SBarry Smith {
3167be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
31686849ba73SBarry Smith   PetscErrorCode ierr;
3169d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3170be6bf707SBarry Smith 
3171be6bf707SBarry Smith   PetscFunctionBegin;
3172be6bf707SBarry Smith   if (aij->nonew != 1) {
3173e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3174be6bf707SBarry Smith   }
3175be6bf707SBarry Smith 
3176be6bf707SBarry Smith   /* allocate space for values if not already there */
3177be6bf707SBarry Smith   if (!aij->saved_values) {
317887828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
31799518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3180be6bf707SBarry Smith   }
3181be6bf707SBarry Smith 
3182be6bf707SBarry Smith   /* copy values over */
318387828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3184be6bf707SBarry Smith   PetscFunctionReturn(0);
3185be6bf707SBarry Smith }
3186fb2e594dSBarry Smith EXTERN_C_END
3187be6bf707SBarry Smith 
31884a2ae208SSatish Balay #undef __FUNCT__
3189b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3190be6bf707SBarry Smith /*@
3191be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3192be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3193be6bf707SBarry Smith        nonlinear portion.
3194be6bf707SBarry Smith 
3195be6bf707SBarry Smith    Collect on Mat
3196be6bf707SBarry Smith 
3197be6bf707SBarry Smith   Input Parameters:
31980e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3199be6bf707SBarry Smith 
320015091d37SBarry Smith   Level: advanced
320115091d37SBarry Smith 
3202be6bf707SBarry Smith   Common Usage, with SNESSolve():
3203be6bf707SBarry Smith $    Create Jacobian matrix
3204be6bf707SBarry Smith $    Set linear terms into matrix
3205be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3206be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3207be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3208512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3209be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3210be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3211be6bf707SBarry Smith $    In your Jacobian routine
3212be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3213be6bf707SBarry Smith $      Set nonlinear terms in matrix
3214be6bf707SBarry Smith 
3215be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3216be6bf707SBarry Smith $    // build linear portion of Jacobian
3217512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3218be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3219be6bf707SBarry Smith $    loop over nonlinear iterations
3220be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3221be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3222be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3223be6bf707SBarry Smith $       Solve linear system with Jacobian
3224be6bf707SBarry Smith $    endloop
3225be6bf707SBarry Smith 
3226be6bf707SBarry Smith   Notes:
3227be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3228512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3229be6bf707SBarry Smith     calling this routine.
3230be6bf707SBarry Smith 
32310c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
32320c468ba9SBarry Smith     and does not allocated additional space.
32330c468ba9SBarry Smith 
3234be6bf707SBarry Smith .seealso: MatRetrieveValues()
3235be6bf707SBarry Smith 
3236be6bf707SBarry Smith @*/
32377087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3238be6bf707SBarry Smith {
32394ac538c5SBarry Smith   PetscErrorCode ierr;
3240be6bf707SBarry Smith 
3241be6bf707SBarry Smith   PetscFunctionBegin;
32420700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3243e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3244e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32454ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3246be6bf707SBarry Smith   PetscFunctionReturn(0);
3247be6bf707SBarry Smith }
3248be6bf707SBarry Smith 
3249fb2e594dSBarry Smith EXTERN_C_BEGIN
32504a2ae208SSatish Balay #undef __FUNCT__
32514a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
32527087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3253be6bf707SBarry Smith {
3254be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
32556849ba73SBarry Smith   PetscErrorCode ierr;
3256d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3257be6bf707SBarry Smith 
3258be6bf707SBarry Smith   PetscFunctionBegin;
3259be6bf707SBarry Smith   if (aij->nonew != 1) {
3260e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3261be6bf707SBarry Smith   }
3262be6bf707SBarry Smith   if (!aij->saved_values) {
3263e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3264be6bf707SBarry Smith   }
3265be6bf707SBarry Smith   /* copy values over */
326687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3267be6bf707SBarry Smith   PetscFunctionReturn(0);
3268be6bf707SBarry Smith }
3269fb2e594dSBarry Smith EXTERN_C_END
3270be6bf707SBarry Smith 
32714a2ae208SSatish Balay #undef __FUNCT__
32724a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3273be6bf707SBarry Smith /*@
3274be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3275be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3276be6bf707SBarry Smith        nonlinear portion.
3277be6bf707SBarry Smith 
3278be6bf707SBarry Smith    Collect on Mat
3279be6bf707SBarry Smith 
3280be6bf707SBarry Smith   Input Parameters:
3281be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3282be6bf707SBarry Smith 
328315091d37SBarry Smith   Level: advanced
328415091d37SBarry Smith 
3285be6bf707SBarry Smith .seealso: MatStoreValues()
3286be6bf707SBarry Smith 
3287be6bf707SBarry Smith @*/
32887087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3289be6bf707SBarry Smith {
32904ac538c5SBarry Smith   PetscErrorCode ierr;
3291be6bf707SBarry Smith 
3292be6bf707SBarry Smith   PetscFunctionBegin;
32930700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3294e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3295e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32964ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3297be6bf707SBarry Smith   PetscFunctionReturn(0);
3298be6bf707SBarry Smith }
3299be6bf707SBarry Smith 
3300f83d6046SBarry Smith 
3301be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
33024a2ae208SSatish Balay #undef __FUNCT__
33034a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
330417ab2063SBarry Smith /*@C
3305682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33060d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33076e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
330851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33092bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
331017ab2063SBarry Smith 
3311db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3312db81eaa0SLois Curfman McInnes 
331317ab2063SBarry Smith    Input Parameters:
3314db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
331517ab2063SBarry Smith .  m - number of rows
331617ab2063SBarry Smith .  n - number of columns
331717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
331851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33192bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
332017ab2063SBarry Smith 
332117ab2063SBarry Smith    Output Parameter:
3322416022c9SBarry Smith .  A - the matrix
332317ab2063SBarry Smith 
3324175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3325ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3326175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3327175b88e8SBarry Smith 
3328b259b22eSLois Curfman McInnes    Notes:
332949a6f317SBarry Smith    If nnz is given then nz is ignored
333049a6f317SBarry Smith 
333117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
333217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
33330002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
333444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
333517ab2063SBarry Smith 
333617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3337a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
33383d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
33396da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
334017ab2063SBarry Smith 
3341682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
33424fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3343682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
33446c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
33456c7ebb05SLois Curfman McInnes 
33466c7ebb05SLois Curfman McInnes    Options Database Keys:
3347698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
33489db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
334917ab2063SBarry Smith 
3350027ccd11SLois Curfman McInnes    Level: intermediate
3351027ccd11SLois Curfman McInnes 
335236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
335336db0b34SBarry Smith 
335417ab2063SBarry Smith @*/
33557087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
335617ab2063SBarry Smith {
3357dfbe8321SBarry Smith   PetscErrorCode ierr;
33586945ee14SBarry Smith 
33593a40ed3dSBarry Smith   PetscFunctionBegin;
3360f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3361117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3362c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3363d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3364273d9f13SBarry Smith   PetscFunctionReturn(0);
3365273d9f13SBarry Smith }
3366273d9f13SBarry Smith 
33674a2ae208SSatish Balay #undef __FUNCT__
33684a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3369273d9f13SBarry Smith /*@C
3370273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3371273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3372273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3373273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3374273d9f13SBarry Smith 
3375273d9f13SBarry Smith    Collective on MPI_Comm
3376273d9f13SBarry Smith 
3377273d9f13SBarry Smith    Input Parameters:
3378117016b1SBarry Smith +  B - The matrix-free
3379273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3380273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3381273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3382273d9f13SBarry Smith 
3383273d9f13SBarry Smith    Notes:
338449a6f317SBarry Smith      If nnz is given then nz is ignored
338549a6f317SBarry Smith 
3386273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3387273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3388273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3389273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3390273d9f13SBarry Smith 
3391273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3392273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3393273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3394273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3395273d9f13SBarry Smith 
3396aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3397aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3398aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3399aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3400aa95bbe8SBarry Smith 
3401a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3402a96a251dSBarry Smith    entries or columns indices
3403a96a251dSBarry Smith 
3404273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3405273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3406273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3407273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3408273d9f13SBarry Smith 
3409273d9f13SBarry Smith    Options Database Keys:
3410698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3411698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3412273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3413273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3414273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3415273d9f13SBarry Smith 
3416273d9f13SBarry Smith    Level: intermediate
3417273d9f13SBarry Smith 
3418aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3419273d9f13SBarry Smith 
3420273d9f13SBarry Smith @*/
34217087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3422273d9f13SBarry Smith {
34234ac538c5SBarry Smith   PetscErrorCode ierr;
3424a23d5eceSKris Buschelman 
3425a23d5eceSKris Buschelman   PetscFunctionBegin;
34264ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3427a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3428a23d5eceSKris Buschelman }
3429a23d5eceSKris Buschelman 
3430a23d5eceSKris Buschelman EXTERN_C_BEGIN
3431a23d5eceSKris Buschelman #undef __FUNCT__
3432a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
34337087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3434a23d5eceSKris Buschelman {
3435273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3436ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
34376849ba73SBarry Smith   PetscErrorCode ierr;
343897f1f81fSBarry Smith   PetscInt       i;
3439273d9f13SBarry Smith 
3440273d9f13SBarry Smith   PetscFunctionBegin;
3441d5d45c9bSBarry Smith 
3442a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3443c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3444c461c341SBarry Smith     nz             = 0;
3445c461c341SBarry Smith   }
3446c461c341SBarry Smith 
344726283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
344826283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
344926283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
345026283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3451899cda47SBarry Smith 
3452435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3453e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3454b73539f3SBarry Smith   if (nnz) {
3455d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3456e32f2f54SBarry 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]);
3457e32f2f54SBarry 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);
3458b73539f3SBarry Smith     }
3459b73539f3SBarry Smith   }
3460b73539f3SBarry Smith 
3461273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3462273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3463273d9f13SBarry Smith 
3464ab93d7beSBarry Smith   if (!skipallocation) {
34652ee49352SLisandro Dalcin     if (!b->imax) {
3466d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3467d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
34682ee49352SLisandro Dalcin     }
3469273d9f13SBarry Smith     if (!nnz) {
3470435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3471c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3472d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3473d0f46423SBarry Smith       nz = nz*B->rmap->n;
3474273d9f13SBarry Smith     } else {
3475273d9f13SBarry Smith       nz = 0;
3476d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3477273d9f13SBarry Smith     }
3478ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3479d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3480ab93d7beSBarry Smith 
3481273d9f13SBarry Smith     /* allocate the matrix space */
34822ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3483d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3484d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3485bfeeae90SHong Zhang     b->i[0] = 0;
3486d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
34875da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
34885da197adSKris Buschelman     }
3489273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3490e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3491e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3492c461c341SBarry Smith   } else {
3493e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3494e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3495c461c341SBarry Smith   }
3496273d9f13SBarry Smith 
3497273d9f13SBarry Smith   b->nz                = 0;
3498273d9f13SBarry Smith   b->maxnz             = nz;
3499273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3500273d9f13SBarry Smith   PetscFunctionReturn(0);
3501273d9f13SBarry Smith }
3502a23d5eceSKris Buschelman EXTERN_C_END
3503273d9f13SBarry Smith 
3504a1661176SMatthew Knepley #undef  __FUNCT__
3505a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
350658d36128SBarry Smith /*@
3507a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3508a1661176SMatthew Knepley 
3509a1661176SMatthew Knepley    Input Parameters:
3510a1661176SMatthew Knepley +  B - the matrix
3511a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3512a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3513a1661176SMatthew Knepley -  v - optional values in the matrix
3514a1661176SMatthew Knepley 
3515a1661176SMatthew Knepley    Level: developer
3516a1661176SMatthew Knepley 
351758d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
351858d36128SBarry Smith 
3519a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3520a1661176SMatthew Knepley 
3521a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3522a1661176SMatthew Knepley @*/
3523a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3524a1661176SMatthew Knepley {
3525a1661176SMatthew Knepley   PetscErrorCode ierr;
3526a1661176SMatthew Knepley 
3527a1661176SMatthew Knepley   PetscFunctionBegin;
35280700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35294ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3530a1661176SMatthew Knepley   PetscFunctionReturn(0);
3531a1661176SMatthew Knepley }
3532a1661176SMatthew Knepley 
3533a1661176SMatthew Knepley EXTERN_C_BEGIN
3534a1661176SMatthew Knepley #undef  __FUNCT__
3535a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
35367087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3537a1661176SMatthew Knepley {
3538a1661176SMatthew Knepley   PetscInt       i;
3539a1661176SMatthew Knepley   PetscInt       m,n;
3540a1661176SMatthew Knepley   PetscInt       nz;
3541a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3542a1661176SMatthew Knepley   PetscScalar    *values;
3543a1661176SMatthew Knepley   PetscErrorCode ierr;
3544a1661176SMatthew Knepley 
3545a1661176SMatthew Knepley   PetscFunctionBegin;
3546a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3547a1661176SMatthew Knepley 
354865e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3549a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3550a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3551b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3552a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
355365e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3554a1661176SMatthew Knepley     nnz[i] = nz;
3555a1661176SMatthew Knepley   }
3556a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3557a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3558a1661176SMatthew Knepley 
3559a1661176SMatthew Knepley   if (v) {
3560a1661176SMatthew Knepley     values = (PetscScalar*) v;
3561a1661176SMatthew Knepley   } else {
35620e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3563a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3564a1661176SMatthew Knepley   }
3565a1661176SMatthew Knepley 
3566a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3567b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3568b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3569a1661176SMatthew Knepley   }
3570a1661176SMatthew Knepley 
3571a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3572a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3573a1661176SMatthew Knepley 
3574a1661176SMatthew Knepley   if (!v) {
3575a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3576a1661176SMatthew Knepley   }
3577a1661176SMatthew Knepley   PetscFunctionReturn(0);
3578a1661176SMatthew Knepley }
3579a1661176SMatthew Knepley EXTERN_C_END
3580a1661176SMatthew Knepley 
3581c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3582c6db04a5SJed Brown #include <private/petscaxpy.h>
3583170fe5c8SBarry Smith 
3584170fe5c8SBarry Smith #undef __FUNCT__
3585170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3586170fe5c8SBarry Smith /*
3587170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3588170fe5c8SBarry Smith 
3589170fe5c8SBarry Smith                n                       p                          p
3590170fe5c8SBarry Smith         (              )       (              )         (                  )
3591170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3592170fe5c8SBarry Smith         (              )       (              )         (                  )
3593170fe5c8SBarry Smith 
3594170fe5c8SBarry Smith */
3595170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3596170fe5c8SBarry Smith {
3597170fe5c8SBarry Smith   PetscErrorCode     ierr;
3598170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3599170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3600170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
36011de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3602170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3603170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3604170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3605170fe5c8SBarry Smith 
3606170fe5c8SBarry Smith   PetscFunctionBegin;
3607d0f46423SBarry Smith   m = A->rmap->n;
3608d0f46423SBarry Smith   n = A->cmap->n;
3609d0f46423SBarry Smith   p = B->cmap->n;
3610170fe5c8SBarry Smith   a = sub_a->v;
3611170fe5c8SBarry Smith   b = sub_b->a;
3612170fe5c8SBarry Smith   c = sub_c->v;
3613170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3614170fe5c8SBarry Smith 
3615170fe5c8SBarry Smith   ii  = sub_b->i;
3616170fe5c8SBarry Smith   idx = sub_b->j;
3617170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3618170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3619170fe5c8SBarry Smith     while (q-->0) {
3620170fe5c8SBarry Smith       c_q = c + m*(*idx);
3621170fe5c8SBarry Smith       a_q = a + m*i;
3622be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3623170fe5c8SBarry Smith       idx++;
3624170fe5c8SBarry Smith       b++;
3625170fe5c8SBarry Smith     }
3626170fe5c8SBarry Smith   }
3627170fe5c8SBarry Smith   PetscFunctionReturn(0);
3628170fe5c8SBarry Smith }
3629170fe5c8SBarry Smith 
3630170fe5c8SBarry Smith #undef __FUNCT__
3631170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3632170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3633170fe5c8SBarry Smith {
3634170fe5c8SBarry Smith   PetscErrorCode ierr;
3635d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3636170fe5c8SBarry Smith   Mat            Cmat;
3637170fe5c8SBarry Smith 
3638170fe5c8SBarry Smith   PetscFunctionBegin;
3639e32f2f54SBarry 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);
364039804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3641170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3642170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3643170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3644170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3645170fe5c8SBarry Smith   *C = Cmat;
3646170fe5c8SBarry Smith   PetscFunctionReturn(0);
3647170fe5c8SBarry Smith }
3648170fe5c8SBarry Smith 
3649170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3650170fe5c8SBarry Smith #undef __FUNCT__
3651170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3652170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3653170fe5c8SBarry Smith {
3654170fe5c8SBarry Smith   PetscErrorCode ierr;
3655170fe5c8SBarry Smith 
3656170fe5c8SBarry Smith   PetscFunctionBegin;
3657170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3658170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3659170fe5c8SBarry Smith   }
3660170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3661170fe5c8SBarry Smith   PetscFunctionReturn(0);
3662170fe5c8SBarry Smith }
3663170fe5c8SBarry Smith 
3664170fe5c8SBarry Smith 
36650bad9183SKris Buschelman /*MC
3666fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
36670bad9183SKris Buschelman    based on compressed sparse row format.
36680bad9183SKris Buschelman 
36690bad9183SKris Buschelman    Options Database Keys:
36700bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
36710bad9183SKris Buschelman 
36720bad9183SKris Buschelman   Level: beginner
36730bad9183SKris Buschelman 
3674f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
36750bad9183SKris Buschelman M*/
36760bad9183SKris Buschelman 
3677a6175056SHong Zhang EXTERN_C_BEGIN
3678b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3679b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3680b5e56a35SBarry Smith #endif
3681ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3682af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3683af1023dbSSatish Balay #endif
36847087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
36857087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
36867087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
36877087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3688611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
36897087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3690611f576cSBarry Smith #endif
3691611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
36927087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3693611f576cSBarry Smith #endif
3694f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3695f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3696f3c0ef26SHong Zhang #endif
3697611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
36987087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3699611f576cSBarry Smith #endif
3700eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
37017087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3702eb3b5408SSatish Balay #endif
3703586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
37047087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3705586621ddSJed Brown #endif
3706719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
37077087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3708719d5645SBarry Smith #endif
3709b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
37107087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
37117087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
37127087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3713b3866ffcSBarry Smith #endif
371417667f90SBarry Smith EXTERN_C_END
371517667f90SBarry Smith 
371617667f90SBarry Smith EXTERN_C_BEGIN
37174a2ae208SSatish Balay #undef __FUNCT__
37184a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
37197087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3720273d9f13SBarry Smith {
3721273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3722dfbe8321SBarry Smith   PetscErrorCode ierr;
372338baddfdSBarry Smith   PetscMPIInt    size;
3724273d9f13SBarry Smith 
3725273d9f13SBarry Smith   PetscFunctionBegin;
37267adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3727e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3728273d9f13SBarry Smith 
372938f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3730b0a32e0cSBarry Smith   B->data             = (void*)b;
3731549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3732416022c9SBarry Smith   b->row              = 0;
3733416022c9SBarry Smith   b->col              = 0;
373482bf6240SBarry Smith   b->icol             = 0;
3735b810aeb4SBarry Smith   b->reallocs         = 0;
373636db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3737f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3738416022c9SBarry Smith   b->nonew             = 0;
3739416022c9SBarry Smith   b->diag              = 0;
3740416022c9SBarry Smith   b->solve_work        = 0;
37412a1b7f2aSHong Zhang   B->spptr             = 0;
3742be6bf707SBarry Smith   b->saved_values      = 0;
3743d7f994e1SBarry Smith   b->idiag             = 0;
374471f1c65dSBarry Smith   b->mdiag             = 0;
374571f1c65dSBarry Smith   b->ssor_work         = 0;
374671f1c65dSBarry Smith   b->omega             = 1.0;
374771f1c65dSBarry Smith   b->fshift            = 0.0;
374871f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3749a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3750a30b2313SHong Zhang   b->xtoy              = 0;
3751a30b2313SHong Zhang   b->XtoY              = 0;
375288e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
375317ab2063SBarry Smith 
375435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3755b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3756700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3757b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3758b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3759b3866ffcSBarry Smith #endif
3760b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3761700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3762b5e56a35SBarry Smith #endif
3763ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3764700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3765719d5645SBarry Smith #endif
3766611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3767700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3768611f576cSBarry Smith #endif
3769f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3770700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3771f3c0ef26SHong Zhang #endif
3772611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3773700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3774611f576cSBarry Smith #endif
3775611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3776700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3777611f576cSBarry Smith #endif
3778eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3779700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3780eb3b5408SSatish Balay #endif
3781586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3782700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3783586621ddSJed Brown #endif
3784719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3785700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3786719d5645SBarry Smith #endif
3787700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3788700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3789700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3790700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3791700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3792700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3793700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3794700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3795700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3796700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3797700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3798700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3799700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3800700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3801700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3802700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3803700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3804700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
38054108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
380617667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
38073a40ed3dSBarry Smith   PetscFunctionReturn(0);
380817ab2063SBarry Smith }
3809273d9f13SBarry Smith EXTERN_C_END
381017ab2063SBarry Smith 
3811*ff34cdc8SBarry Smith #if defined(PETSC_HAVE_PTHREADCLASSES)
381251d315f7SKerry Stevens EXTERN_C_BEGIN
381351d315f7SKerry Stevens #undef __FUNCT__
381451d315f7SKerry Stevens #define __FUNCT__ "MatCreate_SeqPThreadAIJ"
381551d315f7SKerry Stevens PetscErrorCode  MatCreate_SeqPThreadAIJ(Mat B)
381651d315f7SKerry Stevens {
381751d315f7SKerry Stevens   PetscErrorCode ierr;
381851d315f7SKerry Stevens 
381951d315f7SKerry Stevens   PetscFunctionBegin;
382051d315f7SKerry Stevens   ierr = MatCreate_SeqAIJ(B);
382151d315f7SKerry Stevens   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
382251d315f7SKerry Stevens   B->ops->mult = MatMult_SeqPThreadAIJ;
382351d315f7SKerry Stevens   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQPTHREADAIJ);CHKERRQ(ierr);
382451d315f7SKerry Stevens   PetscFunctionReturn(0);
382551d315f7SKerry Stevens }
382651d315f7SKerry Stevens EXTERN_C_END
3827ba61063dSBarry Smith #endif
382851d315f7SKerry Stevens 
38294a2ae208SSatish Balay #undef __FUNCT__
3830b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3831b24902e0SBarry Smith /*
3832b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3833b24902e0SBarry Smith */
3834ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
383517ab2063SBarry Smith {
3836416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
38376849ba73SBarry Smith   PetscErrorCode ierr;
3838d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
383917ab2063SBarry Smith 
38403a40ed3dSBarry Smith   PetscFunctionBegin;
3841273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3842273d9f13SBarry Smith 
3843d5f3da31SBarry Smith   C->factortype     = A->factortype;
3844416022c9SBarry Smith   c->row            = 0;
3845416022c9SBarry Smith   c->col            = 0;
384682bf6240SBarry Smith   c->icol           = 0;
38476ad4291fSHong Zhang   c->reallocs       = 0;
384817ab2063SBarry Smith 
38496ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
385017ab2063SBarry Smith 
3851aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3852aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3853eec197d1SBarry Smith 
385433b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
38559518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
385617ab2063SBarry Smith   for (i=0; i<m; i++) {
3857416022c9SBarry Smith     c->imax[i] = a->imax[i];
3858416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
385917ab2063SBarry Smith   }
386017ab2063SBarry Smith 
386117ab2063SBarry Smith   /* allocate the matrix space */
3862f77e22a1SHong Zhang   if (mallocmatspace){
3863a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
38649518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3865f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
386697f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
386717ab2063SBarry Smith     if (m > 0) {
386897f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3869be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3870bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3871be6bf707SBarry Smith       } else {
3872bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
387317ab2063SBarry Smith       }
387408480c60SBarry Smith     }
3875f77e22a1SHong Zhang   }
387617ab2063SBarry Smith 
38776ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3878416022c9SBarry Smith   c->roworiented       = a->roworiented;
3879416022c9SBarry Smith   c->nonew             = a->nonew;
3880416022c9SBarry Smith   if (a->diag) {
388197f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
388252e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
388317ab2063SBarry Smith     for (i=0; i<m; i++) {
3884416022c9SBarry Smith       c->diag[i] = a->diag[i];
388517ab2063SBarry Smith     }
38863a40ed3dSBarry Smith   } else c->diag           = 0;
38876ad4291fSHong Zhang   c->solve_work            = 0;
38886ad4291fSHong Zhang   c->saved_values          = 0;
38896ad4291fSHong Zhang   c->idiag                 = 0;
389071f1c65dSBarry Smith   c->ssor_work             = 0;
3891a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3892e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3893e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
38946ad4291fSHong Zhang   c->xtoy                  = 0;
38956ad4291fSHong Zhang   c->XtoY                  = 0;
38966ad4291fSHong Zhang 
3897416022c9SBarry Smith   c->nz                 = a->nz;
38988ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3899273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3900754ec7b1SSatish Balay 
39016ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
39026ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3903cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3904cd6b891eSBarry Smith   if (a->compressedrow.use){
39056ad4291fSHong Zhang     i = a->compressedrow.nrows;
39060e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
39076ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
39086ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
390927ea64f8SHong Zhang   } else {
391027ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
391127ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
391227ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
39136ad4291fSHong Zhang   }
391488e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
39154108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
39164846f1f5SKris Buschelman 
39177adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
39183a40ed3dSBarry Smith   PetscFunctionReturn(0);
391917ab2063SBarry Smith }
392017ab2063SBarry Smith 
39214a2ae208SSatish Balay #undef __FUNCT__
3922b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3923b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3924b24902e0SBarry Smith {
3925b24902e0SBarry Smith   PetscErrorCode ierr;
3926b24902e0SBarry Smith 
3927b24902e0SBarry Smith   PetscFunctionBegin;
3928b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
39294b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3930b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3931f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3932b24902e0SBarry Smith   PetscFunctionReturn(0);
3933b24902e0SBarry Smith }
3934b24902e0SBarry Smith 
3935b24902e0SBarry Smith #undef __FUNCT__
39364a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3937112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3938fbdbba38SShri Abhyankar {
3939fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3940fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3941fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3942fbdbba38SShri Abhyankar   int            fd;
3943fbdbba38SShri Abhyankar   PetscMPIInt    size;
3944fbdbba38SShri Abhyankar   MPI_Comm       comm;
3945fbdbba38SShri Abhyankar 
3946fbdbba38SShri Abhyankar   PetscFunctionBegin;
3947fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3948fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3949fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3950fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3951fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3952fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3953fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3954fbdbba38SShri Abhyankar 
3955fbdbba38SShri Abhyankar   if (nz < 0) {
3956fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3957fbdbba38SShri Abhyankar   }
3958fbdbba38SShri Abhyankar 
3959fbdbba38SShri Abhyankar   /* read in row lengths */
3960fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3961fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3962fbdbba38SShri Abhyankar 
3963fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3964fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3965fbdbba38SShri 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);
3966fbdbba38SShri Abhyankar 
3967fbdbba38SShri Abhyankar   /* set global size if not set already*/
3968f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3969fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3970aabbc4fbSShri Abhyankar   } else {
3971fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3972fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3973f501eaabSShri 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);
3974aabbc4fbSShri Abhyankar   }
3975fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3976fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3977fbdbba38SShri Abhyankar 
3978fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3979fbdbba38SShri Abhyankar 
3980fbdbba38SShri Abhyankar   /* read in nonzero values */
3981fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3982fbdbba38SShri Abhyankar 
3983fbdbba38SShri Abhyankar   /* set matrix "i" values */
3984fbdbba38SShri Abhyankar   a->i[0] = 0;
3985fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3986fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3987fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3988fbdbba38SShri Abhyankar   }
3989fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3990fbdbba38SShri Abhyankar 
3991fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3992fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3993fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3994fbdbba38SShri Abhyankar }
3995fbdbba38SShri Abhyankar 
3996fbdbba38SShri Abhyankar #undef __FUNCT__
3997b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3998ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
39997264ac53SSatish Balay {
40007264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
4001dfbe8321SBarry Smith   PetscErrorCode ierr;
4002eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4003eeffb40dSHong Zhang   PetscInt k;
4004eeffb40dSHong Zhang #endif
40057264ac53SSatish Balay 
40063a40ed3dSBarry Smith   PetscFunctionBegin;
4007bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4008d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4009ca44d042SBarry Smith     *flg = PETSC_FALSE;
4010ca44d042SBarry Smith     PetscFunctionReturn(0);
4011bcd2baecSBarry Smith   }
40127264ac53SSatish Balay 
40137264ac53SSatish Balay   /* if the a->i are the same */
4014d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4015abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
40167264ac53SSatish Balay 
40177264ac53SSatish Balay   /* if a->j are the same */
401897f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4019abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4020bcd2baecSBarry Smith 
4021bcd2baecSBarry Smith   /* if a->a are the same */
4022eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4023eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
4024eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
4025eeffb40dSHong Zhang       *flg = PETSC_FALSE;
40263a40ed3dSBarry Smith       PetscFunctionReturn(0);
4027eeffb40dSHong Zhang     }
4028eeffb40dSHong Zhang   }
4029eeffb40dSHong Zhang #else
4030eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4031eeffb40dSHong Zhang #endif
4032eeffb40dSHong Zhang   PetscFunctionReturn(0);
40337264ac53SSatish Balay }
403436db0b34SBarry Smith 
40354a2ae208SSatish Balay #undef __FUNCT__
40364a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
403705869f15SSatish Balay /*@
403836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
403936db0b34SBarry Smith               provided by the user.
404036db0b34SBarry Smith 
4041c75a6043SHong Zhang       Collective on MPI_Comm
404236db0b34SBarry Smith 
404336db0b34SBarry Smith    Input Parameters:
404436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
404536db0b34SBarry Smith .   m - number of rows
404636db0b34SBarry Smith .   n - number of columns
404736db0b34SBarry Smith .   i - row indices
404836db0b34SBarry Smith .   j - column indices
404936db0b34SBarry Smith -   a - matrix values
405036db0b34SBarry Smith 
405136db0b34SBarry Smith    Output Parameter:
405236db0b34SBarry Smith .   mat - the matrix
405336db0b34SBarry Smith 
405436db0b34SBarry Smith    Level: intermediate
405536db0b34SBarry Smith 
405636db0b34SBarry Smith    Notes:
40570551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4058292fb18eSBarry Smith     once the matrix is destroyed and not before
405936db0b34SBarry Smith 
406036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
406136db0b34SBarry Smith 
4062bfeeae90SHong Zhang        The i and j indices are 0 based
406336db0b34SBarry Smith 
4064a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4065a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4066a4552177SSatish Balay     as shown:
4067a4552177SSatish Balay 
4068a4552177SSatish Balay         1 0 0
4069a4552177SSatish Balay         2 0 3
4070a4552177SSatish Balay         4 5 6
4071a4552177SSatish Balay 
4072a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
40739985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4074a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4075a4552177SSatish Balay 
40769985e31cSBarry Smith 
40772fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
407836db0b34SBarry Smith 
407936db0b34SBarry Smith @*/
40807087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
408136db0b34SBarry Smith {
4082dfbe8321SBarry Smith   PetscErrorCode ierr;
4083cbcfb4deSHong Zhang   PetscInt       ii;
408436db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4085cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4086cbcfb4deSHong Zhang   PetscInt       jj;
4087cbcfb4deSHong Zhang #endif
408836db0b34SBarry Smith 
408936db0b34SBarry Smith   PetscFunctionBegin;
4090a96a251dSBarry Smith   if (i[0]) {
4091e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
409236db0b34SBarry Smith   }
4093f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4094f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4095ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4096ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4097ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4098ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4099ab93d7beSBarry Smith 
410036db0b34SBarry Smith   aij->i = i;
410136db0b34SBarry Smith   aij->j = j;
410236db0b34SBarry Smith   aij->a = a;
410336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
410436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4105e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4106e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
410736db0b34SBarry Smith 
410836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
410936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
41102515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4111e32f2f54SBarry 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]);
41129985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4113e32f2f54SBarry 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);
4114e32f2f54SBarry 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);
41159985e31cSBarry Smith     }
411636db0b34SBarry Smith #endif
411736db0b34SBarry Smith   }
41182515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
411936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4120e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4121e32f2f54SBarry 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]);
412236db0b34SBarry Smith   }
412336db0b34SBarry Smith #endif
412436db0b34SBarry Smith 
4125b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4126b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
412736db0b34SBarry Smith   PetscFunctionReturn(0);
412836db0b34SBarry Smith }
412936db0b34SBarry Smith 
4130cc8ba8e1SBarry Smith #undef __FUNCT__
4131ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4132dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4133cc8ba8e1SBarry Smith {
4134dfbe8321SBarry Smith   PetscErrorCode ierr;
4135cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
413636db0b34SBarry Smith 
4137cc8ba8e1SBarry Smith   PetscFunctionBegin;
41388ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4139cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4140cc8ba8e1SBarry Smith     a->coloring = coloring;
414112c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
414297f1f81fSBarry Smith     PetscInt             i,*larray;
414312c595b3SBarry Smith     ISColoring      ocoloring;
414408b6dcc0SBarry Smith     ISColoringValue *colors;
414512c595b3SBarry Smith 
414612c595b3SBarry Smith     /* set coloring for diagonal portion */
41470e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
4148d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
414912c595b3SBarry Smith       larray[i] = i;
415012c595b3SBarry Smith     }
4151992144d0SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
41520e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
4153d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
415412c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
415512c595b3SBarry Smith     }
415612c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
4157d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
415812c595b3SBarry Smith     a->coloring = ocoloring;
415912c595b3SBarry Smith   }
4160cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4161cc8ba8e1SBarry Smith }
4162cc8ba8e1SBarry Smith 
4163dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
4164ee4f033dSBarry Smith EXTERN_C_BEGIN
4165c6db04a5SJed Brown #include <adic/ad_utils.h>
4166ee4f033dSBarry Smith EXTERN_C_END
4167cc8ba8e1SBarry Smith 
4168cc8ba8e1SBarry Smith #undef __FUNCT__
4169ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
4170dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
4171cc8ba8e1SBarry Smith {
4172cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4173d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
41744440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
417508b6dcc0SBarry Smith   ISColoringValue *color;
4176cc8ba8e1SBarry Smith 
4177cc8ba8e1SBarry Smith   PetscFunctionBegin;
4178e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
41794440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
4180cc8ba8e1SBarry Smith   color = a->coloring->colors;
4181cc8ba8e1SBarry Smith   /* loop over rows */
4182cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
4183cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
4184cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
4185cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
4186cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
4187cc8ba8e1SBarry Smith     }
41884440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
4189ee4f033dSBarry Smith   }
4190ee4f033dSBarry Smith   PetscFunctionReturn(0);
4191ee4f033dSBarry Smith }
4192ee4f033dSBarry Smith #endif
4193ee4f033dSBarry Smith 
4194ee4f033dSBarry Smith #undef __FUNCT__
4195ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
419697f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4197ee4f033dSBarry Smith {
4198ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4199d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
420054f21887SBarry Smith   MatScalar       *v = a->a;
420154f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
420208b6dcc0SBarry Smith   ISColoringValue *color;
4203ee4f033dSBarry Smith 
4204ee4f033dSBarry Smith   PetscFunctionBegin;
4205e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4206ee4f033dSBarry Smith   color = a->coloring->colors;
4207ee4f033dSBarry Smith   /* loop over rows */
4208ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4209ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4210ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
4211ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
4212ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
4213ee4f033dSBarry Smith     }
4214ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4215cc8ba8e1SBarry Smith   }
4216cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4217cc8ba8e1SBarry Smith }
421836db0b34SBarry Smith 
421981824310SBarry Smith /*
422081824310SBarry Smith     Special version for direct calls from Fortran
422181824310SBarry Smith */
4222c6db04a5SJed Brown #include <private/fortranimpl.h>
422381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
422481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
422581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
422681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
422781824310SBarry Smith #endif
422881824310SBarry Smith 
422981824310SBarry Smith /* Change these macros so can be used in void function */
423081824310SBarry Smith #undef CHKERRQ
42317adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
423281824310SBarry Smith #undef SETERRQ2
4233e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
423481824310SBarry Smith 
423581824310SBarry Smith EXTERN_C_BEGIN
423681824310SBarry Smith #undef __FUNCT__
423781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
42381f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
423981824310SBarry Smith {
424081824310SBarry Smith   Mat            A = *AA;
424181824310SBarry Smith   PetscInt       m = *mm, n = *nn;
424281824310SBarry Smith   InsertMode     is = *isis;
424381824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
424481824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
424581824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
424681824310SBarry Smith   PetscErrorCode ierr;
424781824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
424854f21887SBarry Smith   MatScalar      *ap,value,*aa;
4249ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4250ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
425181824310SBarry Smith 
425281824310SBarry Smith   PetscFunctionBegin;
4253d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
425481824310SBarry Smith   imax = a->imax;
425581824310SBarry Smith   ai = a->i;
425681824310SBarry Smith   ailen = a->ilen;
425781824310SBarry Smith   aj = a->j;
425881824310SBarry Smith   aa = a->a;
425981824310SBarry Smith 
426081824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
426181824310SBarry Smith     row  = im[k];
426281824310SBarry Smith     if (row < 0) continue;
426381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4264d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
426581824310SBarry Smith #endif
426681824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
426781824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
426881824310SBarry Smith     low  = 0;
426981824310SBarry Smith     high = nrow;
427081824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
427181824310SBarry Smith       if (in[l] < 0) continue;
427281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4273d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
427481824310SBarry Smith #endif
427581824310SBarry Smith       col = in[l];
427681824310SBarry Smith       if (roworiented) {
427781824310SBarry Smith         value = v[l + k*n];
427881824310SBarry Smith       } else {
427981824310SBarry Smith         value = v[k + l*m];
428081824310SBarry Smith       }
428181824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
428281824310SBarry Smith 
428381824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
428481824310SBarry Smith       lastcol = col;
428581824310SBarry Smith       while (high-low > 5) {
428681824310SBarry Smith         t = (low+high)/2;
428781824310SBarry Smith         if (rp[t] > col) high = t;
428881824310SBarry Smith         else             low  = t;
428981824310SBarry Smith       }
429081824310SBarry Smith       for (i=low; i<high; i++) {
429181824310SBarry Smith         if (rp[i] > col) break;
429281824310SBarry Smith         if (rp[i] == col) {
429381824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
429481824310SBarry Smith           else                  ap[i] = value;
429581824310SBarry Smith           goto noinsert;
429681824310SBarry Smith         }
429781824310SBarry Smith       }
429881824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
429981824310SBarry Smith       if (nonew == 1) goto noinsert;
43007adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4301fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
430281824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
430381824310SBarry Smith       /* shift up all the later entries in this row */
430481824310SBarry Smith       for (ii=N; ii>=i; ii--) {
430581824310SBarry Smith         rp[ii+1] = rp[ii];
430681824310SBarry Smith         ap[ii+1] = ap[ii];
430781824310SBarry Smith       }
430881824310SBarry Smith       rp[i] = col;
430981824310SBarry Smith       ap[i] = value;
431081824310SBarry Smith       noinsert:;
431181824310SBarry Smith       low = i + 1;
431281824310SBarry Smith     }
431381824310SBarry Smith     ailen[row] = nrow;
431481824310SBarry Smith   }
431581824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
431681824310SBarry Smith   PetscFunctionReturnVoid();
431781824310SBarry Smith }
431881824310SBarry Smith EXTERN_C_END
431962298a1eSBarry Smith 
4320