xref: /petsc/src/mat/impls/aij/seq/aij.c (revision ba61063db8cd96e5a5f702c43a4ce6e281e3e2a6)
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*ba61063dSBarry Smith #if defined(PETSC_USE_PTHREAD_CLASSES)
12130ca81413SKerry Stevens extern PetscMPIInt PetscMaxThreads;
121451d315f7SKerry 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 //*******************
1387*ba61063dSBarry 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;
139554f21887SBarry Smith   PetscScalar     *x,*y,*z;
139654f21887SBarry Smith   const MatScalar *aa;
1397dfbe8321SBarry Smith   PetscErrorCode  ierr;
1398d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1399aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
140097952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1401362ced78SSatish Balay   PetscScalar     sum;
1402ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1403e36a17ebSSatish Balay #endif
14049ea0dfa2SSatish Balay 
14053a40ed3dSBarry Smith   PetscFunctionBegin;
14061ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
14071ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14082e8a6d31SBarry Smith   if (zz != yy) {
14091ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14102e8a6d31SBarry Smith   } else {
14112e8a6d31SBarry Smith     z = y;
14122e8a6d31SBarry Smith   }
1413bfeeae90SHong Zhang 
141497952fefSHong Zhang   aj  = a->j;
141597952fefSHong Zhang   aa  = a->a;
1416cddf8d76SBarry Smith   ii  = a->i;
1417aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
141897952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
141902ab625aSSatish Balay #else
14204eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
14214eb6d288SHong Zhang     if (zz != yy){
14224eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14234eb6d288SHong Zhang     }
142497952fefSHong Zhang     m    = a->compressedrow.nrows;
142597952fefSHong Zhang     ii   = a->compressedrow.i;
142697952fefSHong Zhang     ridx = a->compressedrow.rindex;
142797952fefSHong Zhang     for (i=0; i<m; i++){
142897952fefSHong Zhang       n  = ii[i+1] - ii[i];
142997952fefSHong Zhang       aj  = a->j + ii[i];
143097952fefSHong Zhang       aa  = a->a + ii[i];
143197952fefSHong Zhang       sum = y[*ridx];
143297952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
143397952fefSHong Zhang       z[*ridx++] = sum;
143497952fefSHong Zhang     }
143597952fefSHong Zhang   } else { /* do not use compressed row format */
143617ab2063SBarry Smith     for (i=0; i<m; i++) {
14379ea0dfa2SSatish Balay       jrow = ii[i];
14389ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
143917ab2063SBarry Smith       sum  = y[i];
14409ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
144197952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
14429ea0dfa2SSatish Balay       }
144317ab2063SBarry Smith       z[i] = sum;
144417ab2063SBarry Smith     }
144597952fefSHong Zhang   }
144602ab625aSSatish Balay #endif
1447dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
14481ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14491ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
14502e8a6d31SBarry Smith   if (zz != yy) {
14511ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
14522e8a6d31SBarry Smith   }
14538154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14546b375ea7SVictor Minden   /*
1455918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1456918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1457918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14586b375ea7SVictor Minden   */
1459918e98c3SVictor Minden #endif
14603a40ed3dSBarry Smith   PetscFunctionReturn(0);
146117ab2063SBarry Smith }
146217ab2063SBarry Smith 
146317ab2063SBarry Smith /*
146417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
146517ab2063SBarry Smith */
14664a2ae208SSatish Balay #undef __FUNCT__
14674a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1468dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
146917ab2063SBarry Smith {
1470416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14716849ba73SBarry Smith   PetscErrorCode ierr;
1472d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
147317ab2063SBarry Smith 
14743a40ed3dSBarry Smith   PetscFunctionBegin;
147509f38230SBarry Smith   if (!a->diag) {
147609f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
14779518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
147809f38230SBarry Smith   }
1479d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
148009f38230SBarry Smith     a->diag[i] = a->i[i+1];
1481bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1482bfeeae90SHong Zhang       if (a->j[j] == i) {
148309f38230SBarry Smith         a->diag[i] = j;
148417ab2063SBarry Smith         break;
148517ab2063SBarry Smith       }
148617ab2063SBarry Smith     }
148717ab2063SBarry Smith   }
14883a40ed3dSBarry Smith   PetscFunctionReturn(0);
148917ab2063SBarry Smith }
149017ab2063SBarry Smith 
1491be5855fcSBarry Smith /*
1492be5855fcSBarry Smith      Checks for missing diagonals
1493be5855fcSBarry Smith */
14944a2ae208SSatish Balay #undef __FUNCT__
14954a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1496ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1497be5855fcSBarry Smith {
1498be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
149997f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1500be5855fcSBarry Smith 
1501be5855fcSBarry Smith   PetscFunctionBegin;
150209f38230SBarry Smith   *missing = PETSC_FALSE;
1503d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
150409f38230SBarry Smith     *missing  = PETSC_TRUE;
150509f38230SBarry Smith     if (d) *d = 0;
150609f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
150709f38230SBarry Smith   } else {
1508f1e2ffcdSBarry Smith     diag = a->diag;
1509d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1510bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
151109f38230SBarry Smith 	*missing = PETSC_TRUE;
151209f38230SBarry Smith 	if (d) *d = i;
151309f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
151409f38230SBarry Smith       }
1515be5855fcSBarry Smith     }
1516be5855fcSBarry Smith   }
1517be5855fcSBarry Smith   PetscFunctionReturn(0);
1518be5855fcSBarry Smith }
1519be5855fcSBarry Smith 
152071f1c65dSBarry Smith EXTERN_C_BEGIN
152171f1c65dSBarry Smith #undef __FUNCT__
152271f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
15237087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
152471f1c65dSBarry Smith {
152571f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
152671f1c65dSBarry Smith   PetscErrorCode ierr;
1527d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
152854f21887SBarry Smith   MatScalar      *v = a->a;
152954f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
153071f1c65dSBarry Smith 
153171f1c65dSBarry Smith   PetscFunctionBegin;
153271f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
153371f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
153471f1c65dSBarry Smith   diag = a->diag;
153571f1c65dSBarry Smith   if (!a->idiag) {
153671f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
153771f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
153871f1c65dSBarry Smith     v        = a->a;
153971f1c65dSBarry Smith   }
154071f1c65dSBarry Smith   mdiag = a->mdiag;
154171f1c65dSBarry Smith   idiag = a->idiag;
154271f1c65dSBarry Smith 
1543028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
154471f1c65dSBarry Smith     for (i=0; i<m; i++) {
154571f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1546e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
154771f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
154871f1c65dSBarry Smith     }
154971f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
155071f1c65dSBarry Smith   } else {
155171f1c65dSBarry Smith     for (i=0; i<m; i++) {
155271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
155371f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
155471f1c65dSBarry Smith     }
1555dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
155671f1c65dSBarry Smith   }
155771f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
155871f1c65dSBarry Smith   PetscFunctionReturn(0);
155971f1c65dSBarry Smith }
15605a9745a3SMatthew Knepley EXTERN_C_END
156171f1c65dSBarry Smith 
1562c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
15634a2ae208SSatish Balay #undef __FUNCT__
156441f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
156541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
156617ab2063SBarry Smith {
1567416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1568e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1569e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
157054f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1571dfbe8321SBarry Smith   PetscErrorCode     ierr;
1572d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
157397f1f81fSBarry Smith   const PetscInt     *idx,*diag;
157417ab2063SBarry Smith 
15753a40ed3dSBarry Smith   PetscFunctionBegin;
1576b965ef7fSBarry Smith   its = its*lits;
157791723122SBarry Smith 
157871f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
157971f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
158071f1c65dSBarry Smith   a->fshift = fshift;
158171f1c65dSBarry Smith   a->omega  = omega;
1582ed480e8bSBarry Smith 
158371f1c65dSBarry Smith   diag = a->diag;
158471f1c65dSBarry Smith   t     = a->ssor_work;
1585ed480e8bSBarry Smith   idiag = a->idiag;
158671f1c65dSBarry Smith   mdiag = a->mdiag;
1587ed480e8bSBarry Smith 
15881ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15893649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
159071f1c65dSBarry Smith   CHKMEMQ;
1591ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
159217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
159317ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1594ed480e8bSBarry Smith     bs = b;
159517ab2063SBarry Smith     for (i=0; i<m; i++) {
159671f1c65dSBarry Smith         d    = fshift + mdiag[i];
1597416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1598ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1599ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
160017ab2063SBarry Smith         sum  = b[i]*d/omega;
1601003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
160217ab2063SBarry Smith         x[i] = sum;
160317ab2063SBarry Smith     }
16041ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16053649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1606efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16073a40ed3dSBarry Smith     PetscFunctionReturn(0);
160817ab2063SBarry Smith   }
1609c783ea89SBarry Smith 
161048af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1611e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16123a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
161317ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1614887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
161517ab2063SBarry Smith 
161617ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
161717ab2063SBarry Smith 
1618887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
161917ab2063SBarry Smith     */
162017ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
162117ab2063SBarry Smith 
162217ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
162317ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1624416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1625ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1626ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
162717ab2063SBarry Smith       sum  = b[i];
1628e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1629ed480e8bSBarry Smith       x[i] = sum*idiag[i];
163017ab2063SBarry Smith     }
163117ab2063SBarry Smith 
163217ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1633416022c9SBarry Smith     v = a->a;
1634ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
163517ab2063SBarry Smith 
163617ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1637ed480e8bSBarry Smith     ts = t;
1638416022c9SBarry Smith     diag = a->diag;
163917ab2063SBarry Smith     for (i=0; i<m; i++) {
1640416022c9SBarry Smith       n    = diag[i] - a->i[i];
1641ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1642ed480e8bSBarry Smith       v    = a->a + a->i[i];
164317ab2063SBarry Smith       sum  = t[i];
1644003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1645ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1646733d66baSBarry Smith       /*  x = x + t */
1647733d66baSBarry Smith       x[i] += t[i];
164817ab2063SBarry Smith     }
164917ab2063SBarry Smith 
1650dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16511ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16523649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16533a40ed3dSBarry Smith     PetscFunctionReturn(0);
165417ab2063SBarry Smith   }
165517ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
165617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
165717ab2063SBarry Smith       for (i=0; i<m; i++) {
1658416022c9SBarry Smith         n    = diag[i] - a->i[i];
1659ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1660ed480e8bSBarry Smith         v    = a->a + a->i[i];
166117ab2063SBarry Smith         sum  = b[i];
1662e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16635c99c7daSBarry Smith         t[i] = sum;
1664ed480e8bSBarry Smith         x[i] = sum*idiag[i];
166517ab2063SBarry Smith       }
16665c99c7daSBarry Smith       xb = t;
1667efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16683a40ed3dSBarry Smith     } else xb = b;
166917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
167017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1671416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1672ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1673ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
167417ab2063SBarry Smith         sum  = xb[i];
1675e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16765c99c7daSBarry Smith         if (xb == b) {
1677ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16785c99c7daSBarry Smith         } else {
16795c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
168017ab2063SBarry Smith         }
16815c99c7daSBarry Smith       }
1682efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
168317ab2063SBarry Smith     }
168417ab2063SBarry Smith     its--;
168517ab2063SBarry Smith   }
168617ab2063SBarry Smith   while (its--) {
168717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
168817ab2063SBarry Smith       for (i=0; i<m; i++) {
1689416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1690ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1691ed480e8bSBarry Smith         v    = a->a + a->i[i];
169217ab2063SBarry Smith         sum  = b[i];
1693e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1694ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
169517ab2063SBarry Smith       }
16969f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
169717ab2063SBarry Smith     }
169817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
169917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1700416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1701ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1702ed480e8bSBarry Smith         v    = a->a + a->i[i];
170317ab2063SBarry Smith         sum  = b[i];
1704e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1705ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
170617ab2063SBarry Smith       }
17079f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
170817ab2063SBarry Smith     }
170917ab2063SBarry Smith   }
17101ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17113649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
171271f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
171317ab2063SBarry Smith }
171417ab2063SBarry Smith 
17152af78befSBarry Smith 
17164a2ae208SSatish Balay #undef __FUNCT__
17174a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1718dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
171917ab2063SBarry Smith {
1720416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17214e220ebcSLois Curfman McInnes 
17223a40ed3dSBarry Smith   PetscFunctionBegin;
17234e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
17244e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
17254e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
17264e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
17274e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
17288e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
17297adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1730d5f3da31SBarry Smith   if (A->factortype) {
17314e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17324e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17334e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17344e220ebcSLois Curfman McInnes   } else {
17354e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17364e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17374e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17384e220ebcSLois Curfman McInnes   }
17393a40ed3dSBarry Smith   PetscFunctionReturn(0);
174017ab2063SBarry Smith }
174117ab2063SBarry Smith 
17424a2ae208SSatish Balay #undef __FUNCT__
17434a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
17442b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
174517ab2063SBarry Smith {
1746416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
17473b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
17486849ba73SBarry Smith   PetscErrorCode    ierr;
174997b48c8fSBarry Smith   const PetscScalar *xx;
175097b48c8fSBarry Smith   PetscScalar       *bb;
1751ace3abfcSBarry Smith   PetscBool         missing;
175217ab2063SBarry Smith 
17533a40ed3dSBarry Smith   PetscFunctionBegin;
175497b48c8fSBarry Smith   if (x && b) {
175597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
175697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
175797b48c8fSBarry Smith     for (i=0; i<N; i++) {
175897b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
175997b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
176097b48c8fSBarry Smith     }
176197b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
176297b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
176397b48c8fSBarry Smith   }
176497b48c8fSBarry Smith 
1765a9817697SBarry Smith   if (a->keepnonzeropattern) {
1766f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1767e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1768bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1769f1e2ffcdSBarry Smith     }
1770f4df32b1SMatthew Knepley     if (diag != 0.0) {
177109f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1772e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1773f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1774f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1775f1e2ffcdSBarry Smith       }
1776f1e2ffcdSBarry Smith     }
177788e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1778f1e2ffcdSBarry Smith   } else {
1779f4df32b1SMatthew Knepley     if (diag != 0.0) {
178017ab2063SBarry Smith       for (i=0; i<N; i++) {
1781e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17827ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1783416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1784f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1785bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
17867ae801bdSBarry Smith         } else { /* in case row was completely empty */
1787f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
178817ab2063SBarry Smith         }
178917ab2063SBarry Smith       }
17903a40ed3dSBarry Smith     } else {
179117ab2063SBarry Smith       for (i=0; i<N; i++) {
1792e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1793416022c9SBarry Smith         a->ilen[rows[i]] = 0;
179417ab2063SBarry Smith       }
179517ab2063SBarry Smith     }
179688e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1797f1e2ffcdSBarry Smith   }
179843a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17993a40ed3dSBarry Smith   PetscFunctionReturn(0);
180017ab2063SBarry Smith }
180117ab2063SBarry Smith 
18024a2ae208SSatish Balay #undef __FUNCT__
18036e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
18046e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18056e169961SBarry Smith {
18066e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18076e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18086e169961SBarry Smith   PetscErrorCode    ierr;
18092b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18106e169961SBarry Smith   const PetscScalar *xx;
18116e169961SBarry Smith   PetscScalar       *bb;
18126e169961SBarry Smith 
18136e169961SBarry Smith   PetscFunctionBegin;
18146e169961SBarry Smith   if (x && b) {
18156e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18166e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18172b40b63fSBarry Smith     vecs = PETSC_TRUE;
18186e169961SBarry Smith   }
18196e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
18206e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
18216e169961SBarry Smith   for (i=0; i<N; i++) {
18226e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18236e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18246e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18256e169961SBarry Smith   }
18266e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18276e169961SBarry Smith     if (!zeroed[i]) {
18286e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18296e169961SBarry Smith         if (zeroed[a->j[j]]) {
18302b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18316e169961SBarry Smith           a->a[j] = 0.0;
18326e169961SBarry Smith         }
18336e169961SBarry Smith       }
18342b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18356e169961SBarry Smith   }
18366e169961SBarry Smith   if (x && b) {
18376e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18386e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18396e169961SBarry Smith   }
18406e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18416e169961SBarry Smith   if (diag != 0.0) {
18426e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18436e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18446e169961SBarry Smith     for (i=0; i<N; i++) {
18456e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
18466e169961SBarry Smith     }
18476e169961SBarry Smith   }
18486e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
18496e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18506e169961SBarry Smith   PetscFunctionReturn(0);
18516e169961SBarry Smith }
18526e169961SBarry Smith 
18536e169961SBarry Smith #undef __FUNCT__
18544a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1855a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
185617ab2063SBarry Smith {
1857416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
185897f1f81fSBarry Smith   PetscInt   *itmp;
185917ab2063SBarry Smith 
18603a40ed3dSBarry Smith   PetscFunctionBegin;
1861e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
186217ab2063SBarry Smith 
1863416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1864bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
186517ab2063SBarry Smith   if (idx) {
1866bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1867bfeeae90SHong Zhang     if (*nz) {
18684e093b46SBarry Smith       *idx = itmp;
186917ab2063SBarry Smith     }
187017ab2063SBarry Smith     else *idx = 0;
187117ab2063SBarry Smith   }
18723a40ed3dSBarry Smith   PetscFunctionReturn(0);
187317ab2063SBarry Smith }
187417ab2063SBarry Smith 
1875bfeeae90SHong Zhang /* remove this function? */
18764a2ae208SSatish Balay #undef __FUNCT__
18774a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1878a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187917ab2063SBarry Smith {
18803a40ed3dSBarry Smith   PetscFunctionBegin;
18813a40ed3dSBarry Smith   PetscFunctionReturn(0);
188217ab2063SBarry Smith }
188317ab2063SBarry Smith 
18844a2ae208SSatish Balay #undef __FUNCT__
18854a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1886dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
188717ab2063SBarry Smith {
1888416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
188954f21887SBarry Smith   MatScalar      *v = a->a;
189036db0b34SBarry Smith   PetscReal      sum = 0.0;
18916849ba73SBarry Smith   PetscErrorCode ierr;
189297f1f81fSBarry Smith   PetscInt       i,j;
189317ab2063SBarry Smith 
18943a40ed3dSBarry Smith   PetscFunctionBegin;
189517ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1896416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1897aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
189836db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
189917ab2063SBarry Smith #else
190017ab2063SBarry Smith       sum += (*v)*(*v); v++;
190117ab2063SBarry Smith #endif
190217ab2063SBarry Smith     }
1903064f8208SBarry Smith     *nrm = sqrt(sum);
19043a40ed3dSBarry Smith   } else if (type == NORM_1) {
190536db0b34SBarry Smith     PetscReal *tmp;
190697f1f81fSBarry Smith     PetscInt    *jj = a->j;
1907d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1908d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1909064f8208SBarry Smith     *nrm = 0.0;
1910416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1911bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
191217ab2063SBarry Smith     }
1913d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1914064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
191517ab2063SBarry Smith     }
1916606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
19173a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1918064f8208SBarry Smith     *nrm = 0.0;
1919d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1920bfeeae90SHong Zhang       v = a->a + a->i[j];
192117ab2063SBarry Smith       sum = 0.0;
1922416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1923cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
192417ab2063SBarry Smith       }
1925064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
192617ab2063SBarry Smith     }
19273a40ed3dSBarry Smith   } else {
1928e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
192917ab2063SBarry Smith   }
19303a40ed3dSBarry Smith   PetscFunctionReturn(0);
193117ab2063SBarry Smith }
193217ab2063SBarry Smith 
19334a2ae208SSatish Balay #undef __FUNCT__
19344a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1935fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
193617ab2063SBarry Smith {
1937416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1938416022c9SBarry Smith   Mat            C;
19396849ba73SBarry Smith   PetscErrorCode ierr;
1940d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
194154f21887SBarry Smith   MatScalar      *array = a->a;
194217ab2063SBarry Smith 
19433a40ed3dSBarry Smith   PetscFunctionBegin;
1944e32f2f54SBarry 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");
1945fc4dec0aSBarry Smith 
1946fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1947d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1948d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1949bfeeae90SHong Zhang 
1950bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
19517adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1952d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
19537adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1954ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1955606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1956a541d17aSBarry Smith   } else {
1957a541d17aSBarry Smith     C = *B;
1958a541d17aSBarry Smith   }
1959a541d17aSBarry Smith 
196017ab2063SBarry Smith   for (i=0; i<m; i++) {
196117ab2063SBarry Smith     len    = ai[i+1]-ai[i];
196287d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1963b9b97703SBarry Smith     array += len;
1964b9b97703SBarry Smith     aj    += len;
196517ab2063SBarry Smith   }
19666d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19676d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
196817ab2063SBarry Smith 
1969815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1970416022c9SBarry Smith     *B = C;
197117ab2063SBarry Smith   } else {
1972eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
197317ab2063SBarry Smith   }
19743a40ed3dSBarry Smith   PetscFunctionReturn(0);
197517ab2063SBarry Smith }
197617ab2063SBarry Smith 
1977cd0d46ebSvictorle EXTERN_C_BEGIN
1978cd0d46ebSvictorle #undef __FUNCT__
19795fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
19807087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1981cd0d46ebSvictorle {
1982cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
198354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
198454f21887SBarry Smith   MatScalar      *va,*vb;
19856849ba73SBarry Smith   PetscErrorCode ierr;
198697f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1987cd0d46ebSvictorle 
1988cd0d46ebSvictorle   PetscFunctionBegin;
1989cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1990cd0d46ebSvictorle 
1991cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1992cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
19935485867bSBarry Smith   if (ma!=nb || na!=mb){
19945485867bSBarry Smith     *f = PETSC_FALSE;
19955485867bSBarry Smith     PetscFunctionReturn(0);
19965485867bSBarry Smith   }
1997cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1998cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1999cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
200097f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
200197f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2002cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2003cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2004cd0d46ebSvictorle 
2005cd0d46ebSvictorle   *f = PETSC_TRUE;
2006cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2007cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
200897f1f81fSBarry Smith       PetscInt         idc,idr;
20095485867bSBarry Smith       PetscScalar vc,vr;
2010cd0d46ebSvictorle       /* column/row index/value */
20115485867bSBarry Smith       idc = adx[aptr[i]];
20125485867bSBarry Smith       idr = bdx[bptr[idc]];
20135485867bSBarry Smith       vc  = va[aptr[i]];
20145485867bSBarry Smith       vr  = vb[bptr[idc]];
20155485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20165485867bSBarry Smith         *f = PETSC_FALSE;
20175485867bSBarry Smith         goto done;
2018cd0d46ebSvictorle       } else {
20195485867bSBarry Smith         aptr[i]++;
20205485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2021cd0d46ebSvictorle       }
2022cd0d46ebSvictorle     }
2023cd0d46ebSvictorle   }
2024cd0d46ebSvictorle  done:
2025cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20263aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2027cd0d46ebSvictorle   PetscFunctionReturn(0);
2028cd0d46ebSvictorle }
2029cd0d46ebSvictorle EXTERN_C_END
2030cd0d46ebSvictorle 
20311cbb95d3SBarry Smith EXTERN_C_BEGIN
20321cbb95d3SBarry Smith #undef __FUNCT__
20331cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
20347087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20351cbb95d3SBarry Smith {
20361cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
203754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
203854f21887SBarry Smith   MatScalar      *va,*vb;
20391cbb95d3SBarry Smith   PetscErrorCode ierr;
20401cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20411cbb95d3SBarry Smith 
20421cbb95d3SBarry Smith   PetscFunctionBegin;
20431cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
20441cbb95d3SBarry Smith 
20451cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20461cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20471cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
20481cbb95d3SBarry Smith     *f = PETSC_FALSE;
20491cbb95d3SBarry Smith     PetscFunctionReturn(0);
20501cbb95d3SBarry Smith   }
20511cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
20521cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
20531cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
20541cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
20551cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
20561cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20571cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20581cbb95d3SBarry Smith 
20591cbb95d3SBarry Smith   *f = PETSC_TRUE;
20601cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20611cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
20621cbb95d3SBarry Smith       PetscInt         idc,idr;
20631cbb95d3SBarry Smith       PetscScalar vc,vr;
20641cbb95d3SBarry Smith       /* column/row index/value */
20651cbb95d3SBarry Smith       idc = adx[aptr[i]];
20661cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
20671cbb95d3SBarry Smith       vc  = va[aptr[i]];
20681cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
20691cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
20701cbb95d3SBarry Smith         *f = PETSC_FALSE;
20711cbb95d3SBarry Smith         goto done;
20721cbb95d3SBarry Smith       } else {
20731cbb95d3SBarry Smith         aptr[i]++;
20741cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
20751cbb95d3SBarry Smith       }
20761cbb95d3SBarry Smith     }
20771cbb95d3SBarry Smith   }
20781cbb95d3SBarry Smith  done:
20791cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
20801cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
20811cbb95d3SBarry Smith   PetscFunctionReturn(0);
20821cbb95d3SBarry Smith }
20831cbb95d3SBarry Smith EXTERN_C_END
20841cbb95d3SBarry Smith 
20859e29f15eSvictorle #undef __FUNCT__
20869e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2087ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20889e29f15eSvictorle {
2089dfbe8321SBarry Smith   PetscErrorCode ierr;
20909e29f15eSvictorle   PetscFunctionBegin;
20915485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
20929e29f15eSvictorle   PetscFunctionReturn(0);
20939e29f15eSvictorle }
20949e29f15eSvictorle 
20954a2ae208SSatish Balay #undef __FUNCT__
20961cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2097ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20981cbb95d3SBarry Smith {
20991cbb95d3SBarry Smith   PetscErrorCode ierr;
21001cbb95d3SBarry Smith   PetscFunctionBegin;
21011cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21021cbb95d3SBarry Smith   PetscFunctionReturn(0);
21031cbb95d3SBarry Smith }
21041cbb95d3SBarry Smith 
21051cbb95d3SBarry Smith #undef __FUNCT__
21064a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2107dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
210817ab2063SBarry Smith {
2109416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
211054f21887SBarry Smith   PetscScalar    *l,*r,x;
211154f21887SBarry Smith   MatScalar      *v;
2112dfbe8321SBarry Smith   PetscErrorCode ierr;
2113d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
211417ab2063SBarry Smith 
21153a40ed3dSBarry Smith   PetscFunctionBegin;
211617ab2063SBarry Smith   if (ll) {
21173ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21183ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2119e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2120e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21211ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2122416022c9SBarry Smith     v = a->a;
212317ab2063SBarry Smith     for (i=0; i<m; i++) {
212417ab2063SBarry Smith       x = l[i];
2125416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
212617ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
212717ab2063SBarry Smith     }
21281ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2129efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
213017ab2063SBarry Smith   }
213117ab2063SBarry Smith   if (rr) {
2132e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2133e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21341ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2135416022c9SBarry Smith     v = a->a; jj = a->j;
213617ab2063SBarry Smith     for (i=0; i<nz; i++) {
2137bfeeae90SHong Zhang       (*v++) *= r[*jj++];
213817ab2063SBarry Smith     }
21391ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2140efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
214117ab2063SBarry Smith   }
21423a40ed3dSBarry Smith   PetscFunctionReturn(0);
214317ab2063SBarry Smith }
214417ab2063SBarry Smith 
21454a2ae208SSatish Balay #undef __FUNCT__
21464a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
214797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
214817ab2063SBarry Smith {
2149db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21506849ba73SBarry Smith   PetscErrorCode ierr;
2151d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
215297f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21535d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21545d0c19d7SBarry Smith   PetscInt       nrows,ncols;
215597f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
215654f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2157416022c9SBarry Smith   Mat            C;
2158ace3abfcSBarry Smith   PetscBool      stride,sorted;
215917ab2063SBarry Smith 
21603a40ed3dSBarry Smith   PetscFunctionBegin;
216114ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2162e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
216314ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2164e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
216599141d43SSatish Balay 
216617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2167b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2168b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
216917ab2063SBarry Smith 
2170fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
21710dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2172fee21e36SBarry Smith   if (stride && step == 1) {
217302834360SBarry Smith     /* special case of contiguous rows */
21740e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
217502834360SBarry Smith     /* loop over new rows determining lens and starting points */
217602834360SBarry Smith     for (i=0; i<nrows; i++) {
2177bfeeae90SHong Zhang       kstart  = ai[irow[i]];
2178a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
217902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2180bfeeae90SHong Zhang         if (aj[k] >= first) {
218102834360SBarry Smith           starts[i] = k;
218202834360SBarry Smith           break;
218302834360SBarry Smith 	}
218402834360SBarry Smith       }
2185a2744918SBarry Smith       sum = 0;
218602834360SBarry Smith       while (k < kend) {
2187bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2188a2744918SBarry Smith         sum++;
218902834360SBarry Smith       }
2190a2744918SBarry Smith       lens[i] = sum;
219102834360SBarry Smith     }
219202834360SBarry Smith     /* create submatrix */
2193cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
219497f1f81fSBarry Smith       PetscInt n_cols,n_rows;
219508480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2196e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2197d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
219808480c60SBarry Smith       C = *B;
21993a40ed3dSBarry Smith     } else {
22007adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2201f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22027adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2203ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
220408480c60SBarry Smith     }
2205db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2206db02288aSLois Curfman McInnes 
220702834360SBarry Smith     /* loop over rows inserting into submatrix */
2208db02288aSLois Curfman McInnes     a_new    = c->a;
2209db02288aSLois Curfman McInnes     j_new    = c->j;
2210db02288aSLois Curfman McInnes     i_new    = c->i;
2211bfeeae90SHong Zhang 
221202834360SBarry Smith     for (i=0; i<nrows; i++) {
2213a2744918SBarry Smith       ii    = starts[i];
2214a2744918SBarry Smith       lensi = lens[i];
2215a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2216a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
221702834360SBarry Smith       }
221887828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2219a2744918SBarry Smith       a_new      += lensi;
2220a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
2221a2744918SBarry Smith       c->ilen[i]  = lensi;
222202834360SBarry Smith     }
22230e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22243a40ed3dSBarry Smith   } else {
222502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22260e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
222797f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
22280e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
222917ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
223002834360SBarry Smith     /* determine lens of each row */
223102834360SBarry Smith     for (i=0; i<nrows; i++) {
2232bfeeae90SHong Zhang       kstart  = ai[irow[i]];
223302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
223402834360SBarry Smith       lens[i] = 0;
223502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2236bfeeae90SHong Zhang         if (smap[aj[k]]) {
223702834360SBarry Smith           lens[i]++;
223802834360SBarry Smith         }
223902834360SBarry Smith       }
224002834360SBarry Smith     }
224117ab2063SBarry Smith     /* Create and fill new matrix */
2242a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2243ace3abfcSBarry Smith       PetscBool  equal;
22440f5bd95cSBarry Smith 
224599141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
2246e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2247d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
22480f5bd95cSBarry Smith       if (!equal) {
2249e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
225099141d43SSatish Balay       }
2251d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
225208480c60SBarry Smith       C = *B;
22533a40ed3dSBarry Smith     } else {
22547adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2255f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22567adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2257ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
225808480c60SBarry Smith     }
225999141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
226017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
226199141d43SSatish Balay       row    = irow[i];
2262bfeeae90SHong Zhang       kstart = ai[row];
226399141d43SSatish Balay       kend   = kstart + a->ilen[row];
2264bfeeae90SHong Zhang       mat_i  = c->i[i];
226599141d43SSatish Balay       mat_j  = c->j + mat_i;
226699141d43SSatish Balay       mat_a  = c->a + mat_i;
226799141d43SSatish Balay       mat_ilen = c->ilen + i;
226817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2269bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2270ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
227199141d43SSatish Balay           *mat_a++ = a->a[k];
227299141d43SSatish Balay           (*mat_ilen)++;
227399141d43SSatish Balay 
227417ab2063SBarry Smith         }
227517ab2063SBarry Smith       }
227617ab2063SBarry Smith     }
227702834360SBarry Smith     /* Free work space */
227802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2279606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2280606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
228102834360SBarry Smith   }
22826d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22836d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228417ab2063SBarry Smith 
228517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2286416022c9SBarry Smith   *B = C;
22873a40ed3dSBarry Smith   PetscFunctionReturn(0);
228817ab2063SBarry Smith }
228917ab2063SBarry Smith 
22901df811f5SHong Zhang #undef __FUNCT__
229182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
229282d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
229382d44351SHong Zhang {
229482d44351SHong Zhang   PetscErrorCode ierr;
229582d44351SHong Zhang   Mat            B;
229682d44351SHong Zhang 
229782d44351SHong Zhang   PetscFunctionBegin;
229882d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
229982d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
230082d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
230182d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
230282d44351SHong Zhang   *subMat = B;
230382d44351SHong Zhang   PetscFunctionReturn(0);
230482d44351SHong Zhang }
230582d44351SHong Zhang 
230682d44351SHong Zhang #undef __FUNCT__
23074a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
23080481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2309a871dcd8SBarry Smith {
231063b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2311dfbe8321SBarry Smith   PetscErrorCode ierr;
231263b91edcSBarry Smith   Mat            outA;
2313ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
231463b91edcSBarry Smith 
23153a40ed3dSBarry Smith   PetscFunctionBegin;
2316e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23171df811f5SHong Zhang 
2318b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2319b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2320a871dcd8SBarry Smith 
232163b91edcSBarry Smith   outA              = inA;
2322d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2323c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23246bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2325c3122656SLisandro Dalcin   a->row = row;
2326c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23276bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2328c3122656SLisandro Dalcin   a->col = col;
232963b91edcSBarry Smith 
233036db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23316bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23324c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
233352e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2334f0ec6fceSSatish Balay 
233594a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2336d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2337d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
233894a9d846SBarry Smith   }
233963b91edcSBarry Smith 
2340f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2341137fb511SHong Zhang   if (row_identity && col_identity) {
2342ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2343137fb511SHong Zhang   } else {
2344719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2345137fb511SHong Zhang   }
23463a40ed3dSBarry Smith   PetscFunctionReturn(0);
2347a871dcd8SBarry Smith }
2348a871dcd8SBarry Smith 
23494a2ae208SSatish Balay #undef __FUNCT__
23504a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2351f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2352f0b747eeSBarry Smith {
2353f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2354f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2355efee365bSSatish Balay   PetscErrorCode ierr;
23560805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
23573a40ed3dSBarry Smith 
23583a40ed3dSBarry Smith   PetscFunctionBegin;
2359f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2360efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
23613a40ed3dSBarry Smith   PetscFunctionReturn(0);
2362f0b747eeSBarry Smith }
2363f0b747eeSBarry Smith 
23644a2ae208SSatish Balay #undef __FUNCT__
23654a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
236697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2367cddf8d76SBarry Smith {
2368dfbe8321SBarry Smith   PetscErrorCode ierr;
236997f1f81fSBarry Smith   PetscInt       i;
2370cddf8d76SBarry Smith 
23713a40ed3dSBarry Smith   PetscFunctionBegin;
2372cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2373b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2374cddf8d76SBarry Smith   }
2375cddf8d76SBarry Smith 
2376cddf8d76SBarry Smith   for (i=0; i<n; i++) {
23776a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2378cddf8d76SBarry Smith   }
23793a40ed3dSBarry Smith   PetscFunctionReturn(0);
2380cddf8d76SBarry Smith }
2381cddf8d76SBarry Smith 
23824a2ae208SSatish Balay #undef __FUNCT__
23834a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
238497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
23854dcbc457SBarry Smith {
2386e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
23876849ba73SBarry Smith   PetscErrorCode ierr;
23885d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
23895d0c19d7SBarry Smith   const PetscInt *idx;
239097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2391f1af5d2fSBarry Smith   PetscBT        table;
2392bbd702dbSSatish Balay 
23933a40ed3dSBarry Smith   PetscFunctionBegin;
2394d0f46423SBarry Smith   m     = A->rmap->n;
2395e4d965acSSatish Balay   ai    = a->i;
2396bfeeae90SHong Zhang   aj    = a->j;
23978a047759SSatish Balay 
2398e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
239906763907SSatish Balay 
240097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
24016831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
240206763907SSatish Balay 
2403e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2404b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2405e4d965acSSatish Balay     isz  = 0;
24066831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2407e4d965acSSatish Balay 
2408e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
24094dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2410b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2411e4d965acSSatish Balay 
2412dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2413e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2414f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
24154dcbc457SBarry Smith     }
241606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
24176bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2418e4d965acSSatish Balay 
241904a348a9SBarry Smith     k = 0;
242004a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
242104a348a9SBarry Smith       n = isz;
242206763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2423e4d965acSSatish Balay         row   = nidx[k];
2424e4d965acSSatish Balay         start = ai[row];
2425e4d965acSSatish Balay         end   = ai[row+1];
242604a348a9SBarry Smith         for (l = start; l<end ; l++){
2427efb16452SHong Zhang           val = aj[l] ;
2428f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2429e4d965acSSatish Balay         }
2430e4d965acSSatish Balay       }
2431e4d965acSSatish Balay     }
243270b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2433e4d965acSSatish Balay   }
24346831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2435606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
24363a40ed3dSBarry Smith   PetscFunctionReturn(0);
24374dcbc457SBarry Smith }
243817ab2063SBarry Smith 
24390513a670SBarry Smith /* -------------------------------------------------------------- */
24404a2ae208SSatish Balay #undef __FUNCT__
24414a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2442dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
24430513a670SBarry Smith {
24440513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24456849ba73SBarry Smith   PetscErrorCode ierr;
24463b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
24475d0c19d7SBarry Smith   const PetscInt *row,*col;
24485d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
244956cd22aeSBarry Smith   IS             icolp,irowp;
24503b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
24513b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
24520513a670SBarry Smith 
24533a40ed3dSBarry Smith   PetscFunctionBegin;
24544c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
245556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
24564c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
245756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
24580513a670SBarry Smith 
24590513a670SBarry Smith   /* determine lengths of permuted rows */
246097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
24610513a670SBarry Smith   for (i=0; i<m; i++) {
24620513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
24630513a670SBarry Smith   }
24647adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2465f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
24667adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2467ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2468606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
24690513a670SBarry Smith 
247097f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
24710513a670SBarry Smith   for (i=0; i<m; i++) {
247232ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24730513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2474cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
247532ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24760513a670SBarry Smith   }
2477606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
24783c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
24790513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24800513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
248156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
248256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
24836bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
24846bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
24853a40ed3dSBarry Smith   PetscFunctionReturn(0);
24860513a670SBarry Smith }
24870513a670SBarry Smith 
24884a2ae208SSatish Balay #undef __FUNCT__
24894a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2490dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2491cb5b572fSBarry Smith {
2492dfbe8321SBarry Smith   PetscErrorCode ierr;
2493cb5b572fSBarry Smith 
2494cb5b572fSBarry Smith   PetscFunctionBegin;
249533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
249633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2497be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2498be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2499be6bf707SBarry Smith 
2500700c5bfcSBarry 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");
2501d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2502cb5b572fSBarry Smith   } else {
2503cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2504cb5b572fSBarry Smith   }
2505cb5b572fSBarry Smith   PetscFunctionReturn(0);
2506cb5b572fSBarry Smith }
2507cb5b572fSBarry Smith 
25084a2ae208SSatish Balay #undef __FUNCT__
25094a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2510dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2511273d9f13SBarry Smith {
2512dfbe8321SBarry Smith   PetscErrorCode ierr;
2513273d9f13SBarry Smith 
2514273d9f13SBarry Smith   PetscFunctionBegin;
2515ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2516273d9f13SBarry Smith   PetscFunctionReturn(0);
2517273d9f13SBarry Smith }
2518273d9f13SBarry Smith 
25194a2ae208SSatish Balay #undef __FUNCT__
25204a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2521a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
25226c0721eeSBarry Smith {
25236c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
25246c0721eeSBarry Smith   PetscFunctionBegin;
25256c0721eeSBarry Smith   *array = a->a;
25266c0721eeSBarry Smith   PetscFunctionReturn(0);
25276c0721eeSBarry Smith }
25286c0721eeSBarry Smith 
25294a2ae208SSatish Balay #undef __FUNCT__
25304a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2531dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
25326c0721eeSBarry Smith {
25336c0721eeSBarry Smith   PetscFunctionBegin;
25346c0721eeSBarry Smith   PetscFunctionReturn(0);
25356c0721eeSBarry Smith }
2536273d9f13SBarry Smith 
2537ee4f033dSBarry Smith #undef __FUNCT__
2538ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2539dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2540ee4f033dSBarry Smith {
25416849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
25426849ba73SBarry Smith   PetscErrorCode ierr;
254397f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2544efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
254587828ca2SBarry Smith   PetscScalar    *vscale_array;
2546ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2547ee4f033dSBarry Smith   Vec            w1,w2,w3;
2548ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2549ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2550ee4f033dSBarry Smith 
2551ee4f033dSBarry Smith   PetscFunctionBegin;
2552ee4f033dSBarry Smith   if (!coloring->w1) {
2553ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
255452e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2555ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
255652e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2557ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
255852e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2559ee4f033dSBarry Smith   }
2560ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2561ee4f033dSBarry Smith 
2562ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2563acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2564ee4f033dSBarry Smith   if (flg) {
2565ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2566ee4f033dSBarry Smith   } else {
2567ace3abfcSBarry Smith     PetscBool  assembled;
25680b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
25690b9b6f31SBarry Smith     if (assembled) {
2570ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2571ee4f033dSBarry Smith     }
25720b9b6f31SBarry Smith   }
2573ee4f033dSBarry Smith 
2574ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2575ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2576ee4f033dSBarry Smith 
2577ee4f033dSBarry Smith   /*
2578ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2579ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2580ee4f033dSBarry Smith   */
2581ee4f033dSBarry Smith   if (coloring->F) {
2582ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2583ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2584ee4f033dSBarry Smith     if (m1 != m2) {
2585ee4f033dSBarry Smith       coloring->F = 0;
2586ee4f033dSBarry Smith     }
2587ee4f033dSBarry Smith   }
2588ee4f033dSBarry Smith 
2589ee4f033dSBarry Smith   if (coloring->F) {
2590ee4f033dSBarry Smith     w1          = coloring->F;
2591ee4f033dSBarry Smith     coloring->F = 0;
2592ee4f033dSBarry Smith   } else {
259366f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2594ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
259566f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2596ee4f033dSBarry Smith   }
2597ee4f033dSBarry Smith 
2598ee4f033dSBarry Smith   /*
2599ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2600ee4f033dSBarry Smith   */
26011ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
26021ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2603ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2604ee4f033dSBarry Smith     /*
2605ee4f033dSBarry Smith        Loop over each column associated with color adding the
2606ee4f033dSBarry Smith        perturbation to the vector w3.
2607ee4f033dSBarry Smith     */
2608ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2609ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2610ee4f033dSBarry Smith       dx  = xx[col];
2611ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2612ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2613ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2614ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2615ee4f033dSBarry Smith #else
2616ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2617ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2618ee4f033dSBarry Smith #endif
2619ee4f033dSBarry Smith       dx                *= epsilon;
2620ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2621ee4f033dSBarry Smith     }
2622ee4f033dSBarry Smith   }
26231ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2624ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2625ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2626ee4f033dSBarry Smith 
2627ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2628ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2629ee4f033dSBarry Smith 
2630ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2631ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2632ee4f033dSBarry Smith 
26331ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2634ee4f033dSBarry Smith   /*
2635ee4f033dSBarry Smith       Loop over each color
2636ee4f033dSBarry Smith   */
2637ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
263849b058dcSBarry Smith     coloring->currentcolor = k;
2639ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
26401ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2641ee4f033dSBarry Smith     /*
2642ee4f033dSBarry Smith        Loop over each column associated with color adding the
2643ee4f033dSBarry Smith        perturbation to the vector w3.
2644ee4f033dSBarry Smith     */
2645ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2646ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2647ee4f033dSBarry Smith       dx  = xx[col];
26485b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2649ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2650ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2651ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2652ee4f033dSBarry Smith #else
2653ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2654ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2655ee4f033dSBarry Smith #endif
2656ee4f033dSBarry Smith       dx            *= epsilon;
2657e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2658ee4f033dSBarry Smith       w3_array[col] += dx;
2659ee4f033dSBarry Smith     }
26601ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2661ee4f033dSBarry Smith 
2662ee4f033dSBarry Smith     /*
2663ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2664ee4f033dSBarry Smith     */
2665ee4f033dSBarry Smith 
266666f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2667ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
266866f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2669efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2670ee4f033dSBarry Smith 
2671ee4f033dSBarry Smith     /*
2672ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2673ee4f033dSBarry Smith     */
26741ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2675ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2676ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2677ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2678ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2679ee4f033dSBarry Smith       srow   = row + start;
2680ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2681ee4f033dSBarry Smith     }
26821ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2683ee4f033dSBarry Smith   }
268449b058dcSBarry Smith   coloring->currentcolor = k;
26851ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
26861ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2687ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2688ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2689ee4f033dSBarry Smith   PetscFunctionReturn(0);
2690ee4f033dSBarry Smith }
2691ee4f033dSBarry Smith 
26928229c054SShri Abhyankar /*
26938229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26948229c054SShri Abhyankar    have different nonzero structure.
26958229c054SShri Abhyankar */
2696ac90fabeSBarry Smith #undef __FUNCT__
26978229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
26988229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2699ec7775f6SShri Abhyankar {
27008229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2701ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2702ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2703ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2704ec7775f6SShri Abhyankar 
2705ec7775f6SShri Abhyankar   PetscFunctionBegin;
2706ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2707ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
27088af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27098af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27108af7cee1SJed Brown     nnz[i] = 0;
27118af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27128af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27138af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27148af7cee1SJed Brown       nnz[i]++;
27158af7cee1SJed Brown     }
27168af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2717ec7775f6SShri Abhyankar   }
2718ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2719ec7775f6SShri Abhyankar }
2720ec7775f6SShri Abhyankar 
2721ec7775f6SShri Abhyankar #undef __FUNCT__
2722ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2723f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2724ac90fabeSBarry Smith {
2725dfbe8321SBarry Smith   PetscErrorCode ierr;
272697f1f81fSBarry Smith   PetscInt       i;
2727ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
27280805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2729ac90fabeSBarry Smith 
2730ac90fabeSBarry Smith   PetscFunctionBegin;
2731ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2732f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2733f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2734c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2735a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2736a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27376bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2738a30b2313SHong Zhang     }
2739a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2740d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2741a30b2313SHong Zhang       y->XtoY = X;
2742407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2743c537a176SHong Zhang     }
2744f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
27451e2582c4SBarry 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);
2746ac90fabeSBarry Smith   } else {
27478229c054SShri Abhyankar     Mat      B;
27488229c054SShri Abhyankar     PetscInt *nnz;
274916b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2750ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2751bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27524aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2753ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
27548229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
27558229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2756ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2757ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27588229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2759ac90fabeSBarry Smith   }
2760ac90fabeSBarry Smith   PetscFunctionReturn(0);
2761ac90fabeSBarry Smith }
2762ac90fabeSBarry Smith 
2763521d7252SBarry Smith #undef __FUNCT__
2764521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2765521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2766521d7252SBarry Smith {
276741c166b1SJed Brown   PetscErrorCode ierr;
276841c166b1SJed Brown 
2769521d7252SBarry Smith   PetscFunctionBegin;
277041c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
277141c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2772521d7252SBarry Smith   PetscFunctionReturn(0);
2773521d7252SBarry Smith }
2774521d7252SBarry Smith 
2775354c94deSBarry Smith #undef __FUNCT__
2776354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27777087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2778354c94deSBarry Smith {
2779354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2780354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2781354c94deSBarry Smith   PetscInt    i,nz;
2782354c94deSBarry Smith   PetscScalar *a;
2783354c94deSBarry Smith 
2784354c94deSBarry Smith   PetscFunctionBegin;
2785354c94deSBarry Smith   nz = aij->nz;
2786354c94deSBarry Smith   a  = aij->a;
2787354c94deSBarry Smith   for (i=0; i<nz; i++) {
2788354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2789354c94deSBarry Smith   }
2790354c94deSBarry Smith #else
2791354c94deSBarry Smith   PetscFunctionBegin;
2792354c94deSBarry Smith #endif
2793354c94deSBarry Smith   PetscFunctionReturn(0);
2794354c94deSBarry Smith }
2795354c94deSBarry Smith 
2796e34fafa9SBarry Smith #undef __FUNCT__
2797985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2798985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2799e34fafa9SBarry Smith {
2800e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2801e34fafa9SBarry Smith   PetscErrorCode ierr;
2802d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2803e34fafa9SBarry Smith   PetscReal      atmp;
2804985db425SBarry Smith   PetscScalar    *x;
2805e34fafa9SBarry Smith   MatScalar      *aa;
2806e34fafa9SBarry Smith 
2807e34fafa9SBarry Smith   PetscFunctionBegin;
2808e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2809e34fafa9SBarry Smith   aa   = a->a;
2810e34fafa9SBarry Smith   ai   = a->i;
2811e34fafa9SBarry Smith   aj   = a->j;
2812e34fafa9SBarry Smith 
2813985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2814e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2815e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2816e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2817e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2818e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28199189402eSHong Zhang     x[i] = 0.0;
2820e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2821985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2822985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2823985db425SBarry Smith       aa++; aj++;
2824985db425SBarry Smith     }
2825985db425SBarry Smith   }
2826985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2827985db425SBarry Smith   PetscFunctionReturn(0);
2828985db425SBarry Smith }
2829985db425SBarry Smith 
2830985db425SBarry Smith #undef __FUNCT__
2831985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2832985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2833985db425SBarry Smith {
2834985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2835985db425SBarry Smith   PetscErrorCode ierr;
2836d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2837985db425SBarry Smith   PetscScalar    *x;
2838985db425SBarry Smith   MatScalar      *aa;
2839985db425SBarry Smith 
2840985db425SBarry Smith   PetscFunctionBegin;
2841e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2842985db425SBarry Smith   aa   = a->a;
2843985db425SBarry Smith   ai   = a->i;
2844985db425SBarry Smith   aj   = a->j;
2845985db425SBarry Smith 
2846985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2847985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2848985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2849e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2850985db425SBarry Smith   for (i=0; i<m; i++) {
2851985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2852d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2853985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2854985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2855985db425SBarry Smith       x[i] = 0.0;
2856985db425SBarry Smith       if (idx) {
2857985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2858985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2859985db425SBarry Smith           if (aj[j] > j) {
2860985db425SBarry Smith             idx[i] = j;
2861985db425SBarry Smith             break;
2862985db425SBarry Smith           }
2863985db425SBarry Smith         }
2864985db425SBarry Smith       }
2865985db425SBarry Smith     }
2866985db425SBarry Smith     for (j=0; j<ncols; j++){
2867985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2868985db425SBarry Smith       aa++; aj++;
2869985db425SBarry Smith     }
2870985db425SBarry Smith   }
2871985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2872985db425SBarry Smith   PetscFunctionReturn(0);
2873985db425SBarry Smith }
2874985db425SBarry Smith 
2875985db425SBarry Smith #undef __FUNCT__
2876c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2877c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2878c87e5d42SMatthew Knepley {
2879c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2880c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2881c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2882c87e5d42SMatthew Knepley   PetscReal      atmp;
2883c87e5d42SMatthew Knepley   PetscScalar    *x;
2884c87e5d42SMatthew Knepley   MatScalar      *aa;
2885c87e5d42SMatthew Knepley 
2886c87e5d42SMatthew Knepley   PetscFunctionBegin;
2887e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2888c87e5d42SMatthew Knepley   aa   = a->a;
2889c87e5d42SMatthew Knepley   ai   = a->i;
2890c87e5d42SMatthew Knepley   aj   = a->j;
2891c87e5d42SMatthew Knepley 
2892c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2893c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2894c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2895e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2896c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2897c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2898289a08f5SMatthew Knepley     if (ncols) {
2899289a08f5SMatthew Knepley       /* Get first nonzero */
2900289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2901289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2902289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2903289a08f5SMatthew Knepley       }
2904289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2905289a08f5SMatthew Knepley     } else {
2906289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2907289a08f5SMatthew Knepley     }
2908c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2909c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2910289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2911c87e5d42SMatthew Knepley       aa++; aj++;
2912c87e5d42SMatthew Knepley     }
2913c87e5d42SMatthew Knepley   }
2914c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2915c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2916c87e5d42SMatthew Knepley }
2917c87e5d42SMatthew Knepley 
2918c87e5d42SMatthew Knepley #undef __FUNCT__
2919985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2920985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2921985db425SBarry Smith {
2922985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2923985db425SBarry Smith   PetscErrorCode ierr;
2924d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2925985db425SBarry Smith   PetscScalar    *x;
2926985db425SBarry Smith   MatScalar      *aa;
2927985db425SBarry Smith 
2928985db425SBarry Smith   PetscFunctionBegin;
2929e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2930985db425SBarry Smith   aa   = a->a;
2931985db425SBarry Smith   ai   = a->i;
2932985db425SBarry Smith   aj   = a->j;
2933985db425SBarry Smith 
2934985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2935985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2936985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2937e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2938985db425SBarry Smith   for (i=0; i<m; i++) {
2939985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2940d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2941985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2942985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2943985db425SBarry Smith       x[i] = 0.0;
2944985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2945985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2946985db425SBarry Smith         for (j=0;j<ncols;j++) {
2947985db425SBarry Smith           if (aj[j] > j) {
2948985db425SBarry Smith             idx[i] = j;
2949985db425SBarry Smith             break;
2950985db425SBarry Smith           }
2951985db425SBarry Smith         }
2952985db425SBarry Smith       }
2953985db425SBarry Smith     }
2954985db425SBarry Smith     for (j=0; j<ncols; j++){
2955985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2956985db425SBarry Smith       aa++; aj++;
2957e34fafa9SBarry Smith     }
2958e34fafa9SBarry Smith   }
2959e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2960e34fafa9SBarry Smith   PetscFunctionReturn(0);
2961e34fafa9SBarry Smith }
29627087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2963682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
29640a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2965cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2966cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2967cb5b572fSBarry Smith        MatMult_SeqAIJ,
296897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
29697c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
29707c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2971db4efbfdSBarry Smith        0,
2972db4efbfdSBarry Smith        0,
2973db4efbfdSBarry Smith        0,
2974db4efbfdSBarry Smith /*10*/ 0,
2975cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2976cb5b572fSBarry Smith        0,
297741f059aeSBarry Smith        MatSOR_SeqAIJ,
297817ab2063SBarry Smith        MatTranspose_SeqAIJ,
297997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2980cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2981cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2982cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2983cb5b572fSBarry Smith        MatNorm_SeqAIJ,
298497304618SKris Buschelman /*20*/ 0,
2985cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2986cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2987cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2988d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2989db4efbfdSBarry Smith        0,
2990db4efbfdSBarry Smith        0,
2991db4efbfdSBarry Smith        0,
2992db4efbfdSBarry Smith        0,
2993d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2994db4efbfdSBarry Smith        0,
2995db4efbfdSBarry Smith        0,
29966c0721eeSBarry Smith        MatGetArray_SeqAIJ,
29976c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2998d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2999cb5b572fSBarry Smith        0,
3000cb5b572fSBarry Smith        0,
3001cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
3002cb5b572fSBarry Smith        0,
3003d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
3004cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
3005cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
3006cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
3007cb5b572fSBarry Smith        MatCopy_SeqAIJ,
3008d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
3009cb5b572fSBarry Smith        MatScale_SeqAIJ,
3010cb5b572fSBarry Smith        0,
301179299369SBarry Smith        MatDiagonalSet_SeqAIJ,
30126e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
3013d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
30143b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
30153b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
30163b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
3017a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
3018d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
3019b9617806SBarry Smith        0,
30200513a670SBarry Smith        0,
3021cda55fadSBarry Smith        MatPermute_SeqAIJ,
3022cda55fadSBarry Smith        0,
3023d519adbfSMatthew Knepley /*59*/ 0,
3024b9b97703SBarry Smith        MatDestroy_SeqAIJ,
3025b9b97703SBarry Smith        MatView_SeqAIJ,
3026357abbc8SBarry Smith        0,
3027ee4f033dSBarry Smith        0,
3028d519adbfSMatthew Knepley /*64*/ 0,
3029ee4f033dSBarry Smith        0,
3030ee4f033dSBarry Smith        0,
3031ee4f033dSBarry Smith        0,
3032ee4f033dSBarry Smith        0,
3033d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
3034c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
3035ee4f033dSBarry Smith        0,
3036ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
3037dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3038ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
3039dcf5cc72SBarry Smith #else
3040dcf5cc72SBarry Smith        0,
3041dcf5cc72SBarry Smith #endif
3042d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
30433acb8795SBarry Smith        MatFDColoringApply_AIJ,
304497304618SKris Buschelman        0,
304597304618SKris Buschelman        0,
304697304618SKris Buschelman        0,
30476ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
304897304618SKris Buschelman        0,
304997304618SKris Buschelman        0,
305097304618SKris Buschelman        0,
3051bc011b1eSHong Zhang        MatLoad_SeqAIJ,
3052d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
30531cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
30546284ec50SHong Zhang        0,
30556284ec50SHong Zhang        0,
3056bc011b1eSHong Zhang        0,
3057d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
305826be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
305926be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
3060d439da42SKris Buschelman        MatPtAP_Basic,
30617ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
3062d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
3063bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
3064bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
3065bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
30667ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
3067d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
3068609c6c4dSKris Buschelman        0,
3069609c6c4dSKris Buschelman        0,
307087d4246cSBarry Smith        MatConjugate_SeqAIJ,
307187d4246cSBarry Smith        0,
3072d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
307399cafbc1SBarry Smith        MatRealPart_SeqAIJ,
3074f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
3075f5edf698SHong Zhang        0,
30762bebee5dSHong Zhang        0,
3077cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
3078985db425SBarry Smith        0,
30792af78befSBarry Smith        MatGetRowMin_SeqAIJ,
30802af78befSBarry Smith        0,
3081599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
3082d519adbfSMatthew Knepley /*114*/0,
3083599ef60dSHong Zhang        0,
30843c2a7987SHong Zhang        0,
3085fe97e370SBarry Smith        0,
3086fbdbba38SShri Abhyankar        0,
3087fbdbba38SShri Abhyankar /*119*/0,
3088fbdbba38SShri Abhyankar        0,
3089fbdbba38SShri Abhyankar        0,
309082d44351SHong Zhang        0,
3091b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
30920716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ,
30930716a85fSBarry Smith        MatGetColumnNorms_SeqAIJ
30949e29f15eSvictorle };
309517ab2063SBarry Smith 
3096fb2e594dSBarry Smith EXTERN_C_BEGIN
30974a2ae208SSatish Balay #undef __FUNCT__
30984a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
30997087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3100bef8e0ddSBarry Smith {
3101bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
310297f1f81fSBarry Smith   PetscInt   i,nz,n;
3103bef8e0ddSBarry Smith 
3104bef8e0ddSBarry Smith   PetscFunctionBegin;
3105bef8e0ddSBarry Smith 
3106bef8e0ddSBarry Smith   nz = aij->maxnz;
3107d0f46423SBarry Smith   n  = mat->rmap->n;
3108bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3109bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3110bef8e0ddSBarry Smith   }
3111bef8e0ddSBarry Smith   aij->nz = nz;
3112bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3113bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3114bef8e0ddSBarry Smith   }
3115bef8e0ddSBarry Smith 
3116bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3117bef8e0ddSBarry Smith }
3118fb2e594dSBarry Smith EXTERN_C_END
3119bef8e0ddSBarry Smith 
31204a2ae208SSatish Balay #undef __FUNCT__
31214a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3122bef8e0ddSBarry Smith /*@
3123bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3124bef8e0ddSBarry Smith        in the matrix.
3125bef8e0ddSBarry Smith 
3126bef8e0ddSBarry Smith   Input Parameters:
3127bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3128bef8e0ddSBarry Smith -  indices - the column indices
3129bef8e0ddSBarry Smith 
313015091d37SBarry Smith   Level: advanced
313115091d37SBarry Smith 
3132bef8e0ddSBarry Smith   Notes:
3133bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3134bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3135bef8e0ddSBarry Smith   of the MatSetValues() operation.
3136bef8e0ddSBarry Smith 
3137bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3138d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3139bef8e0ddSBarry Smith 
3140bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3141bef8e0ddSBarry Smith 
3142b9617806SBarry Smith     The indices should start with zero, not one.
3143b9617806SBarry Smith 
3144bef8e0ddSBarry Smith @*/
31457087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3146bef8e0ddSBarry Smith {
31474ac538c5SBarry Smith   PetscErrorCode ierr;
3148bef8e0ddSBarry Smith 
3149bef8e0ddSBarry Smith   PetscFunctionBegin;
31500700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
31514482741eSBarry Smith   PetscValidPointer(indices,2);
31524ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
3153bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3154bef8e0ddSBarry Smith }
3155bef8e0ddSBarry Smith 
3156be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3157be6bf707SBarry Smith 
3158fb2e594dSBarry Smith EXTERN_C_BEGIN
31594a2ae208SSatish Balay #undef __FUNCT__
31604a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
31617087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3162be6bf707SBarry Smith {
3163be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
31646849ba73SBarry Smith   PetscErrorCode ierr;
3165d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3166be6bf707SBarry Smith 
3167be6bf707SBarry Smith   PetscFunctionBegin;
3168be6bf707SBarry Smith   if (aij->nonew != 1) {
3169e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3170be6bf707SBarry Smith   }
3171be6bf707SBarry Smith 
3172be6bf707SBarry Smith   /* allocate space for values if not already there */
3173be6bf707SBarry Smith   if (!aij->saved_values) {
317487828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
31759518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3176be6bf707SBarry Smith   }
3177be6bf707SBarry Smith 
3178be6bf707SBarry Smith   /* copy values over */
317987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3180be6bf707SBarry Smith   PetscFunctionReturn(0);
3181be6bf707SBarry Smith }
3182fb2e594dSBarry Smith EXTERN_C_END
3183be6bf707SBarry Smith 
31844a2ae208SSatish Balay #undef __FUNCT__
3185b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3186be6bf707SBarry Smith /*@
3187be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3188be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3189be6bf707SBarry Smith        nonlinear portion.
3190be6bf707SBarry Smith 
3191be6bf707SBarry Smith    Collect on Mat
3192be6bf707SBarry Smith 
3193be6bf707SBarry Smith   Input Parameters:
31940e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3195be6bf707SBarry Smith 
319615091d37SBarry Smith   Level: advanced
319715091d37SBarry Smith 
3198be6bf707SBarry Smith   Common Usage, with SNESSolve():
3199be6bf707SBarry Smith $    Create Jacobian matrix
3200be6bf707SBarry Smith $    Set linear terms into matrix
3201be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3202be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3203be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3204512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3205be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3206be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3207be6bf707SBarry Smith $    In your Jacobian routine
3208be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3209be6bf707SBarry Smith $      Set nonlinear terms in matrix
3210be6bf707SBarry Smith 
3211be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3212be6bf707SBarry Smith $    // build linear portion of Jacobian
3213512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3214be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3215be6bf707SBarry Smith $    loop over nonlinear iterations
3216be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3217be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3218be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3219be6bf707SBarry Smith $       Solve linear system with Jacobian
3220be6bf707SBarry Smith $    endloop
3221be6bf707SBarry Smith 
3222be6bf707SBarry Smith   Notes:
3223be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3224512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3225be6bf707SBarry Smith     calling this routine.
3226be6bf707SBarry Smith 
32270c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
32280c468ba9SBarry Smith     and does not allocated additional space.
32290c468ba9SBarry Smith 
3230be6bf707SBarry Smith .seealso: MatRetrieveValues()
3231be6bf707SBarry Smith 
3232be6bf707SBarry Smith @*/
32337087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3234be6bf707SBarry Smith {
32354ac538c5SBarry Smith   PetscErrorCode ierr;
3236be6bf707SBarry Smith 
3237be6bf707SBarry Smith   PetscFunctionBegin;
32380700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3239e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3240e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32414ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3242be6bf707SBarry Smith   PetscFunctionReturn(0);
3243be6bf707SBarry Smith }
3244be6bf707SBarry Smith 
3245fb2e594dSBarry Smith EXTERN_C_BEGIN
32464a2ae208SSatish Balay #undef __FUNCT__
32474a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
32487087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3249be6bf707SBarry Smith {
3250be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
32516849ba73SBarry Smith   PetscErrorCode ierr;
3252d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3253be6bf707SBarry Smith 
3254be6bf707SBarry Smith   PetscFunctionBegin;
3255be6bf707SBarry Smith   if (aij->nonew != 1) {
3256e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3257be6bf707SBarry Smith   }
3258be6bf707SBarry Smith   if (!aij->saved_values) {
3259e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3260be6bf707SBarry Smith   }
3261be6bf707SBarry Smith   /* copy values over */
326287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3263be6bf707SBarry Smith   PetscFunctionReturn(0);
3264be6bf707SBarry Smith }
3265fb2e594dSBarry Smith EXTERN_C_END
3266be6bf707SBarry Smith 
32674a2ae208SSatish Balay #undef __FUNCT__
32684a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3269be6bf707SBarry Smith /*@
3270be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3271be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3272be6bf707SBarry Smith        nonlinear portion.
3273be6bf707SBarry Smith 
3274be6bf707SBarry Smith    Collect on Mat
3275be6bf707SBarry Smith 
3276be6bf707SBarry Smith   Input Parameters:
3277be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3278be6bf707SBarry Smith 
327915091d37SBarry Smith   Level: advanced
328015091d37SBarry Smith 
3281be6bf707SBarry Smith .seealso: MatStoreValues()
3282be6bf707SBarry Smith 
3283be6bf707SBarry Smith @*/
32847087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3285be6bf707SBarry Smith {
32864ac538c5SBarry Smith   PetscErrorCode ierr;
3287be6bf707SBarry Smith 
3288be6bf707SBarry Smith   PetscFunctionBegin;
32890700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3290e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3291e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32924ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3293be6bf707SBarry Smith   PetscFunctionReturn(0);
3294be6bf707SBarry Smith }
3295be6bf707SBarry Smith 
3296f83d6046SBarry Smith 
3297be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
32984a2ae208SSatish Balay #undef __FUNCT__
32994a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
330017ab2063SBarry Smith /*@C
3301682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33020d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33036e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
330451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33052bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
330617ab2063SBarry Smith 
3307db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3308db81eaa0SLois Curfman McInnes 
330917ab2063SBarry Smith    Input Parameters:
3310db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
331117ab2063SBarry Smith .  m - number of rows
331217ab2063SBarry Smith .  n - number of columns
331317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
331451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33152bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
331617ab2063SBarry Smith 
331717ab2063SBarry Smith    Output Parameter:
3318416022c9SBarry Smith .  A - the matrix
331917ab2063SBarry Smith 
3320175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3321ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3322175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3323175b88e8SBarry Smith 
3324b259b22eSLois Curfman McInnes    Notes:
332549a6f317SBarry Smith    If nnz is given then nz is ignored
332649a6f317SBarry Smith 
332717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
332817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
33290002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
333044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
333117ab2063SBarry Smith 
333217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3333a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
33343d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
33356da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
333617ab2063SBarry Smith 
3337682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
33384fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3339682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
33406c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
33416c7ebb05SLois Curfman McInnes 
33426c7ebb05SLois Curfman McInnes    Options Database Keys:
3343698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
33449db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
334517ab2063SBarry Smith 
3346027ccd11SLois Curfman McInnes    Level: intermediate
3347027ccd11SLois Curfman McInnes 
334836db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
334936db0b34SBarry Smith 
335017ab2063SBarry Smith @*/
33517087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
335217ab2063SBarry Smith {
3353dfbe8321SBarry Smith   PetscErrorCode ierr;
33546945ee14SBarry Smith 
33553a40ed3dSBarry Smith   PetscFunctionBegin;
3356f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3357117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3358c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3359d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3360273d9f13SBarry Smith   PetscFunctionReturn(0);
3361273d9f13SBarry Smith }
3362273d9f13SBarry Smith 
33634a2ae208SSatish Balay #undef __FUNCT__
33644a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3365273d9f13SBarry Smith /*@C
3366273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3367273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3368273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3369273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3370273d9f13SBarry Smith 
3371273d9f13SBarry Smith    Collective on MPI_Comm
3372273d9f13SBarry Smith 
3373273d9f13SBarry Smith    Input Parameters:
3374117016b1SBarry Smith +  B - The matrix-free
3375273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3376273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3377273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3378273d9f13SBarry Smith 
3379273d9f13SBarry Smith    Notes:
338049a6f317SBarry Smith      If nnz is given then nz is ignored
338149a6f317SBarry Smith 
3382273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3383273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3384273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3385273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3386273d9f13SBarry Smith 
3387273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3388273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3389273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3390273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3391273d9f13SBarry Smith 
3392aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3393aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3394aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3395aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3396aa95bbe8SBarry Smith 
3397a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3398a96a251dSBarry Smith    entries or columns indices
3399a96a251dSBarry Smith 
3400273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3401273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3402273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3403273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3404273d9f13SBarry Smith 
3405273d9f13SBarry Smith    Options Database Keys:
3406698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3407698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3408273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3409273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3410273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3411273d9f13SBarry Smith 
3412273d9f13SBarry Smith    Level: intermediate
3413273d9f13SBarry Smith 
3414aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3415273d9f13SBarry Smith 
3416273d9f13SBarry Smith @*/
34177087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3418273d9f13SBarry Smith {
34194ac538c5SBarry Smith   PetscErrorCode ierr;
3420a23d5eceSKris Buschelman 
3421a23d5eceSKris Buschelman   PetscFunctionBegin;
34224ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3423a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3424a23d5eceSKris Buschelman }
3425a23d5eceSKris Buschelman 
3426a23d5eceSKris Buschelman EXTERN_C_BEGIN
3427a23d5eceSKris Buschelman #undef __FUNCT__
3428a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
34297087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3430a23d5eceSKris Buschelman {
3431273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3432ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
34336849ba73SBarry Smith   PetscErrorCode ierr;
343497f1f81fSBarry Smith   PetscInt       i;
3435273d9f13SBarry Smith 
3436273d9f13SBarry Smith   PetscFunctionBegin;
3437d5d45c9bSBarry Smith 
3438a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3439c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3440c461c341SBarry Smith     nz             = 0;
3441c461c341SBarry Smith   }
3442c461c341SBarry Smith 
344326283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
344426283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
344526283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
344626283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3447899cda47SBarry Smith 
3448435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3449e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3450b73539f3SBarry Smith   if (nnz) {
3451d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3452e32f2f54SBarry 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]);
3453e32f2f54SBarry 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);
3454b73539f3SBarry Smith     }
3455b73539f3SBarry Smith   }
3456b73539f3SBarry Smith 
3457273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3458273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3459273d9f13SBarry Smith 
3460ab93d7beSBarry Smith   if (!skipallocation) {
34612ee49352SLisandro Dalcin     if (!b->imax) {
3462d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3463d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
34642ee49352SLisandro Dalcin     }
3465273d9f13SBarry Smith     if (!nnz) {
3466435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3467c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3468d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3469d0f46423SBarry Smith       nz = nz*B->rmap->n;
3470273d9f13SBarry Smith     } else {
3471273d9f13SBarry Smith       nz = 0;
3472d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3473273d9f13SBarry Smith     }
3474ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3475d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3476ab93d7beSBarry Smith 
3477273d9f13SBarry Smith     /* allocate the matrix space */
34782ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3479d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3480d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3481bfeeae90SHong Zhang     b->i[0] = 0;
3482d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
34835da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
34845da197adSKris Buschelman     }
3485273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3486e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3487e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3488c461c341SBarry Smith   } else {
3489e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3490e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3491c461c341SBarry Smith   }
3492273d9f13SBarry Smith 
3493273d9f13SBarry Smith   b->nz                = 0;
3494273d9f13SBarry Smith   b->maxnz             = nz;
3495273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3496273d9f13SBarry Smith   PetscFunctionReturn(0);
3497273d9f13SBarry Smith }
3498a23d5eceSKris Buschelman EXTERN_C_END
3499273d9f13SBarry Smith 
3500a1661176SMatthew Knepley #undef  __FUNCT__
3501a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
350258d36128SBarry Smith /*@
3503a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3504a1661176SMatthew Knepley 
3505a1661176SMatthew Knepley    Input Parameters:
3506a1661176SMatthew Knepley +  B - the matrix
3507a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3508a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3509a1661176SMatthew Knepley -  v - optional values in the matrix
3510a1661176SMatthew Knepley 
3511a1661176SMatthew Knepley    Level: developer
3512a1661176SMatthew Knepley 
351358d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
351458d36128SBarry Smith 
3515a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3516a1661176SMatthew Knepley 
3517a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3518a1661176SMatthew Knepley @*/
3519a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3520a1661176SMatthew Knepley {
3521a1661176SMatthew Knepley   PetscErrorCode ierr;
3522a1661176SMatthew Knepley 
3523a1661176SMatthew Knepley   PetscFunctionBegin;
35240700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35254ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3526a1661176SMatthew Knepley   PetscFunctionReturn(0);
3527a1661176SMatthew Knepley }
3528a1661176SMatthew Knepley 
3529a1661176SMatthew Knepley EXTERN_C_BEGIN
3530a1661176SMatthew Knepley #undef  __FUNCT__
3531a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
35327087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3533a1661176SMatthew Knepley {
3534a1661176SMatthew Knepley   PetscInt       i;
3535a1661176SMatthew Knepley   PetscInt       m,n;
3536a1661176SMatthew Knepley   PetscInt       nz;
3537a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3538a1661176SMatthew Knepley   PetscScalar    *values;
3539a1661176SMatthew Knepley   PetscErrorCode ierr;
3540a1661176SMatthew Knepley 
3541a1661176SMatthew Knepley   PetscFunctionBegin;
3542a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3543a1661176SMatthew Knepley 
354465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3545a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3546a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3547b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3548a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
354965e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3550a1661176SMatthew Knepley     nnz[i] = nz;
3551a1661176SMatthew Knepley   }
3552a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3553a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3554a1661176SMatthew Knepley 
3555a1661176SMatthew Knepley   if (v) {
3556a1661176SMatthew Knepley     values = (PetscScalar*) v;
3557a1661176SMatthew Knepley   } else {
35580e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3559a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3560a1661176SMatthew Knepley   }
3561a1661176SMatthew Knepley 
3562a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3563b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3564b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3565a1661176SMatthew Knepley   }
3566a1661176SMatthew Knepley 
3567a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3568a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3569a1661176SMatthew Knepley 
3570a1661176SMatthew Knepley   if (!v) {
3571a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3572a1661176SMatthew Knepley   }
3573a1661176SMatthew Knepley   PetscFunctionReturn(0);
3574a1661176SMatthew Knepley }
3575a1661176SMatthew Knepley EXTERN_C_END
3576a1661176SMatthew Knepley 
3577c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3578c6db04a5SJed Brown #include <private/petscaxpy.h>
3579170fe5c8SBarry Smith 
3580170fe5c8SBarry Smith #undef __FUNCT__
3581170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3582170fe5c8SBarry Smith /*
3583170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3584170fe5c8SBarry Smith 
3585170fe5c8SBarry Smith                n                       p                          p
3586170fe5c8SBarry Smith         (              )       (              )         (                  )
3587170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3588170fe5c8SBarry Smith         (              )       (              )         (                  )
3589170fe5c8SBarry Smith 
3590170fe5c8SBarry Smith */
3591170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3592170fe5c8SBarry Smith {
3593170fe5c8SBarry Smith   PetscErrorCode     ierr;
3594170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3595170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3596170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
35971de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3598170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3599170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3600170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3601170fe5c8SBarry Smith 
3602170fe5c8SBarry Smith   PetscFunctionBegin;
3603d0f46423SBarry Smith   m = A->rmap->n;
3604d0f46423SBarry Smith   n = A->cmap->n;
3605d0f46423SBarry Smith   p = B->cmap->n;
3606170fe5c8SBarry Smith   a = sub_a->v;
3607170fe5c8SBarry Smith   b = sub_b->a;
3608170fe5c8SBarry Smith   c = sub_c->v;
3609170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3610170fe5c8SBarry Smith 
3611170fe5c8SBarry Smith   ii  = sub_b->i;
3612170fe5c8SBarry Smith   idx = sub_b->j;
3613170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3614170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3615170fe5c8SBarry Smith     while (q-->0) {
3616170fe5c8SBarry Smith       c_q = c + m*(*idx);
3617170fe5c8SBarry Smith       a_q = a + m*i;
3618be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3619170fe5c8SBarry Smith       idx++;
3620170fe5c8SBarry Smith       b++;
3621170fe5c8SBarry Smith     }
3622170fe5c8SBarry Smith   }
3623170fe5c8SBarry Smith   PetscFunctionReturn(0);
3624170fe5c8SBarry Smith }
3625170fe5c8SBarry Smith 
3626170fe5c8SBarry Smith #undef __FUNCT__
3627170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3628170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3629170fe5c8SBarry Smith {
3630170fe5c8SBarry Smith   PetscErrorCode ierr;
3631d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3632170fe5c8SBarry Smith   Mat            Cmat;
3633170fe5c8SBarry Smith 
3634170fe5c8SBarry Smith   PetscFunctionBegin;
3635e32f2f54SBarry 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);
363639804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3637170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3638170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3639170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3640170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3641170fe5c8SBarry Smith   *C = Cmat;
3642170fe5c8SBarry Smith   PetscFunctionReturn(0);
3643170fe5c8SBarry Smith }
3644170fe5c8SBarry Smith 
3645170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3646170fe5c8SBarry Smith #undef __FUNCT__
3647170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3648170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3649170fe5c8SBarry Smith {
3650170fe5c8SBarry Smith   PetscErrorCode ierr;
3651170fe5c8SBarry Smith 
3652170fe5c8SBarry Smith   PetscFunctionBegin;
3653170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3654170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3655170fe5c8SBarry Smith   }
3656170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3657170fe5c8SBarry Smith   PetscFunctionReturn(0);
3658170fe5c8SBarry Smith }
3659170fe5c8SBarry Smith 
3660170fe5c8SBarry Smith 
36610bad9183SKris Buschelman /*MC
3662fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
36630bad9183SKris Buschelman    based on compressed sparse row format.
36640bad9183SKris Buschelman 
36650bad9183SKris Buschelman    Options Database Keys:
36660bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
36670bad9183SKris Buschelman 
36680bad9183SKris Buschelman   Level: beginner
36690bad9183SKris Buschelman 
3670f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
36710bad9183SKris Buschelman M*/
36720bad9183SKris Buschelman 
3673a6175056SHong Zhang EXTERN_C_BEGIN
3674b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3675b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3676b5e56a35SBarry Smith #endif
3677ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3678af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3679af1023dbSSatish Balay #endif
36807087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
36817087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
36827087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
36837087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3684611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
36857087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3686611f576cSBarry Smith #endif
3687611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
36887087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3689611f576cSBarry Smith #endif
3690f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3691f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3692f3c0ef26SHong Zhang #endif
3693611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
36947087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3695611f576cSBarry Smith #endif
3696eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
36977087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3698eb3b5408SSatish Balay #endif
3699586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
37007087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3701586621ddSJed Brown #endif
3702719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
37037087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3704719d5645SBarry Smith #endif
3705b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
37067087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
37077087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
37087087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3709b3866ffcSBarry Smith #endif
371017667f90SBarry Smith EXTERN_C_END
371117667f90SBarry Smith 
371217667f90SBarry Smith EXTERN_C_BEGIN
37134a2ae208SSatish Balay #undef __FUNCT__
37144a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
37157087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3716273d9f13SBarry Smith {
3717273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3718dfbe8321SBarry Smith   PetscErrorCode ierr;
371938baddfdSBarry Smith   PetscMPIInt    size;
3720273d9f13SBarry Smith 
3721273d9f13SBarry Smith   PetscFunctionBegin;
37227adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3723e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3724273d9f13SBarry Smith 
372538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3726b0a32e0cSBarry Smith   B->data             = (void*)b;
3727549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3728416022c9SBarry Smith   b->row              = 0;
3729416022c9SBarry Smith   b->col              = 0;
373082bf6240SBarry Smith   b->icol             = 0;
3731b810aeb4SBarry Smith   b->reallocs         = 0;
373236db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3733f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3734416022c9SBarry Smith   b->nonew             = 0;
3735416022c9SBarry Smith   b->diag              = 0;
3736416022c9SBarry Smith   b->solve_work        = 0;
37372a1b7f2aSHong Zhang   B->spptr             = 0;
3738be6bf707SBarry Smith   b->saved_values      = 0;
3739d7f994e1SBarry Smith   b->idiag             = 0;
374071f1c65dSBarry Smith   b->mdiag             = 0;
374171f1c65dSBarry Smith   b->ssor_work         = 0;
374271f1c65dSBarry Smith   b->omega             = 1.0;
374371f1c65dSBarry Smith   b->fshift            = 0.0;
374471f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3745a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3746a30b2313SHong Zhang   b->xtoy              = 0;
3747a30b2313SHong Zhang   b->XtoY              = 0;
374888e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
374917ab2063SBarry Smith 
375035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3751b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3752700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3753b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3754b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3755b3866ffcSBarry Smith #endif
3756b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3757700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3758b5e56a35SBarry Smith #endif
3759ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3760700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3761719d5645SBarry Smith #endif
3762611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3763700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3764611f576cSBarry Smith #endif
3765f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3766700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3767f3c0ef26SHong Zhang #endif
3768611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3769700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3770611f576cSBarry Smith #endif
3771611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3772700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3773611f576cSBarry Smith #endif
3774eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3775700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3776eb3b5408SSatish Balay #endif
3777586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3778700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3779586621ddSJed Brown #endif
3780719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3781700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3782719d5645SBarry Smith #endif
3783700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3784700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3785700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3786700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3787700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3788700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3789700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3790700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3791700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3792700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3793700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3794700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3795700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3796700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3797700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3798700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3799700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3800700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
38014108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
380217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
38033a40ed3dSBarry Smith   PetscFunctionReturn(0);
380417ab2063SBarry Smith }
3805273d9f13SBarry Smith EXTERN_C_END
380617ab2063SBarry Smith 
3807*ba61063dSBarry Smith #if defined(PETSC_USE_PTHREAD_CLASSES)
380851d315f7SKerry Stevens EXTERN_C_BEGIN
380951d315f7SKerry Stevens #undef __FUNCT__
381051d315f7SKerry Stevens #define __FUNCT__ "MatCreate_SeqPThreadAIJ"
381151d315f7SKerry Stevens PetscErrorCode  MatCreate_SeqPThreadAIJ(Mat B)
381251d315f7SKerry Stevens {
381351d315f7SKerry Stevens   PetscErrorCode ierr;
381451d315f7SKerry Stevens 
381551d315f7SKerry Stevens   PetscFunctionBegin;
381651d315f7SKerry Stevens   ierr = MatCreate_SeqAIJ(B);
381751d315f7SKerry Stevens   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
381851d315f7SKerry Stevens   B->ops->mult = MatMult_SeqPThreadAIJ;
381951d315f7SKerry Stevens   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQPTHREADAIJ);CHKERRQ(ierr);
382051d315f7SKerry Stevens   PetscFunctionReturn(0);
382151d315f7SKerry Stevens }
382251d315f7SKerry Stevens EXTERN_C_END
3823*ba61063dSBarry Smith #endif
382451d315f7SKerry Stevens 
38254a2ae208SSatish Balay #undef __FUNCT__
3826b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3827b24902e0SBarry Smith /*
3828b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3829b24902e0SBarry Smith */
3830ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
383117ab2063SBarry Smith {
3832416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
38336849ba73SBarry Smith   PetscErrorCode ierr;
3834d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
383517ab2063SBarry Smith 
38363a40ed3dSBarry Smith   PetscFunctionBegin;
3837273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3838273d9f13SBarry Smith 
3839d5f3da31SBarry Smith   C->factortype     = A->factortype;
3840416022c9SBarry Smith   c->row            = 0;
3841416022c9SBarry Smith   c->col            = 0;
384282bf6240SBarry Smith   c->icol           = 0;
38436ad4291fSHong Zhang   c->reallocs       = 0;
384417ab2063SBarry Smith 
38456ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
384617ab2063SBarry Smith 
3847aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3848aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3849eec197d1SBarry Smith 
385033b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
38519518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
385217ab2063SBarry Smith   for (i=0; i<m; i++) {
3853416022c9SBarry Smith     c->imax[i] = a->imax[i];
3854416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
385517ab2063SBarry Smith   }
385617ab2063SBarry Smith 
385717ab2063SBarry Smith   /* allocate the matrix space */
3858f77e22a1SHong Zhang   if (mallocmatspace){
3859a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
38609518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3861f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
386297f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
386317ab2063SBarry Smith     if (m > 0) {
386497f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3865be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3866bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3867be6bf707SBarry Smith       } else {
3868bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
386917ab2063SBarry Smith       }
387008480c60SBarry Smith     }
3871f77e22a1SHong Zhang   }
387217ab2063SBarry Smith 
38736ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3874416022c9SBarry Smith   c->roworiented       = a->roworiented;
3875416022c9SBarry Smith   c->nonew             = a->nonew;
3876416022c9SBarry Smith   if (a->diag) {
387797f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
387852e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
387917ab2063SBarry Smith     for (i=0; i<m; i++) {
3880416022c9SBarry Smith       c->diag[i] = a->diag[i];
388117ab2063SBarry Smith     }
38823a40ed3dSBarry Smith   } else c->diag           = 0;
38836ad4291fSHong Zhang   c->solve_work            = 0;
38846ad4291fSHong Zhang   c->saved_values          = 0;
38856ad4291fSHong Zhang   c->idiag                 = 0;
388671f1c65dSBarry Smith   c->ssor_work             = 0;
3887a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3888e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3889e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
38906ad4291fSHong Zhang   c->xtoy                  = 0;
38916ad4291fSHong Zhang   c->XtoY                  = 0;
38926ad4291fSHong Zhang 
3893416022c9SBarry Smith   c->nz                 = a->nz;
38948ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3895273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3896754ec7b1SSatish Balay 
38976ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
38986ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3899cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3900cd6b891eSBarry Smith   if (a->compressedrow.use){
39016ad4291fSHong Zhang     i = a->compressedrow.nrows;
39020e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
39036ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
39046ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
390527ea64f8SHong Zhang   } else {
390627ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
390727ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
390827ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
39096ad4291fSHong Zhang   }
391088e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
39114108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
39124846f1f5SKris Buschelman 
39137adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
39143a40ed3dSBarry Smith   PetscFunctionReturn(0);
391517ab2063SBarry Smith }
391617ab2063SBarry Smith 
39174a2ae208SSatish Balay #undef __FUNCT__
3918b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3919b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3920b24902e0SBarry Smith {
3921b24902e0SBarry Smith   PetscErrorCode ierr;
3922b24902e0SBarry Smith 
3923b24902e0SBarry Smith   PetscFunctionBegin;
3924b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
39254b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3926b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3927f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3928b24902e0SBarry Smith   PetscFunctionReturn(0);
3929b24902e0SBarry Smith }
3930b24902e0SBarry Smith 
3931b24902e0SBarry Smith #undef __FUNCT__
39324a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3933112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3934fbdbba38SShri Abhyankar {
3935fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3936fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3937fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3938fbdbba38SShri Abhyankar   int            fd;
3939fbdbba38SShri Abhyankar   PetscMPIInt    size;
3940fbdbba38SShri Abhyankar   MPI_Comm       comm;
3941fbdbba38SShri Abhyankar 
3942fbdbba38SShri Abhyankar   PetscFunctionBegin;
3943fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3944fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3945fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3946fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3947fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3948fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3949fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3950fbdbba38SShri Abhyankar 
3951fbdbba38SShri Abhyankar   if (nz < 0) {
3952fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3953fbdbba38SShri Abhyankar   }
3954fbdbba38SShri Abhyankar 
3955fbdbba38SShri Abhyankar   /* read in row lengths */
3956fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3957fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3958fbdbba38SShri Abhyankar 
3959fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3960fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3961fbdbba38SShri 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);
3962fbdbba38SShri Abhyankar 
3963fbdbba38SShri Abhyankar   /* set global size if not set already*/
3964f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3965fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3966aabbc4fbSShri Abhyankar   } else {
3967fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3968fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3969f501eaabSShri 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);
3970aabbc4fbSShri Abhyankar   }
3971fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3972fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3973fbdbba38SShri Abhyankar 
3974fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3975fbdbba38SShri Abhyankar 
3976fbdbba38SShri Abhyankar   /* read in nonzero values */
3977fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3978fbdbba38SShri Abhyankar 
3979fbdbba38SShri Abhyankar   /* set matrix "i" values */
3980fbdbba38SShri Abhyankar   a->i[0] = 0;
3981fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3982fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3983fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3984fbdbba38SShri Abhyankar   }
3985fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3986fbdbba38SShri Abhyankar 
3987fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3988fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3989fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3990fbdbba38SShri Abhyankar }
3991fbdbba38SShri Abhyankar 
3992fbdbba38SShri Abhyankar #undef __FUNCT__
3993b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3994ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
39957264ac53SSatish Balay {
39967264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3997dfbe8321SBarry Smith   PetscErrorCode ierr;
3998eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3999eeffb40dSHong Zhang   PetscInt k;
4000eeffb40dSHong Zhang #endif
40017264ac53SSatish Balay 
40023a40ed3dSBarry Smith   PetscFunctionBegin;
4003bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4004d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4005ca44d042SBarry Smith     *flg = PETSC_FALSE;
4006ca44d042SBarry Smith     PetscFunctionReturn(0);
4007bcd2baecSBarry Smith   }
40087264ac53SSatish Balay 
40097264ac53SSatish Balay   /* if the a->i are the same */
4010d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4011abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
40127264ac53SSatish Balay 
40137264ac53SSatish Balay   /* if a->j are the same */
401497f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4015abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4016bcd2baecSBarry Smith 
4017bcd2baecSBarry Smith   /* if a->a are the same */
4018eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4019eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
4020eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
4021eeffb40dSHong Zhang       *flg = PETSC_FALSE;
40223a40ed3dSBarry Smith       PetscFunctionReturn(0);
4023eeffb40dSHong Zhang     }
4024eeffb40dSHong Zhang   }
4025eeffb40dSHong Zhang #else
4026eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4027eeffb40dSHong Zhang #endif
4028eeffb40dSHong Zhang   PetscFunctionReturn(0);
40297264ac53SSatish Balay }
403036db0b34SBarry Smith 
40314a2ae208SSatish Balay #undef __FUNCT__
40324a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
403305869f15SSatish Balay /*@
403436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
403536db0b34SBarry Smith               provided by the user.
403636db0b34SBarry Smith 
4037c75a6043SHong Zhang       Collective on MPI_Comm
403836db0b34SBarry Smith 
403936db0b34SBarry Smith    Input Parameters:
404036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
404136db0b34SBarry Smith .   m - number of rows
404236db0b34SBarry Smith .   n - number of columns
404336db0b34SBarry Smith .   i - row indices
404436db0b34SBarry Smith .   j - column indices
404536db0b34SBarry Smith -   a - matrix values
404636db0b34SBarry Smith 
404736db0b34SBarry Smith    Output Parameter:
404836db0b34SBarry Smith .   mat - the matrix
404936db0b34SBarry Smith 
405036db0b34SBarry Smith    Level: intermediate
405136db0b34SBarry Smith 
405236db0b34SBarry Smith    Notes:
40530551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4054292fb18eSBarry Smith     once the matrix is destroyed and not before
405536db0b34SBarry Smith 
405636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
405736db0b34SBarry Smith 
4058bfeeae90SHong Zhang        The i and j indices are 0 based
405936db0b34SBarry Smith 
4060a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4061a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4062a4552177SSatish Balay     as shown:
4063a4552177SSatish Balay 
4064a4552177SSatish Balay         1 0 0
4065a4552177SSatish Balay         2 0 3
4066a4552177SSatish Balay         4 5 6
4067a4552177SSatish Balay 
4068a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
40699985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4070a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4071a4552177SSatish Balay 
40729985e31cSBarry Smith 
40732fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
407436db0b34SBarry Smith 
407536db0b34SBarry Smith @*/
40767087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
407736db0b34SBarry Smith {
4078dfbe8321SBarry Smith   PetscErrorCode ierr;
4079cbcfb4deSHong Zhang   PetscInt       ii;
408036db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4081cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4082cbcfb4deSHong Zhang   PetscInt       jj;
4083cbcfb4deSHong Zhang #endif
408436db0b34SBarry Smith 
408536db0b34SBarry Smith   PetscFunctionBegin;
4086a96a251dSBarry Smith   if (i[0]) {
4087e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
408836db0b34SBarry Smith   }
4089f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4090f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4091ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4092ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4093ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4094ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4095ab93d7beSBarry Smith 
409636db0b34SBarry Smith   aij->i = i;
409736db0b34SBarry Smith   aij->j = j;
409836db0b34SBarry Smith   aij->a = a;
409936db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
410036db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4101e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4102e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
410336db0b34SBarry Smith 
410436db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
410536db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
41062515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4107e32f2f54SBarry 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]);
41089985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4109e32f2f54SBarry 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);
4110e32f2f54SBarry 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);
41119985e31cSBarry Smith     }
411236db0b34SBarry Smith #endif
411336db0b34SBarry Smith   }
41142515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
411536db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4116e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4117e32f2f54SBarry 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]);
411836db0b34SBarry Smith   }
411936db0b34SBarry Smith #endif
412036db0b34SBarry Smith 
4121b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4122b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
412336db0b34SBarry Smith   PetscFunctionReturn(0);
412436db0b34SBarry Smith }
412536db0b34SBarry Smith 
4126cc8ba8e1SBarry Smith #undef __FUNCT__
4127ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4128dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4129cc8ba8e1SBarry Smith {
4130dfbe8321SBarry Smith   PetscErrorCode ierr;
4131cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
413236db0b34SBarry Smith 
4133cc8ba8e1SBarry Smith   PetscFunctionBegin;
41348ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4135cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4136cc8ba8e1SBarry Smith     a->coloring = coloring;
413712c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
413897f1f81fSBarry Smith     PetscInt             i,*larray;
413912c595b3SBarry Smith     ISColoring      ocoloring;
414008b6dcc0SBarry Smith     ISColoringValue *colors;
414112c595b3SBarry Smith 
414212c595b3SBarry Smith     /* set coloring for diagonal portion */
41430e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
4144d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
414512c595b3SBarry Smith       larray[i] = i;
414612c595b3SBarry Smith     }
4147992144d0SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
41480e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
4149d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
415012c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
415112c595b3SBarry Smith     }
415212c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
4153d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
415412c595b3SBarry Smith     a->coloring = ocoloring;
415512c595b3SBarry Smith   }
4156cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4157cc8ba8e1SBarry Smith }
4158cc8ba8e1SBarry Smith 
4159dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
4160ee4f033dSBarry Smith EXTERN_C_BEGIN
4161c6db04a5SJed Brown #include <adic/ad_utils.h>
4162ee4f033dSBarry Smith EXTERN_C_END
4163cc8ba8e1SBarry Smith 
4164cc8ba8e1SBarry Smith #undef __FUNCT__
4165ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
4166dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
4167cc8ba8e1SBarry Smith {
4168cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4169d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
41704440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
417108b6dcc0SBarry Smith   ISColoringValue *color;
4172cc8ba8e1SBarry Smith 
4173cc8ba8e1SBarry Smith   PetscFunctionBegin;
4174e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
41754440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
4176cc8ba8e1SBarry Smith   color = a->coloring->colors;
4177cc8ba8e1SBarry Smith   /* loop over rows */
4178cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
4179cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
4180cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
4181cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
4182cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
4183cc8ba8e1SBarry Smith     }
41844440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
4185ee4f033dSBarry Smith   }
4186ee4f033dSBarry Smith   PetscFunctionReturn(0);
4187ee4f033dSBarry Smith }
4188ee4f033dSBarry Smith #endif
4189ee4f033dSBarry Smith 
4190ee4f033dSBarry Smith #undef __FUNCT__
4191ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
419297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4193ee4f033dSBarry Smith {
4194ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4195d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
419654f21887SBarry Smith   MatScalar       *v = a->a;
419754f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
419808b6dcc0SBarry Smith   ISColoringValue *color;
4199ee4f033dSBarry Smith 
4200ee4f033dSBarry Smith   PetscFunctionBegin;
4201e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4202ee4f033dSBarry Smith   color = a->coloring->colors;
4203ee4f033dSBarry Smith   /* loop over rows */
4204ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4205ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4206ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
4207ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
4208ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
4209ee4f033dSBarry Smith     }
4210ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4211cc8ba8e1SBarry Smith   }
4212cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4213cc8ba8e1SBarry Smith }
421436db0b34SBarry Smith 
421581824310SBarry Smith /*
421681824310SBarry Smith     Special version for direct calls from Fortran
421781824310SBarry Smith */
4218c6db04a5SJed Brown #include <private/fortranimpl.h>
421981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
422081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
422181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
422281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
422381824310SBarry Smith #endif
422481824310SBarry Smith 
422581824310SBarry Smith /* Change these macros so can be used in void function */
422681824310SBarry Smith #undef CHKERRQ
42277adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
422881824310SBarry Smith #undef SETERRQ2
4229e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
423081824310SBarry Smith 
423181824310SBarry Smith EXTERN_C_BEGIN
423281824310SBarry Smith #undef __FUNCT__
423381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
42341f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
423581824310SBarry Smith {
423681824310SBarry Smith   Mat            A = *AA;
423781824310SBarry Smith   PetscInt       m = *mm, n = *nn;
423881824310SBarry Smith   InsertMode     is = *isis;
423981824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
424081824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
424181824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
424281824310SBarry Smith   PetscErrorCode ierr;
424381824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
424454f21887SBarry Smith   MatScalar      *ap,value,*aa;
4245ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4246ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
424781824310SBarry Smith 
424881824310SBarry Smith   PetscFunctionBegin;
4249d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
425081824310SBarry Smith   imax = a->imax;
425181824310SBarry Smith   ai = a->i;
425281824310SBarry Smith   ailen = a->ilen;
425381824310SBarry Smith   aj = a->j;
425481824310SBarry Smith   aa = a->a;
425581824310SBarry Smith 
425681824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
425781824310SBarry Smith     row  = im[k];
425881824310SBarry Smith     if (row < 0) continue;
425981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4260d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
426181824310SBarry Smith #endif
426281824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
426381824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
426481824310SBarry Smith     low  = 0;
426581824310SBarry Smith     high = nrow;
426681824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
426781824310SBarry Smith       if (in[l] < 0) continue;
426881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4269d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
427081824310SBarry Smith #endif
427181824310SBarry Smith       col = in[l];
427281824310SBarry Smith       if (roworiented) {
427381824310SBarry Smith         value = v[l + k*n];
427481824310SBarry Smith       } else {
427581824310SBarry Smith         value = v[k + l*m];
427681824310SBarry Smith       }
427781824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
427881824310SBarry Smith 
427981824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
428081824310SBarry Smith       lastcol = col;
428181824310SBarry Smith       while (high-low > 5) {
428281824310SBarry Smith         t = (low+high)/2;
428381824310SBarry Smith         if (rp[t] > col) high = t;
428481824310SBarry Smith         else             low  = t;
428581824310SBarry Smith       }
428681824310SBarry Smith       for (i=low; i<high; i++) {
428781824310SBarry Smith         if (rp[i] > col) break;
428881824310SBarry Smith         if (rp[i] == col) {
428981824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
429081824310SBarry Smith           else                  ap[i] = value;
429181824310SBarry Smith           goto noinsert;
429281824310SBarry Smith         }
429381824310SBarry Smith       }
429481824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
429581824310SBarry Smith       if (nonew == 1) goto noinsert;
42967adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4297fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
429881824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
429981824310SBarry Smith       /* shift up all the later entries in this row */
430081824310SBarry Smith       for (ii=N; ii>=i; ii--) {
430181824310SBarry Smith         rp[ii+1] = rp[ii];
430281824310SBarry Smith         ap[ii+1] = ap[ii];
430381824310SBarry Smith       }
430481824310SBarry Smith       rp[i] = col;
430581824310SBarry Smith       ap[i] = value;
430681824310SBarry Smith       noinsert:;
430781824310SBarry Smith       low = i + 1;
430881824310SBarry Smith     }
430981824310SBarry Smith     ailen[row] = nrow;
431081824310SBarry Smith   }
431181824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
431281824310SBarry Smith   PetscFunctionReturnVoid();
431381824310SBarry Smith }
431481824310SBarry Smith EXTERN_C_END
431562298a1eSBarry Smith 
4316