xref: /petsc/src/mat/impls/aij/seq/aij.c (revision b3a44c855339f9af6d506e42feff5ceb83ffa793)
1992c00aaSSatish Balay #define PETSCMAT_DLL
2b3cc6726SBarry Smith 
3b377110cSBarry Smith 
4d5d45c9bSBarry Smith /*
53369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
6d5d45c9bSBarry Smith   matrix storage format.
7d5d45c9bSBarry Smith */
83369ce9aSBarry Smith 
97c4f633dSBarry Smith 
107c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
11f3da1532SBarry Smith #include "petscblaslapack.h"
120a835dfdSSatish Balay #include "petscbt.h"
1317ab2063SBarry Smith 
144a2ae208SSatish Balay #undef __FUNCT__
15*b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
16*b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
17*b3a44c85SBarry Smith {
18*b3a44c85SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19*b3a44c85SBarry Smith   const MatScalar   *aa;
20*b3a44c85SBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
21*b3a44c85SBarry Smith   const PetscInt    *ii;
22*b3a44c85SBarry Smith   PetscInt          n,i,j,*rows;
23*b3a44c85SBarry Smith   PetscErrorCode    ierr;
24*b3a44c85SBarry Smith 
25*b3a44c85SBarry Smith   PetscFunctionBegin;
26*b3a44c85SBarry Smith   *keptrows = 0;
27*b3a44c85SBarry Smith   ii        = a->i;
28*b3a44c85SBarry Smith   for (i=0; i<m; i++) {
29*b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
30*b3a44c85SBarry Smith     if (!n) {
31*b3a44c85SBarry Smith       cnt++;
32*b3a44c85SBarry Smith       goto ok1;
33*b3a44c85SBarry Smith     }
34*b3a44c85SBarry Smith     aa  = a->a + ii[i];
35*b3a44c85SBarry Smith     for (j=0; j<n; j++) {
36*b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
37*b3a44c85SBarry Smith     }
38*b3a44c85SBarry Smith     cnt++;
39*b3a44c85SBarry Smith     ok1:;
40*b3a44c85SBarry Smith   }
41*b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
42*b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
43*b3a44c85SBarry Smith   cnt  = 0;
44*b3a44c85SBarry Smith   for (i=0; i<m; i++) {
45*b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
46*b3a44c85SBarry Smith     if (!n) continue;
47*b3a44c85SBarry Smith     aa  = a->a + ii[i];
48*b3a44c85SBarry Smith     for (j=0; j<n; j++) {
49*b3a44c85SBarry Smith       if (aa[j] != 0.0) {
50*b3a44c85SBarry Smith         rows[cnt++] = i;
51*b3a44c85SBarry Smith         break;
52*b3a44c85SBarry Smith       }
53*b3a44c85SBarry Smith     }
54*b3a44c85SBarry Smith   }
55*b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
56*b3a44c85SBarry Smith   PetscFunctionReturn(0);
57*b3a44c85SBarry Smith }
58*b3a44c85SBarry Smith 
59*b3a44c85SBarry Smith #undef __FUNCT__
6079299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
617087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
6279299369SBarry Smith {
6379299369SBarry Smith   PetscErrorCode ierr;
6479299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
65d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
6654f21887SBarry Smith   MatScalar      *aa = aij->a;
6754f21887SBarry Smith   PetscScalar    *v;
68ace3abfcSBarry Smith   PetscBool      missing;
6979299369SBarry Smith 
7079299369SBarry Smith   PetscFunctionBegin;
7109f38230SBarry Smith   if (Y->assembled) {
7209f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
7309f38230SBarry Smith     if (!missing) {
7479299369SBarry Smith       diag = aij->diag;
7579299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
7679299369SBarry Smith       if (is == INSERT_VALUES) {
7779299369SBarry Smith 	for (i=0; i<m; i++) {
7879299369SBarry Smith 	  aa[diag[i]] = v[i];
7979299369SBarry Smith 	}
8079299369SBarry Smith       } else {
8179299369SBarry Smith 	for (i=0; i<m; i++) {
8279299369SBarry Smith 	  aa[diag[i]] += v[i];
8379299369SBarry Smith 	}
8479299369SBarry Smith       }
8579299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
8679299369SBarry Smith       PetscFunctionReturn(0);
8779299369SBarry Smith     }
8809f38230SBarry Smith   }
8909f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
9009f38230SBarry Smith   PetscFunctionReturn(0);
9109f38230SBarry Smith }
9279299369SBarry Smith 
9379299369SBarry Smith #undef __FUNCT__
944a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
95ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
9617ab2063SBarry Smith {
97416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98dfbe8321SBarry Smith   PetscErrorCode ierr;
9997f1f81fSBarry Smith   PetscInt       i,ishift;
10017ab2063SBarry Smith 
1013a40ed3dSBarry Smith   PetscFunctionBegin;
102d0f46423SBarry Smith   *m     = A->rmap->n;
1033a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
104bfeeae90SHong Zhang   ishift = 0;
10553e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
106d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
107bfeeae90SHong Zhang   } else if (oshift == 1) {
108d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1093b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
110d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
111d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
112ecc77c7aSBarry Smith     if (ja) {
11397f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
1143b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
115ecc77c7aSBarry Smith     }
1166945ee14SBarry Smith   } else {
117ecc77c7aSBarry Smith     *ia = a->i;
118ecc77c7aSBarry Smith     if (ja) *ja = a->j;
119a2ce50c7SBarry Smith   }
1203a40ed3dSBarry Smith   PetscFunctionReturn(0);
121a2744918SBarry Smith }
122a2744918SBarry Smith 
1234a2ae208SSatish Balay #undef __FUNCT__
1244a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
125ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1266945ee14SBarry Smith {
127dfbe8321SBarry Smith   PetscErrorCode ierr;
1286945ee14SBarry Smith 
1293a40ed3dSBarry Smith   PetscFunctionBegin;
1303a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
131bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
132606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
133ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
134bcd2baecSBarry Smith   }
1353a40ed3dSBarry Smith   PetscFunctionReturn(0);
13617ab2063SBarry Smith }
13717ab2063SBarry Smith 
1384a2ae208SSatish Balay #undef __FUNCT__
1394a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
140ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1413b2fbd54SBarry Smith {
1423b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
143dfbe8321SBarry Smith   PetscErrorCode ierr;
144d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
14597f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
1463b2fbd54SBarry Smith 
1473a40ed3dSBarry Smith   PetscFunctionBegin;
148899cda47SBarry Smith   *nn = n;
1493a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1503b2fbd54SBarry Smith   if (symmetric) {
151d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
1523b2fbd54SBarry Smith   } else {
15397f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
15497f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
15597f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
15697f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
1573b2fbd54SBarry Smith     jj = a->j;
1583b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
159bfeeae90SHong Zhang       collengths[jj[i]]++;
1603b2fbd54SBarry Smith     }
1613b2fbd54SBarry Smith     cia[0] = oshift;
1623b2fbd54SBarry Smith     for (i=0; i<n; i++) {
1633b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1643b2fbd54SBarry Smith     }
16597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
1663b2fbd54SBarry Smith     jj   = a->j;
167a93ec695SBarry Smith     for (row=0; row<m; row++) {
168a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
169a93ec695SBarry Smith       for (i=0; i<mr; i++) {
170bfeeae90SHong Zhang         col = *jj++;
1713b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1723b2fbd54SBarry Smith       }
1733b2fbd54SBarry Smith     }
174606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1753b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1763b2fbd54SBarry Smith   }
1773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1783b2fbd54SBarry Smith }
1793b2fbd54SBarry Smith 
1804a2ae208SSatish Balay #undef __FUNCT__
1814a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
182ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1833b2fbd54SBarry Smith {
184dfbe8321SBarry Smith   PetscErrorCode ierr;
185606d414cSSatish Balay 
1863a40ed3dSBarry Smith   PetscFunctionBegin;
1873a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1883b2fbd54SBarry Smith 
189606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
190606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1913b2fbd54SBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1933b2fbd54SBarry Smith }
1943b2fbd54SBarry Smith 
19587d4246cSBarry Smith #undef __FUNCT__
19687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
19787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
19887d4246cSBarry Smith {
19987d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
20087d4246cSBarry Smith   PetscInt       *ai = a->i;
20187d4246cSBarry Smith   PetscErrorCode ierr;
20287d4246cSBarry Smith 
20387d4246cSBarry Smith   PetscFunctionBegin;
20487d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
20587d4246cSBarry Smith   PetscFunctionReturn(0);
20687d4246cSBarry Smith }
20787d4246cSBarry Smith 
2084a2ae208SSatish Balay #undef __FUNCT__
2094a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
21097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
21117ab2063SBarry Smith {
212416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
213e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
21497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
2156849ba73SBarry Smith   PetscErrorCode ierr;
216e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
21754f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
218ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
219ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
22017ab2063SBarry Smith 
2213a40ed3dSBarry Smith   PetscFunctionBegin;
22271fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
22317ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
224416022c9SBarry Smith     row  = im[k];
2255ef9f2a5SBarry Smith     if (row < 0) continue;
2262515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
227e32f2f54SBarry 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);
2283b2fbd54SBarry Smith #endif
229bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
23017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
231416022c9SBarry Smith     low  = 0;
232c71e6ed7SBarry Smith     high = nrow;
23317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
2345ef9f2a5SBarry Smith       if (in[l] < 0) continue;
2352515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
236e32f2f54SBarry 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);
2373b2fbd54SBarry Smith #endif
238bfeeae90SHong Zhang       col = in[l];
23916371a99SBarry Smith       if (v) {
2404b0e389bSBarry Smith 	if (roworiented) {
2415ef9f2a5SBarry Smith 	  value = v[l + k*n];
242bef8e0ddSBarry Smith 	} else {
2434b0e389bSBarry Smith 	  value = v[k + l*m];
2444b0e389bSBarry Smith 	}
24516371a99SBarry Smith       } else {
24675567043SBarry Smith         value = 0.;
24716371a99SBarry Smith       }
248abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
24936db0b34SBarry Smith 
2507cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
251e2ee6c50SBarry Smith       lastcol = col;
252416022c9SBarry Smith       while (high-low > 5) {
253416022c9SBarry Smith         t = (low+high)/2;
254416022c9SBarry Smith         if (rp[t] > col) high = t;
255416022c9SBarry Smith         else             low  = t;
25617ab2063SBarry Smith       }
257416022c9SBarry Smith       for (i=low; i<high; i++) {
25817ab2063SBarry Smith         if (rp[i] > col) break;
25917ab2063SBarry Smith         if (rp[i] == col) {
260416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
26117ab2063SBarry Smith           else                  ap[i] = value;
262e44c0bd4SBarry Smith           low = i + 1;
26317ab2063SBarry Smith           goto noinsert;
26417ab2063SBarry Smith         }
26517ab2063SBarry Smith       }
266abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
267c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
268e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
269fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
270c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
271416022c9SBarry Smith       /* shift up all the later entries in this row */
272416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
27317ab2063SBarry Smith         rp[ii+1] = rp[ii];
27417ab2063SBarry Smith         ap[ii+1] = ap[ii];
27517ab2063SBarry Smith       }
27617ab2063SBarry Smith       rp[i] = col;
27717ab2063SBarry Smith       ap[i] = value;
278416022c9SBarry Smith       low   = i + 1;
279e44c0bd4SBarry Smith       noinsert:;
28017ab2063SBarry Smith     }
28117ab2063SBarry Smith     ailen[row] = nrow;
28217ab2063SBarry Smith   }
28388e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
2843a40ed3dSBarry Smith   PetscFunctionReturn(0);
28517ab2063SBarry Smith }
28617ab2063SBarry Smith 
28781824310SBarry Smith 
2884a2ae208SSatish Balay #undef __FUNCT__
2894a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
290a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
2917eb43aa7SLois Curfman McInnes {
2927eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
29397f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
29497f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
29554f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
2967eb43aa7SLois Curfman McInnes 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
2987eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2997eb43aa7SLois Curfman McInnes     row  = im[k];
300e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
301e32f2f54SBarry 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);
302bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
3037eb43aa7SLois Curfman McInnes     nrow = ailen[row];
3047eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
305e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
306e32f2f54SBarry 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);
307bfeeae90SHong Zhang       col = in[l] ;
3087eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
3097eb43aa7SLois Curfman McInnes       while (high-low > 5) {
3107eb43aa7SLois Curfman McInnes         t = (low+high)/2;
3117eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
3127eb43aa7SLois Curfman McInnes         else             low  = t;
3137eb43aa7SLois Curfman McInnes       }
3147eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
3157eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
3167eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
317b49de8d1SLois Curfman McInnes           *v++ = ap[i];
3187eb43aa7SLois Curfman McInnes           goto finished;
3197eb43aa7SLois Curfman McInnes         }
3207eb43aa7SLois Curfman McInnes       }
32197e567efSBarry Smith       *v++ = 0.0;
3227eb43aa7SLois Curfman McInnes       finished:;
3237eb43aa7SLois Curfman McInnes     }
3247eb43aa7SLois Curfman McInnes   }
3253a40ed3dSBarry Smith   PetscFunctionReturn(0);
3267eb43aa7SLois Curfman McInnes }
3277eb43aa7SLois Curfman McInnes 
32817ab2063SBarry Smith 
3294a2ae208SSatish Balay #undef __FUNCT__
3304a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
331dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
33217ab2063SBarry Smith {
333416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3346849ba73SBarry Smith   PetscErrorCode ierr;
3356f69ff64SBarry Smith   PetscInt       i,*col_lens;
3366f69ff64SBarry Smith   int            fd;
33717ab2063SBarry Smith 
3383a40ed3dSBarry Smith   PetscFunctionBegin;
339b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
340d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
3410700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
342d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
343d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
344416022c9SBarry Smith   col_lens[3] = a->nz;
345416022c9SBarry Smith 
346416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
347d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
348416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
34917ab2063SBarry Smith   }
350d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
351606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
352416022c9SBarry Smith 
353416022c9SBarry Smith   /* store column indices (zero start index) */
3546f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
355416022c9SBarry Smith 
356416022c9SBarry Smith   /* store nonzero values */
3576f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
3583a40ed3dSBarry Smith   PetscFunctionReturn(0);
35917ab2063SBarry Smith }
360416022c9SBarry Smith 
36109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
362cd155464SBarry Smith 
3634a2ae208SSatish Balay #undef __FUNCT__
3644a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
365dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
366416022c9SBarry Smith {
367416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
368dfbe8321SBarry Smith   PetscErrorCode    ierr;
369d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
370e060cb09SBarry Smith   const char        *name;
371f3ef73ceSBarry Smith   PetscViewerFormat format;
37217ab2063SBarry Smith 
3733a40ed3dSBarry Smith   PetscFunctionBegin;
374b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
37571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
37697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
377d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
378d00d2cf4SBarry Smith       nofinalvalue = 1;
379d00d2cf4SBarry Smith     }
380d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
381d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
38277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
38377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
384b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
38517ab2063SBarry Smith 
38617ab2063SBarry Smith     for (i=0; i<m; i++) {
387416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
388aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
38977431f27SBarry 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);
39017ab2063SBarry Smith #else
39177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
39217ab2063SBarry Smith #endif
39317ab2063SBarry Smith       }
39417ab2063SBarry Smith     }
395d00d2cf4SBarry Smith     if (nofinalvalue) {
396d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
397d00d2cf4SBarry Smith     }
398317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
399fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
400d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
40168369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
402cd155464SBarry Smith      PetscFunctionReturn(0);
403fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
404d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4057566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
40644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
40777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
40844cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
409aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
41036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
411a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
41236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
413a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
41436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
415a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
4166831982aSBarry Smith         }
41744cd7ae7SLois Curfman McInnes #else
418a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
41944cd7ae7SLois Curfman McInnes #endif
42044cd7ae7SLois Curfman McInnes       }
421b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42244cd7ae7SLois Curfman McInnes     }
423d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
424fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
42597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
426d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4277566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
42897f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
429496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
430496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
431496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
432496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
433aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
43436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
435496be53dSLois Curfman McInnes #else
436496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
437496be53dSLois Curfman McInnes #endif
438496be53dSLois Curfman McInnes         }
439496be53dSLois Curfman McInnes       }
440496be53dSLois Curfman McInnes     }
4412e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
44277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
4432e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
44477431f27SBarry 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);}
44577431f27SBarry 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);}
44677431f27SBarry 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);}
44777431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
44877431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
44977431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
450496be53dSLois Curfman McInnes     }
451b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
452606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
453496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
454496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
45577431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
456496be53dSLois Curfman McInnes       }
457b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
458496be53dSLois Curfman McInnes     }
459b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
460496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
461496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
462496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
463aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
465b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4666831982aSBarry Smith           }
467496be53dSLois Curfman McInnes #else
468b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
469496be53dSLois Curfman McInnes #endif
470496be53dSLois Curfman McInnes         }
471496be53dSLois Curfman McInnes       }
472b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
473496be53dSLois Curfman McInnes     }
474d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
475fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
47697f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
47787828ca2SBarry Smith     PetscScalar value;
47802594712SBarry Smith 
479d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4807566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
48102594712SBarry Smith     for (i=0; i<m; i++) {
48202594712SBarry Smith       jcnt = 0;
483d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
484e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
48502594712SBarry Smith           value = a->a[cnt++];
486e24b481bSBarry Smith           jcnt++;
48702594712SBarry Smith         } else {
48802594712SBarry Smith           value = 0.0;
48902594712SBarry Smith         }
490aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
491b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
49202594712SBarry Smith #else
493b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
49402594712SBarry Smith #endif
49502594712SBarry Smith       }
496b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
49702594712SBarry Smith     }
498d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
4993c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
500d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5017566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
5023c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5033c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
5043c215bfdSMatthew Knepley #else
5053c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
5063c215bfdSMatthew Knepley #endif
507d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
5083c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
5093c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5103c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5113c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
5123c215bfdSMatthew 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);
5133c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
5143c215bfdSMatthew 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);
5153c215bfdSMatthew Knepley         } else {
5163c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5173c215bfdSMatthew Knepley         }
5183c215bfdSMatthew Knepley #else
5193c215bfdSMatthew Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr);
5203c215bfdSMatthew Knepley #endif
5213c215bfdSMatthew Knepley       }
5223c215bfdSMatthew Knepley     }
523d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5243a40ed3dSBarry Smith   } else {
525d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5267566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
527d5f3da31SBarry Smith     if (A->factortype){
52816cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
52916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
53016cd7e1dSShri Abhyankar         /* L part */
53116cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
53216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
53316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
53416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
53516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
53616cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
53716cd7e1dSShri Abhyankar           } else {
53816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
53916cd7e1dSShri Abhyankar           }
54016cd7e1dSShri Abhyankar #else
54116cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
54216cd7e1dSShri Abhyankar #endif
54316cd7e1dSShri Abhyankar         }
54416cd7e1dSShri Abhyankar 	/* diagonal */
54516cd7e1dSShri Abhyankar 	j = a->diag[i];
54616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
54716cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
54816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
54916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
55016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
55116cd7e1dSShri Abhyankar           } else {
55216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
55316cd7e1dSShri Abhyankar           }
55416cd7e1dSShri Abhyankar #else
55516cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
55616cd7e1dSShri Abhyankar #endif
55716cd7e1dSShri Abhyankar 
55816cd7e1dSShri Abhyankar 	/* U part */
55916cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
56016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
56116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
56216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
56416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56516cd7e1dSShri Abhyankar           } else {
56616cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
56716cd7e1dSShri Abhyankar           }
56816cd7e1dSShri Abhyankar #else
56916cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
57016cd7e1dSShri Abhyankar #endif
57116cd7e1dSShri Abhyankar }
57216cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57316cd7e1dSShri Abhyankar         }
57416cd7e1dSShri Abhyankar     } else {
57517ab2063SBarry Smith       for (i=0; i<m; i++) {
57677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
577416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
578aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
57936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
580a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
58136db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
582a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
5833a40ed3dSBarry Smith           } else {
584a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
58517ab2063SBarry Smith           }
58617ab2063SBarry Smith #else
587a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
58817ab2063SBarry Smith #endif
58917ab2063SBarry Smith         }
590b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
59117ab2063SBarry Smith       }
59216cd7e1dSShri Abhyankar     }
593d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
59417ab2063SBarry Smith   }
595b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
5963a40ed3dSBarry Smith   PetscFunctionReturn(0);
597416022c9SBarry Smith }
598416022c9SBarry Smith 
5994a2ae208SSatish Balay #undef __FUNCT__
6004a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
601dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
602416022c9SBarry Smith {
603480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
604416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
605dfbe8321SBarry Smith   PetscErrorCode    ierr;
606d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
60736db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
608b0a32e0cSBarry Smith   PetscViewer       viewer;
609f3ef73ceSBarry Smith   PetscViewerFormat format;
610cddf8d76SBarry Smith 
6113a40ed3dSBarry Smith   PetscFunctionBegin;
612480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
613b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
61419bcc07fSBarry Smith 
615b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
616416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
6170513a670SBarry Smith 
618fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
6190513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
620b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
621416022c9SBarry Smith     for (i=0; i<m; i++) {
622cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
623bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
624bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
625aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
627cddf8d76SBarry Smith #else
628cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
629cddf8d76SBarry Smith #endif
630b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
631cddf8d76SBarry Smith       }
632cddf8d76SBarry Smith     }
633b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
634cddf8d76SBarry Smith     for (i=0; i<m; i++) {
635cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
636bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
637bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
638cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
639b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
640cddf8d76SBarry Smith       }
641cddf8d76SBarry Smith     }
642b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
643cddf8d76SBarry Smith     for (i=0; i<m; i++) {
644cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
645bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
646bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
647aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
649cddf8d76SBarry Smith #else
650cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
651cddf8d76SBarry Smith #endif
652b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
653416022c9SBarry Smith       }
654416022c9SBarry Smith     }
6550513a670SBarry Smith   } else {
6560513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
6570513a670SBarry Smith     /* first determine max of all nonzero values */
65897f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
659b0a32e0cSBarry Smith     PetscDraw   popup;
66036db0b34SBarry Smith     PetscReal scale;
6610513a670SBarry Smith 
6620513a670SBarry Smith     for (i=0; i<nz; i++) {
6630513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
6640513a670SBarry Smith     }
665b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
666b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
667b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
6680513a670SBarry Smith     count = 0;
6690513a670SBarry Smith     for (i=0; i<m; i++) {
6700513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
671bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
672bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
67397f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
674b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
6750513a670SBarry Smith         count++;
6760513a670SBarry Smith       }
6770513a670SBarry Smith     }
6780513a670SBarry Smith   }
679480ef9eaSBarry Smith   PetscFunctionReturn(0);
680480ef9eaSBarry Smith }
681cddf8d76SBarry Smith 
6824a2ae208SSatish Balay #undef __FUNCT__
6834a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
684dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
685480ef9eaSBarry Smith {
686dfbe8321SBarry Smith   PetscErrorCode ierr;
687b0a32e0cSBarry Smith   PetscDraw      draw;
68836db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
689ace3abfcSBarry Smith   PetscBool      isnull;
690480ef9eaSBarry Smith 
691480ef9eaSBarry Smith   PetscFunctionBegin;
692b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
693b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
694480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
695480ef9eaSBarry Smith 
696480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
697d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
698480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
699b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
700b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
701480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7023a40ed3dSBarry Smith   PetscFunctionReturn(0);
703416022c9SBarry Smith }
704416022c9SBarry Smith 
7054a2ae208SSatish Balay #undef __FUNCT__
7064a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
707dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
708416022c9SBarry Smith {
709dfbe8321SBarry Smith   PetscErrorCode ierr;
710ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
711416022c9SBarry Smith 
7123a40ed3dSBarry Smith   PetscFunctionBegin;
7132692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
7142692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
7152692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
716c45a1595SBarry Smith   if (iascii) {
7173a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7180f5bd95cSBarry Smith   } else if (isbinary) {
7193a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
7200f5bd95cSBarry Smith   } else if (isdraw) {
7213a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
7225cd90555SBarry Smith   } else {
723e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
72417ab2063SBarry Smith   }
7254108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
7263a40ed3dSBarry Smith   PetscFunctionReturn(0);
72717ab2063SBarry Smith }
72819bcc07fSBarry Smith 
7294a2ae208SSatish Balay #undef __FUNCT__
7304a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
731dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
73217ab2063SBarry Smith {
733416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7346849ba73SBarry Smith   PetscErrorCode ierr;
73597f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
736d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
73754f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
7383447b6efSHong Zhang   PetscReal      ratio=0.6;
73917ab2063SBarry Smith 
7403a40ed3dSBarry Smith   PetscFunctionBegin;
7413a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
74217ab2063SBarry Smith 
74343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
74417ab2063SBarry Smith   for (i=1; i<m; i++) {
745416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
74617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
74794a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
74817ab2063SBarry Smith     if (fshift) {
749bfeeae90SHong Zhang       ip = aj + ai[i] ;
750bfeeae90SHong Zhang       ap = aa + ai[i] ;
75117ab2063SBarry Smith       N  = ailen[i];
75217ab2063SBarry Smith       for (j=0; j<N; j++) {
75317ab2063SBarry Smith         ip[j-fshift] = ip[j];
75417ab2063SBarry Smith         ap[j-fshift] = ap[j];
75517ab2063SBarry Smith       }
75617ab2063SBarry Smith     }
75717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
75817ab2063SBarry Smith   }
75917ab2063SBarry Smith   if (m) {
76017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
76117ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
76217ab2063SBarry Smith   }
76317ab2063SBarry Smith   /* reset ilen and imax for each row */
76417ab2063SBarry Smith   for (i=0; i<m; i++) {
76517ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
76617ab2063SBarry Smith   }
767bfeeae90SHong Zhang   a->nz = ai[m];
76865e19b50SBarry 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);
76917ab2063SBarry Smith 
77009f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
771d0f46423SBarry 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);
772ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
773ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
7748e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
775dd5f02e7SSatish Balay   a->reallocs          = 0;
7764e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
77736db0b34SBarry Smith   a->rmax              = rmax;
7784e220ebcSLois Curfman McInnes 
779cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
78088e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
78171c2f376SKris Buschelman 
7824108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
78371f1c65dSBarry Smith 
78471f1c65dSBarry Smith   a->idiagvalid = PETSC_FALSE;
7853a40ed3dSBarry Smith   PetscFunctionReturn(0);
78617ab2063SBarry Smith }
78717ab2063SBarry Smith 
7884a2ae208SSatish Balay #undef __FUNCT__
78999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
79099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
79199cafbc1SBarry Smith {
79299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
79399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
79454f21887SBarry Smith   MatScalar      *aa = a->a;
79599cafbc1SBarry Smith 
79699cafbc1SBarry Smith   PetscFunctionBegin;
79799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
79899cafbc1SBarry Smith   PetscFunctionReturn(0);
79999cafbc1SBarry Smith }
80099cafbc1SBarry Smith 
80199cafbc1SBarry Smith #undef __FUNCT__
80299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
80399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
80499cafbc1SBarry Smith {
80599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
80699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
80754f21887SBarry Smith   MatScalar      *aa = a->a;
80899cafbc1SBarry Smith 
80999cafbc1SBarry Smith   PetscFunctionBegin;
81099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
81199cafbc1SBarry Smith   PetscFunctionReturn(0);
81299cafbc1SBarry Smith }
81399cafbc1SBarry Smith 
81499cafbc1SBarry Smith #undef __FUNCT__
8154a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
816dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
81717ab2063SBarry Smith {
818416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
819dfbe8321SBarry Smith   PetscErrorCode ierr;
8203a40ed3dSBarry Smith 
8213a40ed3dSBarry Smith   PetscFunctionBegin;
822d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
8233a40ed3dSBarry Smith   PetscFunctionReturn(0);
82417ab2063SBarry Smith }
825416022c9SBarry Smith 
8264a2ae208SSatish Balay #undef __FUNCT__
8274a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
828dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
82917ab2063SBarry Smith {
830416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
831dfbe8321SBarry Smith   PetscErrorCode ierr;
832d5d45c9bSBarry Smith 
8333a40ed3dSBarry Smith   PetscFunctionBegin;
834aa482453SBarry Smith #if defined(PETSC_USE_LOG)
835d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
83617ab2063SBarry Smith #endif
837e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
838c38d4ed2SBarry Smith   if (a->row) {
839c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
840c38d4ed2SBarry Smith   }
841c38d4ed2SBarry Smith   if (a->col) {
842c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
843c38d4ed2SBarry Smith   }
84405b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
84505b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
84671f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
84705b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
84882bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
84905b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
850cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
85105b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
852407f6b05SHong Zhang   if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);}
853cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
854a30b2313SHong Zhang 
8554108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
8564846f1f5SKris Buschelman 
857606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
858901853e0SKris Buschelman 
859dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
860901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
861901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
862901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
863901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
864901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
8655a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
866901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
867901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
868a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
869901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
8703a40ed3dSBarry Smith   PetscFunctionReturn(0);
87117ab2063SBarry Smith }
87217ab2063SBarry Smith 
8734a2ae208SSatish Balay #undef __FUNCT__
8744a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
875ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
87617ab2063SBarry Smith {
877416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8784846f1f5SKris Buschelman   PetscErrorCode ierr;
8793a40ed3dSBarry Smith 
8803a40ed3dSBarry Smith   PetscFunctionBegin;
881a65d3064SKris Buschelman   switch (op) {
882a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
8834e0d8c25SBarry Smith       a->roworiented       = flg;
884a65d3064SKris Buschelman       break;
885a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
886a9817697SBarry Smith       a->keepnonzeropattern    = flg;
887a65d3064SKris Buschelman       break;
888512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
889512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
890a65d3064SKris Buschelman       break;
891a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
8924e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
893a65d3064SKris Buschelman       break;
894a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
8954e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
896a65d3064SKris Buschelman       break;
89728b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
89828b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
89928b2fa4aSMatthew Knepley       break;
900a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
9014e0d8c25SBarry Smith       a->ignorezeroentries = flg;
9020df259c2SBarry Smith       break;
903cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
904cd6b891eSBarry Smith       a->compressedrow.check = flg;
905d487561eSHong Zhang       break;
9063d472b54SHong Zhang     case MAT_SPD:
9073d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
9083d472b54SHong Zhang       A->spd                             = flg;
9093d472b54SHong Zhang       if (flg) {
9103d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
9113d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
9123d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
9133d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
9143d472b54SHong Zhang       }
9153d472b54SHong Zhang       break;
916b1646e73SJed Brown     case MAT_SYMMETRIC:
917b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
918b1646e73SJed Brown     case MAT_HERMITIAN:
919b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
9204e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
921a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
922a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
923290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
924a65d3064SKris Buschelman       break;
925b87ac2d8SJed Brown     case MAT_USE_INODES:
926b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
927b87ac2d8SJed Brown       break;
928a65d3064SKris Buschelman     default:
929e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
930a65d3064SKris Buschelman   }
9314108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
9323a40ed3dSBarry Smith   PetscFunctionReturn(0);
93317ab2063SBarry Smith }
93417ab2063SBarry Smith 
9354a2ae208SSatish Balay #undef __FUNCT__
9364a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
937dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
93817ab2063SBarry Smith {
939416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9406849ba73SBarry Smith   PetscErrorCode ierr;
941d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
94235e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
94317ab2063SBarry Smith 
9443a40ed3dSBarry Smith   PetscFunctionBegin;
945d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
946e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
94735e7444dSHong Zhang 
948d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
949d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
95035e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
95135e7444dSHong Zhang     for (i=0; i<n; i++) x[i] = aa[diag[i]];
95235e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
95335e7444dSHong Zhang     PetscFunctionReturn(0);
95435e7444dSHong Zhang   }
95535e7444dSHong Zhang 
9562dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
9571ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
95835e7444dSHong Zhang   for (i=0; i<n; i++) {
95935e7444dSHong Zhang     nz = ai[i+1] - ai[i];
9602f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
96135e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
96235e7444dSHong Zhang       if (aj[j] == i) {
96335e7444dSHong Zhang         x[i] = aa[j];
96417ab2063SBarry Smith         break;
96517ab2063SBarry Smith       }
96617ab2063SBarry Smith     }
96717ab2063SBarry Smith   }
9681ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
9693a40ed3dSBarry Smith   PetscFunctionReturn(0);
97017ab2063SBarry Smith }
97117ab2063SBarry Smith 
972b377110cSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h"
9734a2ae208SSatish Balay #undef __FUNCT__
9744a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
975dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
97617ab2063SBarry Smith {
977416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
9785c897100SBarry Smith   PetscScalar       *x,*y;
979dfbe8321SBarry Smith   PetscErrorCode    ierr;
980d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
9815c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
982a77337e4SBarry Smith   MatScalar         *v;
983a77337e4SBarry Smith   PetscScalar       alpha;
98404fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
9853447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
986ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
9875c897100SBarry Smith #endif
98817ab2063SBarry Smith 
9893a40ed3dSBarry Smith   PetscFunctionBegin;
9902e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
9911ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
9921ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9935c897100SBarry Smith 
9945c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
995bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
9965c897100SBarry Smith #else
9973447b6efSHong Zhang   if (usecprow){
9983447b6efSHong Zhang     m    = cprow.nrows;
9993447b6efSHong Zhang     ii   = cprow.i;
10007b2bb3b9SHong Zhang     ridx = cprow.rindex;
10013447b6efSHong Zhang   } else {
10023447b6efSHong Zhang     ii = a->i;
10033447b6efSHong Zhang   }
100417ab2063SBarry Smith   for (i=0; i<m; i++) {
10053447b6efSHong Zhang     idx   = a->j + ii[i] ;
10063447b6efSHong Zhang     v     = a->a + ii[i] ;
10073447b6efSHong Zhang     n     = ii[i+1] - ii[i];
10083447b6efSHong Zhang     if (usecprow){
10097b2bb3b9SHong Zhang       alpha = x[ridx[i]];
10103447b6efSHong Zhang     } else {
101117ab2063SBarry Smith       alpha = x[i];
10123447b6efSHong Zhang     }
101304fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
101417ab2063SBarry Smith   }
10155c897100SBarry Smith #endif
1016dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
10171ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10181ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10193a40ed3dSBarry Smith   PetscFunctionReturn(0);
102017ab2063SBarry Smith }
102117ab2063SBarry Smith 
10224a2ae208SSatish Balay #undef __FUNCT__
10235c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1024dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
10255c897100SBarry Smith {
1026dfbe8321SBarry Smith   PetscErrorCode ierr;
10275c897100SBarry Smith 
10285c897100SBarry Smith   PetscFunctionBegin;
1029170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
10305c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
10315c897100SBarry Smith   PetscFunctionReturn(0);
10325c897100SBarry Smith }
10335c897100SBarry Smith 
1034a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmult.h"
10355c897100SBarry Smith #undef __FUNCT__
10364a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1037dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
103817ab2063SBarry Smith {
1039416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1040d9fead3dSBarry Smith   PetscScalar       *y;
104154f21887SBarry Smith   const PetscScalar *x;
104254f21887SBarry Smith   const MatScalar   *aa;
1043dfbe8321SBarry Smith   PetscErrorCode    ierr;
1044003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1045003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
10468aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1047362ced78SSatish Balay   PetscScalar       sum;
1048ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
104917ab2063SBarry Smith 
1050b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
105197952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1052fee21e36SBarry Smith #endif
1053fee21e36SBarry Smith 
10543a40ed3dSBarry Smith   PetscFunctionBegin;
10553649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10561ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
105797952fefSHong Zhang   aj  = a->j;
105897952fefSHong Zhang   aa  = a->a;
1059416022c9SBarry Smith   ii  = a->i;
10604eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
106197952fefSHong Zhang     m    = a->compressedrow.nrows;
106297952fefSHong Zhang     ii   = a->compressedrow.i;
106397952fefSHong Zhang     ridx = a->compressedrow.rindex;
106497952fefSHong Zhang     for (i=0; i<m; i++){
106597952fefSHong Zhang       n   = ii[i+1] - ii[i];
106697952fefSHong Zhang       aj  = a->j + ii[i];
106797952fefSHong Zhang       aa  = a->a + ii[i];
106897952fefSHong Zhang       sum = 0.0;
1069a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1070003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1071003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
107297952fefSHong Zhang       y[*ridx++] = sum;
107397952fefSHong Zhang     }
107497952fefSHong Zhang   } else { /* do not use compressed row format */
1075b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1076b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1077b05257ddSBarry Smith #else
107817ab2063SBarry Smith     for (i=0; i<m; i++) {
1079003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1080003131ecSBarry Smith       aj  = a->j + ii[i];
1081003131ecSBarry Smith       aa  = a->a + ii[i];
108217ab2063SBarry Smith       sum  = 0.0;
1083a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1084003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
108517ab2063SBarry Smith       y[i] = sum;
108617ab2063SBarry Smith     }
10878d195f9aSBarry Smith #endif
1088b05257ddSBarry Smith   }
1089dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
10903649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
10911ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10923a40ed3dSBarry Smith   PetscFunctionReturn(0);
109317ab2063SBarry Smith }
109417ab2063SBarry Smith 
1095a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h"
10964a2ae208SSatish Balay #undef __FUNCT__
10974a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1098dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
109917ab2063SBarry Smith {
1100416022c9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
110154f21887SBarry Smith   PetscScalar     *x,*y,*z;
110254f21887SBarry Smith   const MatScalar *aa;
1103dfbe8321SBarry Smith   PetscErrorCode  ierr;
1104d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1105aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
110697952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1107362ced78SSatish Balay   PetscScalar     sum;
1108ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1109e36a17ebSSatish Balay #endif
11109ea0dfa2SSatish Balay 
11113a40ed3dSBarry Smith   PetscFunctionBegin;
11121ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11131ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11142e8a6d31SBarry Smith   if (zz != yy) {
11151ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
11162e8a6d31SBarry Smith   } else {
11172e8a6d31SBarry Smith     z = y;
11182e8a6d31SBarry Smith   }
1119bfeeae90SHong Zhang 
112097952fefSHong Zhang   aj  = a->j;
112197952fefSHong Zhang   aa  = a->a;
1122cddf8d76SBarry Smith   ii  = a->i;
1123aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
112497952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
112502ab625aSSatish Balay #else
11264eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
11274eb6d288SHong Zhang     if (zz != yy){
11284eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
11294eb6d288SHong Zhang     }
113097952fefSHong Zhang     m    = a->compressedrow.nrows;
113197952fefSHong Zhang     ii   = a->compressedrow.i;
113297952fefSHong Zhang     ridx = a->compressedrow.rindex;
113397952fefSHong Zhang     for (i=0; i<m; i++){
113497952fefSHong Zhang       n  = ii[i+1] - ii[i];
113597952fefSHong Zhang       aj  = a->j + ii[i];
113697952fefSHong Zhang       aa  = a->a + ii[i];
113797952fefSHong Zhang       sum = y[*ridx];
113897952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
113997952fefSHong Zhang       z[*ridx++] = sum;
114097952fefSHong Zhang     }
114197952fefSHong Zhang   } else { /* do not use compressed row format */
114217ab2063SBarry Smith     for (i=0; i<m; i++) {
11439ea0dfa2SSatish Balay       jrow = ii[i];
11449ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
114517ab2063SBarry Smith       sum  = y[i];
11469ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
114797952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
11489ea0dfa2SSatish Balay       }
114917ab2063SBarry Smith       z[i] = sum;
115017ab2063SBarry Smith     }
115197952fefSHong Zhang   }
115202ab625aSSatish Balay #endif
1153dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11541ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11551ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11562e8a6d31SBarry Smith   if (zz != yy) {
11571ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
11582e8a6d31SBarry Smith   }
1159918e98c3SVictor Minden #if defined(PETSC_HAVE_CUDA)
11606b375ea7SVictor Minden   /*
1161918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1162918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1163918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
11646b375ea7SVictor Minden   */
1165918e98c3SVictor Minden #endif
11663a40ed3dSBarry Smith   PetscFunctionReturn(0);
116717ab2063SBarry Smith }
116817ab2063SBarry Smith 
116917ab2063SBarry Smith /*
117017ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
117117ab2063SBarry Smith */
11724a2ae208SSatish Balay #undef __FUNCT__
11734a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1174dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
117517ab2063SBarry Smith {
1176416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11776849ba73SBarry Smith   PetscErrorCode ierr;
1178d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
117917ab2063SBarry Smith 
11803a40ed3dSBarry Smith   PetscFunctionBegin;
118109f38230SBarry Smith   if (!a->diag) {
118209f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
11839518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
118409f38230SBarry Smith   }
1185d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
118609f38230SBarry Smith     a->diag[i] = a->i[i+1];
1187bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1188bfeeae90SHong Zhang       if (a->j[j] == i) {
118909f38230SBarry Smith         a->diag[i] = j;
119017ab2063SBarry Smith         break;
119117ab2063SBarry Smith       }
119217ab2063SBarry Smith     }
119317ab2063SBarry Smith   }
11943a40ed3dSBarry Smith   PetscFunctionReturn(0);
119517ab2063SBarry Smith }
119617ab2063SBarry Smith 
1197be5855fcSBarry Smith /*
1198be5855fcSBarry Smith      Checks for missing diagonals
1199be5855fcSBarry Smith */
12004a2ae208SSatish Balay #undef __FUNCT__
12014a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1202ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1203be5855fcSBarry Smith {
1204be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
120597f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1206be5855fcSBarry Smith 
1207be5855fcSBarry Smith   PetscFunctionBegin;
120809f38230SBarry Smith   *missing = PETSC_FALSE;
1209d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
121009f38230SBarry Smith     *missing  = PETSC_TRUE;
121109f38230SBarry Smith     if (d) *d = 0;
121209f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
121309f38230SBarry Smith   } else {
1214f1e2ffcdSBarry Smith     diag = a->diag;
1215d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1216bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
121709f38230SBarry Smith 	*missing = PETSC_TRUE;
121809f38230SBarry Smith 	if (d) *d = i;
121909f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
122009f38230SBarry Smith       }
1221be5855fcSBarry Smith     }
1222be5855fcSBarry Smith   }
1223be5855fcSBarry Smith   PetscFunctionReturn(0);
1224be5855fcSBarry Smith }
1225be5855fcSBarry Smith 
122671f1c65dSBarry Smith EXTERN_C_BEGIN
122771f1c65dSBarry Smith #undef __FUNCT__
122871f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
12297087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
123071f1c65dSBarry Smith {
123171f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
123271f1c65dSBarry Smith   PetscErrorCode ierr;
1233d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
123454f21887SBarry Smith   MatScalar      *v = a->a;
123554f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
123671f1c65dSBarry Smith 
123771f1c65dSBarry Smith   PetscFunctionBegin;
123871f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
123971f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
124071f1c65dSBarry Smith   diag = a->diag;
124171f1c65dSBarry Smith   if (!a->idiag) {
124271f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
124371f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
124471f1c65dSBarry Smith     v        = a->a;
124571f1c65dSBarry Smith   }
124671f1c65dSBarry Smith   mdiag = a->mdiag;
124771f1c65dSBarry Smith   idiag = a->idiag;
124871f1c65dSBarry Smith 
1249028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
125071f1c65dSBarry Smith     for (i=0; i<m; i++) {
125171f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1252e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
125371f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
125471f1c65dSBarry Smith     }
125571f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
125671f1c65dSBarry Smith   } else {
125771f1c65dSBarry Smith     for (i=0; i<m; i++) {
125871f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
125971f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
126071f1c65dSBarry Smith     }
1261dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
126271f1c65dSBarry Smith   }
126371f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
126471f1c65dSBarry Smith   PetscFunctionReturn(0);
126571f1c65dSBarry Smith }
12665a9745a3SMatthew Knepley EXTERN_C_END
126771f1c65dSBarry Smith 
1268a4005a5dSBarry Smith #include "../src/mat/impls/aij/seq/ftn-kernels/frelax.h"
12694a2ae208SSatish Balay #undef __FUNCT__
127041f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
127141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
127217ab2063SBarry Smith {
1273416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1274e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1275e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
127654f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1277dfbe8321SBarry Smith   PetscErrorCode     ierr;
1278d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
127997f1f81fSBarry Smith   const PetscInt     *idx,*diag;
128017ab2063SBarry Smith 
12813a40ed3dSBarry Smith   PetscFunctionBegin;
1282b965ef7fSBarry Smith   its = its*lits;
128391723122SBarry Smith 
128471f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
128571f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
128671f1c65dSBarry Smith   a->fshift = fshift;
128771f1c65dSBarry Smith   a->omega  = omega;
1288ed480e8bSBarry Smith 
128971f1c65dSBarry Smith   diag = a->diag;
129071f1c65dSBarry Smith   t     = a->ssor_work;
1291ed480e8bSBarry Smith   idiag = a->idiag;
129271f1c65dSBarry Smith   mdiag = a->mdiag;
1293ed480e8bSBarry Smith 
12941ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
12953649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
129671f1c65dSBarry Smith   CHKMEMQ;
1297ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
129817ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
129917ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1300ed480e8bSBarry Smith     bs = b;
130117ab2063SBarry Smith     for (i=0; i<m; i++) {
130271f1c65dSBarry Smith         d    = fshift + mdiag[i];
1303416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1304ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1305ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
130617ab2063SBarry Smith         sum  = b[i]*d/omega;
1307003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
130817ab2063SBarry Smith         x[i] = sum;
130917ab2063SBarry Smith     }
13101ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13113649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1312efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13133a40ed3dSBarry Smith     PetscFunctionReturn(0);
131417ab2063SBarry Smith   }
1315c783ea89SBarry Smith 
131648af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1317e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
13183a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
131917ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1320887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
132117ab2063SBarry Smith 
132217ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
132317ab2063SBarry Smith 
1324887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
132517ab2063SBarry Smith     */
132617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
132717ab2063SBarry Smith 
132817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
132917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1330416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1331ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1332ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
133317ab2063SBarry Smith       sum  = b[i];
1334e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1335ed480e8bSBarry Smith       x[i] = sum*idiag[i];
133617ab2063SBarry Smith     }
133717ab2063SBarry Smith 
133817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1339416022c9SBarry Smith     v = a->a;
1340ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
134117ab2063SBarry Smith 
134217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1343ed480e8bSBarry Smith     ts = t;
1344416022c9SBarry Smith     diag = a->diag;
134517ab2063SBarry Smith     for (i=0; i<m; i++) {
1346416022c9SBarry Smith       n    = diag[i] - a->i[i];
1347ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1348ed480e8bSBarry Smith       v    = a->a + a->i[i];
134917ab2063SBarry Smith       sum  = t[i];
1350003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1351ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1352733d66baSBarry Smith       /*  x = x + t */
1353733d66baSBarry Smith       x[i] += t[i];
135417ab2063SBarry Smith     }
135517ab2063SBarry Smith 
1356dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
13571ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13583649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
13593a40ed3dSBarry Smith     PetscFunctionReturn(0);
136017ab2063SBarry Smith   }
136117ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
136217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
136317ab2063SBarry Smith       for (i=0; i<m; i++) {
1364416022c9SBarry Smith         n    = diag[i] - a->i[i];
1365ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1366ed480e8bSBarry Smith         v    = a->a + a->i[i];
136717ab2063SBarry Smith         sum  = b[i];
1368e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13695c99c7daSBarry Smith         t[i] = sum;
1370ed480e8bSBarry Smith         x[i] = sum*idiag[i];
137117ab2063SBarry Smith       }
13725c99c7daSBarry Smith       xb = t;
1373efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13743a40ed3dSBarry Smith     } else xb = b;
137517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
137617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1377416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1378ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1379ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
138017ab2063SBarry Smith         sum  = xb[i];
1381e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13825c99c7daSBarry Smith         if (xb == b) {
1383ed480e8bSBarry Smith           x[i] = sum*idiag[i];
13845c99c7daSBarry Smith         } else {
13855c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
138617ab2063SBarry Smith         }
13875c99c7daSBarry Smith       }
1388efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
138917ab2063SBarry Smith     }
139017ab2063SBarry Smith     its--;
139117ab2063SBarry Smith   }
139217ab2063SBarry Smith   while (its--) {
139317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
139417ab2063SBarry Smith       for (i=0; i<m; i++) {
1395416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1396ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1397ed480e8bSBarry Smith         v    = a->a + a->i[i];
139817ab2063SBarry Smith         sum  = b[i];
1399e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1400ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
140117ab2063SBarry Smith       }
14029f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
140317ab2063SBarry Smith     }
140417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
140517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1406416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1407ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1408ed480e8bSBarry Smith         v    = a->a + a->i[i];
140917ab2063SBarry Smith         sum  = b[i];
1410e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1411ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
141217ab2063SBarry Smith       }
14139f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
141417ab2063SBarry Smith     }
141517ab2063SBarry Smith   }
14161ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14173649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
141871f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
141917ab2063SBarry Smith }
142017ab2063SBarry Smith 
14212af78befSBarry Smith 
14224a2ae208SSatish Balay #undef __FUNCT__
14234a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1424dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
142517ab2063SBarry Smith {
1426416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14274e220ebcSLois Curfman McInnes 
14283a40ed3dSBarry Smith   PetscFunctionBegin;
14294e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
14304e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
14314e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
14324e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
14334e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
14348e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
14357adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1436d5f3da31SBarry Smith   if (A->factortype) {
14374e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
14384e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
14394e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
14404e220ebcSLois Curfman McInnes   } else {
14414e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
14424e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
14434e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
14444e220ebcSLois Curfman McInnes   }
14453a40ed3dSBarry Smith   PetscFunctionReturn(0);
144617ab2063SBarry Smith }
144717ab2063SBarry Smith 
14484a2ae208SSatish Balay #undef __FUNCT__
14494a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
14502b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
145117ab2063SBarry Smith {
1452416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14533b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
14546849ba73SBarry Smith   PetscErrorCode    ierr;
145597b48c8fSBarry Smith   const PetscScalar *xx;
145697b48c8fSBarry Smith   PetscScalar       *bb;
1457ace3abfcSBarry Smith   PetscBool         missing;
145817ab2063SBarry Smith 
14593a40ed3dSBarry Smith   PetscFunctionBegin;
146097b48c8fSBarry Smith   if (x && b) {
146197b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
146297b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
146397b48c8fSBarry Smith     for (i=0; i<N; i++) {
146497b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
146597b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
146697b48c8fSBarry Smith     }
146797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
146897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
146997b48c8fSBarry Smith   }
147097b48c8fSBarry Smith 
1471a9817697SBarry Smith   if (a->keepnonzeropattern) {
1472f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1473e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1474bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1475f1e2ffcdSBarry Smith     }
1476f4df32b1SMatthew Knepley     if (diag != 0.0) {
147709f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1478e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1479f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1480f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1481f1e2ffcdSBarry Smith       }
1482f1e2ffcdSBarry Smith     }
148388e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1484f1e2ffcdSBarry Smith   } else {
1485f4df32b1SMatthew Knepley     if (diag != 0.0) {
148617ab2063SBarry Smith       for (i=0; i<N; i++) {
1487e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
14887ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1489416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1490f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1491bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
14927ae801bdSBarry Smith         } else { /* in case row was completely empty */
1493f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
149417ab2063SBarry Smith         }
149517ab2063SBarry Smith       }
14963a40ed3dSBarry Smith     } else {
149717ab2063SBarry Smith       for (i=0; i<N; i++) {
1498e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1499416022c9SBarry Smith         a->ilen[rows[i]] = 0;
150017ab2063SBarry Smith       }
150117ab2063SBarry Smith     }
150288e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1503f1e2ffcdSBarry Smith   }
150443a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15053a40ed3dSBarry Smith   PetscFunctionReturn(0);
150617ab2063SBarry Smith }
150717ab2063SBarry Smith 
15084a2ae208SSatish Balay #undef __FUNCT__
15096e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
15106e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15116e169961SBarry Smith {
15126e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
15136e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
15146e169961SBarry Smith   PetscErrorCode    ierr;
15152b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
15166e169961SBarry Smith   const PetscScalar *xx;
15176e169961SBarry Smith   PetscScalar       *bb;
15186e169961SBarry Smith 
15196e169961SBarry Smith   PetscFunctionBegin;
15206e169961SBarry Smith   if (x && b) {
15216e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
15226e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15232b40b63fSBarry Smith     vecs = PETSC_TRUE;
15246e169961SBarry Smith   }
15256e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
15266e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
15276e169961SBarry Smith   for (i=0; i<N; i++) {
15286e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15296e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
15306e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
15316e169961SBarry Smith   }
15326e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
15336e169961SBarry Smith     if (!zeroed[i]) {
15346e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
15356e169961SBarry Smith         if (zeroed[a->j[j]]) {
15362b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
15376e169961SBarry Smith           a->a[j] = 0.0;
15386e169961SBarry Smith         }
15396e169961SBarry Smith       }
15402b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
15416e169961SBarry Smith   }
15426e169961SBarry Smith   if (x && b) {
15436e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
15446e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
15456e169961SBarry Smith   }
15466e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
15476e169961SBarry Smith   if (diag != 0.0) {
15486e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
15496e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
15506e169961SBarry Smith     for (i=0; i<N; i++) {
15516e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
15526e169961SBarry Smith     }
15536e169961SBarry Smith   }
15546e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
15556e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15566e169961SBarry Smith   PetscFunctionReturn(0);
15576e169961SBarry Smith }
15586e169961SBarry Smith 
15596e169961SBarry Smith #undef __FUNCT__
15604a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1561a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
156217ab2063SBarry Smith {
1563416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
156497f1f81fSBarry Smith   PetscInt   *itmp;
156517ab2063SBarry Smith 
15663a40ed3dSBarry Smith   PetscFunctionBegin;
1567e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
156817ab2063SBarry Smith 
1569416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1570bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
157117ab2063SBarry Smith   if (idx) {
1572bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1573bfeeae90SHong Zhang     if (*nz) {
15744e093b46SBarry Smith       *idx = itmp;
157517ab2063SBarry Smith     }
157617ab2063SBarry Smith     else *idx = 0;
157717ab2063SBarry Smith   }
15783a40ed3dSBarry Smith   PetscFunctionReturn(0);
157917ab2063SBarry Smith }
158017ab2063SBarry Smith 
1581bfeeae90SHong Zhang /* remove this function? */
15824a2ae208SSatish Balay #undef __FUNCT__
15834a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1584a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
158517ab2063SBarry Smith {
15863a40ed3dSBarry Smith   PetscFunctionBegin;
15873a40ed3dSBarry Smith   PetscFunctionReturn(0);
158817ab2063SBarry Smith }
158917ab2063SBarry Smith 
15904a2ae208SSatish Balay #undef __FUNCT__
15914a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1592dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
159317ab2063SBarry Smith {
1594416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
159554f21887SBarry Smith   MatScalar      *v = a->a;
159636db0b34SBarry Smith   PetscReal      sum = 0.0;
15976849ba73SBarry Smith   PetscErrorCode ierr;
159897f1f81fSBarry Smith   PetscInt       i,j;
159917ab2063SBarry Smith 
16003a40ed3dSBarry Smith   PetscFunctionBegin;
160117ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1602416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1603aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
160436db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
160517ab2063SBarry Smith #else
160617ab2063SBarry Smith       sum += (*v)*(*v); v++;
160717ab2063SBarry Smith #endif
160817ab2063SBarry Smith     }
1609064f8208SBarry Smith     *nrm = sqrt(sum);
16103a40ed3dSBarry Smith   } else if (type == NORM_1) {
161136db0b34SBarry Smith     PetscReal *tmp;
161297f1f81fSBarry Smith     PetscInt    *jj = a->j;
1613d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1614d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1615064f8208SBarry Smith     *nrm = 0.0;
1616416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1617bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
161817ab2063SBarry Smith     }
1619d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1620064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
162117ab2063SBarry Smith     }
1622606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
16233a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1624064f8208SBarry Smith     *nrm = 0.0;
1625d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1626bfeeae90SHong Zhang       v = a->a + a->i[j];
162717ab2063SBarry Smith       sum = 0.0;
1628416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1629cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
163017ab2063SBarry Smith       }
1631064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
163217ab2063SBarry Smith     }
16333a40ed3dSBarry Smith   } else {
1634e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
163517ab2063SBarry Smith   }
16363a40ed3dSBarry Smith   PetscFunctionReturn(0);
163717ab2063SBarry Smith }
163817ab2063SBarry Smith 
16394a2ae208SSatish Balay #undef __FUNCT__
16404a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1641fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
164217ab2063SBarry Smith {
1643416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1644416022c9SBarry Smith   Mat            C;
16456849ba73SBarry Smith   PetscErrorCode ierr;
1646d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
164754f21887SBarry Smith   MatScalar      *array = a->a;
164817ab2063SBarry Smith 
16493a40ed3dSBarry Smith   PetscFunctionBegin;
1650e32f2f54SBarry 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");
1651fc4dec0aSBarry Smith 
1652fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1653d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1654d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1655bfeeae90SHong Zhang 
1656bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
16577adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1658d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
16597adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1660ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1661606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1662a541d17aSBarry Smith   } else {
1663a541d17aSBarry Smith     C = *B;
1664a541d17aSBarry Smith   }
1665a541d17aSBarry Smith 
166617ab2063SBarry Smith   for (i=0; i<m; i++) {
166717ab2063SBarry Smith     len    = ai[i+1]-ai[i];
166887d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1669b9b97703SBarry Smith     array += len;
1670b9b97703SBarry Smith     aj    += len;
167117ab2063SBarry Smith   }
16726d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16736d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
167417ab2063SBarry Smith 
1675815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1676416022c9SBarry Smith     *B = C;
167717ab2063SBarry Smith   } else {
1678eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
167917ab2063SBarry Smith   }
16803a40ed3dSBarry Smith   PetscFunctionReturn(0);
168117ab2063SBarry Smith }
168217ab2063SBarry Smith 
1683cd0d46ebSvictorle EXTERN_C_BEGIN
1684cd0d46ebSvictorle #undef __FUNCT__
16855fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
16867087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1687cd0d46ebSvictorle {
1688cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
168954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
169054f21887SBarry Smith   MatScalar      *va,*vb;
16916849ba73SBarry Smith   PetscErrorCode ierr;
169297f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1693cd0d46ebSvictorle 
1694cd0d46ebSvictorle   PetscFunctionBegin;
1695cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1696cd0d46ebSvictorle 
1697cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1698cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
16995485867bSBarry Smith   if (ma!=nb || na!=mb){
17005485867bSBarry Smith     *f = PETSC_FALSE;
17015485867bSBarry Smith     PetscFunctionReturn(0);
17025485867bSBarry Smith   }
1703cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1704cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1705cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
170697f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
170797f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1708cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1709cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1710cd0d46ebSvictorle 
1711cd0d46ebSvictorle   *f = PETSC_TRUE;
1712cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1713cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
171497f1f81fSBarry Smith       PetscInt         idc,idr;
17155485867bSBarry Smith       PetscScalar vc,vr;
1716cd0d46ebSvictorle       /* column/row index/value */
17175485867bSBarry Smith       idc = adx[aptr[i]];
17185485867bSBarry Smith       idr = bdx[bptr[idc]];
17195485867bSBarry Smith       vc  = va[aptr[i]];
17205485867bSBarry Smith       vr  = vb[bptr[idc]];
17215485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
17225485867bSBarry Smith 	*f = PETSC_FALSE;
17235485867bSBarry Smith         goto done;
1724cd0d46ebSvictorle       } else {
17255485867bSBarry Smith 	aptr[i]++;
17265485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1727cd0d46ebSvictorle       }
1728cd0d46ebSvictorle     }
1729cd0d46ebSvictorle   }
1730cd0d46ebSvictorle  done:
1731cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
17323aeef889SHong Zhang   if (B) {
17333aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
17343aeef889SHong Zhang   }
1735cd0d46ebSvictorle   PetscFunctionReturn(0);
1736cd0d46ebSvictorle }
1737cd0d46ebSvictorle EXTERN_C_END
1738cd0d46ebSvictorle 
17391cbb95d3SBarry Smith EXTERN_C_BEGIN
17401cbb95d3SBarry Smith #undef __FUNCT__
17411cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
17427087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
17431cbb95d3SBarry Smith {
17441cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
174554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
174654f21887SBarry Smith   MatScalar      *va,*vb;
17471cbb95d3SBarry Smith   PetscErrorCode ierr;
17481cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
17491cbb95d3SBarry Smith 
17501cbb95d3SBarry Smith   PetscFunctionBegin;
17511cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
17521cbb95d3SBarry Smith 
17531cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
17541cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17551cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
17561cbb95d3SBarry Smith     *f = PETSC_FALSE;
17571cbb95d3SBarry Smith     PetscFunctionReturn(0);
17581cbb95d3SBarry Smith   }
17591cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
17601cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
17611cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
17621cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
17631cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
17641cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
17651cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
17661cbb95d3SBarry Smith 
17671cbb95d3SBarry Smith   *f = PETSC_TRUE;
17681cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
17691cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
17701cbb95d3SBarry Smith       PetscInt         idc,idr;
17711cbb95d3SBarry Smith       PetscScalar vc,vr;
17721cbb95d3SBarry Smith       /* column/row index/value */
17731cbb95d3SBarry Smith       idc = adx[aptr[i]];
17741cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
17751cbb95d3SBarry Smith       vc  = va[aptr[i]];
17761cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
17771cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
17781cbb95d3SBarry Smith 	*f = PETSC_FALSE;
17791cbb95d3SBarry Smith         goto done;
17801cbb95d3SBarry Smith       } else {
17811cbb95d3SBarry Smith 	aptr[i]++;
17821cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
17831cbb95d3SBarry Smith       }
17841cbb95d3SBarry Smith     }
17851cbb95d3SBarry Smith   }
17861cbb95d3SBarry Smith  done:
17871cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
17881cbb95d3SBarry Smith   if (B) {
17891cbb95d3SBarry Smith     ierr = PetscFree(bptr);CHKERRQ(ierr);
17901cbb95d3SBarry Smith   }
17911cbb95d3SBarry Smith   PetscFunctionReturn(0);
17921cbb95d3SBarry Smith }
17931cbb95d3SBarry Smith EXTERN_C_END
17941cbb95d3SBarry Smith 
17959e29f15eSvictorle #undef __FUNCT__
17969e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1797ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
17989e29f15eSvictorle {
1799dfbe8321SBarry Smith   PetscErrorCode ierr;
18009e29f15eSvictorle   PetscFunctionBegin;
18015485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18029e29f15eSvictorle   PetscFunctionReturn(0);
18039e29f15eSvictorle }
18049e29f15eSvictorle 
18054a2ae208SSatish Balay #undef __FUNCT__
18061cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
1807ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
18081cbb95d3SBarry Smith {
18091cbb95d3SBarry Smith   PetscErrorCode ierr;
18101cbb95d3SBarry Smith   PetscFunctionBegin;
18111cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18121cbb95d3SBarry Smith   PetscFunctionReturn(0);
18131cbb95d3SBarry Smith }
18141cbb95d3SBarry Smith 
18151cbb95d3SBarry Smith #undef __FUNCT__
18164a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1817dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
181817ab2063SBarry Smith {
1819416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
182054f21887SBarry Smith   PetscScalar    *l,*r,x;
182154f21887SBarry Smith   MatScalar      *v;
1822dfbe8321SBarry Smith   PetscErrorCode ierr;
1823d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
182417ab2063SBarry Smith 
18253a40ed3dSBarry Smith   PetscFunctionBegin;
182617ab2063SBarry Smith   if (ll) {
18273ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
18283ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1829e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1830e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
18311ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1832416022c9SBarry Smith     v = a->a;
183317ab2063SBarry Smith     for (i=0; i<m; i++) {
183417ab2063SBarry Smith       x = l[i];
1835416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
183617ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
183717ab2063SBarry Smith     }
18381ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1839efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
184017ab2063SBarry Smith   }
184117ab2063SBarry Smith   if (rr) {
1842e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1843e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
18441ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1845416022c9SBarry Smith     v = a->a; jj = a->j;
184617ab2063SBarry Smith     for (i=0; i<nz; i++) {
1847bfeeae90SHong Zhang       (*v++) *= r[*jj++];
184817ab2063SBarry Smith     }
18491ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1850efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
185117ab2063SBarry Smith   }
18523a40ed3dSBarry Smith   PetscFunctionReturn(0);
185317ab2063SBarry Smith }
185417ab2063SBarry Smith 
18554a2ae208SSatish Balay #undef __FUNCT__
18564a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
185797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
185817ab2063SBarry Smith {
1859db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
18606849ba73SBarry Smith   PetscErrorCode ierr;
1861d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
186297f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
18635d0c19d7SBarry Smith   const PetscInt *irow,*icol;
18645d0c19d7SBarry Smith   PetscInt       nrows,ncols;
186597f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
186654f21887SBarry Smith   MatScalar      *a_new,*mat_a;
1867416022c9SBarry Smith   Mat            C;
1868ace3abfcSBarry Smith   PetscBool      stride,sorted;
186917ab2063SBarry Smith 
18703a40ed3dSBarry Smith   PetscFunctionBegin;
187114ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
1872e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
187314ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
1874e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
187599141d43SSatish Balay 
187617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1877b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1878b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
187917ab2063SBarry Smith 
1880fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
18810dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
1882fee21e36SBarry Smith   if (stride && step == 1) {
188302834360SBarry Smith     /* special case of contiguous rows */
18840e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
188502834360SBarry Smith     /* loop over new rows determining lens and starting points */
188602834360SBarry Smith     for (i=0; i<nrows; i++) {
1887bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1888a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
188902834360SBarry Smith       for (k=kstart; k<kend; k++) {
1890bfeeae90SHong Zhang         if (aj[k] >= first) {
189102834360SBarry Smith           starts[i] = k;
189202834360SBarry Smith           break;
189302834360SBarry Smith 	}
189402834360SBarry Smith       }
1895a2744918SBarry Smith       sum = 0;
189602834360SBarry Smith       while (k < kend) {
1897bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1898a2744918SBarry Smith         sum++;
189902834360SBarry Smith       }
1900a2744918SBarry Smith       lens[i] = sum;
190102834360SBarry Smith     }
190202834360SBarry Smith     /* create submatrix */
1903cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
190497f1f81fSBarry Smith       PetscInt n_cols,n_rows;
190508480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1906e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1907d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
190808480c60SBarry Smith       C = *B;
19093a40ed3dSBarry Smith     } else {
19107adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1911f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19127adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1913ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
191408480c60SBarry Smith     }
1915db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1916db02288aSLois Curfman McInnes 
191702834360SBarry Smith     /* loop over rows inserting into submatrix */
1918db02288aSLois Curfman McInnes     a_new    = c->a;
1919db02288aSLois Curfman McInnes     j_new    = c->j;
1920db02288aSLois Curfman McInnes     i_new    = c->i;
1921bfeeae90SHong Zhang 
192202834360SBarry Smith     for (i=0; i<nrows; i++) {
1923a2744918SBarry Smith       ii    = starts[i];
1924a2744918SBarry Smith       lensi = lens[i];
1925a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1926a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
192702834360SBarry Smith       }
192887828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1929a2744918SBarry Smith       a_new      += lensi;
1930a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1931a2744918SBarry Smith       c->ilen[i]  = lensi;
193202834360SBarry Smith     }
19330e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
19343a40ed3dSBarry Smith   } else {
193502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
19360e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
193797f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
19380e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
193917ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
194002834360SBarry Smith     /* determine lens of each row */
194102834360SBarry Smith     for (i=0; i<nrows; i++) {
1942bfeeae90SHong Zhang       kstart  = ai[irow[i]];
194302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
194402834360SBarry Smith       lens[i] = 0;
194502834360SBarry Smith       for (k=kstart; k<kend; k++) {
1946bfeeae90SHong Zhang         if (smap[aj[k]]) {
194702834360SBarry Smith           lens[i]++;
194802834360SBarry Smith         }
194902834360SBarry Smith       }
195002834360SBarry Smith     }
195117ab2063SBarry Smith     /* Create and fill new matrix */
1952a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1953ace3abfcSBarry Smith       PetscBool  equal;
19540f5bd95cSBarry Smith 
195599141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1956e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1957d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
19580f5bd95cSBarry Smith       if (!equal) {
1959e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
196099141d43SSatish Balay       }
1961d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
196208480c60SBarry Smith       C = *B;
19633a40ed3dSBarry Smith     } else {
19647adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1965f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19667adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1967ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
196808480c60SBarry Smith     }
196999141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
197017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
197199141d43SSatish Balay       row    = irow[i];
1972bfeeae90SHong Zhang       kstart = ai[row];
197399141d43SSatish Balay       kend   = kstart + a->ilen[row];
1974bfeeae90SHong Zhang       mat_i  = c->i[i];
197599141d43SSatish Balay       mat_j  = c->j + mat_i;
197699141d43SSatish Balay       mat_a  = c->a + mat_i;
197799141d43SSatish Balay       mat_ilen = c->ilen + i;
197817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
1979bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
1980ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
198199141d43SSatish Balay           *mat_a++ = a->a[k];
198299141d43SSatish Balay           (*mat_ilen)++;
198399141d43SSatish Balay 
198417ab2063SBarry Smith         }
198517ab2063SBarry Smith       }
198617ab2063SBarry Smith     }
198702834360SBarry Smith     /* Free work space */
198802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1989606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1990606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
199102834360SBarry Smith   }
19926d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19936d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
199417ab2063SBarry Smith 
199517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1996416022c9SBarry Smith   *B = C;
19973a40ed3dSBarry Smith   PetscFunctionReturn(0);
199817ab2063SBarry Smith }
199917ab2063SBarry Smith 
20001df811f5SHong Zhang #undef __FUNCT__
200182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
200282d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
200382d44351SHong Zhang {
200482d44351SHong Zhang   PetscErrorCode ierr;
200582d44351SHong Zhang   Mat            B;
200682d44351SHong Zhang 
200782d44351SHong Zhang   PetscFunctionBegin;
200882d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
200982d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
201082d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
201182d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
201282d44351SHong Zhang   *subMat = B;
201382d44351SHong Zhang   PetscFunctionReturn(0);
201482d44351SHong Zhang }
201582d44351SHong Zhang 
201682d44351SHong Zhang #undef __FUNCT__
20174a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
20180481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2019a871dcd8SBarry Smith {
202063b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2021dfbe8321SBarry Smith   PetscErrorCode ierr;
202263b91edcSBarry Smith   Mat            outA;
2023ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
202463b91edcSBarry Smith 
20253a40ed3dSBarry Smith   PetscFunctionBegin;
2026e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
20271df811f5SHong Zhang 
2028b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2029b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2030a871dcd8SBarry Smith 
203163b91edcSBarry Smith   outA              = inA;
2032d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2033c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
2034c3122656SLisandro Dalcin   if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr);}
2035c3122656SLisandro Dalcin   a->row = row;
2036c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
2037c3122656SLisandro Dalcin   if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr);}
2038c3122656SLisandro Dalcin   a->col = col;
203963b91edcSBarry Smith 
204036db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
2041b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
20424c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
204352e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2044f0ec6fceSSatish Balay 
204594a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2046d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2047d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
204894a9d846SBarry Smith   }
204963b91edcSBarry Smith 
2050f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2051137fb511SHong Zhang   if (row_identity && col_identity) {
2052ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2053137fb511SHong Zhang   } else {
2054719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2055137fb511SHong Zhang   }
20563a40ed3dSBarry Smith   PetscFunctionReturn(0);
2057a871dcd8SBarry Smith }
2058a871dcd8SBarry Smith 
20594a2ae208SSatish Balay #undef __FUNCT__
20604a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2061f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2062f0b747eeSBarry Smith {
2063f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2064f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2065efee365bSSatish Balay   PetscErrorCode ierr;
20660805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
20673a40ed3dSBarry Smith 
20683a40ed3dSBarry Smith   PetscFunctionBegin;
2069f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2070efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20713a40ed3dSBarry Smith   PetscFunctionReturn(0);
2072f0b747eeSBarry Smith }
2073f0b747eeSBarry Smith 
20744a2ae208SSatish Balay #undef __FUNCT__
20754a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
207697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2077cddf8d76SBarry Smith {
2078dfbe8321SBarry Smith   PetscErrorCode ierr;
207997f1f81fSBarry Smith   PetscInt       i;
2080cddf8d76SBarry Smith 
20813a40ed3dSBarry Smith   PetscFunctionBegin;
2082cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2083b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2084cddf8d76SBarry Smith   }
2085cddf8d76SBarry Smith 
2086cddf8d76SBarry Smith   for (i=0; i<n; i++) {
20876a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2088cddf8d76SBarry Smith   }
20893a40ed3dSBarry Smith   PetscFunctionReturn(0);
2090cddf8d76SBarry Smith }
2091cddf8d76SBarry Smith 
20924a2ae208SSatish Balay #undef __FUNCT__
20934a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
209497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
20954dcbc457SBarry Smith {
2096e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
20976849ba73SBarry Smith   PetscErrorCode ierr;
20985d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
20995d0c19d7SBarry Smith   const PetscInt *idx;
210097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2101f1af5d2fSBarry Smith   PetscBT        table;
2102bbd702dbSSatish Balay 
21033a40ed3dSBarry Smith   PetscFunctionBegin;
2104d0f46423SBarry Smith   m     = A->rmap->n;
2105e4d965acSSatish Balay   ai    = a->i;
2106bfeeae90SHong Zhang   aj    = a->j;
21078a047759SSatish Balay 
2108e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
210906763907SSatish Balay 
211097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
21116831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
211206763907SSatish Balay 
2113e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2114b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2115e4d965acSSatish Balay     isz  = 0;
21166831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2117e4d965acSSatish Balay 
2118e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
21194dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2120b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2121e4d965acSSatish Balay 
2122dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2123e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2124f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
21254dcbc457SBarry Smith     }
212606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
212706763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
2128e4d965acSSatish Balay 
212904a348a9SBarry Smith     k = 0;
213004a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
213104a348a9SBarry Smith       n = isz;
213206763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2133e4d965acSSatish Balay         row   = nidx[k];
2134e4d965acSSatish Balay         start = ai[row];
2135e4d965acSSatish Balay         end   = ai[row+1];
213604a348a9SBarry Smith         for (l = start; l<end ; l++){
2137efb16452SHong Zhang           val = aj[l] ;
2138f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2139e4d965acSSatish Balay         }
2140e4d965acSSatish Balay       }
2141e4d965acSSatish Balay     }
214270b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2143e4d965acSSatish Balay   }
21446831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2145606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
21463a40ed3dSBarry Smith   PetscFunctionReturn(0);
21474dcbc457SBarry Smith }
214817ab2063SBarry Smith 
21490513a670SBarry Smith /* -------------------------------------------------------------- */
21504a2ae208SSatish Balay #undef __FUNCT__
21514a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2152dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
21530513a670SBarry Smith {
21540513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21556849ba73SBarry Smith   PetscErrorCode ierr;
21563b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
21575d0c19d7SBarry Smith   const PetscInt *row,*col;
21585d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
215956cd22aeSBarry Smith   IS             icolp,irowp;
21603b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
21613b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
21620513a670SBarry Smith 
21633a40ed3dSBarry Smith   PetscFunctionBegin;
21644c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
216556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
21664c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
216756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
21680513a670SBarry Smith 
21690513a670SBarry Smith   /* determine lengths of permuted rows */
217097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
21710513a670SBarry Smith   for (i=0; i<m; i++) {
21720513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
21730513a670SBarry Smith   }
21747adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2175f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
21767adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2177ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2178606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
21790513a670SBarry Smith 
218097f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
21810513a670SBarry Smith   for (i=0; i<m; i++) {
218232ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
21830513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2184cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
218532ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
21860513a670SBarry Smith   }
2187606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
21883c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
21890513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21900513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
219156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
219256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
219356cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
219456cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
21953a40ed3dSBarry Smith   PetscFunctionReturn(0);
21960513a670SBarry Smith }
21970513a670SBarry Smith 
21984a2ae208SSatish Balay #undef __FUNCT__
21994a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2200dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2201cb5b572fSBarry Smith {
2202dfbe8321SBarry Smith   PetscErrorCode ierr;
2203cb5b572fSBarry Smith 
2204cb5b572fSBarry Smith   PetscFunctionBegin;
220533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
220633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2207be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2208be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2209be6bf707SBarry Smith 
2210700c5bfcSBarry 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");
2211d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2212cb5b572fSBarry Smith   } else {
2213cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2214cb5b572fSBarry Smith   }
2215cb5b572fSBarry Smith   PetscFunctionReturn(0);
2216cb5b572fSBarry Smith }
2217cb5b572fSBarry Smith 
22184a2ae208SSatish Balay #undef __FUNCT__
22194a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2220dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2221273d9f13SBarry Smith {
2222dfbe8321SBarry Smith   PetscErrorCode ierr;
2223273d9f13SBarry Smith 
2224273d9f13SBarry Smith   PetscFunctionBegin;
2225ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2226273d9f13SBarry Smith   PetscFunctionReturn(0);
2227273d9f13SBarry Smith }
2228273d9f13SBarry Smith 
22294a2ae208SSatish Balay #undef __FUNCT__
22304a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2231a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
22326c0721eeSBarry Smith {
22336c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
22346c0721eeSBarry Smith   PetscFunctionBegin;
22356c0721eeSBarry Smith   *array = a->a;
22366c0721eeSBarry Smith   PetscFunctionReturn(0);
22376c0721eeSBarry Smith }
22386c0721eeSBarry Smith 
22394a2ae208SSatish Balay #undef __FUNCT__
22404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2241dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
22426c0721eeSBarry Smith {
22436c0721eeSBarry Smith   PetscFunctionBegin;
22446c0721eeSBarry Smith   PetscFunctionReturn(0);
22456c0721eeSBarry Smith }
2246273d9f13SBarry Smith 
2247ee4f033dSBarry Smith #undef __FUNCT__
2248ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2249dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2250ee4f033dSBarry Smith {
22516849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
22526849ba73SBarry Smith   PetscErrorCode ierr;
225397f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2254efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
225587828ca2SBarry Smith   PetscScalar    *vscale_array;
2256ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2257ee4f033dSBarry Smith   Vec            w1,w2,w3;
2258ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2259ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2260ee4f033dSBarry Smith 
2261ee4f033dSBarry Smith   PetscFunctionBegin;
2262ee4f033dSBarry Smith   if (!coloring->w1) {
2263ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
226452e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2265ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
226652e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2267ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
226852e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2269ee4f033dSBarry Smith   }
2270ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2271ee4f033dSBarry Smith 
2272ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2273acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2274ee4f033dSBarry Smith   if (flg) {
2275ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2276ee4f033dSBarry Smith   } else {
2277ace3abfcSBarry Smith     PetscBool  assembled;
22780b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
22790b9b6f31SBarry Smith     if (assembled) {
2280ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2281ee4f033dSBarry Smith     }
22820b9b6f31SBarry Smith   }
2283ee4f033dSBarry Smith 
2284ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2285ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2286ee4f033dSBarry Smith 
2287ee4f033dSBarry Smith   /*
2288ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2289ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2290ee4f033dSBarry Smith   */
2291ee4f033dSBarry Smith   if (coloring->F) {
2292ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2293ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2294ee4f033dSBarry Smith     if (m1 != m2) {
2295ee4f033dSBarry Smith       coloring->F = 0;
2296ee4f033dSBarry Smith     }
2297ee4f033dSBarry Smith   }
2298ee4f033dSBarry Smith 
2299ee4f033dSBarry Smith   if (coloring->F) {
2300ee4f033dSBarry Smith     w1          = coloring->F;
2301ee4f033dSBarry Smith     coloring->F = 0;
2302ee4f033dSBarry Smith   } else {
230366f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2304ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
230566f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2306ee4f033dSBarry Smith   }
2307ee4f033dSBarry Smith 
2308ee4f033dSBarry Smith   /*
2309ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2310ee4f033dSBarry Smith   */
23111ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
23121ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2313ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2314ee4f033dSBarry Smith     /*
2315ee4f033dSBarry Smith        Loop over each column associated with color adding the
2316ee4f033dSBarry Smith        perturbation to the vector w3.
2317ee4f033dSBarry Smith     */
2318ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2319ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2320ee4f033dSBarry Smith       dx  = xx[col];
2321ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2322ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2323ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2324ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2325ee4f033dSBarry Smith #else
2326ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2327ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2328ee4f033dSBarry Smith #endif
2329ee4f033dSBarry Smith       dx                *= epsilon;
2330ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2331ee4f033dSBarry Smith     }
2332ee4f033dSBarry Smith   }
23331ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2334ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2335ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2336ee4f033dSBarry Smith 
2337ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2338ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2339ee4f033dSBarry Smith 
2340ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2341ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2342ee4f033dSBarry Smith 
23431ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2344ee4f033dSBarry Smith   /*
2345ee4f033dSBarry Smith       Loop over each color
2346ee4f033dSBarry Smith   */
2347ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
234849b058dcSBarry Smith     coloring->currentcolor = k;
2349ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
23501ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2351ee4f033dSBarry Smith     /*
2352ee4f033dSBarry Smith        Loop over each column associated with color adding the
2353ee4f033dSBarry Smith        perturbation to the vector w3.
2354ee4f033dSBarry Smith     */
2355ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2356ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2357ee4f033dSBarry Smith       dx  = xx[col];
23585b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2359ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2360ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2361ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2362ee4f033dSBarry Smith #else
2363ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2364ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2365ee4f033dSBarry Smith #endif
2366ee4f033dSBarry Smith       dx            *= epsilon;
2367e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2368ee4f033dSBarry Smith       w3_array[col] += dx;
2369ee4f033dSBarry Smith     }
23701ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2371ee4f033dSBarry Smith 
2372ee4f033dSBarry Smith     /*
2373ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2374ee4f033dSBarry Smith     */
2375ee4f033dSBarry Smith 
237666f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2377ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
237866f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2379efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2380ee4f033dSBarry Smith 
2381ee4f033dSBarry Smith     /*
2382ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2383ee4f033dSBarry Smith     */
23841ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2385ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2386ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2387ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2388ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2389ee4f033dSBarry Smith       srow   = row + start;
2390ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2391ee4f033dSBarry Smith     }
23921ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2393ee4f033dSBarry Smith   }
239449b058dcSBarry Smith   coloring->currentcolor = k;
23951ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
23961ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2397ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2398ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2399ee4f033dSBarry Smith   PetscFunctionReturn(0);
2400ee4f033dSBarry Smith }
2401ee4f033dSBarry Smith 
24028229c054SShri Abhyankar /*
24038229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
24048229c054SShri Abhyankar    have different nonzero structure.
24058229c054SShri Abhyankar */
2406ac90fabeSBarry Smith #undef __FUNCT__
24078229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
24088229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2409ec7775f6SShri Abhyankar {
24108229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2411ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2412ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2413ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2414ec7775f6SShri Abhyankar 
2415ec7775f6SShri Abhyankar   PetscFunctionBegin;
2416ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2417ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
24188af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
24198af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
24208af7cee1SJed Brown     nnz[i] = 0;
24218af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
24228af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
24238af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
24248af7cee1SJed Brown       nnz[i]++;
24258af7cee1SJed Brown     }
24268af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2427ec7775f6SShri Abhyankar   }
2428ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2429ec7775f6SShri Abhyankar }
2430ec7775f6SShri Abhyankar 
2431ec7775f6SShri Abhyankar #undef __FUNCT__
2432ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2433f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2434ac90fabeSBarry Smith {
2435dfbe8321SBarry Smith   PetscErrorCode ierr;
243697f1f81fSBarry Smith   PetscInt       i;
2437ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
24380805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2439ac90fabeSBarry Smith 
2440ac90fabeSBarry Smith   PetscFunctionBegin;
2441ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2442f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2443f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2444c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2445a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2446a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2447a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2448a30b2313SHong Zhang     }
2449a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2450d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2451a30b2313SHong Zhang       y->XtoY = X;
2452407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2453c537a176SHong Zhang     }
2454f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
24551e2582c4SBarry 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);
2456ac90fabeSBarry Smith   } else {
24578229c054SShri Abhyankar     Mat      B;
24588229c054SShri Abhyankar     PetscInt *nnz;
245916b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2460ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2461bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
24624aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2463ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
24648229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
24658229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2466ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2467ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
24688229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2469ac90fabeSBarry Smith   }
2470ac90fabeSBarry Smith   PetscFunctionReturn(0);
2471ac90fabeSBarry Smith }
2472ac90fabeSBarry Smith 
2473521d7252SBarry Smith #undef __FUNCT__
2474521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2475521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2476521d7252SBarry Smith {
247741c166b1SJed Brown   PetscErrorCode ierr;
247841c166b1SJed Brown 
2479521d7252SBarry Smith   PetscFunctionBegin;
248041c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
248141c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2482521d7252SBarry Smith   PetscFunctionReturn(0);
2483521d7252SBarry Smith }
2484521d7252SBarry Smith 
2485354c94deSBarry Smith #undef __FUNCT__
2486354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
24877087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2488354c94deSBarry Smith {
2489354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2490354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2491354c94deSBarry Smith   PetscInt    i,nz;
2492354c94deSBarry Smith   PetscScalar *a;
2493354c94deSBarry Smith 
2494354c94deSBarry Smith   PetscFunctionBegin;
2495354c94deSBarry Smith   nz = aij->nz;
2496354c94deSBarry Smith   a  = aij->a;
2497354c94deSBarry Smith   for (i=0; i<nz; i++) {
2498354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2499354c94deSBarry Smith   }
2500354c94deSBarry Smith #else
2501354c94deSBarry Smith   PetscFunctionBegin;
2502354c94deSBarry Smith #endif
2503354c94deSBarry Smith   PetscFunctionReturn(0);
2504354c94deSBarry Smith }
2505354c94deSBarry Smith 
2506e34fafa9SBarry Smith #undef __FUNCT__
2507985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2508985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2509e34fafa9SBarry Smith {
2510e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2511e34fafa9SBarry Smith   PetscErrorCode ierr;
2512d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2513e34fafa9SBarry Smith   PetscReal      atmp;
2514985db425SBarry Smith   PetscScalar    *x;
2515e34fafa9SBarry Smith   MatScalar      *aa;
2516e34fafa9SBarry Smith 
2517e34fafa9SBarry Smith   PetscFunctionBegin;
2518e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2519e34fafa9SBarry Smith   aa   = a->a;
2520e34fafa9SBarry Smith   ai   = a->i;
2521e34fafa9SBarry Smith   aj   = a->j;
2522e34fafa9SBarry Smith 
2523985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2524e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2525e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2526e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2527e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2528e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
25299189402eSHong Zhang     x[i] = 0.0;
2530e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2531985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2532985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2533985db425SBarry Smith       aa++; aj++;
2534985db425SBarry Smith     }
2535985db425SBarry Smith   }
2536985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2537985db425SBarry Smith   PetscFunctionReturn(0);
2538985db425SBarry Smith }
2539985db425SBarry Smith 
2540985db425SBarry Smith #undef __FUNCT__
2541985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2542985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2543985db425SBarry Smith {
2544985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2545985db425SBarry Smith   PetscErrorCode ierr;
2546d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2547985db425SBarry Smith   PetscScalar    *x;
2548985db425SBarry Smith   MatScalar      *aa;
2549985db425SBarry Smith 
2550985db425SBarry Smith   PetscFunctionBegin;
2551e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2552985db425SBarry Smith   aa   = a->a;
2553985db425SBarry Smith   ai   = a->i;
2554985db425SBarry Smith   aj   = a->j;
2555985db425SBarry Smith 
2556985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2557985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2558985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2559e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2560985db425SBarry Smith   for (i=0; i<m; i++) {
2561985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2562d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2563985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2564985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2565985db425SBarry Smith       x[i] = 0.0;
2566985db425SBarry Smith       if (idx) {
2567985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2568985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2569985db425SBarry Smith           if (aj[j] > j) {
2570985db425SBarry Smith             idx[i] = j;
2571985db425SBarry Smith             break;
2572985db425SBarry Smith           }
2573985db425SBarry Smith         }
2574985db425SBarry Smith       }
2575985db425SBarry Smith     }
2576985db425SBarry Smith     for (j=0; j<ncols; j++){
2577985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2578985db425SBarry Smith       aa++; aj++;
2579985db425SBarry Smith     }
2580985db425SBarry Smith   }
2581985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2582985db425SBarry Smith   PetscFunctionReturn(0);
2583985db425SBarry Smith }
2584985db425SBarry Smith 
2585985db425SBarry Smith #undef __FUNCT__
2586c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2587c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2588c87e5d42SMatthew Knepley {
2589c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2590c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2591c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2592c87e5d42SMatthew Knepley   PetscReal      atmp;
2593c87e5d42SMatthew Knepley   PetscScalar    *x;
2594c87e5d42SMatthew Knepley   MatScalar      *aa;
2595c87e5d42SMatthew Knepley 
2596c87e5d42SMatthew Knepley   PetscFunctionBegin;
2597e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2598c87e5d42SMatthew Knepley   aa   = a->a;
2599c87e5d42SMatthew Knepley   ai   = a->i;
2600c87e5d42SMatthew Knepley   aj   = a->j;
2601c87e5d42SMatthew Knepley 
2602c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2603c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2604c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2605e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2606c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2607c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2608289a08f5SMatthew Knepley     if (ncols) {
2609289a08f5SMatthew Knepley       /* Get first nonzero */
2610289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2611289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2612289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2613289a08f5SMatthew Knepley       }
2614289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2615289a08f5SMatthew Knepley     } else {
2616289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2617289a08f5SMatthew Knepley     }
2618c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2619c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2620289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2621c87e5d42SMatthew Knepley       aa++; aj++;
2622c87e5d42SMatthew Knepley     }
2623c87e5d42SMatthew Knepley   }
2624c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2625c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2626c87e5d42SMatthew Knepley }
2627c87e5d42SMatthew Knepley 
2628c87e5d42SMatthew Knepley #undef __FUNCT__
2629985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2630985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2631985db425SBarry Smith {
2632985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2633985db425SBarry Smith   PetscErrorCode ierr;
2634d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2635985db425SBarry Smith   PetscScalar    *x;
2636985db425SBarry Smith   MatScalar      *aa;
2637985db425SBarry Smith 
2638985db425SBarry Smith   PetscFunctionBegin;
2639e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2640985db425SBarry Smith   aa   = a->a;
2641985db425SBarry Smith   ai   = a->i;
2642985db425SBarry Smith   aj   = a->j;
2643985db425SBarry Smith 
2644985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2645985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2646985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2647e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2648985db425SBarry Smith   for (i=0; i<m; i++) {
2649985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2650d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2651985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2652985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2653985db425SBarry Smith       x[i] = 0.0;
2654985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2655985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2656985db425SBarry Smith         for (j=0;j<ncols;j++) {
2657985db425SBarry Smith           if (aj[j] > j) {
2658985db425SBarry Smith             idx[i] = j;
2659985db425SBarry Smith             break;
2660985db425SBarry Smith           }
2661985db425SBarry Smith         }
2662985db425SBarry Smith       }
2663985db425SBarry Smith     }
2664985db425SBarry Smith     for (j=0; j<ncols; j++){
2665985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2666985db425SBarry Smith       aa++; aj++;
2667e34fafa9SBarry Smith     }
2668e34fafa9SBarry Smith   }
2669e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2670e34fafa9SBarry Smith   PetscFunctionReturn(0);
2671e34fafa9SBarry Smith }
26727087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2673682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
26740a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2675cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2676cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2677cb5b572fSBarry Smith        MatMult_SeqAIJ,
267897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
26797c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
26807c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2681db4efbfdSBarry Smith        0,
2682db4efbfdSBarry Smith        0,
2683db4efbfdSBarry Smith        0,
2684db4efbfdSBarry Smith /*10*/ 0,
2685cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2686cb5b572fSBarry Smith        0,
268741f059aeSBarry Smith        MatSOR_SeqAIJ,
268817ab2063SBarry Smith        MatTranspose_SeqAIJ,
268997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2690cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2691cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2692cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2693cb5b572fSBarry Smith        MatNorm_SeqAIJ,
269497304618SKris Buschelman /*20*/ 0,
2695cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2696cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2697cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2698d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2699db4efbfdSBarry Smith        0,
2700db4efbfdSBarry Smith        0,
2701db4efbfdSBarry Smith        0,
2702db4efbfdSBarry Smith        0,
2703d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2704db4efbfdSBarry Smith        0,
2705db4efbfdSBarry Smith        0,
27066c0721eeSBarry Smith        MatGetArray_SeqAIJ,
27076c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2708d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2709cb5b572fSBarry Smith        0,
2710cb5b572fSBarry Smith        0,
2711cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2712cb5b572fSBarry Smith        0,
2713d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
2714cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2715cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2716cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2717cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2718d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
2719cb5b572fSBarry Smith        MatScale_SeqAIJ,
2720cb5b572fSBarry Smith        0,
272179299369SBarry Smith        MatDiagonalSet_SeqAIJ,
27226e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
2723d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
27243b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
27253b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
27263b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2727a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2728d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
2729b9617806SBarry Smith        0,
27300513a670SBarry Smith        0,
2731cda55fadSBarry Smith        MatPermute_SeqAIJ,
2732cda55fadSBarry Smith        0,
2733d519adbfSMatthew Knepley /*59*/ 0,
2734b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2735b9b97703SBarry Smith        MatView_SeqAIJ,
2736357abbc8SBarry Smith        0,
2737ee4f033dSBarry Smith        0,
2738d519adbfSMatthew Knepley /*64*/ 0,
2739ee4f033dSBarry Smith        0,
2740ee4f033dSBarry Smith        0,
2741ee4f033dSBarry Smith        0,
2742ee4f033dSBarry Smith        0,
2743d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
2744c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
2745ee4f033dSBarry Smith        0,
2746ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2747dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2748ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2749dcf5cc72SBarry Smith #else
2750dcf5cc72SBarry Smith        0,
2751dcf5cc72SBarry Smith #endif
2752d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
27533acb8795SBarry Smith        MatFDColoringApply_AIJ,
275497304618SKris Buschelman        0,
275597304618SKris Buschelman        0,
275697304618SKris Buschelman        0,
2757d519adbfSMatthew Knepley /*79*/ 0,
275897304618SKris Buschelman        0,
275997304618SKris Buschelman        0,
276097304618SKris Buschelman        0,
2761bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2762d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
27631cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
27646284ec50SHong Zhang        0,
27656284ec50SHong Zhang        0,
2766bc011b1eSHong Zhang        0,
2767d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
276826be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
276926be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2770d439da42SKris Buschelman        MatPtAP_Basic,
27717ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
2772d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
2773bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2774bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2775bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
27767ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
2777d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
2778609c6c4dSKris Buschelman        0,
2779609c6c4dSKris Buschelman        0,
278087d4246cSBarry Smith        MatConjugate_SeqAIJ,
278187d4246cSBarry Smith        0,
2782d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
278399cafbc1SBarry Smith        MatRealPart_SeqAIJ,
2784f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
2785f5edf698SHong Zhang        0,
27862bebee5dSHong Zhang        0,
2787d519adbfSMatthew Knepley /*109*/0,
2788985db425SBarry Smith        0,
27892af78befSBarry Smith        MatGetRowMin_SeqAIJ,
27902af78befSBarry Smith        0,
2791599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
2792d519adbfSMatthew Knepley /*114*/0,
2793599ef60dSHong Zhang        0,
27943c2a7987SHong Zhang        0,
2795fe97e370SBarry Smith        0,
2796fbdbba38SShri Abhyankar        0,
2797fbdbba38SShri Abhyankar /*119*/0,
2798fbdbba38SShri Abhyankar        0,
2799fbdbba38SShri Abhyankar        0,
280082d44351SHong Zhang        0,
2801*b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
2802*b3a44c85SBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ
28039e29f15eSvictorle };
280417ab2063SBarry Smith 
2805fb2e594dSBarry Smith EXTERN_C_BEGIN
28064a2ae208SSatish Balay #undef __FUNCT__
28074a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
28087087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2809bef8e0ddSBarry Smith {
2810bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
281197f1f81fSBarry Smith   PetscInt   i,nz,n;
2812bef8e0ddSBarry Smith 
2813bef8e0ddSBarry Smith   PetscFunctionBegin;
2814bef8e0ddSBarry Smith 
2815bef8e0ddSBarry Smith   nz = aij->maxnz;
2816d0f46423SBarry Smith   n  = mat->rmap->n;
2817bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2818bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2819bef8e0ddSBarry Smith   }
2820bef8e0ddSBarry Smith   aij->nz = nz;
2821bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2822bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2823bef8e0ddSBarry Smith   }
2824bef8e0ddSBarry Smith 
2825bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2826bef8e0ddSBarry Smith }
2827fb2e594dSBarry Smith EXTERN_C_END
2828bef8e0ddSBarry Smith 
28294a2ae208SSatish Balay #undef __FUNCT__
28304a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2831bef8e0ddSBarry Smith /*@
2832bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2833bef8e0ddSBarry Smith        in the matrix.
2834bef8e0ddSBarry Smith 
2835bef8e0ddSBarry Smith   Input Parameters:
2836bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2837bef8e0ddSBarry Smith -  indices - the column indices
2838bef8e0ddSBarry Smith 
283915091d37SBarry Smith   Level: advanced
284015091d37SBarry Smith 
2841bef8e0ddSBarry Smith   Notes:
2842bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2843bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2844bef8e0ddSBarry Smith   of the MatSetValues() operation.
2845bef8e0ddSBarry Smith 
2846bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2847d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2848bef8e0ddSBarry Smith 
2849bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2850bef8e0ddSBarry Smith 
2851b9617806SBarry Smith     The indices should start with zero, not one.
2852b9617806SBarry Smith 
2853bef8e0ddSBarry Smith @*/
28547087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2855bef8e0ddSBarry Smith {
28564ac538c5SBarry Smith   PetscErrorCode ierr;
2857bef8e0ddSBarry Smith 
2858bef8e0ddSBarry Smith   PetscFunctionBegin;
28590700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
28604482741eSBarry Smith   PetscValidPointer(indices,2);
28614ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
2862bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2863bef8e0ddSBarry Smith }
2864bef8e0ddSBarry Smith 
2865be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2866be6bf707SBarry Smith 
2867fb2e594dSBarry Smith EXTERN_C_BEGIN
28684a2ae208SSatish Balay #undef __FUNCT__
28694a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
28707087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
2871be6bf707SBarry Smith {
2872be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
28736849ba73SBarry Smith   PetscErrorCode ierr;
2874d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
2875be6bf707SBarry Smith 
2876be6bf707SBarry Smith   PetscFunctionBegin;
2877be6bf707SBarry Smith   if (aij->nonew != 1) {
2878e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2879be6bf707SBarry Smith   }
2880be6bf707SBarry Smith 
2881be6bf707SBarry Smith   /* allocate space for values if not already there */
2882be6bf707SBarry Smith   if (!aij->saved_values) {
288387828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
28849518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
2885be6bf707SBarry Smith   }
2886be6bf707SBarry Smith 
2887be6bf707SBarry Smith   /* copy values over */
288887828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2889be6bf707SBarry Smith   PetscFunctionReturn(0);
2890be6bf707SBarry Smith }
2891fb2e594dSBarry Smith EXTERN_C_END
2892be6bf707SBarry Smith 
28934a2ae208SSatish Balay #undef __FUNCT__
2894b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2895be6bf707SBarry Smith /*@
2896be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2897be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2898be6bf707SBarry Smith        nonlinear portion.
2899be6bf707SBarry Smith 
2900be6bf707SBarry Smith    Collect on Mat
2901be6bf707SBarry Smith 
2902be6bf707SBarry Smith   Input Parameters:
29030e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2904be6bf707SBarry Smith 
290515091d37SBarry Smith   Level: advanced
290615091d37SBarry Smith 
2907be6bf707SBarry Smith   Common Usage, with SNESSolve():
2908be6bf707SBarry Smith $    Create Jacobian matrix
2909be6bf707SBarry Smith $    Set linear terms into matrix
2910be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2911be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2912be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2913512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2914be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2915be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2916be6bf707SBarry Smith $    In your Jacobian routine
2917be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2918be6bf707SBarry Smith $      Set nonlinear terms in matrix
2919be6bf707SBarry Smith 
2920be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2921be6bf707SBarry Smith $    // build linear portion of Jacobian
2922512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2923be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2924be6bf707SBarry Smith $    loop over nonlinear iterations
2925be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2926be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2927be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2928be6bf707SBarry Smith $       Solve linear system with Jacobian
2929be6bf707SBarry Smith $    endloop
2930be6bf707SBarry Smith 
2931be6bf707SBarry Smith   Notes:
2932be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2933512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
2934be6bf707SBarry Smith     calling this routine.
2935be6bf707SBarry Smith 
29360c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
29370c468ba9SBarry Smith     and does not allocated additional space.
29380c468ba9SBarry Smith 
2939be6bf707SBarry Smith .seealso: MatRetrieveValues()
2940be6bf707SBarry Smith 
2941be6bf707SBarry Smith @*/
29427087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
2943be6bf707SBarry Smith {
29444ac538c5SBarry Smith   PetscErrorCode ierr;
2945be6bf707SBarry Smith 
2946be6bf707SBarry Smith   PetscFunctionBegin;
29470700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2948e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2949e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
29504ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
2951be6bf707SBarry Smith   PetscFunctionReturn(0);
2952be6bf707SBarry Smith }
2953be6bf707SBarry Smith 
2954fb2e594dSBarry Smith EXTERN_C_BEGIN
29554a2ae208SSatish Balay #undef __FUNCT__
29564a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
29577087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
2958be6bf707SBarry Smith {
2959be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
29606849ba73SBarry Smith   PetscErrorCode ierr;
2961d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
2962be6bf707SBarry Smith 
2963be6bf707SBarry Smith   PetscFunctionBegin;
2964be6bf707SBarry Smith   if (aij->nonew != 1) {
2965e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2966be6bf707SBarry Smith   }
2967be6bf707SBarry Smith   if (!aij->saved_values) {
2968e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2969be6bf707SBarry Smith   }
2970be6bf707SBarry Smith   /* copy values over */
297187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2972be6bf707SBarry Smith   PetscFunctionReturn(0);
2973be6bf707SBarry Smith }
2974fb2e594dSBarry Smith EXTERN_C_END
2975be6bf707SBarry Smith 
29764a2ae208SSatish Balay #undef __FUNCT__
29774a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2978be6bf707SBarry Smith /*@
2979be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2980be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2981be6bf707SBarry Smith        nonlinear portion.
2982be6bf707SBarry Smith 
2983be6bf707SBarry Smith    Collect on Mat
2984be6bf707SBarry Smith 
2985be6bf707SBarry Smith   Input Parameters:
2986be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2987be6bf707SBarry Smith 
298815091d37SBarry Smith   Level: advanced
298915091d37SBarry Smith 
2990be6bf707SBarry Smith .seealso: MatStoreValues()
2991be6bf707SBarry Smith 
2992be6bf707SBarry Smith @*/
29937087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
2994be6bf707SBarry Smith {
29954ac538c5SBarry Smith   PetscErrorCode ierr;
2996be6bf707SBarry Smith 
2997be6bf707SBarry Smith   PetscFunctionBegin;
29980700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2999e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3000e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
30014ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3002be6bf707SBarry Smith   PetscFunctionReturn(0);
3003be6bf707SBarry Smith }
3004be6bf707SBarry Smith 
3005f83d6046SBarry Smith 
3006be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
30074a2ae208SSatish Balay #undef __FUNCT__
30084a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
300917ab2063SBarry Smith /*@C
3010682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
30110d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
30126e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
301351c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
30142bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
301517ab2063SBarry Smith 
3016db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3017db81eaa0SLois Curfman McInnes 
301817ab2063SBarry Smith    Input Parameters:
3019db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
302017ab2063SBarry Smith .  m - number of rows
302117ab2063SBarry Smith .  n - number of columns
302217ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
302351c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
30242bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
302517ab2063SBarry Smith 
302617ab2063SBarry Smith    Output Parameter:
3027416022c9SBarry Smith .  A - the matrix
302817ab2063SBarry Smith 
3029175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3030ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3031175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3032175b88e8SBarry Smith 
3033b259b22eSLois Curfman McInnes    Notes:
303449a6f317SBarry Smith    If nnz is given then nz is ignored
303549a6f317SBarry Smith 
303617ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
303717ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
30380002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
303944cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
304017ab2063SBarry Smith 
304117ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3042a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
30433d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
30446da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
304517ab2063SBarry Smith 
3046682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
30474fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3048682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
30496c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
30506c7ebb05SLois Curfman McInnes 
30516c7ebb05SLois Curfman McInnes    Options Database Keys:
3052698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
30539db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
305417ab2063SBarry Smith 
3055027ccd11SLois Curfman McInnes    Level: intermediate
3056027ccd11SLois Curfman McInnes 
305736db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
305836db0b34SBarry Smith 
305917ab2063SBarry Smith @*/
30607087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
306117ab2063SBarry Smith {
3062dfbe8321SBarry Smith   PetscErrorCode ierr;
30636945ee14SBarry Smith 
30643a40ed3dSBarry Smith   PetscFunctionBegin;
3065f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3066117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3067c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3068d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3069273d9f13SBarry Smith   PetscFunctionReturn(0);
3070273d9f13SBarry Smith }
3071273d9f13SBarry Smith 
30724a2ae208SSatish Balay #undef __FUNCT__
30734a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3074273d9f13SBarry Smith /*@C
3075273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3076273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3077273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3078273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3079273d9f13SBarry Smith 
3080273d9f13SBarry Smith    Collective on MPI_Comm
3081273d9f13SBarry Smith 
3082273d9f13SBarry Smith    Input Parameters:
3083117016b1SBarry Smith +  B - The matrix-free
3084273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3085273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3086273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3087273d9f13SBarry Smith 
3088273d9f13SBarry Smith    Notes:
308949a6f317SBarry Smith      If nnz is given then nz is ignored
309049a6f317SBarry Smith 
3091273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3092273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3093273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3094273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3095273d9f13SBarry Smith 
3096273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3097273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3098273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3099273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3100273d9f13SBarry Smith 
3101aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3102aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3103aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3104aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3105aa95bbe8SBarry Smith 
3106a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3107a96a251dSBarry Smith    entries or columns indices
3108a96a251dSBarry Smith 
3109273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3110273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3111273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3112273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3113273d9f13SBarry Smith 
3114273d9f13SBarry Smith    Options Database Keys:
3115698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3116698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3117273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3118273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3119273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3120273d9f13SBarry Smith 
3121273d9f13SBarry Smith    Level: intermediate
3122273d9f13SBarry Smith 
3123aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3124273d9f13SBarry Smith 
3125273d9f13SBarry Smith @*/
31267087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3127273d9f13SBarry Smith {
31284ac538c5SBarry Smith   PetscErrorCode ierr;
3129a23d5eceSKris Buschelman 
3130a23d5eceSKris Buschelman   PetscFunctionBegin;
31314ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3132a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3133a23d5eceSKris Buschelman }
3134a23d5eceSKris Buschelman 
3135a23d5eceSKris Buschelman EXTERN_C_BEGIN
3136a23d5eceSKris Buschelman #undef __FUNCT__
3137a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
31387087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3139a23d5eceSKris Buschelman {
3140273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3141ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
31426849ba73SBarry Smith   PetscErrorCode ierr;
314397f1f81fSBarry Smith   PetscInt       i;
3144273d9f13SBarry Smith 
3145273d9f13SBarry Smith   PetscFunctionBegin;
3146d5d45c9bSBarry Smith 
3147a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3148c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3149c461c341SBarry Smith     nz             = 0;
3150c461c341SBarry Smith   }
3151c461c341SBarry Smith 
315226283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
315326283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
315426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
315526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3156899cda47SBarry Smith 
3157435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3158e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3159b73539f3SBarry Smith   if (nnz) {
3160d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3161e32f2f54SBarry 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]);
3162e32f2f54SBarry 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);
3163b73539f3SBarry Smith     }
3164b73539f3SBarry Smith   }
3165b73539f3SBarry Smith 
3166273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3167273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3168273d9f13SBarry Smith 
3169ab93d7beSBarry Smith   if (!skipallocation) {
31702ee49352SLisandro Dalcin     if (!b->imax) {
3171d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3172d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
31732ee49352SLisandro Dalcin     }
3174273d9f13SBarry Smith     if (!nnz) {
3175435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3176c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3177d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3178d0f46423SBarry Smith       nz = nz*B->rmap->n;
3179273d9f13SBarry Smith     } else {
3180273d9f13SBarry Smith       nz = 0;
3181d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3182273d9f13SBarry Smith     }
3183ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3184d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3185ab93d7beSBarry Smith 
3186273d9f13SBarry Smith     /* allocate the matrix space */
31872ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3188d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3189d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3190bfeeae90SHong Zhang     b->i[0] = 0;
3191d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
31925da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
31935da197adSKris Buschelman     }
3194273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3195e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3196e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3197c461c341SBarry Smith   } else {
3198e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3199e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3200c461c341SBarry Smith   }
3201273d9f13SBarry Smith 
3202273d9f13SBarry Smith   b->nz                = 0;
3203273d9f13SBarry Smith   b->maxnz             = nz;
3204273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3205273d9f13SBarry Smith   PetscFunctionReturn(0);
3206273d9f13SBarry Smith }
3207a23d5eceSKris Buschelman EXTERN_C_END
3208273d9f13SBarry Smith 
3209a1661176SMatthew Knepley #undef  __FUNCT__
3210a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
321158d36128SBarry Smith /*@
3212a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3213a1661176SMatthew Knepley 
3214a1661176SMatthew Knepley    Input Parameters:
3215a1661176SMatthew Knepley +  B - the matrix
3216a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3217a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3218a1661176SMatthew Knepley -  v - optional values in the matrix
3219a1661176SMatthew Knepley 
3220a1661176SMatthew Knepley    Level: developer
3221a1661176SMatthew Knepley 
322258d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
322358d36128SBarry Smith 
3224a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3225a1661176SMatthew Knepley 
3226a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3227a1661176SMatthew Knepley @*/
3228a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3229a1661176SMatthew Knepley {
3230a1661176SMatthew Knepley   PetscErrorCode ierr;
3231a1661176SMatthew Knepley 
3232a1661176SMatthew Knepley   PetscFunctionBegin;
32330700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
32344ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3235a1661176SMatthew Knepley   PetscFunctionReturn(0);
3236a1661176SMatthew Knepley }
3237a1661176SMatthew Knepley 
3238a1661176SMatthew Knepley EXTERN_C_BEGIN
3239a1661176SMatthew Knepley #undef  __FUNCT__
3240a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
32417087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3242a1661176SMatthew Knepley {
3243a1661176SMatthew Knepley   PetscInt       i;
3244a1661176SMatthew Knepley   PetscInt       m,n;
3245a1661176SMatthew Knepley   PetscInt       nz;
3246a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3247a1661176SMatthew Knepley   PetscScalar    *values;
3248a1661176SMatthew Knepley   PetscErrorCode ierr;
3249a1661176SMatthew Knepley 
3250a1661176SMatthew Knepley   PetscFunctionBegin;
3251a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3252a1661176SMatthew Knepley 
325365e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3254a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3255a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3256b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3257a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
325865e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3259a1661176SMatthew Knepley     nnz[i] = nz;
3260a1661176SMatthew Knepley   }
3261a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3262a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3263a1661176SMatthew Knepley 
3264a1661176SMatthew Knepley   if (v) {
3265a1661176SMatthew Knepley     values = (PetscScalar*) v;
3266a1661176SMatthew Knepley   } else {
32670e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3268a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3269a1661176SMatthew Knepley   }
3270a1661176SMatthew Knepley 
3271a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3272b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3273b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3274a1661176SMatthew Knepley   }
3275a1661176SMatthew Knepley 
3276a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3277a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3278a1661176SMatthew Knepley 
3279a1661176SMatthew Knepley   if (!v) {
3280a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3281a1661176SMatthew Knepley   }
3282a1661176SMatthew Knepley   PetscFunctionReturn(0);
3283a1661176SMatthew Knepley }
3284a1661176SMatthew Knepley EXTERN_C_END
3285a1661176SMatthew Knepley 
32867c4f633dSBarry Smith #include "../src/mat/impls/dense/seq/dense.h"
3287be7314b0SBarry Smith #include "private/petscaxpy.h"
3288170fe5c8SBarry Smith 
3289170fe5c8SBarry Smith #undef __FUNCT__
3290170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3291170fe5c8SBarry Smith /*
3292170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3293170fe5c8SBarry Smith 
3294170fe5c8SBarry Smith                n                       p                          p
3295170fe5c8SBarry Smith         (              )       (              )         (                  )
3296170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3297170fe5c8SBarry Smith         (              )       (              )         (                  )
3298170fe5c8SBarry Smith 
3299170fe5c8SBarry Smith */
3300170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3301170fe5c8SBarry Smith {
3302170fe5c8SBarry Smith   PetscErrorCode     ierr;
3303170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3304170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3305170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
33061de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3307170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3308170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3309170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3310170fe5c8SBarry Smith 
3311170fe5c8SBarry Smith   PetscFunctionBegin;
3312d0f46423SBarry Smith   m = A->rmap->n;
3313d0f46423SBarry Smith   n = A->cmap->n;
3314d0f46423SBarry Smith   p = B->cmap->n;
3315170fe5c8SBarry Smith   a = sub_a->v;
3316170fe5c8SBarry Smith   b = sub_b->a;
3317170fe5c8SBarry Smith   c = sub_c->v;
3318170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3319170fe5c8SBarry Smith 
3320170fe5c8SBarry Smith   ii  = sub_b->i;
3321170fe5c8SBarry Smith   idx = sub_b->j;
3322170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3323170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3324170fe5c8SBarry Smith     while (q-->0) {
3325170fe5c8SBarry Smith       c_q = c + m*(*idx);
3326170fe5c8SBarry Smith       a_q = a + m*i;
3327be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3328170fe5c8SBarry Smith       idx++;
3329170fe5c8SBarry Smith       b++;
3330170fe5c8SBarry Smith     }
3331170fe5c8SBarry Smith   }
3332170fe5c8SBarry Smith   PetscFunctionReturn(0);
3333170fe5c8SBarry Smith }
3334170fe5c8SBarry Smith 
3335170fe5c8SBarry Smith #undef __FUNCT__
3336170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3337170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3338170fe5c8SBarry Smith {
3339170fe5c8SBarry Smith   PetscErrorCode ierr;
3340d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3341170fe5c8SBarry Smith   Mat            Cmat;
3342170fe5c8SBarry Smith 
3343170fe5c8SBarry Smith   PetscFunctionBegin;
3344e32f2f54SBarry 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);
334539804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3346170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3347170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3348170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3349170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3350170fe5c8SBarry Smith   *C = Cmat;
3351170fe5c8SBarry Smith   PetscFunctionReturn(0);
3352170fe5c8SBarry Smith }
3353170fe5c8SBarry Smith 
3354170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3355170fe5c8SBarry Smith #undef __FUNCT__
3356170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3357170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3358170fe5c8SBarry Smith {
3359170fe5c8SBarry Smith   PetscErrorCode ierr;
3360170fe5c8SBarry Smith 
3361170fe5c8SBarry Smith   PetscFunctionBegin;
3362170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3363170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3364170fe5c8SBarry Smith   }
3365170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3366170fe5c8SBarry Smith   PetscFunctionReturn(0);
3367170fe5c8SBarry Smith }
3368170fe5c8SBarry Smith 
3369170fe5c8SBarry Smith 
33700bad9183SKris Buschelman /*MC
3371fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
33720bad9183SKris Buschelman    based on compressed sparse row format.
33730bad9183SKris Buschelman 
33740bad9183SKris Buschelman    Options Database Keys:
33750bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
33760bad9183SKris Buschelman 
33770bad9183SKris Buschelman   Level: beginner
33780bad9183SKris Buschelman 
3379f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
33800bad9183SKris Buschelman M*/
33810bad9183SKris Buschelman 
3382a6175056SHong Zhang EXTERN_C_BEGIN
3383b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3384b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3385b5e56a35SBarry Smith #endif
338665460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE)
3387af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3388af1023dbSSatish Balay #endif
33897087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
33907087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
33917087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
33927087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3393611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
33947087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3395611f576cSBarry Smith #endif
3396611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
33977087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3398611f576cSBarry Smith #endif
3399f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3400f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3401f3c0ef26SHong Zhang #endif
3402611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
34037087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3404611f576cSBarry Smith #endif
3405eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
34067087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3407eb3b5408SSatish Balay #endif
3408586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
34097087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3410586621ddSJed Brown #endif
3411719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
34127087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3413719d5645SBarry Smith #endif
3414b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
34157087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
34167087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
34177087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3418b3866ffcSBarry Smith #endif
341917667f90SBarry Smith EXTERN_C_END
342017667f90SBarry Smith 
3421b24902e0SBarry Smith 
342217667f90SBarry Smith EXTERN_C_BEGIN
34234a2ae208SSatish Balay #undef __FUNCT__
34244a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
34257087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3426273d9f13SBarry Smith {
3427273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3428dfbe8321SBarry Smith   PetscErrorCode ierr;
342938baddfdSBarry Smith   PetscMPIInt    size;
3430273d9f13SBarry Smith 
3431273d9f13SBarry Smith   PetscFunctionBegin;
34327adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3433e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3434273d9f13SBarry Smith 
343538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3436b0a32e0cSBarry Smith   B->data             = (void*)b;
3437549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3438416022c9SBarry Smith   b->row              = 0;
3439416022c9SBarry Smith   b->col              = 0;
344082bf6240SBarry Smith   b->icol             = 0;
3441b810aeb4SBarry Smith   b->reallocs         = 0;
344236db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3443f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3444416022c9SBarry Smith   b->nonew             = 0;
3445416022c9SBarry Smith   b->diag              = 0;
3446416022c9SBarry Smith   b->solve_work        = 0;
34472a1b7f2aSHong Zhang   B->spptr             = 0;
3448be6bf707SBarry Smith   b->saved_values      = 0;
3449d7f994e1SBarry Smith   b->idiag             = 0;
345071f1c65dSBarry Smith   b->mdiag             = 0;
345171f1c65dSBarry Smith   b->ssor_work         = 0;
345271f1c65dSBarry Smith   b->omega             = 1.0;
345371f1c65dSBarry Smith   b->fshift            = 0.0;
345471f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3455a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3456a30b2313SHong Zhang   b->xtoy              = 0;
3457a30b2313SHong Zhang   b->XtoY              = 0;
345888e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
345917ab2063SBarry Smith 
346035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3461b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3462700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3463b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3464b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3465b3866ffcSBarry Smith #endif
3466b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3467700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3468b5e56a35SBarry Smith #endif
346965460251SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE)
3470700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3471719d5645SBarry Smith #endif
3472611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3473700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3474611f576cSBarry Smith #endif
3475f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3476700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3477f3c0ef26SHong Zhang #endif
3478611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3479700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3480611f576cSBarry Smith #endif
3481611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3482700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3483611f576cSBarry Smith #endif
3484eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3485700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3486eb3b5408SSatish Balay #endif
3487586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3488700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3489586621ddSJed Brown #endif
3490719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3491700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3492719d5645SBarry Smith #endif
3493700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3494700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3495700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3496700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3497700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3498700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3499700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3500700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3501700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3502700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3503700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3504700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3505700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3506700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3507700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3508700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3509700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3510700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
35114108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
351217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
35133a40ed3dSBarry Smith   PetscFunctionReturn(0);
351417ab2063SBarry Smith }
3515273d9f13SBarry Smith EXTERN_C_END
351617ab2063SBarry Smith 
35174a2ae208SSatish Balay #undef __FUNCT__
3518b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3519b24902e0SBarry Smith /*
3520b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3521b24902e0SBarry Smith */
3522ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
352317ab2063SBarry Smith {
3524416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
35256849ba73SBarry Smith   PetscErrorCode ierr;
3526d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
352717ab2063SBarry Smith 
35283a40ed3dSBarry Smith   PetscFunctionBegin;
3529273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3530273d9f13SBarry Smith 
3531d5f3da31SBarry Smith   C->factortype     = A->factortype;
3532416022c9SBarry Smith   c->row            = 0;
3533416022c9SBarry Smith   c->col            = 0;
353482bf6240SBarry Smith   c->icol           = 0;
35356ad4291fSHong Zhang   c->reallocs       = 0;
353617ab2063SBarry Smith 
35376ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
353817ab2063SBarry Smith 
353926283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->rmap,1);CHKERRQ(ierr);
354026283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->cmap,1);CHKERRQ(ierr);
354126283091SBarry Smith   ierr = PetscLayoutSetUp(C->rmap);CHKERRQ(ierr);
354226283091SBarry Smith   ierr = PetscLayoutSetUp(C->cmap);CHKERRQ(ierr);
3543eec197d1SBarry Smith 
354433b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
35459518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
354617ab2063SBarry Smith   for (i=0; i<m; i++) {
3547416022c9SBarry Smith     c->imax[i] = a->imax[i];
3548416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
354917ab2063SBarry Smith   }
355017ab2063SBarry Smith 
355117ab2063SBarry Smith   /* allocate the matrix space */
3552f77e22a1SHong Zhang   if (mallocmatspace){
3553a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
35549518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3555f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
355697f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
355717ab2063SBarry Smith     if (m > 0) {
355897f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3559be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3560bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3561be6bf707SBarry Smith       } else {
3562bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
356317ab2063SBarry Smith       }
356408480c60SBarry Smith     }
3565f77e22a1SHong Zhang   }
356617ab2063SBarry Smith 
35676ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3568416022c9SBarry Smith   c->roworiented       = a->roworiented;
3569416022c9SBarry Smith   c->nonew             = a->nonew;
3570416022c9SBarry Smith   if (a->diag) {
357197f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
357252e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
357317ab2063SBarry Smith     for (i=0; i<m; i++) {
3574416022c9SBarry Smith       c->diag[i] = a->diag[i];
357517ab2063SBarry Smith     }
35763a40ed3dSBarry Smith   } else c->diag           = 0;
35776ad4291fSHong Zhang   c->solve_work            = 0;
35786ad4291fSHong Zhang   c->saved_values          = 0;
35796ad4291fSHong Zhang   c->idiag                 = 0;
358071f1c65dSBarry Smith   c->ssor_work             = 0;
3581a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3582e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3583e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
35846ad4291fSHong Zhang   c->xtoy                  = 0;
35856ad4291fSHong Zhang   c->XtoY                  = 0;
35866ad4291fSHong Zhang 
3587416022c9SBarry Smith   c->nz                 = a->nz;
35888ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3589273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3590754ec7b1SSatish Balay 
35916ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
35926ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3593cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3594cd6b891eSBarry Smith   if (a->compressedrow.use){
35956ad4291fSHong Zhang     i = a->compressedrow.nrows;
35960e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
35976ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
35986ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
359927ea64f8SHong Zhang   } else {
360027ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
360127ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
360227ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
36036ad4291fSHong Zhang   }
360488e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
36054108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
36064846f1f5SKris Buschelman 
36077adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
36083a40ed3dSBarry Smith   PetscFunctionReturn(0);
360917ab2063SBarry Smith }
361017ab2063SBarry Smith 
36114a2ae208SSatish Balay #undef __FUNCT__
3612b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3613b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3614b24902e0SBarry Smith {
3615b24902e0SBarry Smith   PetscErrorCode ierr;
3616b24902e0SBarry Smith 
3617b24902e0SBarry Smith   PetscFunctionBegin;
3618b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
36194b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3620b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3621f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3622b24902e0SBarry Smith   PetscFunctionReturn(0);
3623b24902e0SBarry Smith }
3624b24902e0SBarry Smith 
3625b24902e0SBarry Smith #undef __FUNCT__
36264a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3627112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3628fbdbba38SShri Abhyankar {
3629fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3630fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3631fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3632fbdbba38SShri Abhyankar   int            fd;
3633fbdbba38SShri Abhyankar   PetscMPIInt    size;
3634fbdbba38SShri Abhyankar   MPI_Comm       comm;
3635fbdbba38SShri Abhyankar 
3636fbdbba38SShri Abhyankar   PetscFunctionBegin;
3637fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3638fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3639fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3640fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3641fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3642fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3643fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3644fbdbba38SShri Abhyankar 
3645fbdbba38SShri Abhyankar   if (nz < 0) {
3646fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3647fbdbba38SShri Abhyankar   }
3648fbdbba38SShri Abhyankar 
3649fbdbba38SShri Abhyankar   /* read in row lengths */
3650fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3651fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3652fbdbba38SShri Abhyankar 
3653fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3654fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3655fbdbba38SShri 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);
3656fbdbba38SShri Abhyankar 
3657fbdbba38SShri Abhyankar   /* set global size if not set already*/
3658f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3659fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3660aabbc4fbSShri Abhyankar   } else {
3661fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3662fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3663f501eaabSShri 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);
3664aabbc4fbSShri Abhyankar   }
3665fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3666fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3667fbdbba38SShri Abhyankar 
3668fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3669fbdbba38SShri Abhyankar 
3670fbdbba38SShri Abhyankar   /* read in nonzero values */
3671fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3672fbdbba38SShri Abhyankar 
3673fbdbba38SShri Abhyankar   /* set matrix "i" values */
3674fbdbba38SShri Abhyankar   a->i[0] = 0;
3675fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3676fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3677fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3678fbdbba38SShri Abhyankar   }
3679fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3680fbdbba38SShri Abhyankar 
3681fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3682fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3683fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3684fbdbba38SShri Abhyankar }
3685fbdbba38SShri Abhyankar 
3686fbdbba38SShri Abhyankar #undef __FUNCT__
3687b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3688ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
36897264ac53SSatish Balay {
36907264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3691dfbe8321SBarry Smith   PetscErrorCode ierr;
3692eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3693eeffb40dSHong Zhang   PetscInt k;
3694eeffb40dSHong Zhang #endif
36957264ac53SSatish Balay 
36963a40ed3dSBarry Smith   PetscFunctionBegin;
3697bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3698d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
3699ca44d042SBarry Smith     *flg = PETSC_FALSE;
3700ca44d042SBarry Smith     PetscFunctionReturn(0);
3701bcd2baecSBarry Smith   }
37027264ac53SSatish Balay 
37037264ac53SSatish Balay   /* if the a->i are the same */
3704d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3705abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
37067264ac53SSatish Balay 
37077264ac53SSatish Balay   /* if a->j are the same */
370897f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3709abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3710bcd2baecSBarry Smith 
3711bcd2baecSBarry Smith   /* if a->a are the same */
3712eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3713eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
3714eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
3715eeffb40dSHong Zhang       *flg = PETSC_FALSE;
37163a40ed3dSBarry Smith       PetscFunctionReturn(0);
3717eeffb40dSHong Zhang     }
3718eeffb40dSHong Zhang   }
3719eeffb40dSHong Zhang #else
3720eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
3721eeffb40dSHong Zhang #endif
3722eeffb40dSHong Zhang   PetscFunctionReturn(0);
37237264ac53SSatish Balay }
372436db0b34SBarry Smith 
37254a2ae208SSatish Balay #undef __FUNCT__
37264a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
372705869f15SSatish Balay /*@
372836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
372936db0b34SBarry Smith               provided by the user.
373036db0b34SBarry Smith 
3731c75a6043SHong Zhang       Collective on MPI_Comm
373236db0b34SBarry Smith 
373336db0b34SBarry Smith    Input Parameters:
373436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
373536db0b34SBarry Smith .   m - number of rows
373636db0b34SBarry Smith .   n - number of columns
373736db0b34SBarry Smith .   i - row indices
373836db0b34SBarry Smith .   j - column indices
373936db0b34SBarry Smith -   a - matrix values
374036db0b34SBarry Smith 
374136db0b34SBarry Smith    Output Parameter:
374236db0b34SBarry Smith .   mat - the matrix
374336db0b34SBarry Smith 
374436db0b34SBarry Smith    Level: intermediate
374536db0b34SBarry Smith 
374636db0b34SBarry Smith    Notes:
37470551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
374836db0b34SBarry Smith     once the matrix is destroyed
374936db0b34SBarry Smith 
375036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
375136db0b34SBarry Smith 
3752bfeeae90SHong Zhang        The i and j indices are 0 based
375336db0b34SBarry Smith 
3754a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
3755a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
3756a4552177SSatish Balay     as shown:
3757a4552177SSatish Balay 
3758a4552177SSatish Balay         1 0 0
3759a4552177SSatish Balay         2 0 3
3760a4552177SSatish Balay         4 5 6
3761a4552177SSatish Balay 
3762a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
37639985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
3764a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
3765a4552177SSatish Balay 
37669985e31cSBarry Smith 
37672fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
376836db0b34SBarry Smith 
376936db0b34SBarry Smith @*/
37707087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
377136db0b34SBarry Smith {
3772dfbe8321SBarry Smith   PetscErrorCode ierr;
3773cbcfb4deSHong Zhang   PetscInt       ii;
377436db0b34SBarry Smith   Mat_SeqAIJ     *aij;
3775cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
3776cbcfb4deSHong Zhang   PetscInt       jj;
3777cbcfb4deSHong Zhang #endif
377836db0b34SBarry Smith 
377936db0b34SBarry Smith   PetscFunctionBegin;
3780a96a251dSBarry Smith   if (i[0]) {
3781e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
378236db0b34SBarry Smith   }
3783f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3784f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3785ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3786ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3787ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3788ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3789ab93d7beSBarry Smith 
379036db0b34SBarry Smith   aij->i = i;
379136db0b34SBarry Smith   aij->j = j;
379236db0b34SBarry Smith   aij->a = a;
379336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
379436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
3795e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
3796e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
379736db0b34SBarry Smith 
379836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
379936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
38002515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
3801e32f2f54SBarry 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]);
38029985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
3803e32f2f54SBarry 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);
3804e32f2f54SBarry 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);
38059985e31cSBarry Smith     }
380636db0b34SBarry Smith #endif
380736db0b34SBarry Smith   }
38082515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
380936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
3810e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
3811e32f2f54SBarry 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]);
381236db0b34SBarry Smith   }
381336db0b34SBarry Smith #endif
381436db0b34SBarry Smith 
3815b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3816b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
381736db0b34SBarry Smith   PetscFunctionReturn(0);
381836db0b34SBarry Smith }
381936db0b34SBarry Smith 
3820cc8ba8e1SBarry Smith #undef __FUNCT__
3821ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3822dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3823cc8ba8e1SBarry Smith {
3824dfbe8321SBarry Smith   PetscErrorCode ierr;
3825cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
382636db0b34SBarry Smith 
3827cc8ba8e1SBarry Smith   PetscFunctionBegin;
38288ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
3829cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3830cc8ba8e1SBarry Smith     a->coloring = coloring;
383112c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
383297f1f81fSBarry Smith     PetscInt             i,*larray;
383312c595b3SBarry Smith     ISColoring      ocoloring;
383408b6dcc0SBarry Smith     ISColoringValue *colors;
383512c595b3SBarry Smith 
383612c595b3SBarry Smith     /* set coloring for diagonal portion */
38370e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
3838d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
383912c595b3SBarry Smith       larray[i] = i;
384012c595b3SBarry Smith     }
3841784ac674SJed Brown     ierr = ISGlobalToLocalMappingApply(A->cmapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
38420e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
3843d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
384412c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
384512c595b3SBarry Smith     }
384612c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
3847d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
384812c595b3SBarry Smith     a->coloring = ocoloring;
384912c595b3SBarry Smith   }
3850cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3851cc8ba8e1SBarry Smith }
3852cc8ba8e1SBarry Smith 
3853dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3854ee4f033dSBarry Smith EXTERN_C_BEGIN
385529c1e371SBarry Smith #include "adic/ad_utils.h"
3856ee4f033dSBarry Smith EXTERN_C_END
3857cc8ba8e1SBarry Smith 
3858cc8ba8e1SBarry Smith #undef __FUNCT__
3859ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3860dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3861cc8ba8e1SBarry Smith {
3862cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3863d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
38644440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
386508b6dcc0SBarry Smith   ISColoringValue *color;
3866cc8ba8e1SBarry Smith 
3867cc8ba8e1SBarry Smith   PetscFunctionBegin;
3868e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
38694440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3870cc8ba8e1SBarry Smith   color = a->coloring->colors;
3871cc8ba8e1SBarry Smith   /* loop over rows */
3872cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3873cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3874cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3875cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3876cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3877cc8ba8e1SBarry Smith     }
38784440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3879ee4f033dSBarry Smith   }
3880ee4f033dSBarry Smith   PetscFunctionReturn(0);
3881ee4f033dSBarry Smith }
3882ee4f033dSBarry Smith #endif
3883ee4f033dSBarry Smith 
3884ee4f033dSBarry Smith #undef __FUNCT__
3885ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
388697f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3887ee4f033dSBarry Smith {
3888ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3889d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
389054f21887SBarry Smith   MatScalar       *v = a->a;
389154f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
389208b6dcc0SBarry Smith   ISColoringValue *color;
3893ee4f033dSBarry Smith 
3894ee4f033dSBarry Smith   PetscFunctionBegin;
3895e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3896ee4f033dSBarry Smith   color = a->coloring->colors;
3897ee4f033dSBarry Smith   /* loop over rows */
3898ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3899ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3900ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3901ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3902ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3903ee4f033dSBarry Smith     }
3904ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3905cc8ba8e1SBarry Smith   }
3906cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3907cc8ba8e1SBarry Smith }
390836db0b34SBarry Smith 
390981824310SBarry Smith /*
391081824310SBarry Smith     Special version for direct calls from Fortran
391181824310SBarry Smith */
39127087cfbeSBarry Smith #include "private/fortranimpl.h"
391381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
391481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
391581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
391681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
391781824310SBarry Smith #endif
391881824310SBarry Smith 
391981824310SBarry Smith /* Change these macros so can be used in void function */
392081824310SBarry Smith #undef CHKERRQ
39217adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
392281824310SBarry Smith #undef SETERRQ2
3923e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
392481824310SBarry Smith 
392581824310SBarry Smith EXTERN_C_BEGIN
392681824310SBarry Smith #undef __FUNCT__
392781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
39281f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
392981824310SBarry Smith {
393081824310SBarry Smith   Mat            A = *AA;
393181824310SBarry Smith   PetscInt       m = *mm, n = *nn;
393281824310SBarry Smith   InsertMode     is = *isis;
393381824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
393481824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
393581824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
393681824310SBarry Smith   PetscErrorCode ierr;
393781824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
393854f21887SBarry Smith   MatScalar      *ap,value,*aa;
3939ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
3940ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
394181824310SBarry Smith 
394281824310SBarry Smith   PetscFunctionBegin;
3943d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
394481824310SBarry Smith   imax = a->imax;
394581824310SBarry Smith   ai = a->i;
394681824310SBarry Smith   ailen = a->ilen;
394781824310SBarry Smith   aj = a->j;
394881824310SBarry Smith   aa = a->a;
394981824310SBarry Smith 
395081824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
395181824310SBarry Smith     row  = im[k];
395281824310SBarry Smith     if (row < 0) continue;
395381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3954d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
395581824310SBarry Smith #endif
395681824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
395781824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
395881824310SBarry Smith     low  = 0;
395981824310SBarry Smith     high = nrow;
396081824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
396181824310SBarry Smith       if (in[l] < 0) continue;
396281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3963d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
396481824310SBarry Smith #endif
396581824310SBarry Smith       col = in[l];
396681824310SBarry Smith       if (roworiented) {
396781824310SBarry Smith         value = v[l + k*n];
396881824310SBarry Smith       } else {
396981824310SBarry Smith         value = v[k + l*m];
397081824310SBarry Smith       }
397181824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
397281824310SBarry Smith 
397381824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
397481824310SBarry Smith       lastcol = col;
397581824310SBarry Smith       while (high-low > 5) {
397681824310SBarry Smith         t = (low+high)/2;
397781824310SBarry Smith         if (rp[t] > col) high = t;
397881824310SBarry Smith         else             low  = t;
397981824310SBarry Smith       }
398081824310SBarry Smith       for (i=low; i<high; i++) {
398181824310SBarry Smith         if (rp[i] > col) break;
398281824310SBarry Smith         if (rp[i] == col) {
398381824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
398481824310SBarry Smith           else                  ap[i] = value;
398581824310SBarry Smith           goto noinsert;
398681824310SBarry Smith         }
398781824310SBarry Smith       }
398881824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
398981824310SBarry Smith       if (nonew == 1) goto noinsert;
39907adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
3991fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
399281824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
399381824310SBarry Smith       /* shift up all the later entries in this row */
399481824310SBarry Smith       for (ii=N; ii>=i; ii--) {
399581824310SBarry Smith         rp[ii+1] = rp[ii];
399681824310SBarry Smith         ap[ii+1] = ap[ii];
399781824310SBarry Smith       }
399881824310SBarry Smith       rp[i] = col;
399981824310SBarry Smith       ap[i] = value;
400081824310SBarry Smith       noinsert:;
400181824310SBarry Smith       low = i + 1;
400281824310SBarry Smith     }
400381824310SBarry Smith     ailen[row] = nrow;
400481824310SBarry Smith   }
400581824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
400681824310SBarry Smith   PetscFunctionReturnVoid();
400781824310SBarry Smith }
400881824310SBarry Smith EXTERN_C_END
400962298a1eSBarry Smith 
4010