xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 6bf464f92cc51e6fd6163850774a6badb2f63b6b)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
1117ab2063SBarry Smith 
124a2ae208SSatish Balay #undef __FUNCT__
136ce1633cSBarry Smith #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
146ce1633cSBarry Smith PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
156ce1633cSBarry Smith {
166ce1633cSBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
176ce1633cSBarry Smith   const MatScalar   *aa = a->a;
186ce1633cSBarry Smith   PetscInt          i,m=A->rmap->n,cnt = 0;
196ce1633cSBarry Smith   const PetscInt    *jj = a->j,*diag;
206ce1633cSBarry Smith   PetscInt          *rows;
216ce1633cSBarry Smith   PetscErrorCode    ierr;
226ce1633cSBarry Smith 
236ce1633cSBarry Smith   PetscFunctionBegin;
246ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
256ce1633cSBarry Smith   diag = a->diag;
266ce1633cSBarry Smith   for (i=0; i<m; i++) {
276ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
286ce1633cSBarry Smith       cnt++;
296ce1633cSBarry Smith     }
306ce1633cSBarry Smith   }
316ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr);
326ce1633cSBarry Smith   cnt  = 0;
336ce1633cSBarry Smith   for (i=0; i<m; i++) {
346ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
356ce1633cSBarry Smith       rows[cnt++] = i;
366ce1633cSBarry Smith     }
376ce1633cSBarry Smith   }
386ce1633cSBarry Smith   ierr = ISCreateGeneral(((PetscObject)A)->comm,cnt,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
396ce1633cSBarry Smith   PetscFunctionReturn(0);
406ce1633cSBarry Smith }
416ce1633cSBarry Smith 
426ce1633cSBarry Smith #undef __FUNCT__
43b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
44b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
45b3a44c85SBarry Smith {
46b3a44c85SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
47b3a44c85SBarry Smith   const MatScalar   *aa;
48b3a44c85SBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
49b3a44c85SBarry Smith   const PetscInt    *ii;
50b3a44c85SBarry Smith   PetscInt          n,i,j,*rows;
51b3a44c85SBarry Smith   PetscErrorCode    ierr;
52b3a44c85SBarry Smith 
53b3a44c85SBarry Smith   PetscFunctionBegin;
54b3a44c85SBarry Smith   *keptrows = 0;
55b3a44c85SBarry Smith   ii        = a->i;
56b3a44c85SBarry Smith   for (i=0; i<m; i++) {
57b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
58b3a44c85SBarry Smith     if (!n) {
59b3a44c85SBarry Smith       cnt++;
60b3a44c85SBarry Smith       goto ok1;
61b3a44c85SBarry Smith     }
62b3a44c85SBarry Smith     aa  = a->a + ii[i];
63b3a44c85SBarry Smith     for (j=0; j<n; j++) {
64b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
65b3a44c85SBarry Smith     }
66b3a44c85SBarry Smith     cnt++;
67b3a44c85SBarry Smith     ok1:;
68b3a44c85SBarry Smith   }
69b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
70b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
71b3a44c85SBarry Smith   cnt  = 0;
72b3a44c85SBarry Smith   for (i=0; i<m; i++) {
73b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
74b3a44c85SBarry Smith     if (!n) continue;
75b3a44c85SBarry Smith     aa  = a->a + ii[i];
76b3a44c85SBarry Smith     for (j=0; j<n; j++) {
77b3a44c85SBarry Smith       if (aa[j] != 0.0) {
78b3a44c85SBarry Smith         rows[cnt++] = i;
79b3a44c85SBarry Smith         break;
80b3a44c85SBarry Smith       }
81b3a44c85SBarry Smith     }
82b3a44c85SBarry Smith   }
83b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
84b3a44c85SBarry Smith   PetscFunctionReturn(0);
85b3a44c85SBarry Smith }
86b3a44c85SBarry Smith 
87b3a44c85SBarry Smith #undef __FUNCT__
8879299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
897087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
9079299369SBarry Smith {
9179299369SBarry Smith   PetscErrorCode ierr;
9279299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
93d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
9454f21887SBarry Smith   MatScalar      *aa = aij->a;
9554f21887SBarry Smith   PetscScalar    *v;
96ace3abfcSBarry Smith   PetscBool      missing;
9779299369SBarry Smith 
9879299369SBarry Smith   PetscFunctionBegin;
9909f38230SBarry Smith   if (Y->assembled) {
10009f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
10109f38230SBarry Smith     if (!missing) {
10279299369SBarry Smith       diag = aij->diag;
10379299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
10479299369SBarry Smith       if (is == INSERT_VALUES) {
10579299369SBarry Smith 	for (i=0; i<m; i++) {
10679299369SBarry Smith 	  aa[diag[i]] = v[i];
10779299369SBarry Smith 	}
10879299369SBarry Smith       } else {
10979299369SBarry Smith 	for (i=0; i<m; i++) {
11079299369SBarry Smith 	  aa[diag[i]] += v[i];
11179299369SBarry Smith 	}
11279299369SBarry Smith       }
11379299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
11479299369SBarry Smith       PetscFunctionReturn(0);
11579299369SBarry Smith     }
11609f38230SBarry Smith   }
11709f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
11809f38230SBarry Smith   PetscFunctionReturn(0);
11909f38230SBarry Smith }
12079299369SBarry Smith 
12179299369SBarry Smith #undef __FUNCT__
1224a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
123ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
12417ab2063SBarry Smith {
125416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
126dfbe8321SBarry Smith   PetscErrorCode ierr;
12797f1f81fSBarry Smith   PetscInt       i,ishift;
12817ab2063SBarry Smith 
1293a40ed3dSBarry Smith   PetscFunctionBegin;
130d0f46423SBarry Smith   *m     = A->rmap->n;
1313a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
132bfeeae90SHong Zhang   ishift = 0;
13353e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
134d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
135bfeeae90SHong Zhang   } else if (oshift == 1) {
136d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1373b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
138d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
139d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
140ecc77c7aSBarry Smith     if (ja) {
14197f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
1423b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
143ecc77c7aSBarry Smith     }
1446945ee14SBarry Smith   } else {
145ecc77c7aSBarry Smith     *ia = a->i;
146ecc77c7aSBarry Smith     if (ja) *ja = a->j;
147a2ce50c7SBarry Smith   }
1483a40ed3dSBarry Smith   PetscFunctionReturn(0);
149a2744918SBarry Smith }
150a2744918SBarry Smith 
1514a2ae208SSatish Balay #undef __FUNCT__
1524a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
153ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1546945ee14SBarry Smith {
155dfbe8321SBarry Smith   PetscErrorCode ierr;
1566945ee14SBarry Smith 
1573a40ed3dSBarry Smith   PetscFunctionBegin;
1583a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
159bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
160606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
161ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
162bcd2baecSBarry Smith   }
1633a40ed3dSBarry Smith   PetscFunctionReturn(0);
16417ab2063SBarry Smith }
16517ab2063SBarry Smith 
1664a2ae208SSatish Balay #undef __FUNCT__
1674a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
168ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
1693b2fbd54SBarry Smith {
1703b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
171dfbe8321SBarry Smith   PetscErrorCode ierr;
172d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
17397f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
1743b2fbd54SBarry Smith 
1753a40ed3dSBarry Smith   PetscFunctionBegin;
176899cda47SBarry Smith   *nn = n;
1773a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1783b2fbd54SBarry Smith   if (symmetric) {
179d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
1803b2fbd54SBarry Smith   } else {
18197f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
18297f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
18397f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
18497f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
1853b2fbd54SBarry Smith     jj = a->j;
1863b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
187bfeeae90SHong Zhang       collengths[jj[i]]++;
1883b2fbd54SBarry Smith     }
1893b2fbd54SBarry Smith     cia[0] = oshift;
1903b2fbd54SBarry Smith     for (i=0; i<n; i++) {
1913b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1923b2fbd54SBarry Smith     }
19397f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
1943b2fbd54SBarry Smith     jj   = a->j;
195a93ec695SBarry Smith     for (row=0; row<m; row++) {
196a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
197a93ec695SBarry Smith       for (i=0; i<mr; i++) {
198bfeeae90SHong Zhang         col = *jj++;
1993b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2003b2fbd54SBarry Smith       }
2013b2fbd54SBarry Smith     }
202606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2033b2fbd54SBarry Smith     *ia = cia; *ja = cja;
2043b2fbd54SBarry Smith   }
2053a40ed3dSBarry Smith   PetscFunctionReturn(0);
2063b2fbd54SBarry Smith }
2073b2fbd54SBarry Smith 
2084a2ae208SSatish Balay #undef __FUNCT__
2094a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
210ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2113b2fbd54SBarry Smith {
212dfbe8321SBarry Smith   PetscErrorCode ierr;
213606d414cSSatish Balay 
2143a40ed3dSBarry Smith   PetscFunctionBegin;
2153a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2163b2fbd54SBarry Smith 
217606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
218606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2193b2fbd54SBarry Smith 
2203a40ed3dSBarry Smith   PetscFunctionReturn(0);
2213b2fbd54SBarry Smith }
2223b2fbd54SBarry Smith 
22387d4246cSBarry Smith #undef __FUNCT__
22487d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
22587d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
22687d4246cSBarry Smith {
22787d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
22887d4246cSBarry Smith   PetscInt       *ai = a->i;
22987d4246cSBarry Smith   PetscErrorCode ierr;
23087d4246cSBarry Smith 
23187d4246cSBarry Smith   PetscFunctionBegin;
23287d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
23387d4246cSBarry Smith   PetscFunctionReturn(0);
23487d4246cSBarry Smith }
23587d4246cSBarry Smith 
2364a2ae208SSatish Balay #undef __FUNCT__
2374a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
23897f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
23917ab2063SBarry Smith {
240416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
241e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
24297f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
2436849ba73SBarry Smith   PetscErrorCode ierr;
244e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
24554f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
246ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
247ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
24817ab2063SBarry Smith 
2493a40ed3dSBarry Smith   PetscFunctionBegin;
25071fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
25117ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
252416022c9SBarry Smith     row  = im[k];
2535ef9f2a5SBarry Smith     if (row < 0) continue;
2542515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
255e32f2f54SBarry 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);
2563b2fbd54SBarry Smith #endif
257bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
25817ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
259416022c9SBarry Smith     low  = 0;
260c71e6ed7SBarry Smith     high = nrow;
26117ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
2625ef9f2a5SBarry Smith       if (in[l] < 0) continue;
2632515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
264e32f2f54SBarry 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);
2653b2fbd54SBarry Smith #endif
266bfeeae90SHong Zhang       col = in[l];
26716371a99SBarry Smith       if (v) {
2684b0e389bSBarry Smith 	if (roworiented) {
2695ef9f2a5SBarry Smith 	  value = v[l + k*n];
270bef8e0ddSBarry Smith 	} else {
2714b0e389bSBarry Smith 	  value = v[k + l*m];
2724b0e389bSBarry Smith 	}
27316371a99SBarry Smith       } else {
27475567043SBarry Smith         value = 0.;
27516371a99SBarry Smith       }
276abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
27736db0b34SBarry Smith 
2787cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
279e2ee6c50SBarry Smith       lastcol = col;
280416022c9SBarry Smith       while (high-low > 5) {
281416022c9SBarry Smith         t = (low+high)/2;
282416022c9SBarry Smith         if (rp[t] > col) high = t;
283416022c9SBarry Smith         else             low  = t;
28417ab2063SBarry Smith       }
285416022c9SBarry Smith       for (i=low; i<high; i++) {
28617ab2063SBarry Smith         if (rp[i] > col) break;
28717ab2063SBarry Smith         if (rp[i] == col) {
288416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
28917ab2063SBarry Smith           else                  ap[i] = value;
290e44c0bd4SBarry Smith           low = i + 1;
29117ab2063SBarry Smith           goto noinsert;
29217ab2063SBarry Smith         }
29317ab2063SBarry Smith       }
294abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
295c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
296e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
297fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
298c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
299416022c9SBarry Smith       /* shift up all the later entries in this row */
300416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
30117ab2063SBarry Smith         rp[ii+1] = rp[ii];
30217ab2063SBarry Smith         ap[ii+1] = ap[ii];
30317ab2063SBarry Smith       }
30417ab2063SBarry Smith       rp[i] = col;
30517ab2063SBarry Smith       ap[i] = value;
306416022c9SBarry Smith       low   = i + 1;
307e44c0bd4SBarry Smith       noinsert:;
30817ab2063SBarry Smith     }
30917ab2063SBarry Smith     ailen[row] = nrow;
31017ab2063SBarry Smith   }
31188e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
3123a40ed3dSBarry Smith   PetscFunctionReturn(0);
31317ab2063SBarry Smith }
31417ab2063SBarry Smith 
31581824310SBarry Smith 
3164a2ae208SSatish Balay #undef __FUNCT__
3174a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
318a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
3197eb43aa7SLois Curfman McInnes {
3207eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
32197f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
32297f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
32354f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
3247eb43aa7SLois Curfman McInnes 
3253a40ed3dSBarry Smith   PetscFunctionBegin;
3267eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
3277eb43aa7SLois Curfman McInnes     row  = im[k];
328e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
329e32f2f54SBarry 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);
330bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
3317eb43aa7SLois Curfman McInnes     nrow = ailen[row];
3327eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
333e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
334e32f2f54SBarry 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);
335bfeeae90SHong Zhang       col = in[l] ;
3367eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
3377eb43aa7SLois Curfman McInnes       while (high-low > 5) {
3387eb43aa7SLois Curfman McInnes         t = (low+high)/2;
3397eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
3407eb43aa7SLois Curfman McInnes         else             low  = t;
3417eb43aa7SLois Curfman McInnes       }
3427eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
3437eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
3447eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
345b49de8d1SLois Curfman McInnes           *v++ = ap[i];
3467eb43aa7SLois Curfman McInnes           goto finished;
3477eb43aa7SLois Curfman McInnes         }
3487eb43aa7SLois Curfman McInnes       }
34997e567efSBarry Smith       *v++ = 0.0;
3507eb43aa7SLois Curfman McInnes       finished:;
3517eb43aa7SLois Curfman McInnes     }
3527eb43aa7SLois Curfman McInnes   }
3533a40ed3dSBarry Smith   PetscFunctionReturn(0);
3547eb43aa7SLois Curfman McInnes }
3557eb43aa7SLois Curfman McInnes 
35617ab2063SBarry Smith 
3574a2ae208SSatish Balay #undef __FUNCT__
3584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
359dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
36017ab2063SBarry Smith {
361416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3626849ba73SBarry Smith   PetscErrorCode ierr;
3636f69ff64SBarry Smith   PetscInt       i,*col_lens;
3646f69ff64SBarry Smith   int            fd;
36517ab2063SBarry Smith 
3663a40ed3dSBarry Smith   PetscFunctionBegin;
367b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
368d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
3690700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
370d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
371d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
372416022c9SBarry Smith   col_lens[3] = a->nz;
373416022c9SBarry Smith 
374416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
375d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
376416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
37717ab2063SBarry Smith   }
378d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
379606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
380416022c9SBarry Smith 
381416022c9SBarry Smith   /* store column indices (zero start index) */
3826f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
383416022c9SBarry Smith 
384416022c9SBarry Smith   /* store nonzero values */
3856f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
3863a40ed3dSBarry Smith   PetscFunctionReturn(0);
38717ab2063SBarry Smith }
388416022c9SBarry Smith 
38909573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
390cd155464SBarry Smith 
3914a2ae208SSatish Balay #undef __FUNCT__
3924a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
393dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
394416022c9SBarry Smith {
395416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
396dfbe8321SBarry Smith   PetscErrorCode    ierr;
397d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
398e060cb09SBarry Smith   const char        *name;
399f3ef73ceSBarry Smith   PetscViewerFormat format;
40017ab2063SBarry Smith 
4013a40ed3dSBarry Smith   PetscFunctionBegin;
402b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
40371c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
40497f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
405d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
406d00d2cf4SBarry Smith       nofinalvalue = 1;
407d00d2cf4SBarry Smith     }
408d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
409d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
41077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
41177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
412b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
41317ab2063SBarry Smith 
41417ab2063SBarry Smith     for (i=0; i<m; i++) {
415416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
416aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
41777431f27SBarry 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);
41817ab2063SBarry Smith #else
41977431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
42017ab2063SBarry Smith #endif
42117ab2063SBarry Smith       }
42217ab2063SBarry Smith     }
423d00d2cf4SBarry Smith     if (nofinalvalue) {
424d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
425d00d2cf4SBarry Smith     }
426317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
427fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
428d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
42968369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
430cd155464SBarry Smith      PetscFunctionReturn(0);
431fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
432d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4337566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
43444cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
43577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
43644cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
437aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
43836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
439a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
44036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
441a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
44236db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
443a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
4446831982aSBarry Smith         }
44544cd7ae7SLois Curfman McInnes #else
446a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
44744cd7ae7SLois Curfman McInnes #endif
44844cd7ae7SLois Curfman McInnes       }
449b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45044cd7ae7SLois Curfman McInnes     }
451d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
452fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
45397f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
454d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4557566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
45697f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
457496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
458496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
459496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
460496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
461aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
463496be53dSLois Curfman McInnes #else
464496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
465496be53dSLois Curfman McInnes #endif
466496be53dSLois Curfman McInnes         }
467496be53dSLois Curfman McInnes       }
468496be53dSLois Curfman McInnes     }
4692e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
47077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
4712e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
47277431f27SBarry 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);}
47377431f27SBarry 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);}
47477431f27SBarry 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);}
47577431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
47677431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
47777431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
478496be53dSLois Curfman McInnes     }
479b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
480606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
481496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
482496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
48377431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
484496be53dSLois Curfman McInnes       }
485b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
486496be53dSLois Curfman McInnes     }
487b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
488496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
489496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
490496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
491aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
493b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4946831982aSBarry Smith           }
495496be53dSLois Curfman McInnes #else
496b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
497496be53dSLois Curfman McInnes #endif
498496be53dSLois Curfman McInnes         }
499496be53dSLois Curfman McInnes       }
500b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
501496be53dSLois Curfman McInnes     }
502d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
503fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
50497f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
50587828ca2SBarry Smith     PetscScalar value;
50602594712SBarry Smith 
507d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5087566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
50902594712SBarry Smith     for (i=0; i<m; i++) {
51002594712SBarry Smith       jcnt = 0;
511d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
512e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
51302594712SBarry Smith           value = a->a[cnt++];
514e24b481bSBarry Smith           jcnt++;
51502594712SBarry Smith         } else {
51602594712SBarry Smith           value = 0.0;
51702594712SBarry Smith         }
518aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
519b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
52002594712SBarry Smith #else
521b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
52202594712SBarry Smith #endif
52302594712SBarry Smith       }
524b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
52502594712SBarry Smith     }
526d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5273c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
528d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5297566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
5303c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5313c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
5323c215bfdSMatthew Knepley #else
5333c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
5343c215bfdSMatthew Knepley #endif
535d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
5363c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
5373c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5383c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5393c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
5403c215bfdSMatthew 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);
5413c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
5423c215bfdSMatthew 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);
5433c215bfdSMatthew Knepley         } else {
5443c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5453c215bfdSMatthew Knepley         }
5463c215bfdSMatthew Knepley #else
5473c215bfdSMatthew Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr);
5483c215bfdSMatthew Knepley #endif
5493c215bfdSMatthew Knepley       }
5503c215bfdSMatthew Knepley     }
551d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5523a40ed3dSBarry Smith   } else {
553d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5547566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
555d5f3da31SBarry Smith     if (A->factortype){
55616cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
55716cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
55816cd7e1dSShri Abhyankar         /* L part */
55916cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+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 	/* diagonal */
57316cd7e1dSShri Abhyankar 	j = a->diag[i];
57416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
57516cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
57616cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57716cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
57816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57916cd7e1dSShri Abhyankar           } else {
58016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
58116cd7e1dSShri Abhyankar           }
58216cd7e1dSShri Abhyankar #else
58316cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
58416cd7e1dSShri Abhyankar #endif
58516cd7e1dSShri Abhyankar 
58616cd7e1dSShri Abhyankar 	/* U part */
58716cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
58816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
58916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
59016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
59216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59316cd7e1dSShri Abhyankar           } else {
59416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
59516cd7e1dSShri Abhyankar           }
59616cd7e1dSShri Abhyankar #else
59716cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
59816cd7e1dSShri Abhyankar #endif
59916cd7e1dSShri Abhyankar }
60016cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
60116cd7e1dSShri Abhyankar         }
60216cd7e1dSShri Abhyankar     } else {
60317ab2063SBarry Smith       for (i=0; i<m; i++) {
60477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
605416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
606aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
60736db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
608a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
60936db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
610a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6113a40ed3dSBarry Smith           } else {
612a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
61317ab2063SBarry Smith           }
61417ab2063SBarry Smith #else
615a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
61617ab2063SBarry Smith #endif
61717ab2063SBarry Smith         }
618b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
61917ab2063SBarry Smith       }
62016cd7e1dSShri Abhyankar     }
621d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
62217ab2063SBarry Smith   }
623b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6243a40ed3dSBarry Smith   PetscFunctionReturn(0);
625416022c9SBarry Smith }
626416022c9SBarry Smith 
6274a2ae208SSatish Balay #undef __FUNCT__
6284a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
629dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
630416022c9SBarry Smith {
631480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
632416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
633dfbe8321SBarry Smith   PetscErrorCode    ierr;
634d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
63536db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
636b0a32e0cSBarry Smith   PetscViewer       viewer;
637f3ef73ceSBarry Smith   PetscViewerFormat format;
638cddf8d76SBarry Smith 
6393a40ed3dSBarry Smith   PetscFunctionBegin;
640480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
641b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
64219bcc07fSBarry Smith 
643b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
644416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
6450513a670SBarry Smith 
646fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
6470513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
648b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
649416022c9SBarry Smith     for (i=0; i<m; i++) {
650cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
651bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
652bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
653aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
65436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
655cddf8d76SBarry Smith #else
656cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
657cddf8d76SBarry Smith #endif
658b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
659cddf8d76SBarry Smith       }
660cddf8d76SBarry Smith     }
661b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
662cddf8d76SBarry Smith     for (i=0; i<m; i++) {
663cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
664bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
665bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
666cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
667b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
668cddf8d76SBarry Smith       }
669cddf8d76SBarry Smith     }
670b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
671cddf8d76SBarry Smith     for (i=0; i<m; i++) {
672cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
673bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
674bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
675aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
67636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
677cddf8d76SBarry Smith #else
678cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
679cddf8d76SBarry Smith #endif
680b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
681416022c9SBarry Smith       }
682416022c9SBarry Smith     }
6830513a670SBarry Smith   } else {
6840513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
6850513a670SBarry Smith     /* first determine max of all nonzero values */
68697f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
687b0a32e0cSBarry Smith     PetscDraw   popup;
68836db0b34SBarry Smith     PetscReal scale;
6890513a670SBarry Smith 
6900513a670SBarry Smith     for (i=0; i<nz; i++) {
6910513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
6920513a670SBarry Smith     }
693b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
694b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
695b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
6960513a670SBarry Smith     count = 0;
6970513a670SBarry Smith     for (i=0; i<m; i++) {
6980513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
699bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
700bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
70197f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
702b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
7030513a670SBarry Smith         count++;
7040513a670SBarry Smith       }
7050513a670SBarry Smith     }
7060513a670SBarry Smith   }
707480ef9eaSBarry Smith   PetscFunctionReturn(0);
708480ef9eaSBarry Smith }
709cddf8d76SBarry Smith 
7104a2ae208SSatish Balay #undef __FUNCT__
7114a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
712dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
713480ef9eaSBarry Smith {
714dfbe8321SBarry Smith   PetscErrorCode ierr;
715b0a32e0cSBarry Smith   PetscDraw      draw;
71636db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
717ace3abfcSBarry Smith   PetscBool      isnull;
718480ef9eaSBarry Smith 
719480ef9eaSBarry Smith   PetscFunctionBegin;
720b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
721b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
722480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
723480ef9eaSBarry Smith 
724480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
725d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
726480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
727b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
728b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
729480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7303a40ed3dSBarry Smith   PetscFunctionReturn(0);
731416022c9SBarry Smith }
732416022c9SBarry Smith 
7334a2ae208SSatish Balay #undef __FUNCT__
7344a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
735dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
736416022c9SBarry Smith {
737dfbe8321SBarry Smith   PetscErrorCode ierr;
738ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
739416022c9SBarry Smith 
7403a40ed3dSBarry Smith   PetscFunctionBegin;
7412692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
7422692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
7432692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
744c45a1595SBarry Smith   if (iascii) {
7453a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7460f5bd95cSBarry Smith   } else if (isbinary) {
7473a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
7480f5bd95cSBarry Smith   } else if (isdraw) {
7493a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
7505cd90555SBarry Smith   } else {
751e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
75217ab2063SBarry Smith   }
7534108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
7543a40ed3dSBarry Smith   PetscFunctionReturn(0);
75517ab2063SBarry Smith }
75619bcc07fSBarry Smith 
7574a2ae208SSatish Balay #undef __FUNCT__
7584a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
759dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
76017ab2063SBarry Smith {
761416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7626849ba73SBarry Smith   PetscErrorCode ierr;
76397f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
764d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
76554f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
7663447b6efSHong Zhang   PetscReal      ratio=0.6;
76717ab2063SBarry Smith 
7683a40ed3dSBarry Smith   PetscFunctionBegin;
7693a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
77017ab2063SBarry Smith 
77143ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
77217ab2063SBarry Smith   for (i=1; i<m; i++) {
773416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
77417ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
77594a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
77617ab2063SBarry Smith     if (fshift) {
777bfeeae90SHong Zhang       ip = aj + ai[i] ;
778bfeeae90SHong Zhang       ap = aa + ai[i] ;
77917ab2063SBarry Smith       N  = ailen[i];
78017ab2063SBarry Smith       for (j=0; j<N; j++) {
78117ab2063SBarry Smith         ip[j-fshift] = ip[j];
78217ab2063SBarry Smith         ap[j-fshift] = ap[j];
78317ab2063SBarry Smith       }
78417ab2063SBarry Smith     }
78517ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
78617ab2063SBarry Smith   }
78717ab2063SBarry Smith   if (m) {
78817ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
78917ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
79017ab2063SBarry Smith   }
79117ab2063SBarry Smith   /* reset ilen and imax for each row */
79217ab2063SBarry Smith   for (i=0; i<m; i++) {
79317ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
79417ab2063SBarry Smith   }
795bfeeae90SHong Zhang   a->nz = ai[m];
79665e19b50SBarry 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);
79717ab2063SBarry Smith 
79809f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
799d0f46423SBarry 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);
800ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
801ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
8028e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
803dd5f02e7SSatish Balay   a->reallocs          = 0;
8044e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
80536db0b34SBarry Smith   a->rmax              = rmax;
8064e220ebcSLois Curfman McInnes 
807cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
80888e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
80971c2f376SKris Buschelman 
8104108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
81171f1c65dSBarry Smith 
81271f1c65dSBarry Smith   a->idiagvalid = PETSC_FALSE;
8133a40ed3dSBarry Smith   PetscFunctionReturn(0);
81417ab2063SBarry Smith }
81517ab2063SBarry Smith 
8164a2ae208SSatish Balay #undef __FUNCT__
81799cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
81899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
81999cafbc1SBarry Smith {
82099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
82199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
82254f21887SBarry Smith   MatScalar      *aa = a->a;
82399cafbc1SBarry Smith 
82499cafbc1SBarry Smith   PetscFunctionBegin;
82599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
82699cafbc1SBarry Smith   PetscFunctionReturn(0);
82799cafbc1SBarry Smith }
82899cafbc1SBarry Smith 
82999cafbc1SBarry Smith #undef __FUNCT__
83099cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
83199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
83299cafbc1SBarry Smith {
83399cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
83499cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
83554f21887SBarry Smith   MatScalar      *aa = a->a;
83699cafbc1SBarry Smith 
83799cafbc1SBarry Smith   PetscFunctionBegin;
83899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
83999cafbc1SBarry Smith   PetscFunctionReturn(0);
84099cafbc1SBarry Smith }
84199cafbc1SBarry Smith 
84299cafbc1SBarry Smith #undef __FUNCT__
8434a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
844dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
84517ab2063SBarry Smith {
846416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
847dfbe8321SBarry Smith   PetscErrorCode ierr;
8483a40ed3dSBarry Smith 
8493a40ed3dSBarry Smith   PetscFunctionBegin;
850d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
8513a40ed3dSBarry Smith   PetscFunctionReturn(0);
85217ab2063SBarry Smith }
853416022c9SBarry Smith 
8544a2ae208SSatish Balay #undef __FUNCT__
8554a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
856dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
85717ab2063SBarry Smith {
858416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
859dfbe8321SBarry Smith   PetscErrorCode ierr;
860d5d45c9bSBarry Smith 
8613a40ed3dSBarry Smith   PetscFunctionBegin;
862aa482453SBarry Smith #if defined(PETSC_USE_LOG)
863d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
86417ab2063SBarry Smith #endif
865e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
866*6bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
867*6bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
86805b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
86905b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
87071f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
87105b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
872*6bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
87305b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
874*6bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
87505b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
876*6bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
877cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
878a30b2313SHong Zhang 
8794108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
8804846f1f5SKris Buschelman 
881606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
882901853e0SKris Buschelman 
883dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
884901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
885901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
886901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
887901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
888901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
8895a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
890901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
891901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
892a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
893901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
89517ab2063SBarry Smith }
89617ab2063SBarry Smith 
8974a2ae208SSatish Balay #undef __FUNCT__
8984a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
899ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
90017ab2063SBarry Smith {
901416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9024846f1f5SKris Buschelman   PetscErrorCode ierr;
9033a40ed3dSBarry Smith 
9043a40ed3dSBarry Smith   PetscFunctionBegin;
905a65d3064SKris Buschelman   switch (op) {
906a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
9074e0d8c25SBarry Smith       a->roworiented       = flg;
908a65d3064SKris Buschelman       break;
909a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
910a9817697SBarry Smith       a->keepnonzeropattern    = flg;
911a65d3064SKris Buschelman       break;
912512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
913512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
914a65d3064SKris Buschelman       break;
915a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
9164e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
917a65d3064SKris Buschelman       break;
918a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
9194e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
920a65d3064SKris Buschelman       break;
92128b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
92228b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
92328b2fa4aSMatthew Knepley       break;
924a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
9254e0d8c25SBarry Smith       a->ignorezeroentries = flg;
9260df259c2SBarry Smith       break;
927cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
928cd6b891eSBarry Smith       a->compressedrow.check = flg;
929d487561eSHong Zhang       break;
9303d472b54SHong Zhang     case MAT_SPD:
9313d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
9323d472b54SHong Zhang       A->spd                             = flg;
9333d472b54SHong Zhang       if (flg) {
9343d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
9353d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
9363d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
9373d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
9383d472b54SHong Zhang       }
9393d472b54SHong Zhang       break;
940b1646e73SJed Brown     case MAT_SYMMETRIC:
941b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
942b1646e73SJed Brown     case MAT_HERMITIAN:
943b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
9444e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
945a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
946a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
947290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
948a65d3064SKris Buschelman       break;
949b87ac2d8SJed Brown     case MAT_USE_INODES:
950b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
951b87ac2d8SJed Brown       break;
952a65d3064SKris Buschelman     default:
953e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
954a65d3064SKris Buschelman   }
9554108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
9563a40ed3dSBarry Smith   PetscFunctionReturn(0);
95717ab2063SBarry Smith }
95817ab2063SBarry Smith 
9594a2ae208SSatish Balay #undef __FUNCT__
9604a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
961dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
96217ab2063SBarry Smith {
963416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9646849ba73SBarry Smith   PetscErrorCode ierr;
965d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
96635e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
96717ab2063SBarry Smith 
9683a40ed3dSBarry Smith   PetscFunctionBegin;
969d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
970e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
97135e7444dSHong Zhang 
972d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
973d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
97435e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
97535e7444dSHong Zhang     for (i=0; i<n; i++) x[i] = aa[diag[i]];
97635e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
97735e7444dSHong Zhang     PetscFunctionReturn(0);
97835e7444dSHong Zhang   }
97935e7444dSHong Zhang 
9802dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
9811ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
98235e7444dSHong Zhang   for (i=0; i<n; i++) {
98335e7444dSHong Zhang     nz = ai[i+1] - ai[i];
9842f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
98535e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
98635e7444dSHong Zhang       if (aj[j] == i) {
98735e7444dSHong Zhang         x[i] = aa[j];
98817ab2063SBarry Smith         break;
98917ab2063SBarry Smith       }
99017ab2063SBarry Smith     }
99117ab2063SBarry Smith   }
9921ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
9933a40ed3dSBarry Smith   PetscFunctionReturn(0);
99417ab2063SBarry Smith }
99517ab2063SBarry Smith 
996c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
9974a2ae208SSatish Balay #undef __FUNCT__
9984a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
999dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
100017ab2063SBarry Smith {
1001416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
10025c897100SBarry Smith   PetscScalar       *x,*y;
1003dfbe8321SBarry Smith   PetscErrorCode    ierr;
1004d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
10055c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1006a77337e4SBarry Smith   MatScalar         *v;
1007a77337e4SBarry Smith   PetscScalar       alpha;
100804fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
10093447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
1010ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
10115c897100SBarry Smith #endif
101217ab2063SBarry Smith 
10133a40ed3dSBarry Smith   PetscFunctionBegin;
10142e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
10151ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
10161ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10175c897100SBarry Smith 
10185c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1019bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
10205c897100SBarry Smith #else
10213447b6efSHong Zhang   if (usecprow){
10223447b6efSHong Zhang     m    = cprow.nrows;
10233447b6efSHong Zhang     ii   = cprow.i;
10247b2bb3b9SHong Zhang     ridx = cprow.rindex;
10253447b6efSHong Zhang   } else {
10263447b6efSHong Zhang     ii = a->i;
10273447b6efSHong Zhang   }
102817ab2063SBarry Smith   for (i=0; i<m; i++) {
10293447b6efSHong Zhang     idx   = a->j + ii[i] ;
10303447b6efSHong Zhang     v     = a->a + ii[i] ;
10313447b6efSHong Zhang     n     = ii[i+1] - ii[i];
10323447b6efSHong Zhang     if (usecprow){
10337b2bb3b9SHong Zhang       alpha = x[ridx[i]];
10343447b6efSHong Zhang     } else {
103517ab2063SBarry Smith       alpha = x[i];
10363447b6efSHong Zhang     }
103704fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
103817ab2063SBarry Smith   }
10395c897100SBarry Smith #endif
1040dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
10411ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10421ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10433a40ed3dSBarry Smith   PetscFunctionReturn(0);
104417ab2063SBarry Smith }
104517ab2063SBarry Smith 
10464a2ae208SSatish Balay #undef __FUNCT__
10475c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1048dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
10495c897100SBarry Smith {
1050dfbe8321SBarry Smith   PetscErrorCode ierr;
10515c897100SBarry Smith 
10525c897100SBarry Smith   PetscFunctionBegin;
1053170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
10545c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
10555c897100SBarry Smith   PetscFunctionReturn(0);
10565c897100SBarry Smith }
10575c897100SBarry Smith 
1058c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10595c897100SBarry Smith #undef __FUNCT__
10604a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1061dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
106217ab2063SBarry Smith {
1063416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1064d9fead3dSBarry Smith   PetscScalar       *y;
106554f21887SBarry Smith   const PetscScalar *x;
106654f21887SBarry Smith   const MatScalar   *aa;
1067dfbe8321SBarry Smith   PetscErrorCode    ierr;
1068003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1069003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
10708aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1071362ced78SSatish Balay   PetscScalar       sum;
1072ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
107317ab2063SBarry Smith 
1074b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
107597952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1076fee21e36SBarry Smith #endif
1077fee21e36SBarry Smith 
10783a40ed3dSBarry Smith   PetscFunctionBegin;
10793649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10801ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
108197952fefSHong Zhang   aj  = a->j;
108297952fefSHong Zhang   aa  = a->a;
1083416022c9SBarry Smith   ii  = a->i;
10844eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
108597952fefSHong Zhang     m    = a->compressedrow.nrows;
108697952fefSHong Zhang     ii   = a->compressedrow.i;
108797952fefSHong Zhang     ridx = a->compressedrow.rindex;
108897952fefSHong Zhang     for (i=0; i<m; i++){
108997952fefSHong Zhang       n   = ii[i+1] - ii[i];
109097952fefSHong Zhang       aj  = a->j + ii[i];
109197952fefSHong Zhang       aa  = a->a + ii[i];
109297952fefSHong Zhang       sum = 0.0;
1093a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1094003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1095003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
109697952fefSHong Zhang       y[*ridx++] = sum;
109797952fefSHong Zhang     }
109897952fefSHong Zhang   } else { /* do not use compressed row format */
1099b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1100b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1101b05257ddSBarry Smith #else
110217ab2063SBarry Smith     for (i=0; i<m; i++) {
1103003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1104003131ecSBarry Smith       aj  = a->j + ii[i];
1105003131ecSBarry Smith       aa  = a->a + ii[i];
110617ab2063SBarry Smith       sum  = 0.0;
1107a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1108003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
110917ab2063SBarry Smith       y[i] = sum;
111017ab2063SBarry Smith     }
11118d195f9aSBarry Smith #endif
1112b05257ddSBarry Smith   }
1113dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
11143649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11151ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11163a40ed3dSBarry Smith   PetscFunctionReturn(0);
111717ab2063SBarry Smith }
111817ab2063SBarry Smith 
1119c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
11204a2ae208SSatish Balay #undef __FUNCT__
11214a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1122dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
112317ab2063SBarry Smith {
1124416022c9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
112554f21887SBarry Smith   PetscScalar     *x,*y,*z;
112654f21887SBarry Smith   const MatScalar *aa;
1127dfbe8321SBarry Smith   PetscErrorCode  ierr;
1128d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1129aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
113097952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1131362ced78SSatish Balay   PetscScalar     sum;
1132ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1133e36a17ebSSatish Balay #endif
11349ea0dfa2SSatish Balay 
11353a40ed3dSBarry Smith   PetscFunctionBegin;
11361ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11371ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11382e8a6d31SBarry Smith   if (zz != yy) {
11391ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
11402e8a6d31SBarry Smith   } else {
11412e8a6d31SBarry Smith     z = y;
11422e8a6d31SBarry Smith   }
1143bfeeae90SHong Zhang 
114497952fefSHong Zhang   aj  = a->j;
114597952fefSHong Zhang   aa  = a->a;
1146cddf8d76SBarry Smith   ii  = a->i;
1147aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
114897952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
114902ab625aSSatish Balay #else
11504eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
11514eb6d288SHong Zhang     if (zz != yy){
11524eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
11534eb6d288SHong Zhang     }
115497952fefSHong Zhang     m    = a->compressedrow.nrows;
115597952fefSHong Zhang     ii   = a->compressedrow.i;
115697952fefSHong Zhang     ridx = a->compressedrow.rindex;
115797952fefSHong Zhang     for (i=0; i<m; i++){
115897952fefSHong Zhang       n  = ii[i+1] - ii[i];
115997952fefSHong Zhang       aj  = a->j + ii[i];
116097952fefSHong Zhang       aa  = a->a + ii[i];
116197952fefSHong Zhang       sum = y[*ridx];
116297952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
116397952fefSHong Zhang       z[*ridx++] = sum;
116497952fefSHong Zhang     }
116597952fefSHong Zhang   } else { /* do not use compressed row format */
116617ab2063SBarry Smith     for (i=0; i<m; i++) {
11679ea0dfa2SSatish Balay       jrow = ii[i];
11689ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
116917ab2063SBarry Smith       sum  = y[i];
11709ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
117197952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
11729ea0dfa2SSatish Balay       }
117317ab2063SBarry Smith       z[i] = sum;
117417ab2063SBarry Smith     }
117597952fefSHong Zhang   }
117602ab625aSSatish Balay #endif
1177dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11781ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11791ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11802e8a6d31SBarry Smith   if (zz != yy) {
11811ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
11822e8a6d31SBarry Smith   }
11838154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
11846b375ea7SVictor Minden   /*
1185918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1186918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1187918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
11886b375ea7SVictor Minden   */
1189918e98c3SVictor Minden #endif
11903a40ed3dSBarry Smith   PetscFunctionReturn(0);
119117ab2063SBarry Smith }
119217ab2063SBarry Smith 
119317ab2063SBarry Smith /*
119417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
119517ab2063SBarry Smith */
11964a2ae208SSatish Balay #undef __FUNCT__
11974a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1198dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
119917ab2063SBarry Smith {
1200416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12016849ba73SBarry Smith   PetscErrorCode ierr;
1202d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
120317ab2063SBarry Smith 
12043a40ed3dSBarry Smith   PetscFunctionBegin;
120509f38230SBarry Smith   if (!a->diag) {
120609f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
12079518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
120809f38230SBarry Smith   }
1209d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
121009f38230SBarry Smith     a->diag[i] = a->i[i+1];
1211bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1212bfeeae90SHong Zhang       if (a->j[j] == i) {
121309f38230SBarry Smith         a->diag[i] = j;
121417ab2063SBarry Smith         break;
121517ab2063SBarry Smith       }
121617ab2063SBarry Smith     }
121717ab2063SBarry Smith   }
12183a40ed3dSBarry Smith   PetscFunctionReturn(0);
121917ab2063SBarry Smith }
122017ab2063SBarry Smith 
1221be5855fcSBarry Smith /*
1222be5855fcSBarry Smith      Checks for missing diagonals
1223be5855fcSBarry Smith */
12244a2ae208SSatish Balay #undef __FUNCT__
12254a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1226ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1227be5855fcSBarry Smith {
1228be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
122997f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1230be5855fcSBarry Smith 
1231be5855fcSBarry Smith   PetscFunctionBegin;
123209f38230SBarry Smith   *missing = PETSC_FALSE;
1233d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
123409f38230SBarry Smith     *missing  = PETSC_TRUE;
123509f38230SBarry Smith     if (d) *d = 0;
123609f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
123709f38230SBarry Smith   } else {
1238f1e2ffcdSBarry Smith     diag = a->diag;
1239d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1240bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
124109f38230SBarry Smith 	*missing = PETSC_TRUE;
124209f38230SBarry Smith 	if (d) *d = i;
124309f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
124409f38230SBarry Smith       }
1245be5855fcSBarry Smith     }
1246be5855fcSBarry Smith   }
1247be5855fcSBarry Smith   PetscFunctionReturn(0);
1248be5855fcSBarry Smith }
1249be5855fcSBarry Smith 
125071f1c65dSBarry Smith EXTERN_C_BEGIN
125171f1c65dSBarry Smith #undef __FUNCT__
125271f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
12537087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
125471f1c65dSBarry Smith {
125571f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
125671f1c65dSBarry Smith   PetscErrorCode ierr;
1257d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
125854f21887SBarry Smith   MatScalar      *v = a->a;
125954f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
126071f1c65dSBarry Smith 
126171f1c65dSBarry Smith   PetscFunctionBegin;
126271f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
126371f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
126471f1c65dSBarry Smith   diag = a->diag;
126571f1c65dSBarry Smith   if (!a->idiag) {
126671f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
126771f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
126871f1c65dSBarry Smith     v        = a->a;
126971f1c65dSBarry Smith   }
127071f1c65dSBarry Smith   mdiag = a->mdiag;
127171f1c65dSBarry Smith   idiag = a->idiag;
127271f1c65dSBarry Smith 
1273028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
127471f1c65dSBarry Smith     for (i=0; i<m; i++) {
127571f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1276e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
127771f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
127871f1c65dSBarry Smith     }
127971f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
128071f1c65dSBarry Smith   } else {
128171f1c65dSBarry Smith     for (i=0; i<m; i++) {
128271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
128371f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
128471f1c65dSBarry Smith     }
1285dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
128671f1c65dSBarry Smith   }
128771f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
128871f1c65dSBarry Smith   PetscFunctionReturn(0);
128971f1c65dSBarry Smith }
12905a9745a3SMatthew Knepley EXTERN_C_END
129171f1c65dSBarry Smith 
1292c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
12934a2ae208SSatish Balay #undef __FUNCT__
129441f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
129541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
129617ab2063SBarry Smith {
1297416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1298e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1299e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
130054f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1301dfbe8321SBarry Smith   PetscErrorCode     ierr;
1302d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
130397f1f81fSBarry Smith   const PetscInt     *idx,*diag;
130417ab2063SBarry Smith 
13053a40ed3dSBarry Smith   PetscFunctionBegin;
1306b965ef7fSBarry Smith   its = its*lits;
130791723122SBarry Smith 
130871f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
130971f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
131071f1c65dSBarry Smith   a->fshift = fshift;
131171f1c65dSBarry Smith   a->omega  = omega;
1312ed480e8bSBarry Smith 
131371f1c65dSBarry Smith   diag = a->diag;
131471f1c65dSBarry Smith   t     = a->ssor_work;
1315ed480e8bSBarry Smith   idiag = a->idiag;
131671f1c65dSBarry Smith   mdiag = a->mdiag;
1317ed480e8bSBarry Smith 
13181ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
13193649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
132071f1c65dSBarry Smith   CHKMEMQ;
1321ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
132217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
132317ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1324ed480e8bSBarry Smith     bs = b;
132517ab2063SBarry Smith     for (i=0; i<m; i++) {
132671f1c65dSBarry Smith         d    = fshift + mdiag[i];
1327416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1328ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1329ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
133017ab2063SBarry Smith         sum  = b[i]*d/omega;
1331003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
133217ab2063SBarry Smith         x[i] = sum;
133317ab2063SBarry Smith     }
13341ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13353649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1336efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13373a40ed3dSBarry Smith     PetscFunctionReturn(0);
133817ab2063SBarry Smith   }
1339c783ea89SBarry Smith 
134048af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1341e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
13423a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
134317ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1344887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
134517ab2063SBarry Smith 
134617ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
134717ab2063SBarry Smith 
1348887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
134917ab2063SBarry Smith     */
135017ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
135117ab2063SBarry Smith 
135217ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
135317ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1354416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1355ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1356ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
135717ab2063SBarry Smith       sum  = b[i];
1358e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1359ed480e8bSBarry Smith       x[i] = sum*idiag[i];
136017ab2063SBarry Smith     }
136117ab2063SBarry Smith 
136217ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1363416022c9SBarry Smith     v = a->a;
1364ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
136517ab2063SBarry Smith 
136617ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1367ed480e8bSBarry Smith     ts = t;
1368416022c9SBarry Smith     diag = a->diag;
136917ab2063SBarry Smith     for (i=0; i<m; i++) {
1370416022c9SBarry Smith       n    = diag[i] - a->i[i];
1371ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1372ed480e8bSBarry Smith       v    = a->a + a->i[i];
137317ab2063SBarry Smith       sum  = t[i];
1374003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1375ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1376733d66baSBarry Smith       /*  x = x + t */
1377733d66baSBarry Smith       x[i] += t[i];
137817ab2063SBarry Smith     }
137917ab2063SBarry Smith 
1380dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
13811ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13823649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
13833a40ed3dSBarry Smith     PetscFunctionReturn(0);
138417ab2063SBarry Smith   }
138517ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
138617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
138717ab2063SBarry Smith       for (i=0; i<m; i++) {
1388416022c9SBarry Smith         n    = diag[i] - a->i[i];
1389ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1390ed480e8bSBarry Smith         v    = a->a + a->i[i];
139117ab2063SBarry Smith         sum  = b[i];
1392e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13935c99c7daSBarry Smith         t[i] = sum;
1394ed480e8bSBarry Smith         x[i] = sum*idiag[i];
139517ab2063SBarry Smith       }
13965c99c7daSBarry Smith       xb = t;
1397efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13983a40ed3dSBarry Smith     } else xb = b;
139917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
140017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1401416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1402ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1403ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
140417ab2063SBarry Smith         sum  = xb[i];
1405e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
14065c99c7daSBarry Smith         if (xb == b) {
1407ed480e8bSBarry Smith           x[i] = sum*idiag[i];
14085c99c7daSBarry Smith         } else {
14095c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
141017ab2063SBarry Smith         }
14115c99c7daSBarry Smith       }
1412efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
141317ab2063SBarry Smith     }
141417ab2063SBarry Smith     its--;
141517ab2063SBarry Smith   }
141617ab2063SBarry Smith   while (its--) {
141717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
141817ab2063SBarry Smith       for (i=0; i<m; i++) {
1419416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1420ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1421ed480e8bSBarry Smith         v    = a->a + a->i[i];
142217ab2063SBarry Smith         sum  = b[i];
1423e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1424ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
142517ab2063SBarry Smith       }
14269f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
142717ab2063SBarry Smith     }
142817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
142917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1430416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1431ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1432ed480e8bSBarry Smith         v    = a->a + a->i[i];
143317ab2063SBarry Smith         sum  = b[i];
1434e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1435ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
143617ab2063SBarry Smith       }
14379f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
143817ab2063SBarry Smith     }
143917ab2063SBarry Smith   }
14401ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14413649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
144271f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
144317ab2063SBarry Smith }
144417ab2063SBarry Smith 
14452af78befSBarry Smith 
14464a2ae208SSatish Balay #undef __FUNCT__
14474a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1448dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
144917ab2063SBarry Smith {
1450416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14514e220ebcSLois Curfman McInnes 
14523a40ed3dSBarry Smith   PetscFunctionBegin;
14534e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
14544e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
14554e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
14564e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
14574e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
14588e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
14597adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1460d5f3da31SBarry Smith   if (A->factortype) {
14614e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
14624e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
14634e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
14644e220ebcSLois Curfman McInnes   } else {
14654e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
14664e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
14674e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
14684e220ebcSLois Curfman McInnes   }
14693a40ed3dSBarry Smith   PetscFunctionReturn(0);
147017ab2063SBarry Smith }
147117ab2063SBarry Smith 
14724a2ae208SSatish Balay #undef __FUNCT__
14734a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
14742b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
147517ab2063SBarry Smith {
1476416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14773b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
14786849ba73SBarry Smith   PetscErrorCode    ierr;
147997b48c8fSBarry Smith   const PetscScalar *xx;
148097b48c8fSBarry Smith   PetscScalar       *bb;
1481ace3abfcSBarry Smith   PetscBool         missing;
148217ab2063SBarry Smith 
14833a40ed3dSBarry Smith   PetscFunctionBegin;
148497b48c8fSBarry Smith   if (x && b) {
148597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
148697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
148797b48c8fSBarry Smith     for (i=0; i<N; i++) {
148897b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
148997b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
149097b48c8fSBarry Smith     }
149197b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
149297b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
149397b48c8fSBarry Smith   }
149497b48c8fSBarry Smith 
1495a9817697SBarry Smith   if (a->keepnonzeropattern) {
1496f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1497e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1498bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1499f1e2ffcdSBarry Smith     }
1500f4df32b1SMatthew Knepley     if (diag != 0.0) {
150109f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1502e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1503f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1504f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1505f1e2ffcdSBarry Smith       }
1506f1e2ffcdSBarry Smith     }
150788e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1508f1e2ffcdSBarry Smith   } else {
1509f4df32b1SMatthew Knepley     if (diag != 0.0) {
151017ab2063SBarry Smith       for (i=0; i<N; i++) {
1511e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15127ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1513416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1514f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1515bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
15167ae801bdSBarry Smith         } else { /* in case row was completely empty */
1517f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
151817ab2063SBarry Smith         }
151917ab2063SBarry Smith       }
15203a40ed3dSBarry Smith     } else {
152117ab2063SBarry Smith       for (i=0; i<N; i++) {
1522e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1523416022c9SBarry Smith         a->ilen[rows[i]] = 0;
152417ab2063SBarry Smith       }
152517ab2063SBarry Smith     }
152688e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1527f1e2ffcdSBarry Smith   }
152843a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15293a40ed3dSBarry Smith   PetscFunctionReturn(0);
153017ab2063SBarry Smith }
153117ab2063SBarry Smith 
15324a2ae208SSatish Balay #undef __FUNCT__
15336e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
15346e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15356e169961SBarry Smith {
15366e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
15376e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
15386e169961SBarry Smith   PetscErrorCode    ierr;
15392b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
15406e169961SBarry Smith   const PetscScalar *xx;
15416e169961SBarry Smith   PetscScalar       *bb;
15426e169961SBarry Smith 
15436e169961SBarry Smith   PetscFunctionBegin;
15446e169961SBarry Smith   if (x && b) {
15456e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
15466e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15472b40b63fSBarry Smith     vecs = PETSC_TRUE;
15486e169961SBarry Smith   }
15496e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
15506e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
15516e169961SBarry Smith   for (i=0; i<N; i++) {
15526e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15536e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
15546e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
15556e169961SBarry Smith   }
15566e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
15576e169961SBarry Smith     if (!zeroed[i]) {
15586e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
15596e169961SBarry Smith         if (zeroed[a->j[j]]) {
15602b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
15616e169961SBarry Smith           a->a[j] = 0.0;
15626e169961SBarry Smith         }
15636e169961SBarry Smith       }
15642b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
15656e169961SBarry Smith   }
15666e169961SBarry Smith   if (x && b) {
15676e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
15686e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
15696e169961SBarry Smith   }
15706e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
15716e169961SBarry Smith   if (diag != 0.0) {
15726e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
15736e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
15746e169961SBarry Smith     for (i=0; i<N; i++) {
15756e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
15766e169961SBarry Smith     }
15776e169961SBarry Smith   }
15786e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
15796e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15806e169961SBarry Smith   PetscFunctionReturn(0);
15816e169961SBarry Smith }
15826e169961SBarry Smith 
15836e169961SBarry Smith #undef __FUNCT__
15844a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1585a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
158617ab2063SBarry Smith {
1587416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
158897f1f81fSBarry Smith   PetscInt   *itmp;
158917ab2063SBarry Smith 
15903a40ed3dSBarry Smith   PetscFunctionBegin;
1591e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
159217ab2063SBarry Smith 
1593416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1594bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
159517ab2063SBarry Smith   if (idx) {
1596bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1597bfeeae90SHong Zhang     if (*nz) {
15984e093b46SBarry Smith       *idx = itmp;
159917ab2063SBarry Smith     }
160017ab2063SBarry Smith     else *idx = 0;
160117ab2063SBarry Smith   }
16023a40ed3dSBarry Smith   PetscFunctionReturn(0);
160317ab2063SBarry Smith }
160417ab2063SBarry Smith 
1605bfeeae90SHong Zhang /* remove this function? */
16064a2ae208SSatish Balay #undef __FUNCT__
16074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1608a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
160917ab2063SBarry Smith {
16103a40ed3dSBarry Smith   PetscFunctionBegin;
16113a40ed3dSBarry Smith   PetscFunctionReturn(0);
161217ab2063SBarry Smith }
161317ab2063SBarry Smith 
16144a2ae208SSatish Balay #undef __FUNCT__
16154a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1616dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
161717ab2063SBarry Smith {
1618416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
161954f21887SBarry Smith   MatScalar      *v = a->a;
162036db0b34SBarry Smith   PetscReal      sum = 0.0;
16216849ba73SBarry Smith   PetscErrorCode ierr;
162297f1f81fSBarry Smith   PetscInt       i,j;
162317ab2063SBarry Smith 
16243a40ed3dSBarry Smith   PetscFunctionBegin;
162517ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1626416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1627aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
162836db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
162917ab2063SBarry Smith #else
163017ab2063SBarry Smith       sum += (*v)*(*v); v++;
163117ab2063SBarry Smith #endif
163217ab2063SBarry Smith     }
1633064f8208SBarry Smith     *nrm = sqrt(sum);
16343a40ed3dSBarry Smith   } else if (type == NORM_1) {
163536db0b34SBarry Smith     PetscReal *tmp;
163697f1f81fSBarry Smith     PetscInt    *jj = a->j;
1637d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1638d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1639064f8208SBarry Smith     *nrm = 0.0;
1640416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1641bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
164217ab2063SBarry Smith     }
1643d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1644064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
164517ab2063SBarry Smith     }
1646606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
16473a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1648064f8208SBarry Smith     *nrm = 0.0;
1649d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1650bfeeae90SHong Zhang       v = a->a + a->i[j];
165117ab2063SBarry Smith       sum = 0.0;
1652416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1653cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
165417ab2063SBarry Smith       }
1655064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
165617ab2063SBarry Smith     }
16573a40ed3dSBarry Smith   } else {
1658e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
165917ab2063SBarry Smith   }
16603a40ed3dSBarry Smith   PetscFunctionReturn(0);
166117ab2063SBarry Smith }
166217ab2063SBarry Smith 
16634a2ae208SSatish Balay #undef __FUNCT__
16644a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1665fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
166617ab2063SBarry Smith {
1667416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1668416022c9SBarry Smith   Mat            C;
16696849ba73SBarry Smith   PetscErrorCode ierr;
1670d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
167154f21887SBarry Smith   MatScalar      *array = a->a;
167217ab2063SBarry Smith 
16733a40ed3dSBarry Smith   PetscFunctionBegin;
1674e32f2f54SBarry 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");
1675fc4dec0aSBarry Smith 
1676fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1677d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1678d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1679bfeeae90SHong Zhang 
1680bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
16817adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1682d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
16837adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1684ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1685606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1686a541d17aSBarry Smith   } else {
1687a541d17aSBarry Smith     C = *B;
1688a541d17aSBarry Smith   }
1689a541d17aSBarry Smith 
169017ab2063SBarry Smith   for (i=0; i<m; i++) {
169117ab2063SBarry Smith     len    = ai[i+1]-ai[i];
169287d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1693b9b97703SBarry Smith     array += len;
1694b9b97703SBarry Smith     aj    += len;
169517ab2063SBarry Smith   }
16966d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16976d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
169817ab2063SBarry Smith 
1699815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1700416022c9SBarry Smith     *B = C;
170117ab2063SBarry Smith   } else {
1702eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
170317ab2063SBarry Smith   }
17043a40ed3dSBarry Smith   PetscFunctionReturn(0);
170517ab2063SBarry Smith }
170617ab2063SBarry Smith 
1707cd0d46ebSvictorle EXTERN_C_BEGIN
1708cd0d46ebSvictorle #undef __FUNCT__
17095fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
17107087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1711cd0d46ebSvictorle {
1712cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
171354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
171454f21887SBarry Smith   MatScalar      *va,*vb;
17156849ba73SBarry Smith   PetscErrorCode ierr;
171697f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1717cd0d46ebSvictorle 
1718cd0d46ebSvictorle   PetscFunctionBegin;
1719cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1720cd0d46ebSvictorle 
1721cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1722cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17235485867bSBarry Smith   if (ma!=nb || na!=mb){
17245485867bSBarry Smith     *f = PETSC_FALSE;
17255485867bSBarry Smith     PetscFunctionReturn(0);
17265485867bSBarry Smith   }
1727cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1728cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1729cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
173097f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
173197f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1732cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1733cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1734cd0d46ebSvictorle 
1735cd0d46ebSvictorle   *f = PETSC_TRUE;
1736cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1737cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
173897f1f81fSBarry Smith       PetscInt         idc,idr;
17395485867bSBarry Smith       PetscScalar vc,vr;
1740cd0d46ebSvictorle       /* column/row index/value */
17415485867bSBarry Smith       idc = adx[aptr[i]];
17425485867bSBarry Smith       idr = bdx[bptr[idc]];
17435485867bSBarry Smith       vc  = va[aptr[i]];
17445485867bSBarry Smith       vr  = vb[bptr[idc]];
17455485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
17465485867bSBarry Smith 	*f = PETSC_FALSE;
17475485867bSBarry Smith         goto done;
1748cd0d46ebSvictorle       } else {
17495485867bSBarry Smith 	aptr[i]++;
17505485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1751cd0d46ebSvictorle       }
1752cd0d46ebSvictorle     }
1753cd0d46ebSvictorle   }
1754cd0d46ebSvictorle  done:
1755cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
17563aeef889SHong Zhang   if (B) {
17573aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
17583aeef889SHong Zhang   }
1759cd0d46ebSvictorle   PetscFunctionReturn(0);
1760cd0d46ebSvictorle }
1761cd0d46ebSvictorle EXTERN_C_END
1762cd0d46ebSvictorle 
17631cbb95d3SBarry Smith EXTERN_C_BEGIN
17641cbb95d3SBarry Smith #undef __FUNCT__
17651cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
17667087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
17671cbb95d3SBarry Smith {
17681cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
176954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
177054f21887SBarry Smith   MatScalar      *va,*vb;
17711cbb95d3SBarry Smith   PetscErrorCode ierr;
17721cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
17731cbb95d3SBarry Smith 
17741cbb95d3SBarry Smith   PetscFunctionBegin;
17751cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
17761cbb95d3SBarry Smith 
17771cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
17781cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17791cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
17801cbb95d3SBarry Smith     *f = PETSC_FALSE;
17811cbb95d3SBarry Smith     PetscFunctionReturn(0);
17821cbb95d3SBarry Smith   }
17831cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
17841cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
17851cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
17861cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
17871cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
17881cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
17891cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
17901cbb95d3SBarry Smith 
17911cbb95d3SBarry Smith   *f = PETSC_TRUE;
17921cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
17931cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
17941cbb95d3SBarry Smith       PetscInt         idc,idr;
17951cbb95d3SBarry Smith       PetscScalar vc,vr;
17961cbb95d3SBarry Smith       /* column/row index/value */
17971cbb95d3SBarry Smith       idc = adx[aptr[i]];
17981cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
17991cbb95d3SBarry Smith       vc  = va[aptr[i]];
18001cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
18011cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
18021cbb95d3SBarry Smith 	*f = PETSC_FALSE;
18031cbb95d3SBarry Smith         goto done;
18041cbb95d3SBarry Smith       } else {
18051cbb95d3SBarry Smith 	aptr[i]++;
18061cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
18071cbb95d3SBarry Smith       }
18081cbb95d3SBarry Smith     }
18091cbb95d3SBarry Smith   }
18101cbb95d3SBarry Smith  done:
18111cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
18121cbb95d3SBarry Smith   if (B) {
18131cbb95d3SBarry Smith     ierr = PetscFree(bptr);CHKERRQ(ierr);
18141cbb95d3SBarry Smith   }
18151cbb95d3SBarry Smith   PetscFunctionReturn(0);
18161cbb95d3SBarry Smith }
18171cbb95d3SBarry Smith EXTERN_C_END
18181cbb95d3SBarry Smith 
18199e29f15eSvictorle #undef __FUNCT__
18209e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1821ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
18229e29f15eSvictorle {
1823dfbe8321SBarry Smith   PetscErrorCode ierr;
18249e29f15eSvictorle   PetscFunctionBegin;
18255485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18269e29f15eSvictorle   PetscFunctionReturn(0);
18279e29f15eSvictorle }
18289e29f15eSvictorle 
18294a2ae208SSatish Balay #undef __FUNCT__
18301cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
1831ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
18321cbb95d3SBarry Smith {
18331cbb95d3SBarry Smith   PetscErrorCode ierr;
18341cbb95d3SBarry Smith   PetscFunctionBegin;
18351cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18361cbb95d3SBarry Smith   PetscFunctionReturn(0);
18371cbb95d3SBarry Smith }
18381cbb95d3SBarry Smith 
18391cbb95d3SBarry Smith #undef __FUNCT__
18404a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1841dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
184217ab2063SBarry Smith {
1843416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
184454f21887SBarry Smith   PetscScalar    *l,*r,x;
184554f21887SBarry Smith   MatScalar      *v;
1846dfbe8321SBarry Smith   PetscErrorCode ierr;
1847d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
184817ab2063SBarry Smith 
18493a40ed3dSBarry Smith   PetscFunctionBegin;
185017ab2063SBarry Smith   if (ll) {
18513ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
18523ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1853e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1854e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
18551ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1856416022c9SBarry Smith     v = a->a;
185717ab2063SBarry Smith     for (i=0; i<m; i++) {
185817ab2063SBarry Smith       x = l[i];
1859416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
186017ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
186117ab2063SBarry Smith     }
18621ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1863efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
186417ab2063SBarry Smith   }
186517ab2063SBarry Smith   if (rr) {
1866e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1867e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
18681ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1869416022c9SBarry Smith     v = a->a; jj = a->j;
187017ab2063SBarry Smith     for (i=0; i<nz; i++) {
1871bfeeae90SHong Zhang       (*v++) *= r[*jj++];
187217ab2063SBarry Smith     }
18731ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1874efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
187517ab2063SBarry Smith   }
18763a40ed3dSBarry Smith   PetscFunctionReturn(0);
187717ab2063SBarry Smith }
187817ab2063SBarry Smith 
18794a2ae208SSatish Balay #undef __FUNCT__
18804a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
188197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
188217ab2063SBarry Smith {
1883db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
18846849ba73SBarry Smith   PetscErrorCode ierr;
1885d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
188697f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
18875d0c19d7SBarry Smith   const PetscInt *irow,*icol;
18885d0c19d7SBarry Smith   PetscInt       nrows,ncols;
188997f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
189054f21887SBarry Smith   MatScalar      *a_new,*mat_a;
1891416022c9SBarry Smith   Mat            C;
1892ace3abfcSBarry Smith   PetscBool      stride,sorted;
189317ab2063SBarry Smith 
18943a40ed3dSBarry Smith   PetscFunctionBegin;
189514ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
1896e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
189714ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
1898e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
189999141d43SSatish Balay 
190017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1901b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1902b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
190317ab2063SBarry Smith 
1904fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
19050dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
1906fee21e36SBarry Smith   if (stride && step == 1) {
190702834360SBarry Smith     /* special case of contiguous rows */
19080e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
190902834360SBarry Smith     /* loop over new rows determining lens and starting points */
191002834360SBarry Smith     for (i=0; i<nrows; i++) {
1911bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1912a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
191302834360SBarry Smith       for (k=kstart; k<kend; k++) {
1914bfeeae90SHong Zhang         if (aj[k] >= first) {
191502834360SBarry Smith           starts[i] = k;
191602834360SBarry Smith           break;
191702834360SBarry Smith 	}
191802834360SBarry Smith       }
1919a2744918SBarry Smith       sum = 0;
192002834360SBarry Smith       while (k < kend) {
1921bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1922a2744918SBarry Smith         sum++;
192302834360SBarry Smith       }
1924a2744918SBarry Smith       lens[i] = sum;
192502834360SBarry Smith     }
192602834360SBarry Smith     /* create submatrix */
1927cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
192897f1f81fSBarry Smith       PetscInt n_cols,n_rows;
192908480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1930e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1931d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
193208480c60SBarry Smith       C = *B;
19333a40ed3dSBarry Smith     } else {
19347adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1935f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19367adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1937ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
193808480c60SBarry Smith     }
1939db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1940db02288aSLois Curfman McInnes 
194102834360SBarry Smith     /* loop over rows inserting into submatrix */
1942db02288aSLois Curfman McInnes     a_new    = c->a;
1943db02288aSLois Curfman McInnes     j_new    = c->j;
1944db02288aSLois Curfman McInnes     i_new    = c->i;
1945bfeeae90SHong Zhang 
194602834360SBarry Smith     for (i=0; i<nrows; i++) {
1947a2744918SBarry Smith       ii    = starts[i];
1948a2744918SBarry Smith       lensi = lens[i];
1949a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1950a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
195102834360SBarry Smith       }
195287828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1953a2744918SBarry Smith       a_new      += lensi;
1954a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1955a2744918SBarry Smith       c->ilen[i]  = lensi;
195602834360SBarry Smith     }
19570e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
19583a40ed3dSBarry Smith   } else {
195902834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
19600e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
196197f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
19620e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
196317ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
196402834360SBarry Smith     /* determine lens of each row */
196502834360SBarry Smith     for (i=0; i<nrows; i++) {
1966bfeeae90SHong Zhang       kstart  = ai[irow[i]];
196702834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
196802834360SBarry Smith       lens[i] = 0;
196902834360SBarry Smith       for (k=kstart; k<kend; k++) {
1970bfeeae90SHong Zhang         if (smap[aj[k]]) {
197102834360SBarry Smith           lens[i]++;
197202834360SBarry Smith         }
197302834360SBarry Smith       }
197402834360SBarry Smith     }
197517ab2063SBarry Smith     /* Create and fill new matrix */
1976a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1977ace3abfcSBarry Smith       PetscBool  equal;
19780f5bd95cSBarry Smith 
197999141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1980e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1981d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
19820f5bd95cSBarry Smith       if (!equal) {
1983e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
198499141d43SSatish Balay       }
1985d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
198608480c60SBarry Smith       C = *B;
19873a40ed3dSBarry Smith     } else {
19887adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1989f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19907adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1991ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
199208480c60SBarry Smith     }
199399141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
199417ab2063SBarry Smith     for (i=0; i<nrows; i++) {
199599141d43SSatish Balay       row    = irow[i];
1996bfeeae90SHong Zhang       kstart = ai[row];
199799141d43SSatish Balay       kend   = kstart + a->ilen[row];
1998bfeeae90SHong Zhang       mat_i  = c->i[i];
199999141d43SSatish Balay       mat_j  = c->j + mat_i;
200099141d43SSatish Balay       mat_a  = c->a + mat_i;
200199141d43SSatish Balay       mat_ilen = c->ilen + i;
200217ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2003bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2004ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
200599141d43SSatish Balay           *mat_a++ = a->a[k];
200699141d43SSatish Balay           (*mat_ilen)++;
200799141d43SSatish Balay 
200817ab2063SBarry Smith         }
200917ab2063SBarry Smith       }
201017ab2063SBarry Smith     }
201102834360SBarry Smith     /* Free work space */
201202834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2013606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2014606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
201502834360SBarry Smith   }
20166d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20176d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
201817ab2063SBarry Smith 
201917ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2020416022c9SBarry Smith   *B = C;
20213a40ed3dSBarry Smith   PetscFunctionReturn(0);
202217ab2063SBarry Smith }
202317ab2063SBarry Smith 
20241df811f5SHong Zhang #undef __FUNCT__
202582d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
202682d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
202782d44351SHong Zhang {
202882d44351SHong Zhang   PetscErrorCode ierr;
202982d44351SHong Zhang   Mat            B;
203082d44351SHong Zhang 
203182d44351SHong Zhang   PetscFunctionBegin;
203282d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
203382d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
203482d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
203582d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
203682d44351SHong Zhang   *subMat = B;
203782d44351SHong Zhang   PetscFunctionReturn(0);
203882d44351SHong Zhang }
203982d44351SHong Zhang 
204082d44351SHong Zhang #undef __FUNCT__
20414a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
20420481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2043a871dcd8SBarry Smith {
204463b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2045dfbe8321SBarry Smith   PetscErrorCode ierr;
204663b91edcSBarry Smith   Mat            outA;
2047ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
204863b91edcSBarry Smith 
20493a40ed3dSBarry Smith   PetscFunctionBegin;
2050e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
20511df811f5SHong Zhang 
2052b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2053b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2054a871dcd8SBarry Smith 
205563b91edcSBarry Smith   outA              = inA;
2056d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2057c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
2058*6bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2059c3122656SLisandro Dalcin   a->row = row;
2060c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
2061*6bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2062c3122656SLisandro Dalcin   a->col = col;
206363b91edcSBarry Smith 
206436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
2065*6bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
20664c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
206752e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2068f0ec6fceSSatish Balay 
206994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2070d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2071d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
207294a9d846SBarry Smith   }
207363b91edcSBarry Smith 
2074f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2075137fb511SHong Zhang   if (row_identity && col_identity) {
2076ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2077137fb511SHong Zhang   } else {
2078719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2079137fb511SHong Zhang   }
20803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2081a871dcd8SBarry Smith }
2082a871dcd8SBarry Smith 
20834a2ae208SSatish Balay #undef __FUNCT__
20844a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2085f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2086f0b747eeSBarry Smith {
2087f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2088f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2089efee365bSSatish Balay   PetscErrorCode ierr;
20900805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
20913a40ed3dSBarry Smith 
20923a40ed3dSBarry Smith   PetscFunctionBegin;
2093f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2094efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2096f0b747eeSBarry Smith }
2097f0b747eeSBarry Smith 
20984a2ae208SSatish Balay #undef __FUNCT__
20994a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
210097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2101cddf8d76SBarry Smith {
2102dfbe8321SBarry Smith   PetscErrorCode ierr;
210397f1f81fSBarry Smith   PetscInt       i;
2104cddf8d76SBarry Smith 
21053a40ed3dSBarry Smith   PetscFunctionBegin;
2106cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2107b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2108cddf8d76SBarry Smith   }
2109cddf8d76SBarry Smith 
2110cddf8d76SBarry Smith   for (i=0; i<n; i++) {
21116a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2112cddf8d76SBarry Smith   }
21133a40ed3dSBarry Smith   PetscFunctionReturn(0);
2114cddf8d76SBarry Smith }
2115cddf8d76SBarry Smith 
21164a2ae208SSatish Balay #undef __FUNCT__
21174a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
211897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
21194dcbc457SBarry Smith {
2120e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21216849ba73SBarry Smith   PetscErrorCode ierr;
21225d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
21235d0c19d7SBarry Smith   const PetscInt *idx;
212497f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2125f1af5d2fSBarry Smith   PetscBT        table;
2126bbd702dbSSatish Balay 
21273a40ed3dSBarry Smith   PetscFunctionBegin;
2128d0f46423SBarry Smith   m     = A->rmap->n;
2129e4d965acSSatish Balay   ai    = a->i;
2130bfeeae90SHong Zhang   aj    = a->j;
21318a047759SSatish Balay 
2132e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
213306763907SSatish Balay 
213497f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
21356831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
213606763907SSatish Balay 
2137e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2138b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2139e4d965acSSatish Balay     isz  = 0;
21406831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2141e4d965acSSatish Balay 
2142e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
21434dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2144b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2145e4d965acSSatish Balay 
2146dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2147e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2148f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
21494dcbc457SBarry Smith     }
215006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
2151*6bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2152e4d965acSSatish Balay 
215304a348a9SBarry Smith     k = 0;
215404a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
215504a348a9SBarry Smith       n = isz;
215606763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2157e4d965acSSatish Balay         row   = nidx[k];
2158e4d965acSSatish Balay         start = ai[row];
2159e4d965acSSatish Balay         end   = ai[row+1];
216004a348a9SBarry Smith         for (l = start; l<end ; l++){
2161efb16452SHong Zhang           val = aj[l] ;
2162f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2163e4d965acSSatish Balay         }
2164e4d965acSSatish Balay       }
2165e4d965acSSatish Balay     }
216670b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2167e4d965acSSatish Balay   }
21686831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2169606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
21703a40ed3dSBarry Smith   PetscFunctionReturn(0);
21714dcbc457SBarry Smith }
217217ab2063SBarry Smith 
21730513a670SBarry Smith /* -------------------------------------------------------------- */
21744a2ae208SSatish Balay #undef __FUNCT__
21754a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2176dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
21770513a670SBarry Smith {
21780513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21796849ba73SBarry Smith   PetscErrorCode ierr;
21803b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
21815d0c19d7SBarry Smith   const PetscInt *row,*col;
21825d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
218356cd22aeSBarry Smith   IS             icolp,irowp;
21843b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
21853b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
21860513a670SBarry Smith 
21873a40ed3dSBarry Smith   PetscFunctionBegin;
21884c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
218956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
21904c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
219156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
21920513a670SBarry Smith 
21930513a670SBarry Smith   /* determine lengths of permuted rows */
219497f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
21950513a670SBarry Smith   for (i=0; i<m; i++) {
21960513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
21970513a670SBarry Smith   }
21987adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2199f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
22007adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2201ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2202606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
22030513a670SBarry Smith 
220497f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
22050513a670SBarry Smith   for (i=0; i<m; i++) {
220632ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
22070513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2208cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
220932ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
22100513a670SBarry Smith   }
2211606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
22123c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
22130513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22140513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
221556cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
221656cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
2217*6bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
2218*6bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
22193a40ed3dSBarry Smith   PetscFunctionReturn(0);
22200513a670SBarry Smith }
22210513a670SBarry Smith 
22224a2ae208SSatish Balay #undef __FUNCT__
22234a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2224dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2225cb5b572fSBarry Smith {
2226dfbe8321SBarry Smith   PetscErrorCode ierr;
2227cb5b572fSBarry Smith 
2228cb5b572fSBarry Smith   PetscFunctionBegin;
222933f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
223033f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2231be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2232be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2233be6bf707SBarry Smith 
2234700c5bfcSBarry 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");
2235d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2236cb5b572fSBarry Smith   } else {
2237cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2238cb5b572fSBarry Smith   }
2239cb5b572fSBarry Smith   PetscFunctionReturn(0);
2240cb5b572fSBarry Smith }
2241cb5b572fSBarry Smith 
22424a2ae208SSatish Balay #undef __FUNCT__
22434a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2244dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2245273d9f13SBarry Smith {
2246dfbe8321SBarry Smith   PetscErrorCode ierr;
2247273d9f13SBarry Smith 
2248273d9f13SBarry Smith   PetscFunctionBegin;
2249ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2250273d9f13SBarry Smith   PetscFunctionReturn(0);
2251273d9f13SBarry Smith }
2252273d9f13SBarry Smith 
22534a2ae208SSatish Balay #undef __FUNCT__
22544a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2255a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
22566c0721eeSBarry Smith {
22576c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
22586c0721eeSBarry Smith   PetscFunctionBegin;
22596c0721eeSBarry Smith   *array = a->a;
22606c0721eeSBarry Smith   PetscFunctionReturn(0);
22616c0721eeSBarry Smith }
22626c0721eeSBarry Smith 
22634a2ae208SSatish Balay #undef __FUNCT__
22644a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2265dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
22666c0721eeSBarry Smith {
22676c0721eeSBarry Smith   PetscFunctionBegin;
22686c0721eeSBarry Smith   PetscFunctionReturn(0);
22696c0721eeSBarry Smith }
2270273d9f13SBarry Smith 
2271ee4f033dSBarry Smith #undef __FUNCT__
2272ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2273dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2274ee4f033dSBarry Smith {
22756849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
22766849ba73SBarry Smith   PetscErrorCode ierr;
227797f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2278efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
227987828ca2SBarry Smith   PetscScalar    *vscale_array;
2280ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2281ee4f033dSBarry Smith   Vec            w1,w2,w3;
2282ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2283ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2284ee4f033dSBarry Smith 
2285ee4f033dSBarry Smith   PetscFunctionBegin;
2286ee4f033dSBarry Smith   if (!coloring->w1) {
2287ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
228852e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2289ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
229052e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2291ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
229252e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2293ee4f033dSBarry Smith   }
2294ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2295ee4f033dSBarry Smith 
2296ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2297acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2298ee4f033dSBarry Smith   if (flg) {
2299ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2300ee4f033dSBarry Smith   } else {
2301ace3abfcSBarry Smith     PetscBool  assembled;
23020b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
23030b9b6f31SBarry Smith     if (assembled) {
2304ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2305ee4f033dSBarry Smith     }
23060b9b6f31SBarry Smith   }
2307ee4f033dSBarry Smith 
2308ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2309ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2310ee4f033dSBarry Smith 
2311ee4f033dSBarry Smith   /*
2312ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2313ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2314ee4f033dSBarry Smith   */
2315ee4f033dSBarry Smith   if (coloring->F) {
2316ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2317ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2318ee4f033dSBarry Smith     if (m1 != m2) {
2319ee4f033dSBarry Smith       coloring->F = 0;
2320ee4f033dSBarry Smith     }
2321ee4f033dSBarry Smith   }
2322ee4f033dSBarry Smith 
2323ee4f033dSBarry Smith   if (coloring->F) {
2324ee4f033dSBarry Smith     w1          = coloring->F;
2325ee4f033dSBarry Smith     coloring->F = 0;
2326ee4f033dSBarry Smith   } else {
232766f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2328ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
232966f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2330ee4f033dSBarry Smith   }
2331ee4f033dSBarry Smith 
2332ee4f033dSBarry Smith   /*
2333ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2334ee4f033dSBarry Smith   */
23351ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
23361ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2337ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2338ee4f033dSBarry Smith     /*
2339ee4f033dSBarry Smith        Loop over each column associated with color adding the
2340ee4f033dSBarry Smith        perturbation to the vector w3.
2341ee4f033dSBarry Smith     */
2342ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2343ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2344ee4f033dSBarry Smith       dx  = xx[col];
2345ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2346ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2347ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2348ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2349ee4f033dSBarry Smith #else
2350ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2351ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2352ee4f033dSBarry Smith #endif
2353ee4f033dSBarry Smith       dx                *= epsilon;
2354ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2355ee4f033dSBarry Smith     }
2356ee4f033dSBarry Smith   }
23571ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2358ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2359ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2360ee4f033dSBarry Smith 
2361ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2362ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2363ee4f033dSBarry Smith 
2364ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2365ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2366ee4f033dSBarry Smith 
23671ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2368ee4f033dSBarry Smith   /*
2369ee4f033dSBarry Smith       Loop over each color
2370ee4f033dSBarry Smith   */
2371ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
237249b058dcSBarry Smith     coloring->currentcolor = k;
2373ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
23741ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2375ee4f033dSBarry Smith     /*
2376ee4f033dSBarry Smith        Loop over each column associated with color adding the
2377ee4f033dSBarry Smith        perturbation to the vector w3.
2378ee4f033dSBarry Smith     */
2379ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2380ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2381ee4f033dSBarry Smith       dx  = xx[col];
23825b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2383ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2384ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2385ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2386ee4f033dSBarry Smith #else
2387ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2388ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2389ee4f033dSBarry Smith #endif
2390ee4f033dSBarry Smith       dx            *= epsilon;
2391e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2392ee4f033dSBarry Smith       w3_array[col] += dx;
2393ee4f033dSBarry Smith     }
23941ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2395ee4f033dSBarry Smith 
2396ee4f033dSBarry Smith     /*
2397ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2398ee4f033dSBarry Smith     */
2399ee4f033dSBarry Smith 
240066f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2401ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
240266f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2403efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2404ee4f033dSBarry Smith 
2405ee4f033dSBarry Smith     /*
2406ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2407ee4f033dSBarry Smith     */
24081ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2409ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2410ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2411ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2412ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2413ee4f033dSBarry Smith       srow   = row + start;
2414ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2415ee4f033dSBarry Smith     }
24161ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2417ee4f033dSBarry Smith   }
241849b058dcSBarry Smith   coloring->currentcolor = k;
24191ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
24201ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2421ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2422ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2423ee4f033dSBarry Smith   PetscFunctionReturn(0);
2424ee4f033dSBarry Smith }
2425ee4f033dSBarry Smith 
24268229c054SShri Abhyankar /*
24278229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
24288229c054SShri Abhyankar    have different nonzero structure.
24298229c054SShri Abhyankar */
2430ac90fabeSBarry Smith #undef __FUNCT__
24318229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
24328229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2433ec7775f6SShri Abhyankar {
24348229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2435ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2436ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2437ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2438ec7775f6SShri Abhyankar 
2439ec7775f6SShri Abhyankar   PetscFunctionBegin;
2440ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2441ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
24428af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
24438af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
24448af7cee1SJed Brown     nnz[i] = 0;
24458af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
24468af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
24478af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
24488af7cee1SJed Brown       nnz[i]++;
24498af7cee1SJed Brown     }
24508af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2451ec7775f6SShri Abhyankar   }
2452ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2453ec7775f6SShri Abhyankar }
2454ec7775f6SShri Abhyankar 
2455ec7775f6SShri Abhyankar #undef __FUNCT__
2456ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2457f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2458ac90fabeSBarry Smith {
2459dfbe8321SBarry Smith   PetscErrorCode ierr;
246097f1f81fSBarry Smith   PetscInt       i;
2461ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
24620805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2463ac90fabeSBarry Smith 
2464ac90fabeSBarry Smith   PetscFunctionBegin;
2465ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2466f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2467f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2468c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2469a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2470a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2471*6bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2472a30b2313SHong Zhang     }
2473a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2474d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2475a30b2313SHong Zhang       y->XtoY = X;
2476407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2477c537a176SHong Zhang     }
2478f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
24791e2582c4SBarry 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);
2480ac90fabeSBarry Smith   } else {
24818229c054SShri Abhyankar     Mat      B;
24828229c054SShri Abhyankar     PetscInt *nnz;
248316b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2484ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2485bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
24864aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2487ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
24888229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
24898229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2490ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2491ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
24928229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2493ac90fabeSBarry Smith   }
2494ac90fabeSBarry Smith   PetscFunctionReturn(0);
2495ac90fabeSBarry Smith }
2496ac90fabeSBarry Smith 
2497521d7252SBarry Smith #undef __FUNCT__
2498521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2499521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2500521d7252SBarry Smith {
250141c166b1SJed Brown   PetscErrorCode ierr;
250241c166b1SJed Brown 
2503521d7252SBarry Smith   PetscFunctionBegin;
250441c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
250541c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2506521d7252SBarry Smith   PetscFunctionReturn(0);
2507521d7252SBarry Smith }
2508521d7252SBarry Smith 
2509354c94deSBarry Smith #undef __FUNCT__
2510354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
25117087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2512354c94deSBarry Smith {
2513354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2514354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2515354c94deSBarry Smith   PetscInt    i,nz;
2516354c94deSBarry Smith   PetscScalar *a;
2517354c94deSBarry Smith 
2518354c94deSBarry Smith   PetscFunctionBegin;
2519354c94deSBarry Smith   nz = aij->nz;
2520354c94deSBarry Smith   a  = aij->a;
2521354c94deSBarry Smith   for (i=0; i<nz; i++) {
2522354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2523354c94deSBarry Smith   }
2524354c94deSBarry Smith #else
2525354c94deSBarry Smith   PetscFunctionBegin;
2526354c94deSBarry Smith #endif
2527354c94deSBarry Smith   PetscFunctionReturn(0);
2528354c94deSBarry Smith }
2529354c94deSBarry Smith 
2530e34fafa9SBarry Smith #undef __FUNCT__
2531985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2532985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2533e34fafa9SBarry Smith {
2534e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2535e34fafa9SBarry Smith   PetscErrorCode ierr;
2536d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2537e34fafa9SBarry Smith   PetscReal      atmp;
2538985db425SBarry Smith   PetscScalar    *x;
2539e34fafa9SBarry Smith   MatScalar      *aa;
2540e34fafa9SBarry Smith 
2541e34fafa9SBarry Smith   PetscFunctionBegin;
2542e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2543e34fafa9SBarry Smith   aa   = a->a;
2544e34fafa9SBarry Smith   ai   = a->i;
2545e34fafa9SBarry Smith   aj   = a->j;
2546e34fafa9SBarry Smith 
2547985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2548e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2549e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2550e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2551e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2552e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
25539189402eSHong Zhang     x[i] = 0.0;
2554e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2555985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2556985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2557985db425SBarry Smith       aa++; aj++;
2558985db425SBarry Smith     }
2559985db425SBarry Smith   }
2560985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2561985db425SBarry Smith   PetscFunctionReturn(0);
2562985db425SBarry Smith }
2563985db425SBarry Smith 
2564985db425SBarry Smith #undef __FUNCT__
2565985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2566985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2567985db425SBarry Smith {
2568985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2569985db425SBarry Smith   PetscErrorCode ierr;
2570d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2571985db425SBarry Smith   PetscScalar    *x;
2572985db425SBarry Smith   MatScalar      *aa;
2573985db425SBarry Smith 
2574985db425SBarry Smith   PetscFunctionBegin;
2575e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2576985db425SBarry Smith   aa   = a->a;
2577985db425SBarry Smith   ai   = a->i;
2578985db425SBarry Smith   aj   = a->j;
2579985db425SBarry Smith 
2580985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2581985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2582985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2583e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2584985db425SBarry Smith   for (i=0; i<m; i++) {
2585985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2586d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2587985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2588985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2589985db425SBarry Smith       x[i] = 0.0;
2590985db425SBarry Smith       if (idx) {
2591985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2592985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2593985db425SBarry Smith           if (aj[j] > j) {
2594985db425SBarry Smith             idx[i] = j;
2595985db425SBarry Smith             break;
2596985db425SBarry Smith           }
2597985db425SBarry Smith         }
2598985db425SBarry Smith       }
2599985db425SBarry Smith     }
2600985db425SBarry Smith     for (j=0; j<ncols; j++){
2601985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2602985db425SBarry Smith       aa++; aj++;
2603985db425SBarry Smith     }
2604985db425SBarry Smith   }
2605985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2606985db425SBarry Smith   PetscFunctionReturn(0);
2607985db425SBarry Smith }
2608985db425SBarry Smith 
2609985db425SBarry Smith #undef __FUNCT__
2610c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2611c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2612c87e5d42SMatthew Knepley {
2613c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2614c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2615c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2616c87e5d42SMatthew Knepley   PetscReal      atmp;
2617c87e5d42SMatthew Knepley   PetscScalar    *x;
2618c87e5d42SMatthew Knepley   MatScalar      *aa;
2619c87e5d42SMatthew Knepley 
2620c87e5d42SMatthew Knepley   PetscFunctionBegin;
2621e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2622c87e5d42SMatthew Knepley   aa   = a->a;
2623c87e5d42SMatthew Knepley   ai   = a->i;
2624c87e5d42SMatthew Knepley   aj   = a->j;
2625c87e5d42SMatthew Knepley 
2626c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2627c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2628c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2629e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2630c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2631c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2632289a08f5SMatthew Knepley     if (ncols) {
2633289a08f5SMatthew Knepley       /* Get first nonzero */
2634289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2635289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2636289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2637289a08f5SMatthew Knepley       }
2638289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2639289a08f5SMatthew Knepley     } else {
2640289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2641289a08f5SMatthew Knepley     }
2642c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2643c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2644289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2645c87e5d42SMatthew Knepley       aa++; aj++;
2646c87e5d42SMatthew Knepley     }
2647c87e5d42SMatthew Knepley   }
2648c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2649c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2650c87e5d42SMatthew Knepley }
2651c87e5d42SMatthew Knepley 
2652c87e5d42SMatthew Knepley #undef __FUNCT__
2653985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2654985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2655985db425SBarry Smith {
2656985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2657985db425SBarry Smith   PetscErrorCode ierr;
2658d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2659985db425SBarry Smith   PetscScalar    *x;
2660985db425SBarry Smith   MatScalar      *aa;
2661985db425SBarry Smith 
2662985db425SBarry Smith   PetscFunctionBegin;
2663e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2664985db425SBarry Smith   aa   = a->a;
2665985db425SBarry Smith   ai   = a->i;
2666985db425SBarry Smith   aj   = a->j;
2667985db425SBarry Smith 
2668985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2669985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2670985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2671e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2672985db425SBarry Smith   for (i=0; i<m; i++) {
2673985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2674d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2675985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2676985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2677985db425SBarry Smith       x[i] = 0.0;
2678985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2679985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2680985db425SBarry Smith         for (j=0;j<ncols;j++) {
2681985db425SBarry Smith           if (aj[j] > j) {
2682985db425SBarry Smith             idx[i] = j;
2683985db425SBarry Smith             break;
2684985db425SBarry Smith           }
2685985db425SBarry Smith         }
2686985db425SBarry Smith       }
2687985db425SBarry Smith     }
2688985db425SBarry Smith     for (j=0; j<ncols; j++){
2689985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2690985db425SBarry Smith       aa++; aj++;
2691e34fafa9SBarry Smith     }
2692e34fafa9SBarry Smith   }
2693e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2694e34fafa9SBarry Smith   PetscFunctionReturn(0);
2695e34fafa9SBarry Smith }
26967087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2697682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
26980a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2699cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2700cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2701cb5b572fSBarry Smith        MatMult_SeqAIJ,
270297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
27037c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
27047c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2705db4efbfdSBarry Smith        0,
2706db4efbfdSBarry Smith        0,
2707db4efbfdSBarry Smith        0,
2708db4efbfdSBarry Smith /*10*/ 0,
2709cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2710cb5b572fSBarry Smith        0,
271141f059aeSBarry Smith        MatSOR_SeqAIJ,
271217ab2063SBarry Smith        MatTranspose_SeqAIJ,
271397304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2714cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2715cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2716cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2717cb5b572fSBarry Smith        MatNorm_SeqAIJ,
271897304618SKris Buschelman /*20*/ 0,
2719cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2720cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2721cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2722d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2723db4efbfdSBarry Smith        0,
2724db4efbfdSBarry Smith        0,
2725db4efbfdSBarry Smith        0,
2726db4efbfdSBarry Smith        0,
2727d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2728db4efbfdSBarry Smith        0,
2729db4efbfdSBarry Smith        0,
27306c0721eeSBarry Smith        MatGetArray_SeqAIJ,
27316c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2732d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2733cb5b572fSBarry Smith        0,
2734cb5b572fSBarry Smith        0,
2735cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2736cb5b572fSBarry Smith        0,
2737d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
2738cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2739cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2740cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2741cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2742d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
2743cb5b572fSBarry Smith        MatScale_SeqAIJ,
2744cb5b572fSBarry Smith        0,
274579299369SBarry Smith        MatDiagonalSet_SeqAIJ,
27466e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
2747d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
27483b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
27493b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
27503b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2751a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2752d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
2753b9617806SBarry Smith        0,
27540513a670SBarry Smith        0,
2755cda55fadSBarry Smith        MatPermute_SeqAIJ,
2756cda55fadSBarry Smith        0,
2757d519adbfSMatthew Knepley /*59*/ 0,
2758b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2759b9b97703SBarry Smith        MatView_SeqAIJ,
2760357abbc8SBarry Smith        0,
2761ee4f033dSBarry Smith        0,
2762d519adbfSMatthew Knepley /*64*/ 0,
2763ee4f033dSBarry Smith        0,
2764ee4f033dSBarry Smith        0,
2765ee4f033dSBarry Smith        0,
2766ee4f033dSBarry Smith        0,
2767d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
2768c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
2769ee4f033dSBarry Smith        0,
2770ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2771dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2772ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2773dcf5cc72SBarry Smith #else
2774dcf5cc72SBarry Smith        0,
2775dcf5cc72SBarry Smith #endif
2776d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
27773acb8795SBarry Smith        MatFDColoringApply_AIJ,
277897304618SKris Buschelman        0,
277997304618SKris Buschelman        0,
278097304618SKris Buschelman        0,
27816ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
278297304618SKris Buschelman        0,
278397304618SKris Buschelman        0,
278497304618SKris Buschelman        0,
2785bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2786d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
27871cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
27886284ec50SHong Zhang        0,
27896284ec50SHong Zhang        0,
2790bc011b1eSHong Zhang        0,
2791d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
279226be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
279326be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2794d439da42SKris Buschelman        MatPtAP_Basic,
27957ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
2796d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
2797bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2798bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2799bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
28007ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
2801d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
2802609c6c4dSKris Buschelman        0,
2803609c6c4dSKris Buschelman        0,
280487d4246cSBarry Smith        MatConjugate_SeqAIJ,
280587d4246cSBarry Smith        0,
2806d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
280799cafbc1SBarry Smith        MatRealPart_SeqAIJ,
2808f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
2809f5edf698SHong Zhang        0,
28102bebee5dSHong Zhang        0,
2811cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
2812985db425SBarry Smith        0,
28132af78befSBarry Smith        MatGetRowMin_SeqAIJ,
28142af78befSBarry Smith        0,
2815599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
2816d519adbfSMatthew Knepley /*114*/0,
2817599ef60dSHong Zhang        0,
28183c2a7987SHong Zhang        0,
2819fe97e370SBarry Smith        0,
2820fbdbba38SShri Abhyankar        0,
2821fbdbba38SShri Abhyankar /*119*/0,
2822fbdbba38SShri Abhyankar        0,
2823fbdbba38SShri Abhyankar        0,
282482d44351SHong Zhang        0,
2825b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
2826b3a44c85SBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ
28279e29f15eSvictorle };
282817ab2063SBarry Smith 
2829fb2e594dSBarry Smith EXTERN_C_BEGIN
28304a2ae208SSatish Balay #undef __FUNCT__
28314a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
28327087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2833bef8e0ddSBarry Smith {
2834bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
283597f1f81fSBarry Smith   PetscInt   i,nz,n;
2836bef8e0ddSBarry Smith 
2837bef8e0ddSBarry Smith   PetscFunctionBegin;
2838bef8e0ddSBarry Smith 
2839bef8e0ddSBarry Smith   nz = aij->maxnz;
2840d0f46423SBarry Smith   n  = mat->rmap->n;
2841bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2842bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2843bef8e0ddSBarry Smith   }
2844bef8e0ddSBarry Smith   aij->nz = nz;
2845bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2846bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2847bef8e0ddSBarry Smith   }
2848bef8e0ddSBarry Smith 
2849bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2850bef8e0ddSBarry Smith }
2851fb2e594dSBarry Smith EXTERN_C_END
2852bef8e0ddSBarry Smith 
28534a2ae208SSatish Balay #undef __FUNCT__
28544a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2855bef8e0ddSBarry Smith /*@
2856bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2857bef8e0ddSBarry Smith        in the matrix.
2858bef8e0ddSBarry Smith 
2859bef8e0ddSBarry Smith   Input Parameters:
2860bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2861bef8e0ddSBarry Smith -  indices - the column indices
2862bef8e0ddSBarry Smith 
286315091d37SBarry Smith   Level: advanced
286415091d37SBarry Smith 
2865bef8e0ddSBarry Smith   Notes:
2866bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2867bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2868bef8e0ddSBarry Smith   of the MatSetValues() operation.
2869bef8e0ddSBarry Smith 
2870bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2871d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2872bef8e0ddSBarry Smith 
2873bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2874bef8e0ddSBarry Smith 
2875b9617806SBarry Smith     The indices should start with zero, not one.
2876b9617806SBarry Smith 
2877bef8e0ddSBarry Smith @*/
28787087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2879bef8e0ddSBarry Smith {
28804ac538c5SBarry Smith   PetscErrorCode ierr;
2881bef8e0ddSBarry Smith 
2882bef8e0ddSBarry Smith   PetscFunctionBegin;
28830700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
28844482741eSBarry Smith   PetscValidPointer(indices,2);
28854ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
2886bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2887bef8e0ddSBarry Smith }
2888bef8e0ddSBarry Smith 
2889be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2890be6bf707SBarry Smith 
2891fb2e594dSBarry Smith EXTERN_C_BEGIN
28924a2ae208SSatish Balay #undef __FUNCT__
28934a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
28947087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
2895be6bf707SBarry Smith {
2896be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
28976849ba73SBarry Smith   PetscErrorCode ierr;
2898d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
2899be6bf707SBarry Smith 
2900be6bf707SBarry Smith   PetscFunctionBegin;
2901be6bf707SBarry Smith   if (aij->nonew != 1) {
2902e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2903be6bf707SBarry Smith   }
2904be6bf707SBarry Smith 
2905be6bf707SBarry Smith   /* allocate space for values if not already there */
2906be6bf707SBarry Smith   if (!aij->saved_values) {
290787828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
29089518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
2909be6bf707SBarry Smith   }
2910be6bf707SBarry Smith 
2911be6bf707SBarry Smith   /* copy values over */
291287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2913be6bf707SBarry Smith   PetscFunctionReturn(0);
2914be6bf707SBarry Smith }
2915fb2e594dSBarry Smith EXTERN_C_END
2916be6bf707SBarry Smith 
29174a2ae208SSatish Balay #undef __FUNCT__
2918b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2919be6bf707SBarry Smith /*@
2920be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2921be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2922be6bf707SBarry Smith        nonlinear portion.
2923be6bf707SBarry Smith 
2924be6bf707SBarry Smith    Collect on Mat
2925be6bf707SBarry Smith 
2926be6bf707SBarry Smith   Input Parameters:
29270e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2928be6bf707SBarry Smith 
292915091d37SBarry Smith   Level: advanced
293015091d37SBarry Smith 
2931be6bf707SBarry Smith   Common Usage, with SNESSolve():
2932be6bf707SBarry Smith $    Create Jacobian matrix
2933be6bf707SBarry Smith $    Set linear terms into matrix
2934be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2935be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2936be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2937512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2938be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2939be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2940be6bf707SBarry Smith $    In your Jacobian routine
2941be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2942be6bf707SBarry Smith $      Set nonlinear terms in matrix
2943be6bf707SBarry Smith 
2944be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2945be6bf707SBarry Smith $    // build linear portion of Jacobian
2946512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2947be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2948be6bf707SBarry Smith $    loop over nonlinear iterations
2949be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2950be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2951be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2952be6bf707SBarry Smith $       Solve linear system with Jacobian
2953be6bf707SBarry Smith $    endloop
2954be6bf707SBarry Smith 
2955be6bf707SBarry Smith   Notes:
2956be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2957512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
2958be6bf707SBarry Smith     calling this routine.
2959be6bf707SBarry Smith 
29600c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
29610c468ba9SBarry Smith     and does not allocated additional space.
29620c468ba9SBarry Smith 
2963be6bf707SBarry Smith .seealso: MatRetrieveValues()
2964be6bf707SBarry Smith 
2965be6bf707SBarry Smith @*/
29667087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
2967be6bf707SBarry Smith {
29684ac538c5SBarry Smith   PetscErrorCode ierr;
2969be6bf707SBarry Smith 
2970be6bf707SBarry Smith   PetscFunctionBegin;
29710700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2972e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2973e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
29744ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
2975be6bf707SBarry Smith   PetscFunctionReturn(0);
2976be6bf707SBarry Smith }
2977be6bf707SBarry Smith 
2978fb2e594dSBarry Smith EXTERN_C_BEGIN
29794a2ae208SSatish Balay #undef __FUNCT__
29804a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
29817087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
2982be6bf707SBarry Smith {
2983be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
29846849ba73SBarry Smith   PetscErrorCode ierr;
2985d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
2986be6bf707SBarry Smith 
2987be6bf707SBarry Smith   PetscFunctionBegin;
2988be6bf707SBarry Smith   if (aij->nonew != 1) {
2989e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2990be6bf707SBarry Smith   }
2991be6bf707SBarry Smith   if (!aij->saved_values) {
2992e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2993be6bf707SBarry Smith   }
2994be6bf707SBarry Smith   /* copy values over */
299587828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2996be6bf707SBarry Smith   PetscFunctionReturn(0);
2997be6bf707SBarry Smith }
2998fb2e594dSBarry Smith EXTERN_C_END
2999be6bf707SBarry Smith 
30004a2ae208SSatish Balay #undef __FUNCT__
30014a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3002be6bf707SBarry Smith /*@
3003be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3004be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3005be6bf707SBarry Smith        nonlinear portion.
3006be6bf707SBarry Smith 
3007be6bf707SBarry Smith    Collect on Mat
3008be6bf707SBarry Smith 
3009be6bf707SBarry Smith   Input Parameters:
3010be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3011be6bf707SBarry Smith 
301215091d37SBarry Smith   Level: advanced
301315091d37SBarry Smith 
3014be6bf707SBarry Smith .seealso: MatStoreValues()
3015be6bf707SBarry Smith 
3016be6bf707SBarry Smith @*/
30177087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3018be6bf707SBarry Smith {
30194ac538c5SBarry Smith   PetscErrorCode ierr;
3020be6bf707SBarry Smith 
3021be6bf707SBarry Smith   PetscFunctionBegin;
30220700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3023e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3024e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
30254ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3026be6bf707SBarry Smith   PetscFunctionReturn(0);
3027be6bf707SBarry Smith }
3028be6bf707SBarry Smith 
3029f83d6046SBarry Smith 
3030be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
30314a2ae208SSatish Balay #undef __FUNCT__
30324a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
303317ab2063SBarry Smith /*@C
3034682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
30350d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
30366e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
303751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
30382bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
303917ab2063SBarry Smith 
3040db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3041db81eaa0SLois Curfman McInnes 
304217ab2063SBarry Smith    Input Parameters:
3043db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
304417ab2063SBarry Smith .  m - number of rows
304517ab2063SBarry Smith .  n - number of columns
304617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
304751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
30482bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
304917ab2063SBarry Smith 
305017ab2063SBarry Smith    Output Parameter:
3051416022c9SBarry Smith .  A - the matrix
305217ab2063SBarry Smith 
3053175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3054ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3055175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3056175b88e8SBarry Smith 
3057b259b22eSLois Curfman McInnes    Notes:
305849a6f317SBarry Smith    If nnz is given then nz is ignored
305949a6f317SBarry Smith 
306017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
306117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
30620002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
306344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
306417ab2063SBarry Smith 
306517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3066a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
30673d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
30686da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
306917ab2063SBarry Smith 
3070682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
30714fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3072682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
30736c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
30746c7ebb05SLois Curfman McInnes 
30756c7ebb05SLois Curfman McInnes    Options Database Keys:
3076698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
30779db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
307817ab2063SBarry Smith 
3079027ccd11SLois Curfman McInnes    Level: intermediate
3080027ccd11SLois Curfman McInnes 
308136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
308236db0b34SBarry Smith 
308317ab2063SBarry Smith @*/
30847087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
308517ab2063SBarry Smith {
3086dfbe8321SBarry Smith   PetscErrorCode ierr;
30876945ee14SBarry Smith 
30883a40ed3dSBarry Smith   PetscFunctionBegin;
3089f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3090117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3091c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3092d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3093273d9f13SBarry Smith   PetscFunctionReturn(0);
3094273d9f13SBarry Smith }
3095273d9f13SBarry Smith 
30964a2ae208SSatish Balay #undef __FUNCT__
30974a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3098273d9f13SBarry Smith /*@C
3099273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3100273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3101273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3102273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3103273d9f13SBarry Smith 
3104273d9f13SBarry Smith    Collective on MPI_Comm
3105273d9f13SBarry Smith 
3106273d9f13SBarry Smith    Input Parameters:
3107117016b1SBarry Smith +  B - The matrix-free
3108273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3109273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3110273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3111273d9f13SBarry Smith 
3112273d9f13SBarry Smith    Notes:
311349a6f317SBarry Smith      If nnz is given then nz is ignored
311449a6f317SBarry Smith 
3115273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3116273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3117273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3118273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3119273d9f13SBarry Smith 
3120273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3121273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3122273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3123273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3124273d9f13SBarry Smith 
3125aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3126aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3127aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3128aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3129aa95bbe8SBarry Smith 
3130a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3131a96a251dSBarry Smith    entries or columns indices
3132a96a251dSBarry Smith 
3133273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3134273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3135273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3136273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3137273d9f13SBarry Smith 
3138273d9f13SBarry Smith    Options Database Keys:
3139698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3140698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3141273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3142273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3143273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3144273d9f13SBarry Smith 
3145273d9f13SBarry Smith    Level: intermediate
3146273d9f13SBarry Smith 
3147aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3148273d9f13SBarry Smith 
3149273d9f13SBarry Smith @*/
31507087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3151273d9f13SBarry Smith {
31524ac538c5SBarry Smith   PetscErrorCode ierr;
3153a23d5eceSKris Buschelman 
3154a23d5eceSKris Buschelman   PetscFunctionBegin;
31554ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3156a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3157a23d5eceSKris Buschelman }
3158a23d5eceSKris Buschelman 
3159a23d5eceSKris Buschelman EXTERN_C_BEGIN
3160a23d5eceSKris Buschelman #undef __FUNCT__
3161a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
31627087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3163a23d5eceSKris Buschelman {
3164273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3165ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
31666849ba73SBarry Smith   PetscErrorCode ierr;
316797f1f81fSBarry Smith   PetscInt       i;
3168273d9f13SBarry Smith 
3169273d9f13SBarry Smith   PetscFunctionBegin;
3170d5d45c9bSBarry Smith 
3171a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3172c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3173c461c341SBarry Smith     nz             = 0;
3174c461c341SBarry Smith   }
3175c461c341SBarry Smith 
317626283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
317726283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
317826283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
317926283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3180899cda47SBarry Smith 
3181435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3182e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3183b73539f3SBarry Smith   if (nnz) {
3184d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3185e32f2f54SBarry 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]);
3186e32f2f54SBarry 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);
3187b73539f3SBarry Smith     }
3188b73539f3SBarry Smith   }
3189b73539f3SBarry Smith 
3190273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3191273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3192273d9f13SBarry Smith 
3193ab93d7beSBarry Smith   if (!skipallocation) {
31942ee49352SLisandro Dalcin     if (!b->imax) {
3195d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3196d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
31972ee49352SLisandro Dalcin     }
3198273d9f13SBarry Smith     if (!nnz) {
3199435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3200c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3201d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3202d0f46423SBarry Smith       nz = nz*B->rmap->n;
3203273d9f13SBarry Smith     } else {
3204273d9f13SBarry Smith       nz = 0;
3205d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3206273d9f13SBarry Smith     }
3207ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3208d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3209ab93d7beSBarry Smith 
3210273d9f13SBarry Smith     /* allocate the matrix space */
32112ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3212d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3213d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3214bfeeae90SHong Zhang     b->i[0] = 0;
3215d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
32165da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
32175da197adSKris Buschelman     }
3218273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3219e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3220e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3221c461c341SBarry Smith   } else {
3222e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3223e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3224c461c341SBarry Smith   }
3225273d9f13SBarry Smith 
3226273d9f13SBarry Smith   b->nz                = 0;
3227273d9f13SBarry Smith   b->maxnz             = nz;
3228273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3229273d9f13SBarry Smith   PetscFunctionReturn(0);
3230273d9f13SBarry Smith }
3231a23d5eceSKris Buschelman EXTERN_C_END
3232273d9f13SBarry Smith 
3233a1661176SMatthew Knepley #undef  __FUNCT__
3234a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
323558d36128SBarry Smith /*@
3236a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3237a1661176SMatthew Knepley 
3238a1661176SMatthew Knepley    Input Parameters:
3239a1661176SMatthew Knepley +  B - the matrix
3240a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3241a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3242a1661176SMatthew Knepley -  v - optional values in the matrix
3243a1661176SMatthew Knepley 
3244a1661176SMatthew Knepley    Level: developer
3245a1661176SMatthew Knepley 
324658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
324758d36128SBarry Smith 
3248a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3249a1661176SMatthew Knepley 
3250a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3251a1661176SMatthew Knepley @*/
3252a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3253a1661176SMatthew Knepley {
3254a1661176SMatthew Knepley   PetscErrorCode ierr;
3255a1661176SMatthew Knepley 
3256a1661176SMatthew Knepley   PetscFunctionBegin;
32570700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
32584ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3259a1661176SMatthew Knepley   PetscFunctionReturn(0);
3260a1661176SMatthew Knepley }
3261a1661176SMatthew Knepley 
3262a1661176SMatthew Knepley EXTERN_C_BEGIN
3263a1661176SMatthew Knepley #undef  __FUNCT__
3264a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
32657087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3266a1661176SMatthew Knepley {
3267a1661176SMatthew Knepley   PetscInt       i;
3268a1661176SMatthew Knepley   PetscInt       m,n;
3269a1661176SMatthew Knepley   PetscInt       nz;
3270a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3271a1661176SMatthew Knepley   PetscScalar    *values;
3272a1661176SMatthew Knepley   PetscErrorCode ierr;
3273a1661176SMatthew Knepley 
3274a1661176SMatthew Knepley   PetscFunctionBegin;
3275a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3276a1661176SMatthew Knepley 
327765e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3278a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3279a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3280b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3281a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
328265e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3283a1661176SMatthew Knepley     nnz[i] = nz;
3284a1661176SMatthew Knepley   }
3285a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3286a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3287a1661176SMatthew Knepley 
3288a1661176SMatthew Knepley   if (v) {
3289a1661176SMatthew Knepley     values = (PetscScalar*) v;
3290a1661176SMatthew Knepley   } else {
32910e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3292a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3293a1661176SMatthew Knepley   }
3294a1661176SMatthew Knepley 
3295a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3296b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3297b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3298a1661176SMatthew Knepley   }
3299a1661176SMatthew Knepley 
3300a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3301a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3302a1661176SMatthew Knepley 
3303a1661176SMatthew Knepley   if (!v) {
3304a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3305a1661176SMatthew Knepley   }
3306a1661176SMatthew Knepley   PetscFunctionReturn(0);
3307a1661176SMatthew Knepley }
3308a1661176SMatthew Knepley EXTERN_C_END
3309a1661176SMatthew Knepley 
3310c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3311c6db04a5SJed Brown #include <private/petscaxpy.h>
3312170fe5c8SBarry Smith 
3313170fe5c8SBarry Smith #undef __FUNCT__
3314170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3315170fe5c8SBarry Smith /*
3316170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3317170fe5c8SBarry Smith 
3318170fe5c8SBarry Smith                n                       p                          p
3319170fe5c8SBarry Smith         (              )       (              )         (                  )
3320170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3321170fe5c8SBarry Smith         (              )       (              )         (                  )
3322170fe5c8SBarry Smith 
3323170fe5c8SBarry Smith */
3324170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3325170fe5c8SBarry Smith {
3326170fe5c8SBarry Smith   PetscErrorCode     ierr;
3327170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3328170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3329170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
33301de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3331170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3332170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3333170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3334170fe5c8SBarry Smith 
3335170fe5c8SBarry Smith   PetscFunctionBegin;
3336d0f46423SBarry Smith   m = A->rmap->n;
3337d0f46423SBarry Smith   n = A->cmap->n;
3338d0f46423SBarry Smith   p = B->cmap->n;
3339170fe5c8SBarry Smith   a = sub_a->v;
3340170fe5c8SBarry Smith   b = sub_b->a;
3341170fe5c8SBarry Smith   c = sub_c->v;
3342170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3343170fe5c8SBarry Smith 
3344170fe5c8SBarry Smith   ii  = sub_b->i;
3345170fe5c8SBarry Smith   idx = sub_b->j;
3346170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3347170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3348170fe5c8SBarry Smith     while (q-->0) {
3349170fe5c8SBarry Smith       c_q = c + m*(*idx);
3350170fe5c8SBarry Smith       a_q = a + m*i;
3351be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3352170fe5c8SBarry Smith       idx++;
3353170fe5c8SBarry Smith       b++;
3354170fe5c8SBarry Smith     }
3355170fe5c8SBarry Smith   }
3356170fe5c8SBarry Smith   PetscFunctionReturn(0);
3357170fe5c8SBarry Smith }
3358170fe5c8SBarry Smith 
3359170fe5c8SBarry Smith #undef __FUNCT__
3360170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3361170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3362170fe5c8SBarry Smith {
3363170fe5c8SBarry Smith   PetscErrorCode ierr;
3364d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3365170fe5c8SBarry Smith   Mat            Cmat;
3366170fe5c8SBarry Smith 
3367170fe5c8SBarry Smith   PetscFunctionBegin;
3368e32f2f54SBarry 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);
336939804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3370170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3371170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3372170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3373170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3374170fe5c8SBarry Smith   *C = Cmat;
3375170fe5c8SBarry Smith   PetscFunctionReturn(0);
3376170fe5c8SBarry Smith }
3377170fe5c8SBarry Smith 
3378170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3379170fe5c8SBarry Smith #undef __FUNCT__
3380170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3381170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3382170fe5c8SBarry Smith {
3383170fe5c8SBarry Smith   PetscErrorCode ierr;
3384170fe5c8SBarry Smith 
3385170fe5c8SBarry Smith   PetscFunctionBegin;
3386170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3387170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3388170fe5c8SBarry Smith   }
3389170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3390170fe5c8SBarry Smith   PetscFunctionReturn(0);
3391170fe5c8SBarry Smith }
3392170fe5c8SBarry Smith 
3393170fe5c8SBarry Smith 
33940bad9183SKris Buschelman /*MC
3395fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
33960bad9183SKris Buschelman    based on compressed sparse row format.
33970bad9183SKris Buschelman 
33980bad9183SKris Buschelman    Options Database Keys:
33990bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
34000bad9183SKris Buschelman 
34010bad9183SKris Buschelman   Level: beginner
34020bad9183SKris Buschelman 
3403f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
34040bad9183SKris Buschelman M*/
34050bad9183SKris Buschelman 
3406a6175056SHong Zhang EXTERN_C_BEGIN
3407b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3408b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3409b5e56a35SBarry Smith #endif
3410ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3411af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3412af1023dbSSatish Balay #endif
34137087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
34147087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
34157087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
34167087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3417611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
34187087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3419611f576cSBarry Smith #endif
3420611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
34217087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3422611f576cSBarry Smith #endif
3423f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3424f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3425f3c0ef26SHong Zhang #endif
3426611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
34277087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3428611f576cSBarry Smith #endif
3429eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
34307087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3431eb3b5408SSatish Balay #endif
3432586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
34337087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3434586621ddSJed Brown #endif
3435719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
34367087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3437719d5645SBarry Smith #endif
3438b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
34397087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
34407087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
34417087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3442b3866ffcSBarry Smith #endif
344317667f90SBarry Smith EXTERN_C_END
344417667f90SBarry Smith 
344517667f90SBarry Smith EXTERN_C_BEGIN
34464a2ae208SSatish Balay #undef __FUNCT__
34474a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
34487087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3449273d9f13SBarry Smith {
3450273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3451dfbe8321SBarry Smith   PetscErrorCode ierr;
345238baddfdSBarry Smith   PetscMPIInt    size;
3453273d9f13SBarry Smith 
3454273d9f13SBarry Smith   PetscFunctionBegin;
34557adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3456e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3457273d9f13SBarry Smith 
345838f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3459b0a32e0cSBarry Smith   B->data             = (void*)b;
3460549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3461416022c9SBarry Smith   b->row              = 0;
3462416022c9SBarry Smith   b->col              = 0;
346382bf6240SBarry Smith   b->icol             = 0;
3464b810aeb4SBarry Smith   b->reallocs         = 0;
346536db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3466f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3467416022c9SBarry Smith   b->nonew             = 0;
3468416022c9SBarry Smith   b->diag              = 0;
3469416022c9SBarry Smith   b->solve_work        = 0;
34702a1b7f2aSHong Zhang   B->spptr             = 0;
3471be6bf707SBarry Smith   b->saved_values      = 0;
3472d7f994e1SBarry Smith   b->idiag             = 0;
347371f1c65dSBarry Smith   b->mdiag             = 0;
347471f1c65dSBarry Smith   b->ssor_work         = 0;
347571f1c65dSBarry Smith   b->omega             = 1.0;
347671f1c65dSBarry Smith   b->fshift            = 0.0;
347771f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3478a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3479a30b2313SHong Zhang   b->xtoy              = 0;
3480a30b2313SHong Zhang   b->XtoY              = 0;
348188e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
348217ab2063SBarry Smith 
348335d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3484b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3485700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3486b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3487b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3488b3866ffcSBarry Smith #endif
3489b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3490700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3491b5e56a35SBarry Smith #endif
3492ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3493700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3494719d5645SBarry Smith #endif
3495611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3496700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3497611f576cSBarry Smith #endif
3498f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3499700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3500f3c0ef26SHong Zhang #endif
3501611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3502700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3503611f576cSBarry Smith #endif
3504611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3505700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3506611f576cSBarry Smith #endif
3507eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3508700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3509eb3b5408SSatish Balay #endif
3510586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3511700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3512586621ddSJed Brown #endif
3513719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3514700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3515719d5645SBarry Smith #endif
3516700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3517700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3518700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3519700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3520700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3521700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3522700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3523700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3524700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3525700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3526700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3527700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3528700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3529700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3530700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3531700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3532700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3533700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
35344108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
353517667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
35363a40ed3dSBarry Smith   PetscFunctionReturn(0);
353717ab2063SBarry Smith }
3538273d9f13SBarry Smith EXTERN_C_END
353917ab2063SBarry Smith 
35404a2ae208SSatish Balay #undef __FUNCT__
3541b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3542b24902e0SBarry Smith /*
3543b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3544b24902e0SBarry Smith */
3545ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
354617ab2063SBarry Smith {
3547416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
35486849ba73SBarry Smith   PetscErrorCode ierr;
3549d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
355017ab2063SBarry Smith 
35513a40ed3dSBarry Smith   PetscFunctionBegin;
3552273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3553273d9f13SBarry Smith 
3554d5f3da31SBarry Smith   C->factortype     = A->factortype;
3555416022c9SBarry Smith   c->row            = 0;
3556416022c9SBarry Smith   c->col            = 0;
355782bf6240SBarry Smith   c->icol           = 0;
35586ad4291fSHong Zhang   c->reallocs       = 0;
355917ab2063SBarry Smith 
35606ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
356117ab2063SBarry Smith 
356226283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->rmap,1);CHKERRQ(ierr);
356326283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->cmap,1);CHKERRQ(ierr);
356426283091SBarry Smith   ierr = PetscLayoutSetUp(C->rmap);CHKERRQ(ierr);
356526283091SBarry Smith   ierr = PetscLayoutSetUp(C->cmap);CHKERRQ(ierr);
3566eec197d1SBarry Smith 
356733b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
35689518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
356917ab2063SBarry Smith   for (i=0; i<m; i++) {
3570416022c9SBarry Smith     c->imax[i] = a->imax[i];
3571416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
357217ab2063SBarry Smith   }
357317ab2063SBarry Smith 
357417ab2063SBarry Smith   /* allocate the matrix space */
3575f77e22a1SHong Zhang   if (mallocmatspace){
3576a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
35779518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3578f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
357997f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
358017ab2063SBarry Smith     if (m > 0) {
358197f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3582be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3583bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3584be6bf707SBarry Smith       } else {
3585bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
358617ab2063SBarry Smith       }
358708480c60SBarry Smith     }
3588f77e22a1SHong Zhang   }
358917ab2063SBarry Smith 
35906ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3591416022c9SBarry Smith   c->roworiented       = a->roworiented;
3592416022c9SBarry Smith   c->nonew             = a->nonew;
3593416022c9SBarry Smith   if (a->diag) {
359497f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
359552e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
359617ab2063SBarry Smith     for (i=0; i<m; i++) {
3597416022c9SBarry Smith       c->diag[i] = a->diag[i];
359817ab2063SBarry Smith     }
35993a40ed3dSBarry Smith   } else c->diag           = 0;
36006ad4291fSHong Zhang   c->solve_work            = 0;
36016ad4291fSHong Zhang   c->saved_values          = 0;
36026ad4291fSHong Zhang   c->idiag                 = 0;
360371f1c65dSBarry Smith   c->ssor_work             = 0;
3604a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3605e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3606e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
36076ad4291fSHong Zhang   c->xtoy                  = 0;
36086ad4291fSHong Zhang   c->XtoY                  = 0;
36096ad4291fSHong Zhang 
3610416022c9SBarry Smith   c->nz                 = a->nz;
36118ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3612273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3613754ec7b1SSatish Balay 
36146ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
36156ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3616cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3617cd6b891eSBarry Smith   if (a->compressedrow.use){
36186ad4291fSHong Zhang     i = a->compressedrow.nrows;
36190e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
36206ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
36216ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
362227ea64f8SHong Zhang   } else {
362327ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
362427ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
362527ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
36266ad4291fSHong Zhang   }
362788e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
36284108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
36294846f1f5SKris Buschelman 
36307adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
36313a40ed3dSBarry Smith   PetscFunctionReturn(0);
363217ab2063SBarry Smith }
363317ab2063SBarry Smith 
36344a2ae208SSatish Balay #undef __FUNCT__
3635b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3636b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3637b24902e0SBarry Smith {
3638b24902e0SBarry Smith   PetscErrorCode ierr;
3639b24902e0SBarry Smith 
3640b24902e0SBarry Smith   PetscFunctionBegin;
3641b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
36424b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3643b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3644f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3645b24902e0SBarry Smith   PetscFunctionReturn(0);
3646b24902e0SBarry Smith }
3647b24902e0SBarry Smith 
3648b24902e0SBarry Smith #undef __FUNCT__
36494a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3650112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3651fbdbba38SShri Abhyankar {
3652fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3653fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3654fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3655fbdbba38SShri Abhyankar   int            fd;
3656fbdbba38SShri Abhyankar   PetscMPIInt    size;
3657fbdbba38SShri Abhyankar   MPI_Comm       comm;
3658fbdbba38SShri Abhyankar 
3659fbdbba38SShri Abhyankar   PetscFunctionBegin;
3660fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3661fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3662fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3663fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3664fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3665fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3666fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3667fbdbba38SShri Abhyankar 
3668fbdbba38SShri Abhyankar   if (nz < 0) {
3669fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3670fbdbba38SShri Abhyankar   }
3671fbdbba38SShri Abhyankar 
3672fbdbba38SShri Abhyankar   /* read in row lengths */
3673fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3674fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3675fbdbba38SShri Abhyankar 
3676fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3677fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3678fbdbba38SShri 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);
3679fbdbba38SShri Abhyankar 
3680fbdbba38SShri Abhyankar   /* set global size if not set already*/
3681f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3682fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3683aabbc4fbSShri Abhyankar   } else {
3684fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3685fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3686f501eaabSShri 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);
3687aabbc4fbSShri Abhyankar   }
3688fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3689fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3690fbdbba38SShri Abhyankar 
3691fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3692fbdbba38SShri Abhyankar 
3693fbdbba38SShri Abhyankar   /* read in nonzero values */
3694fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3695fbdbba38SShri Abhyankar 
3696fbdbba38SShri Abhyankar   /* set matrix "i" values */
3697fbdbba38SShri Abhyankar   a->i[0] = 0;
3698fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3699fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3700fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3701fbdbba38SShri Abhyankar   }
3702fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3703fbdbba38SShri Abhyankar 
3704fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3705fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3706fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3707fbdbba38SShri Abhyankar }
3708fbdbba38SShri Abhyankar 
3709fbdbba38SShri Abhyankar #undef __FUNCT__
3710b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3711ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
37127264ac53SSatish Balay {
37137264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3714dfbe8321SBarry Smith   PetscErrorCode ierr;
3715eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3716eeffb40dSHong Zhang   PetscInt k;
3717eeffb40dSHong Zhang #endif
37187264ac53SSatish Balay 
37193a40ed3dSBarry Smith   PetscFunctionBegin;
3720bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3721d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
3722ca44d042SBarry Smith     *flg = PETSC_FALSE;
3723ca44d042SBarry Smith     PetscFunctionReturn(0);
3724bcd2baecSBarry Smith   }
37257264ac53SSatish Balay 
37267264ac53SSatish Balay   /* if the a->i are the same */
3727d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3728abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
37297264ac53SSatish Balay 
37307264ac53SSatish Balay   /* if a->j are the same */
373197f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3732abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3733bcd2baecSBarry Smith 
3734bcd2baecSBarry Smith   /* if a->a are the same */
3735eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3736eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
3737eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
3738eeffb40dSHong Zhang       *flg = PETSC_FALSE;
37393a40ed3dSBarry Smith       PetscFunctionReturn(0);
3740eeffb40dSHong Zhang     }
3741eeffb40dSHong Zhang   }
3742eeffb40dSHong Zhang #else
3743eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
3744eeffb40dSHong Zhang #endif
3745eeffb40dSHong Zhang   PetscFunctionReturn(0);
37467264ac53SSatish Balay }
374736db0b34SBarry Smith 
37484a2ae208SSatish Balay #undef __FUNCT__
37494a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
375005869f15SSatish Balay /*@
375136db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
375236db0b34SBarry Smith               provided by the user.
375336db0b34SBarry Smith 
3754c75a6043SHong Zhang       Collective on MPI_Comm
375536db0b34SBarry Smith 
375636db0b34SBarry Smith    Input Parameters:
375736db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
375836db0b34SBarry Smith .   m - number of rows
375936db0b34SBarry Smith .   n - number of columns
376036db0b34SBarry Smith .   i - row indices
376136db0b34SBarry Smith .   j - column indices
376236db0b34SBarry Smith -   a - matrix values
376336db0b34SBarry Smith 
376436db0b34SBarry Smith    Output Parameter:
376536db0b34SBarry Smith .   mat - the matrix
376636db0b34SBarry Smith 
376736db0b34SBarry Smith    Level: intermediate
376836db0b34SBarry Smith 
376936db0b34SBarry Smith    Notes:
37700551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
3771292fb18eSBarry Smith     once the matrix is destroyed and not before
377236db0b34SBarry Smith 
377336db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
377436db0b34SBarry Smith 
3775bfeeae90SHong Zhang        The i and j indices are 0 based
377636db0b34SBarry Smith 
3777a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
3778a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
3779a4552177SSatish Balay     as shown:
3780a4552177SSatish Balay 
3781a4552177SSatish Balay         1 0 0
3782a4552177SSatish Balay         2 0 3
3783a4552177SSatish Balay         4 5 6
3784a4552177SSatish Balay 
3785a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
37869985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
3787a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
3788a4552177SSatish Balay 
37899985e31cSBarry Smith 
37902fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
379136db0b34SBarry Smith 
379236db0b34SBarry Smith @*/
37937087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
379436db0b34SBarry Smith {
3795dfbe8321SBarry Smith   PetscErrorCode ierr;
3796cbcfb4deSHong Zhang   PetscInt       ii;
379736db0b34SBarry Smith   Mat_SeqAIJ     *aij;
3798cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
3799cbcfb4deSHong Zhang   PetscInt       jj;
3800cbcfb4deSHong Zhang #endif
380136db0b34SBarry Smith 
380236db0b34SBarry Smith   PetscFunctionBegin;
3803a96a251dSBarry Smith   if (i[0]) {
3804e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
380536db0b34SBarry Smith   }
3806f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3807f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3808ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3809ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3810ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3811ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3812ab93d7beSBarry Smith 
381336db0b34SBarry Smith   aij->i = i;
381436db0b34SBarry Smith   aij->j = j;
381536db0b34SBarry Smith   aij->a = a;
381636db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
381736db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
3818e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
3819e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
382036db0b34SBarry Smith 
382136db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
382236db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
38232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
3824e32f2f54SBarry 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]);
38259985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
3826e32f2f54SBarry 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);
3827e32f2f54SBarry 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);
38289985e31cSBarry Smith     }
382936db0b34SBarry Smith #endif
383036db0b34SBarry Smith   }
38312515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
383236db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
3833e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
3834e32f2f54SBarry 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]);
383536db0b34SBarry Smith   }
383636db0b34SBarry Smith #endif
383736db0b34SBarry Smith 
3838b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3839b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
384036db0b34SBarry Smith   PetscFunctionReturn(0);
384136db0b34SBarry Smith }
384236db0b34SBarry Smith 
3843cc8ba8e1SBarry Smith #undef __FUNCT__
3844ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3845dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3846cc8ba8e1SBarry Smith {
3847dfbe8321SBarry Smith   PetscErrorCode ierr;
3848cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
384936db0b34SBarry Smith 
3850cc8ba8e1SBarry Smith   PetscFunctionBegin;
38518ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
3852cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3853cc8ba8e1SBarry Smith     a->coloring = coloring;
385412c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
385597f1f81fSBarry Smith     PetscInt             i,*larray;
385612c595b3SBarry Smith     ISColoring      ocoloring;
385708b6dcc0SBarry Smith     ISColoringValue *colors;
385812c595b3SBarry Smith 
385912c595b3SBarry Smith     /* set coloring for diagonal portion */
38600e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
3861d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
386212c595b3SBarry Smith       larray[i] = i;
386312c595b3SBarry Smith     }
3864784ac674SJed Brown     ierr = ISGlobalToLocalMappingApply(A->cmapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
38650e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
3866d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
386712c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
386812c595b3SBarry Smith     }
386912c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
3870d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
387112c595b3SBarry Smith     a->coloring = ocoloring;
387212c595b3SBarry Smith   }
3873cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3874cc8ba8e1SBarry Smith }
3875cc8ba8e1SBarry Smith 
3876dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3877ee4f033dSBarry Smith EXTERN_C_BEGIN
3878c6db04a5SJed Brown #include <adic/ad_utils.h>
3879ee4f033dSBarry Smith EXTERN_C_END
3880cc8ba8e1SBarry Smith 
3881cc8ba8e1SBarry Smith #undef __FUNCT__
3882ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3883dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3884cc8ba8e1SBarry Smith {
3885cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3886d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
38874440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
388808b6dcc0SBarry Smith   ISColoringValue *color;
3889cc8ba8e1SBarry Smith 
3890cc8ba8e1SBarry Smith   PetscFunctionBegin;
3891e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
38924440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3893cc8ba8e1SBarry Smith   color = a->coloring->colors;
3894cc8ba8e1SBarry Smith   /* loop over rows */
3895cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3896cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3897cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3898cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3899cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3900cc8ba8e1SBarry Smith     }
39014440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3902ee4f033dSBarry Smith   }
3903ee4f033dSBarry Smith   PetscFunctionReturn(0);
3904ee4f033dSBarry Smith }
3905ee4f033dSBarry Smith #endif
3906ee4f033dSBarry Smith 
3907ee4f033dSBarry Smith #undef __FUNCT__
3908ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
390997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3910ee4f033dSBarry Smith {
3911ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3912d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
391354f21887SBarry Smith   MatScalar       *v = a->a;
391454f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
391508b6dcc0SBarry Smith   ISColoringValue *color;
3916ee4f033dSBarry Smith 
3917ee4f033dSBarry Smith   PetscFunctionBegin;
3918e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3919ee4f033dSBarry Smith   color = a->coloring->colors;
3920ee4f033dSBarry Smith   /* loop over rows */
3921ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3922ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3923ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3924ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3925ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3926ee4f033dSBarry Smith     }
3927ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3928cc8ba8e1SBarry Smith   }
3929cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3930cc8ba8e1SBarry Smith }
393136db0b34SBarry Smith 
393281824310SBarry Smith /*
393381824310SBarry Smith     Special version for direct calls from Fortran
393481824310SBarry Smith */
3935c6db04a5SJed Brown #include <private/fortranimpl.h>
393681824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
393781824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
393881824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
393981824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
394081824310SBarry Smith #endif
394181824310SBarry Smith 
394281824310SBarry Smith /* Change these macros so can be used in void function */
394381824310SBarry Smith #undef CHKERRQ
39447adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
394581824310SBarry Smith #undef SETERRQ2
3946e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
394781824310SBarry Smith 
394881824310SBarry Smith EXTERN_C_BEGIN
394981824310SBarry Smith #undef __FUNCT__
395081824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
39511f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
395281824310SBarry Smith {
395381824310SBarry Smith   Mat            A = *AA;
395481824310SBarry Smith   PetscInt       m = *mm, n = *nn;
395581824310SBarry Smith   InsertMode     is = *isis;
395681824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
395781824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
395881824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
395981824310SBarry Smith   PetscErrorCode ierr;
396081824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
396154f21887SBarry Smith   MatScalar      *ap,value,*aa;
3962ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
3963ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
396481824310SBarry Smith 
396581824310SBarry Smith   PetscFunctionBegin;
3966d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
396781824310SBarry Smith   imax = a->imax;
396881824310SBarry Smith   ai = a->i;
396981824310SBarry Smith   ailen = a->ilen;
397081824310SBarry Smith   aj = a->j;
397181824310SBarry Smith   aa = a->a;
397281824310SBarry Smith 
397381824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
397481824310SBarry Smith     row  = im[k];
397581824310SBarry Smith     if (row < 0) continue;
397681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3977d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
397881824310SBarry Smith #endif
397981824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
398081824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
398181824310SBarry Smith     low  = 0;
398281824310SBarry Smith     high = nrow;
398381824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
398481824310SBarry Smith       if (in[l] < 0) continue;
398581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3986d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
398781824310SBarry Smith #endif
398881824310SBarry Smith       col = in[l];
398981824310SBarry Smith       if (roworiented) {
399081824310SBarry Smith         value = v[l + k*n];
399181824310SBarry Smith       } else {
399281824310SBarry Smith         value = v[k + l*m];
399381824310SBarry Smith       }
399481824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
399581824310SBarry Smith 
399681824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
399781824310SBarry Smith       lastcol = col;
399881824310SBarry Smith       while (high-low > 5) {
399981824310SBarry Smith         t = (low+high)/2;
400081824310SBarry Smith         if (rp[t] > col) high = t;
400181824310SBarry Smith         else             low  = t;
400281824310SBarry Smith       }
400381824310SBarry Smith       for (i=low; i<high; i++) {
400481824310SBarry Smith         if (rp[i] > col) break;
400581824310SBarry Smith         if (rp[i] == col) {
400681824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
400781824310SBarry Smith           else                  ap[i] = value;
400881824310SBarry Smith           goto noinsert;
400981824310SBarry Smith         }
401081824310SBarry Smith       }
401181824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
401281824310SBarry Smith       if (nonew == 1) goto noinsert;
40137adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4014fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
401581824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
401681824310SBarry Smith       /* shift up all the later entries in this row */
401781824310SBarry Smith       for (ii=N; ii>=i; ii--) {
401881824310SBarry Smith         rp[ii+1] = rp[ii];
401981824310SBarry Smith         ap[ii+1] = ap[ii];
402081824310SBarry Smith       }
402181824310SBarry Smith       rp[i] = col;
402281824310SBarry Smith       ap[i] = value;
402381824310SBarry Smith       noinsert:;
402481824310SBarry Smith       low = i + 1;
402581824310SBarry Smith     }
402681824310SBarry Smith     ailen[row] = nrow;
402781824310SBarry Smith   }
402881824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
402981824310SBarry Smith   PetscFunctionReturnVoid();
403081824310SBarry Smith }
403181824310SBarry Smith EXTERN_C_END
403262298a1eSBarry Smith 
4033