xref: /petsc/src/mat/impls/aij/seq/aij.c (revision ce63c4c16a990ef3f7b411630a7c76f93edb2e1f)
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);
866c38d4ed2SBarry Smith   if (a->row) {
867c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
868c38d4ed2SBarry Smith   }
869c38d4ed2SBarry Smith   if (a->col) {
870c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
871c38d4ed2SBarry Smith   }
87205b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
87305b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
87471f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
87505b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
87682bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
87705b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
878cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
87905b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
880407f6b05SHong Zhang   if (a->XtoY) {ierr = MatDestroy(a->XtoY);CHKERRQ(ierr);}
881cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
882a30b2313SHong Zhang 
8834108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
8844846f1f5SKris Buschelman 
885606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
886901853e0SKris Buschelman 
887dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
888901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
889901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
890901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
891901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
892901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
8935a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
894901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
895901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
896a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
897901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
8983a40ed3dSBarry Smith   PetscFunctionReturn(0);
89917ab2063SBarry Smith }
90017ab2063SBarry Smith 
9014a2ae208SSatish Balay #undef __FUNCT__
9024a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
903ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
90417ab2063SBarry Smith {
905416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9064846f1f5SKris Buschelman   PetscErrorCode ierr;
9073a40ed3dSBarry Smith 
9083a40ed3dSBarry Smith   PetscFunctionBegin;
909a65d3064SKris Buschelman   switch (op) {
910a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
9114e0d8c25SBarry Smith       a->roworiented       = flg;
912a65d3064SKris Buschelman       break;
913a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
914a9817697SBarry Smith       a->keepnonzeropattern    = flg;
915a65d3064SKris Buschelman       break;
916512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
917512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
918a65d3064SKris Buschelman       break;
919a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
9204e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
921a65d3064SKris Buschelman       break;
922a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
9234e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
924a65d3064SKris Buschelman       break;
92528b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
92628b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
92728b2fa4aSMatthew Knepley       break;
928a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
9294e0d8c25SBarry Smith       a->ignorezeroentries = flg;
9300df259c2SBarry Smith       break;
931cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
932cd6b891eSBarry Smith       a->compressedrow.check = flg;
933d487561eSHong Zhang       break;
9343d472b54SHong Zhang     case MAT_SPD:
9353d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
9363d472b54SHong Zhang       A->spd                             = flg;
9373d472b54SHong Zhang       if (flg) {
9383d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
9393d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
9403d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
9413d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
9423d472b54SHong Zhang       }
9433d472b54SHong Zhang       break;
944b1646e73SJed Brown     case MAT_SYMMETRIC:
945b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
946b1646e73SJed Brown     case MAT_HERMITIAN:
947b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
9484e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
949a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
950a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
951290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
952a65d3064SKris Buschelman       break;
953b87ac2d8SJed Brown     case MAT_USE_INODES:
954b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
955b87ac2d8SJed Brown       break;
956a65d3064SKris Buschelman     default:
957e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
958a65d3064SKris Buschelman   }
9594108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
9603a40ed3dSBarry Smith   PetscFunctionReturn(0);
96117ab2063SBarry Smith }
96217ab2063SBarry Smith 
9634a2ae208SSatish Balay #undef __FUNCT__
9644a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
965dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
96617ab2063SBarry Smith {
967416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9686849ba73SBarry Smith   PetscErrorCode ierr;
969d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
97035e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
97117ab2063SBarry Smith 
9723a40ed3dSBarry Smith   PetscFunctionBegin;
973d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
974e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
97535e7444dSHong Zhang 
976d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
977d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
97835e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
97935e7444dSHong Zhang     for (i=0; i<n; i++) x[i] = aa[diag[i]];
98035e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
98135e7444dSHong Zhang     PetscFunctionReturn(0);
98235e7444dSHong Zhang   }
98335e7444dSHong Zhang 
9842dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
9851ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
98635e7444dSHong Zhang   for (i=0; i<n; i++) {
98735e7444dSHong Zhang     nz = ai[i+1] - ai[i];
9882f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
98935e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
99035e7444dSHong Zhang       if (aj[j] == i) {
99135e7444dSHong Zhang         x[i] = aa[j];
99217ab2063SBarry Smith         break;
99317ab2063SBarry Smith       }
99417ab2063SBarry Smith     }
99517ab2063SBarry Smith   }
9961ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
9973a40ed3dSBarry Smith   PetscFunctionReturn(0);
99817ab2063SBarry Smith }
99917ab2063SBarry Smith 
1000c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10014a2ae208SSatish Balay #undef __FUNCT__
10024a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1003dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
100417ab2063SBarry Smith {
1005416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
10065c897100SBarry Smith   PetscScalar       *x,*y;
1007dfbe8321SBarry Smith   PetscErrorCode    ierr;
1008d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
10095c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1010a77337e4SBarry Smith   MatScalar         *v;
1011a77337e4SBarry Smith   PetscScalar       alpha;
101204fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
10133447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
1014ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
10155c897100SBarry Smith #endif
101617ab2063SBarry Smith 
10173a40ed3dSBarry Smith   PetscFunctionBegin;
10182e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
10191ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
10201ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10215c897100SBarry Smith 
10225c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1023bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
10245c897100SBarry Smith #else
10253447b6efSHong Zhang   if (usecprow){
10263447b6efSHong Zhang     m    = cprow.nrows;
10273447b6efSHong Zhang     ii   = cprow.i;
10287b2bb3b9SHong Zhang     ridx = cprow.rindex;
10293447b6efSHong Zhang   } else {
10303447b6efSHong Zhang     ii = a->i;
10313447b6efSHong Zhang   }
103217ab2063SBarry Smith   for (i=0; i<m; i++) {
10333447b6efSHong Zhang     idx   = a->j + ii[i] ;
10343447b6efSHong Zhang     v     = a->a + ii[i] ;
10353447b6efSHong Zhang     n     = ii[i+1] - ii[i];
10363447b6efSHong Zhang     if (usecprow){
10377b2bb3b9SHong Zhang       alpha = x[ridx[i]];
10383447b6efSHong Zhang     } else {
103917ab2063SBarry Smith       alpha = x[i];
10403447b6efSHong Zhang     }
104104fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
104217ab2063SBarry Smith   }
10435c897100SBarry Smith #endif
1044dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
10451ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10461ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10473a40ed3dSBarry Smith   PetscFunctionReturn(0);
104817ab2063SBarry Smith }
104917ab2063SBarry Smith 
10504a2ae208SSatish Balay #undef __FUNCT__
10515c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1052dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
10535c897100SBarry Smith {
1054dfbe8321SBarry Smith   PetscErrorCode ierr;
10555c897100SBarry Smith 
10565c897100SBarry Smith   PetscFunctionBegin;
1057170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
10585c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
10595c897100SBarry Smith   PetscFunctionReturn(0);
10605c897100SBarry Smith }
10615c897100SBarry Smith 
1062c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10635c897100SBarry Smith #undef __FUNCT__
10644a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1065dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
106617ab2063SBarry Smith {
1067416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1068d9fead3dSBarry Smith   PetscScalar       *y;
106954f21887SBarry Smith   const PetscScalar *x;
107054f21887SBarry Smith   const MatScalar   *aa;
1071dfbe8321SBarry Smith   PetscErrorCode    ierr;
1072003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1073003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
10748aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1075362ced78SSatish Balay   PetscScalar       sum;
1076ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
107717ab2063SBarry Smith 
1078b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
107997952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1080fee21e36SBarry Smith #endif
1081fee21e36SBarry Smith 
10823a40ed3dSBarry Smith   PetscFunctionBegin;
10833649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
108597952fefSHong Zhang   aj  = a->j;
108697952fefSHong Zhang   aa  = a->a;
1087416022c9SBarry Smith   ii  = a->i;
10884eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
108997952fefSHong Zhang     m    = a->compressedrow.nrows;
109097952fefSHong Zhang     ii   = a->compressedrow.i;
109197952fefSHong Zhang     ridx = a->compressedrow.rindex;
109297952fefSHong Zhang     for (i=0; i<m; i++){
109397952fefSHong Zhang       n   = ii[i+1] - ii[i];
109497952fefSHong Zhang       aj  = a->j + ii[i];
109597952fefSHong Zhang       aa  = a->a + ii[i];
109697952fefSHong Zhang       sum = 0.0;
1097a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1098003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1099003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
110097952fefSHong Zhang       y[*ridx++] = sum;
110197952fefSHong Zhang     }
110297952fefSHong Zhang   } else { /* do not use compressed row format */
1103b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1104b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1105b05257ddSBarry Smith #else
110617ab2063SBarry Smith     for (i=0; i<m; i++) {
1107003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1108003131ecSBarry Smith       aj  = a->j + ii[i];
1109003131ecSBarry Smith       aa  = a->a + ii[i];
111017ab2063SBarry Smith       sum  = 0.0;
1111a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1112003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
111317ab2063SBarry Smith       y[i] = sum;
111417ab2063SBarry Smith     }
11158d195f9aSBarry Smith #endif
1116b05257ddSBarry Smith   }
1117dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
11183649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11191ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11203a40ed3dSBarry Smith   PetscFunctionReturn(0);
112117ab2063SBarry Smith }
112217ab2063SBarry Smith 
1123c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
11244a2ae208SSatish Balay #undef __FUNCT__
11254a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1126dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
112717ab2063SBarry Smith {
1128416022c9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
112954f21887SBarry Smith   PetscScalar     *x,*y,*z;
113054f21887SBarry Smith   const MatScalar *aa;
1131dfbe8321SBarry Smith   PetscErrorCode  ierr;
1132d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*aj,*ii;
1133aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
113497952fefSHong Zhang   PetscInt        n,i,jrow,j,*ridx=PETSC_NULL;
1135362ced78SSatish Balay   PetscScalar     sum;
1136ace3abfcSBarry Smith   PetscBool       usecprow=a->compressedrow.use;
1137e36a17ebSSatish Balay #endif
11389ea0dfa2SSatish Balay 
11393a40ed3dSBarry Smith   PetscFunctionBegin;
11401ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11411ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11422e8a6d31SBarry Smith   if (zz != yy) {
11431ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
11442e8a6d31SBarry Smith   } else {
11452e8a6d31SBarry Smith     z = y;
11462e8a6d31SBarry Smith   }
1147bfeeae90SHong Zhang 
114897952fefSHong Zhang   aj  = a->j;
114997952fefSHong Zhang   aa  = a->a;
1150cddf8d76SBarry Smith   ii  = a->i;
1151aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
115297952fefSHong Zhang   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
115302ab625aSSatish Balay #else
11544eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
11554eb6d288SHong Zhang     if (zz != yy){
11564eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
11574eb6d288SHong Zhang     }
115897952fefSHong Zhang     m    = a->compressedrow.nrows;
115997952fefSHong Zhang     ii   = a->compressedrow.i;
116097952fefSHong Zhang     ridx = a->compressedrow.rindex;
116197952fefSHong Zhang     for (i=0; i<m; i++){
116297952fefSHong Zhang       n  = ii[i+1] - ii[i];
116397952fefSHong Zhang       aj  = a->j + ii[i];
116497952fefSHong Zhang       aa  = a->a + ii[i];
116597952fefSHong Zhang       sum = y[*ridx];
116697952fefSHong Zhang       for (j=0; j<n; j++) sum += (*aa++)*x[*aj++];
116797952fefSHong Zhang       z[*ridx++] = sum;
116897952fefSHong Zhang     }
116997952fefSHong Zhang   } else { /* do not use compressed row format */
117017ab2063SBarry Smith     for (i=0; i<m; i++) {
11719ea0dfa2SSatish Balay       jrow = ii[i];
11729ea0dfa2SSatish Balay       n    = ii[i+1] - jrow;
117317ab2063SBarry Smith       sum  = y[i];
11749ea0dfa2SSatish Balay       for (j=0; j<n; j++) {
117597952fefSHong Zhang         sum += aa[jrow]*x[aj[jrow]]; jrow++;
11769ea0dfa2SSatish Balay       }
117717ab2063SBarry Smith       z[i] = sum;
117817ab2063SBarry Smith     }
117997952fefSHong Zhang   }
118002ab625aSSatish Balay #endif
1181dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11821ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11831ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11842e8a6d31SBarry Smith   if (zz != yy) {
11851ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
11862e8a6d31SBarry Smith   }
11878154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
11886b375ea7SVictor Minden   /*
1189918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1190918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1191918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
11926b375ea7SVictor Minden   */
1193918e98c3SVictor Minden #endif
11943a40ed3dSBarry Smith   PetscFunctionReturn(0);
119517ab2063SBarry Smith }
119617ab2063SBarry Smith 
119717ab2063SBarry Smith /*
119817ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
119917ab2063SBarry Smith */
12004a2ae208SSatish Balay #undef __FUNCT__
12014a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1202dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
120317ab2063SBarry Smith {
1204416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12056849ba73SBarry Smith   PetscErrorCode ierr;
1206d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
120717ab2063SBarry Smith 
12083a40ed3dSBarry Smith   PetscFunctionBegin;
120909f38230SBarry Smith   if (!a->diag) {
121009f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
12119518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
121209f38230SBarry Smith   }
1213d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
121409f38230SBarry Smith     a->diag[i] = a->i[i+1];
1215bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1216bfeeae90SHong Zhang       if (a->j[j] == i) {
121709f38230SBarry Smith         a->diag[i] = j;
121817ab2063SBarry Smith         break;
121917ab2063SBarry Smith       }
122017ab2063SBarry Smith     }
122117ab2063SBarry Smith   }
12223a40ed3dSBarry Smith   PetscFunctionReturn(0);
122317ab2063SBarry Smith }
122417ab2063SBarry Smith 
1225be5855fcSBarry Smith /*
1226be5855fcSBarry Smith      Checks for missing diagonals
1227be5855fcSBarry Smith */
12284a2ae208SSatish Balay #undef __FUNCT__
12294a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1230ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1231be5855fcSBarry Smith {
1232be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
123397f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1234be5855fcSBarry Smith 
1235be5855fcSBarry Smith   PetscFunctionBegin;
123609f38230SBarry Smith   *missing = PETSC_FALSE;
1237d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
123809f38230SBarry Smith     *missing  = PETSC_TRUE;
123909f38230SBarry Smith     if (d) *d = 0;
124009f38230SBarry Smith     PetscInfo(A,"Matrix has no entries therefor is missing diagonal");
124109f38230SBarry Smith   } else {
1242f1e2ffcdSBarry Smith     diag = a->diag;
1243d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1244bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
124509f38230SBarry Smith 	*missing = PETSC_TRUE;
124609f38230SBarry Smith 	if (d) *d = i;
124709f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
124809f38230SBarry Smith       }
1249be5855fcSBarry Smith     }
1250be5855fcSBarry Smith   }
1251be5855fcSBarry Smith   PetscFunctionReturn(0);
1252be5855fcSBarry Smith }
1253be5855fcSBarry Smith 
125471f1c65dSBarry Smith EXTERN_C_BEGIN
125571f1c65dSBarry Smith #undef __FUNCT__
125671f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
12577087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
125871f1c65dSBarry Smith {
125971f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
126071f1c65dSBarry Smith   PetscErrorCode ierr;
1261d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
126254f21887SBarry Smith   MatScalar      *v = a->a;
126354f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
126471f1c65dSBarry Smith 
126571f1c65dSBarry Smith   PetscFunctionBegin;
126671f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
126771f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
126871f1c65dSBarry Smith   diag = a->diag;
126971f1c65dSBarry Smith   if (!a->idiag) {
127071f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
127171f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
127271f1c65dSBarry Smith     v        = a->a;
127371f1c65dSBarry Smith   }
127471f1c65dSBarry Smith   mdiag = a->mdiag;
127571f1c65dSBarry Smith   idiag = a->idiag;
127671f1c65dSBarry Smith 
1277028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
127871f1c65dSBarry Smith     for (i=0; i<m; i++) {
127971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1280e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
128171f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
128271f1c65dSBarry Smith     }
128371f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
128471f1c65dSBarry Smith   } else {
128571f1c65dSBarry Smith     for (i=0; i<m; i++) {
128671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
128771f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
128871f1c65dSBarry Smith     }
1289dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
129071f1c65dSBarry Smith   }
129171f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
129271f1c65dSBarry Smith   PetscFunctionReturn(0);
129371f1c65dSBarry Smith }
12945a9745a3SMatthew Knepley EXTERN_C_END
129571f1c65dSBarry Smith 
1296c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
12974a2ae208SSatish Balay #undef __FUNCT__
129841f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
129941f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
130017ab2063SBarry Smith {
1301416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1302e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1303e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
130454f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1305dfbe8321SBarry Smith   PetscErrorCode     ierr;
1306d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
130797f1f81fSBarry Smith   const PetscInt     *idx,*diag;
130817ab2063SBarry Smith 
13093a40ed3dSBarry Smith   PetscFunctionBegin;
1310b965ef7fSBarry Smith   its = its*lits;
131191723122SBarry Smith 
131271f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
131371f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
131471f1c65dSBarry Smith   a->fshift = fshift;
131571f1c65dSBarry Smith   a->omega  = omega;
1316ed480e8bSBarry Smith 
131771f1c65dSBarry Smith   diag = a->diag;
131871f1c65dSBarry Smith   t     = a->ssor_work;
1319ed480e8bSBarry Smith   idiag = a->idiag;
132071f1c65dSBarry Smith   mdiag = a->mdiag;
1321ed480e8bSBarry Smith 
13221ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
13233649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
132471f1c65dSBarry Smith   CHKMEMQ;
1325ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
132617ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
132717ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1328ed480e8bSBarry Smith     bs = b;
132917ab2063SBarry Smith     for (i=0; i<m; i++) {
133071f1c65dSBarry Smith         d    = fshift + mdiag[i];
1331416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1332ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1333ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
133417ab2063SBarry Smith         sum  = b[i]*d/omega;
1335003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
133617ab2063SBarry Smith         x[i] = sum;
133717ab2063SBarry Smith     }
13381ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13393649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1340efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13413a40ed3dSBarry Smith     PetscFunctionReturn(0);
134217ab2063SBarry Smith   }
1343c783ea89SBarry Smith 
134448af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1345e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
13463a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
134717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1348887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
134917ab2063SBarry Smith 
135017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
135117ab2063SBarry Smith 
1352887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
135317ab2063SBarry Smith     */
135417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
135517ab2063SBarry Smith 
135617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
135717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1358416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1359ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1360ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
136117ab2063SBarry Smith       sum  = b[i];
1362e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1363ed480e8bSBarry Smith       x[i] = sum*idiag[i];
136417ab2063SBarry Smith     }
136517ab2063SBarry Smith 
136617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1367416022c9SBarry Smith     v = a->a;
1368ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
136917ab2063SBarry Smith 
137017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1371ed480e8bSBarry Smith     ts = t;
1372416022c9SBarry Smith     diag = a->diag;
137317ab2063SBarry Smith     for (i=0; i<m; i++) {
1374416022c9SBarry Smith       n    = diag[i] - a->i[i];
1375ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1376ed480e8bSBarry Smith       v    = a->a + a->i[i];
137717ab2063SBarry Smith       sum  = t[i];
1378003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1379ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1380733d66baSBarry Smith       /*  x = x + t */
1381733d66baSBarry Smith       x[i] += t[i];
138217ab2063SBarry Smith     }
138317ab2063SBarry Smith 
1384dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
13851ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13863649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
13873a40ed3dSBarry Smith     PetscFunctionReturn(0);
138817ab2063SBarry Smith   }
138917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
139017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
139117ab2063SBarry Smith       for (i=0; i<m; i++) {
1392416022c9SBarry Smith         n    = diag[i] - a->i[i];
1393ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1394ed480e8bSBarry Smith         v    = a->a + a->i[i];
139517ab2063SBarry Smith         sum  = b[i];
1396e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
13975c99c7daSBarry Smith         t[i] = sum;
1398ed480e8bSBarry Smith         x[i] = sum*idiag[i];
139917ab2063SBarry Smith       }
14005c99c7daSBarry Smith       xb = t;
1401efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
14023a40ed3dSBarry Smith     } else xb = b;
140317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
140417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1405416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1406ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1407ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
140817ab2063SBarry Smith         sum  = xb[i];
1409e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
14105c99c7daSBarry Smith         if (xb == b) {
1411ed480e8bSBarry Smith           x[i] = sum*idiag[i];
14125c99c7daSBarry Smith         } else {
14135c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
141417ab2063SBarry Smith         }
14155c99c7daSBarry Smith       }
1416efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
141717ab2063SBarry Smith     }
141817ab2063SBarry Smith     its--;
141917ab2063SBarry Smith   }
142017ab2063SBarry Smith   while (its--) {
142117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
142217ab2063SBarry Smith       for (i=0; i<m; i++) {
1423416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1424ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1425ed480e8bSBarry Smith         v    = a->a + a->i[i];
142617ab2063SBarry Smith         sum  = b[i];
1427e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1428ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
142917ab2063SBarry Smith       }
14309f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
143117ab2063SBarry Smith     }
143217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
143317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1434416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1435ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1436ed480e8bSBarry Smith         v    = a->a + a->i[i];
143717ab2063SBarry Smith         sum  = b[i];
1438e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1439ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
144017ab2063SBarry Smith       }
14419f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
144217ab2063SBarry Smith     }
144317ab2063SBarry Smith   }
14441ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14453649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
144671f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
144717ab2063SBarry Smith }
144817ab2063SBarry Smith 
14492af78befSBarry Smith 
14504a2ae208SSatish Balay #undef __FUNCT__
14514a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1452dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
145317ab2063SBarry Smith {
1454416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14554e220ebcSLois Curfman McInnes 
14563a40ed3dSBarry Smith   PetscFunctionBegin;
14574e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
14584e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
14594e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
14604e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
14614e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
14628e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
14637adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1464d5f3da31SBarry Smith   if (A->factortype) {
14654e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
14664e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
14674e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
14684e220ebcSLois Curfman McInnes   } else {
14694e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
14704e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
14714e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
14724e220ebcSLois Curfman McInnes   }
14733a40ed3dSBarry Smith   PetscFunctionReturn(0);
147417ab2063SBarry Smith }
147517ab2063SBarry Smith 
14764a2ae208SSatish Balay #undef __FUNCT__
14774a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
14782b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
147917ab2063SBarry Smith {
1480416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14813b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
14826849ba73SBarry Smith   PetscErrorCode    ierr;
148397b48c8fSBarry Smith   const PetscScalar *xx;
148497b48c8fSBarry Smith   PetscScalar       *bb;
1485ace3abfcSBarry Smith   PetscBool         missing;
148617ab2063SBarry Smith 
14873a40ed3dSBarry Smith   PetscFunctionBegin;
148897b48c8fSBarry Smith   if (x && b) {
148997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
149097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
149197b48c8fSBarry Smith     for (i=0; i<N; i++) {
149297b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
149397b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
149497b48c8fSBarry Smith     }
149597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
149697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
149797b48c8fSBarry Smith   }
149897b48c8fSBarry Smith 
1499a9817697SBarry Smith   if (a->keepnonzeropattern) {
1500f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1501e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1502bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1503f1e2ffcdSBarry Smith     }
1504f4df32b1SMatthew Knepley     if (diag != 0.0) {
150509f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1506e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1507f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1508f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1509f1e2ffcdSBarry Smith       }
1510f1e2ffcdSBarry Smith     }
151188e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1512f1e2ffcdSBarry Smith   } else {
1513f4df32b1SMatthew Knepley     if (diag != 0.0) {
151417ab2063SBarry Smith       for (i=0; i<N; i++) {
1515e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15167ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1517416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1518f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1519bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
15207ae801bdSBarry Smith         } else { /* in case row was completely empty */
1521f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
152217ab2063SBarry Smith         }
152317ab2063SBarry Smith       }
15243a40ed3dSBarry Smith     } else {
152517ab2063SBarry Smith       for (i=0; i<N; i++) {
1526e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1527416022c9SBarry Smith         a->ilen[rows[i]] = 0;
152817ab2063SBarry Smith       }
152917ab2063SBarry Smith     }
153088e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1531f1e2ffcdSBarry Smith   }
153243a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15333a40ed3dSBarry Smith   PetscFunctionReturn(0);
153417ab2063SBarry Smith }
153517ab2063SBarry Smith 
15364a2ae208SSatish Balay #undef __FUNCT__
15376e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
15386e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15396e169961SBarry Smith {
15406e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
15416e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
15426e169961SBarry Smith   PetscErrorCode    ierr;
15432b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
15446e169961SBarry Smith   const PetscScalar *xx;
15456e169961SBarry Smith   PetscScalar       *bb;
15466e169961SBarry Smith 
15476e169961SBarry Smith   PetscFunctionBegin;
15486e169961SBarry Smith   if (x && b) {
15496e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
15506e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15512b40b63fSBarry Smith     vecs = PETSC_TRUE;
15526e169961SBarry Smith   }
15536e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
15546e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
15556e169961SBarry Smith   for (i=0; i<N; i++) {
15566e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15576e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
15586e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
15596e169961SBarry Smith   }
15606e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
15616e169961SBarry Smith     if (!zeroed[i]) {
15626e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
15636e169961SBarry Smith         if (zeroed[a->j[j]]) {
15642b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
15656e169961SBarry Smith           a->a[j] = 0.0;
15666e169961SBarry Smith         }
15676e169961SBarry Smith       }
15682b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
15696e169961SBarry Smith   }
15706e169961SBarry Smith   if (x && b) {
15716e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
15726e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
15736e169961SBarry Smith   }
15746e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
15756e169961SBarry Smith   if (diag != 0.0) {
15766e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
15776e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
15786e169961SBarry Smith     for (i=0; i<N; i++) {
15796e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
15806e169961SBarry Smith     }
15816e169961SBarry Smith   }
15826e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
15836e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15846e169961SBarry Smith   PetscFunctionReturn(0);
15856e169961SBarry Smith }
15866e169961SBarry Smith 
15876e169961SBarry Smith #undef __FUNCT__
15884a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1589a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
159017ab2063SBarry Smith {
1591416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
159297f1f81fSBarry Smith   PetscInt   *itmp;
159317ab2063SBarry Smith 
15943a40ed3dSBarry Smith   PetscFunctionBegin;
1595e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
159617ab2063SBarry Smith 
1597416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1598bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
159917ab2063SBarry Smith   if (idx) {
1600bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1601bfeeae90SHong Zhang     if (*nz) {
16024e093b46SBarry Smith       *idx = itmp;
160317ab2063SBarry Smith     }
160417ab2063SBarry Smith     else *idx = 0;
160517ab2063SBarry Smith   }
16063a40ed3dSBarry Smith   PetscFunctionReturn(0);
160717ab2063SBarry Smith }
160817ab2063SBarry Smith 
1609bfeeae90SHong Zhang /* remove this function? */
16104a2ae208SSatish Balay #undef __FUNCT__
16114a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1612a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
161317ab2063SBarry Smith {
16143a40ed3dSBarry Smith   PetscFunctionBegin;
16153a40ed3dSBarry Smith   PetscFunctionReturn(0);
161617ab2063SBarry Smith }
161717ab2063SBarry Smith 
16184a2ae208SSatish Balay #undef __FUNCT__
16194a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1620dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
162117ab2063SBarry Smith {
1622416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
162354f21887SBarry Smith   MatScalar      *v = a->a;
162436db0b34SBarry Smith   PetscReal      sum = 0.0;
16256849ba73SBarry Smith   PetscErrorCode ierr;
162697f1f81fSBarry Smith   PetscInt       i,j;
162717ab2063SBarry Smith 
16283a40ed3dSBarry Smith   PetscFunctionBegin;
162917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1630416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1631aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
163236db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
163317ab2063SBarry Smith #else
163417ab2063SBarry Smith       sum += (*v)*(*v); v++;
163517ab2063SBarry Smith #endif
163617ab2063SBarry Smith     }
1637064f8208SBarry Smith     *nrm = sqrt(sum);
16383a40ed3dSBarry Smith   } else if (type == NORM_1) {
163936db0b34SBarry Smith     PetscReal *tmp;
164097f1f81fSBarry Smith     PetscInt    *jj = a->j;
1641d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1642d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1643064f8208SBarry Smith     *nrm = 0.0;
1644416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1645bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
164617ab2063SBarry Smith     }
1647d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1648064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
164917ab2063SBarry Smith     }
1650606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
16513a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1652064f8208SBarry Smith     *nrm = 0.0;
1653d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1654bfeeae90SHong Zhang       v = a->a + a->i[j];
165517ab2063SBarry Smith       sum = 0.0;
1656416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1657cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
165817ab2063SBarry Smith       }
1659064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
166017ab2063SBarry Smith     }
16613a40ed3dSBarry Smith   } else {
1662e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
166317ab2063SBarry Smith   }
16643a40ed3dSBarry Smith   PetscFunctionReturn(0);
166517ab2063SBarry Smith }
166617ab2063SBarry Smith 
16674a2ae208SSatish Balay #undef __FUNCT__
16684a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1669fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
167017ab2063SBarry Smith {
1671416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1672416022c9SBarry Smith   Mat            C;
16736849ba73SBarry Smith   PetscErrorCode ierr;
1674d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
167554f21887SBarry Smith   MatScalar      *array = a->a;
167617ab2063SBarry Smith 
16773a40ed3dSBarry Smith   PetscFunctionBegin;
1678e32f2f54SBarry 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");
1679fc4dec0aSBarry Smith 
1680fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1681d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1682d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1683bfeeae90SHong Zhang 
1684bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
16857adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1686d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
16877adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1688ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1689606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1690a541d17aSBarry Smith   } else {
1691a541d17aSBarry Smith     C = *B;
1692a541d17aSBarry Smith   }
1693a541d17aSBarry Smith 
169417ab2063SBarry Smith   for (i=0; i<m; i++) {
169517ab2063SBarry Smith     len    = ai[i+1]-ai[i];
169687d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1697b9b97703SBarry Smith     array += len;
1698b9b97703SBarry Smith     aj    += len;
169917ab2063SBarry Smith   }
17006d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17016d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
170217ab2063SBarry Smith 
1703815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1704416022c9SBarry Smith     *B = C;
170517ab2063SBarry Smith   } else {
1706eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
170717ab2063SBarry Smith   }
17083a40ed3dSBarry Smith   PetscFunctionReturn(0);
170917ab2063SBarry Smith }
171017ab2063SBarry Smith 
1711cd0d46ebSvictorle EXTERN_C_BEGIN
1712cd0d46ebSvictorle #undef __FUNCT__
17135fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
17147087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1715cd0d46ebSvictorle {
1716cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
171754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
171854f21887SBarry Smith   MatScalar      *va,*vb;
17196849ba73SBarry Smith   PetscErrorCode ierr;
172097f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1721cd0d46ebSvictorle 
1722cd0d46ebSvictorle   PetscFunctionBegin;
1723cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1724cd0d46ebSvictorle 
1725cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1726cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17275485867bSBarry Smith   if (ma!=nb || na!=mb){
17285485867bSBarry Smith     *f = PETSC_FALSE;
17295485867bSBarry Smith     PetscFunctionReturn(0);
17305485867bSBarry Smith   }
1731cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1732cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1733cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
173497f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
173597f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1736cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1737cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1738cd0d46ebSvictorle 
1739cd0d46ebSvictorle   *f = PETSC_TRUE;
1740cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1741cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
174297f1f81fSBarry Smith       PetscInt         idc,idr;
17435485867bSBarry Smith       PetscScalar vc,vr;
1744cd0d46ebSvictorle       /* column/row index/value */
17455485867bSBarry Smith       idc = adx[aptr[i]];
17465485867bSBarry Smith       idr = bdx[bptr[idc]];
17475485867bSBarry Smith       vc  = va[aptr[i]];
17485485867bSBarry Smith       vr  = vb[bptr[idc]];
17495485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
17505485867bSBarry Smith 	*f = PETSC_FALSE;
17515485867bSBarry Smith         goto done;
1752cd0d46ebSvictorle       } else {
17535485867bSBarry Smith 	aptr[i]++;
17545485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1755cd0d46ebSvictorle       }
1756cd0d46ebSvictorle     }
1757cd0d46ebSvictorle   }
1758cd0d46ebSvictorle  done:
1759cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
17603aeef889SHong Zhang   if (B) {
17613aeef889SHong Zhang     ierr = PetscFree(bptr);CHKERRQ(ierr);
17623aeef889SHong Zhang   }
1763cd0d46ebSvictorle   PetscFunctionReturn(0);
1764cd0d46ebSvictorle }
1765cd0d46ebSvictorle EXTERN_C_END
1766cd0d46ebSvictorle 
17671cbb95d3SBarry Smith EXTERN_C_BEGIN
17681cbb95d3SBarry Smith #undef __FUNCT__
17691cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
17707087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
17711cbb95d3SBarry Smith {
17721cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
177354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
177454f21887SBarry Smith   MatScalar      *va,*vb;
17751cbb95d3SBarry Smith   PetscErrorCode ierr;
17761cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
17771cbb95d3SBarry Smith 
17781cbb95d3SBarry Smith   PetscFunctionBegin;
17791cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
17801cbb95d3SBarry Smith 
17811cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
17821cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
17831cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
17841cbb95d3SBarry Smith     *f = PETSC_FALSE;
17851cbb95d3SBarry Smith     PetscFunctionReturn(0);
17861cbb95d3SBarry Smith   }
17871cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
17881cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
17891cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
17901cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
17911cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
17921cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
17931cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
17941cbb95d3SBarry Smith 
17951cbb95d3SBarry Smith   *f = PETSC_TRUE;
17961cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
17971cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
17981cbb95d3SBarry Smith       PetscInt         idc,idr;
17991cbb95d3SBarry Smith       PetscScalar vc,vr;
18001cbb95d3SBarry Smith       /* column/row index/value */
18011cbb95d3SBarry Smith       idc = adx[aptr[i]];
18021cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
18031cbb95d3SBarry Smith       vc  = va[aptr[i]];
18041cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
18051cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
18061cbb95d3SBarry Smith 	*f = PETSC_FALSE;
18071cbb95d3SBarry Smith         goto done;
18081cbb95d3SBarry Smith       } else {
18091cbb95d3SBarry Smith 	aptr[i]++;
18101cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
18111cbb95d3SBarry Smith       }
18121cbb95d3SBarry Smith     }
18131cbb95d3SBarry Smith   }
18141cbb95d3SBarry Smith  done:
18151cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
18161cbb95d3SBarry Smith   if (B) {
18171cbb95d3SBarry Smith     ierr = PetscFree(bptr);CHKERRQ(ierr);
18181cbb95d3SBarry Smith   }
18191cbb95d3SBarry Smith   PetscFunctionReturn(0);
18201cbb95d3SBarry Smith }
18211cbb95d3SBarry Smith EXTERN_C_END
18221cbb95d3SBarry Smith 
18239e29f15eSvictorle #undef __FUNCT__
18249e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1825ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
18269e29f15eSvictorle {
1827dfbe8321SBarry Smith   PetscErrorCode ierr;
18289e29f15eSvictorle   PetscFunctionBegin;
18295485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18309e29f15eSvictorle   PetscFunctionReturn(0);
18319e29f15eSvictorle }
18329e29f15eSvictorle 
18334a2ae208SSatish Balay #undef __FUNCT__
18341cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
1835ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
18361cbb95d3SBarry Smith {
18371cbb95d3SBarry Smith   PetscErrorCode ierr;
18381cbb95d3SBarry Smith   PetscFunctionBegin;
18391cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
18401cbb95d3SBarry Smith   PetscFunctionReturn(0);
18411cbb95d3SBarry Smith }
18421cbb95d3SBarry Smith 
18431cbb95d3SBarry Smith #undef __FUNCT__
18444a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1845dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
184617ab2063SBarry Smith {
1847416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
184854f21887SBarry Smith   PetscScalar    *l,*r,x;
184954f21887SBarry Smith   MatScalar      *v;
1850dfbe8321SBarry Smith   PetscErrorCode ierr;
1851d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
185217ab2063SBarry Smith 
18533a40ed3dSBarry Smith   PetscFunctionBegin;
185417ab2063SBarry Smith   if (ll) {
18553ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
18563ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1857e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1858e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
18591ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1860416022c9SBarry Smith     v = a->a;
186117ab2063SBarry Smith     for (i=0; i<m; i++) {
186217ab2063SBarry Smith       x = l[i];
1863416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
186417ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
186517ab2063SBarry Smith     }
18661ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1867efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
186817ab2063SBarry Smith   }
186917ab2063SBarry Smith   if (rr) {
1870e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1871e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
18721ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1873416022c9SBarry Smith     v = a->a; jj = a->j;
187417ab2063SBarry Smith     for (i=0; i<nz; i++) {
1875bfeeae90SHong Zhang       (*v++) *= r[*jj++];
187617ab2063SBarry Smith     }
18771ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1878efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
187917ab2063SBarry Smith   }
18803a40ed3dSBarry Smith   PetscFunctionReturn(0);
188117ab2063SBarry Smith }
188217ab2063SBarry Smith 
18834a2ae208SSatish Balay #undef __FUNCT__
18844a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
188597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
188617ab2063SBarry Smith {
1887db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
18886849ba73SBarry Smith   PetscErrorCode ierr;
1889d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
189097f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
18915d0c19d7SBarry Smith   const PetscInt *irow,*icol;
18925d0c19d7SBarry Smith   PetscInt       nrows,ncols;
189397f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
189454f21887SBarry Smith   MatScalar      *a_new,*mat_a;
1895416022c9SBarry Smith   Mat            C;
1896ace3abfcSBarry Smith   PetscBool      stride,sorted;
189717ab2063SBarry Smith 
18983a40ed3dSBarry Smith   PetscFunctionBegin;
189914ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
1900e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
190114ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
1902e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
190399141d43SSatish Balay 
190417ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1905b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1906b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
190717ab2063SBarry Smith 
1908fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
19090dbe5b1eSSatish Balay   ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
1910fee21e36SBarry Smith   if (stride && step == 1) {
191102834360SBarry Smith     /* special case of contiguous rows */
19120e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
191302834360SBarry Smith     /* loop over new rows determining lens and starting points */
191402834360SBarry Smith     for (i=0; i<nrows; i++) {
1915bfeeae90SHong Zhang       kstart  = ai[irow[i]];
1916a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
191702834360SBarry Smith       for (k=kstart; k<kend; k++) {
1918bfeeae90SHong Zhang         if (aj[k] >= first) {
191902834360SBarry Smith           starts[i] = k;
192002834360SBarry Smith           break;
192102834360SBarry Smith 	}
192202834360SBarry Smith       }
1923a2744918SBarry Smith       sum = 0;
192402834360SBarry Smith       while (k < kend) {
1925bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
1926a2744918SBarry Smith         sum++;
192702834360SBarry Smith       }
1928a2744918SBarry Smith       lens[i] = sum;
192902834360SBarry Smith     }
193002834360SBarry Smith     /* create submatrix */
1931cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
193297f1f81fSBarry Smith       PetscInt n_cols,n_rows;
193308480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1934e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1935d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
193608480c60SBarry Smith       C = *B;
19373a40ed3dSBarry Smith     } else {
19387adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1939f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19407adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1941ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
194208480c60SBarry Smith     }
1943db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1944db02288aSLois Curfman McInnes 
194502834360SBarry Smith     /* loop over rows inserting into submatrix */
1946db02288aSLois Curfman McInnes     a_new    = c->a;
1947db02288aSLois Curfman McInnes     j_new    = c->j;
1948db02288aSLois Curfman McInnes     i_new    = c->i;
1949bfeeae90SHong Zhang 
195002834360SBarry Smith     for (i=0; i<nrows; i++) {
1951a2744918SBarry Smith       ii    = starts[i];
1952a2744918SBarry Smith       lensi = lens[i];
1953a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1954a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
195502834360SBarry Smith       }
195687828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1957a2744918SBarry Smith       a_new      += lensi;
1958a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1959a2744918SBarry Smith       c->ilen[i]  = lensi;
196002834360SBarry Smith     }
19610e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
19623a40ed3dSBarry Smith   } else {
196302834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
19640e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
196597f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
19660e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
196717ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
196802834360SBarry Smith     /* determine lens of each row */
196902834360SBarry Smith     for (i=0; i<nrows; i++) {
1970bfeeae90SHong Zhang       kstart  = ai[irow[i]];
197102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
197202834360SBarry Smith       lens[i] = 0;
197302834360SBarry Smith       for (k=kstart; k<kend; k++) {
1974bfeeae90SHong Zhang         if (smap[aj[k]]) {
197502834360SBarry Smith           lens[i]++;
197602834360SBarry Smith         }
197702834360SBarry Smith       }
197802834360SBarry Smith     }
197917ab2063SBarry Smith     /* Create and fill new matrix */
1980a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
1981ace3abfcSBarry Smith       PetscBool  equal;
19820f5bd95cSBarry Smith 
198399141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1984e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1985d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
19860f5bd95cSBarry Smith       if (!equal) {
1987e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
198899141d43SSatish Balay       }
1989d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
199008480c60SBarry Smith       C = *B;
19913a40ed3dSBarry Smith     } else {
19927adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1993f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
19947adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1995ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
199608480c60SBarry Smith     }
199799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
199817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
199999141d43SSatish Balay       row    = irow[i];
2000bfeeae90SHong Zhang       kstart = ai[row];
200199141d43SSatish Balay       kend   = kstart + a->ilen[row];
2002bfeeae90SHong Zhang       mat_i  = c->i[i];
200399141d43SSatish Balay       mat_j  = c->j + mat_i;
200499141d43SSatish Balay       mat_a  = c->a + mat_i;
200599141d43SSatish Balay       mat_ilen = c->ilen + i;
200617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2007bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2008ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
200999141d43SSatish Balay           *mat_a++ = a->a[k];
201099141d43SSatish Balay           (*mat_ilen)++;
201199141d43SSatish Balay 
201217ab2063SBarry Smith         }
201317ab2063SBarry Smith       }
201417ab2063SBarry Smith     }
201502834360SBarry Smith     /* Free work space */
201602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2017606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2018606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
201902834360SBarry Smith   }
20206d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20216d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
202217ab2063SBarry Smith 
202317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2024416022c9SBarry Smith   *B = C;
20253a40ed3dSBarry Smith   PetscFunctionReturn(0);
202617ab2063SBarry Smith }
202717ab2063SBarry Smith 
20281df811f5SHong Zhang #undef __FUNCT__
202982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
203082d44351SHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat)
203182d44351SHong Zhang {
203282d44351SHong Zhang   PetscErrorCode ierr;
203382d44351SHong Zhang   Mat            B;
203482d44351SHong Zhang 
203582d44351SHong Zhang   PetscFunctionBegin;
203682d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
203782d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
203882d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
203982d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
204082d44351SHong Zhang   *subMat = B;
204182d44351SHong Zhang   PetscFunctionReturn(0);
204282d44351SHong Zhang }
204382d44351SHong Zhang 
204482d44351SHong Zhang #undef __FUNCT__
20454a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
20460481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2047a871dcd8SBarry Smith {
204863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2049dfbe8321SBarry Smith   PetscErrorCode ierr;
205063b91edcSBarry Smith   Mat            outA;
2051ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
205263b91edcSBarry Smith 
20533a40ed3dSBarry Smith   PetscFunctionBegin;
2054e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
20551df811f5SHong Zhang 
2056b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2057b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2058a871dcd8SBarry Smith 
205963b91edcSBarry Smith   outA              = inA;
2060d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2061c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
2062c3122656SLisandro Dalcin   if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr);}
2063c3122656SLisandro Dalcin   a->row = row;
2064c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
2065c3122656SLisandro Dalcin   if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr);}
2066c3122656SLisandro Dalcin   a->col = col;
206763b91edcSBarry Smith 
206836db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
2069b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
20704c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
207152e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2072f0ec6fceSSatish Balay 
207394a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2074d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2075d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
207694a9d846SBarry Smith   }
207763b91edcSBarry Smith 
2078f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2079137fb511SHong Zhang   if (row_identity && col_identity) {
2080ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2081137fb511SHong Zhang   } else {
2082719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2083137fb511SHong Zhang   }
20843a40ed3dSBarry Smith   PetscFunctionReturn(0);
2085a871dcd8SBarry Smith }
2086a871dcd8SBarry Smith 
20874a2ae208SSatish Balay #undef __FUNCT__
20884a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2089f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2090f0b747eeSBarry Smith {
2091f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2092f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2093efee365bSSatish Balay   PetscErrorCode ierr;
20940805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
20953a40ed3dSBarry Smith 
20963a40ed3dSBarry Smith   PetscFunctionBegin;
2097f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2098efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20993a40ed3dSBarry Smith   PetscFunctionReturn(0);
2100f0b747eeSBarry Smith }
2101f0b747eeSBarry Smith 
21024a2ae208SSatish Balay #undef __FUNCT__
21034a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
210497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2105cddf8d76SBarry Smith {
2106dfbe8321SBarry Smith   PetscErrorCode ierr;
210797f1f81fSBarry Smith   PetscInt       i;
2108cddf8d76SBarry Smith 
21093a40ed3dSBarry Smith   PetscFunctionBegin;
2110cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2111b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2112cddf8d76SBarry Smith   }
2113cddf8d76SBarry Smith 
2114cddf8d76SBarry Smith   for (i=0; i<n; i++) {
21156a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2116cddf8d76SBarry Smith   }
21173a40ed3dSBarry Smith   PetscFunctionReturn(0);
2118cddf8d76SBarry Smith }
2119cddf8d76SBarry Smith 
21204a2ae208SSatish Balay #undef __FUNCT__
21214a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
212297f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
21234dcbc457SBarry Smith {
2124e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21256849ba73SBarry Smith   PetscErrorCode ierr;
21265d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
21275d0c19d7SBarry Smith   const PetscInt *idx;
212897f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2129f1af5d2fSBarry Smith   PetscBT        table;
2130bbd702dbSSatish Balay 
21313a40ed3dSBarry Smith   PetscFunctionBegin;
2132d0f46423SBarry Smith   m     = A->rmap->n;
2133e4d965acSSatish Balay   ai    = a->i;
2134bfeeae90SHong Zhang   aj    = a->j;
21358a047759SSatish Balay 
2136e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
213706763907SSatish Balay 
213897f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
21396831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
214006763907SSatish Balay 
2141e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2142b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2143e4d965acSSatish Balay     isz  = 0;
21446831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2145e4d965acSSatish Balay 
2146e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
21474dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2148b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2149e4d965acSSatish Balay 
2150dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2151e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2152f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
21534dcbc457SBarry Smith     }
215406763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
215506763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
2156e4d965acSSatish Balay 
215704a348a9SBarry Smith     k = 0;
215804a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
215904a348a9SBarry Smith       n = isz;
216006763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2161e4d965acSSatish Balay         row   = nidx[k];
2162e4d965acSSatish Balay         start = ai[row];
2163e4d965acSSatish Balay         end   = ai[row+1];
216404a348a9SBarry Smith         for (l = start; l<end ; l++){
2165efb16452SHong Zhang           val = aj[l] ;
2166f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2167e4d965acSSatish Balay         }
2168e4d965acSSatish Balay       }
2169e4d965acSSatish Balay     }
217070b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2171e4d965acSSatish Balay   }
21726831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
2173606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
21743a40ed3dSBarry Smith   PetscFunctionReturn(0);
21754dcbc457SBarry Smith }
217617ab2063SBarry Smith 
21770513a670SBarry Smith /* -------------------------------------------------------------- */
21784a2ae208SSatish Balay #undef __FUNCT__
21794a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2180dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
21810513a670SBarry Smith {
21820513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
21836849ba73SBarry Smith   PetscErrorCode ierr;
21843b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
21855d0c19d7SBarry Smith   const PetscInt *row,*col;
21865d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
218756cd22aeSBarry Smith   IS             icolp,irowp;
21883b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
21893b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
21900513a670SBarry Smith 
21913a40ed3dSBarry Smith   PetscFunctionBegin;
21924c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
219356cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
21944c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
219556cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
21960513a670SBarry Smith 
21970513a670SBarry Smith   /* determine lengths of permuted rows */
219897f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
21990513a670SBarry Smith   for (i=0; i<m; i++) {
22000513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
22010513a670SBarry Smith   }
22027adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2203f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
22047adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2205ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2206606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
22070513a670SBarry Smith 
220897f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
22090513a670SBarry Smith   for (i=0; i<m; i++) {
221032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
22110513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2212cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
221332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
22140513a670SBarry Smith   }
2215606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
22163c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
22170513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22180513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
221956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
222056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
222156cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
222256cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
22233a40ed3dSBarry Smith   PetscFunctionReturn(0);
22240513a670SBarry Smith }
22250513a670SBarry Smith 
22264a2ae208SSatish Balay #undef __FUNCT__
22274a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2228dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2229cb5b572fSBarry Smith {
2230dfbe8321SBarry Smith   PetscErrorCode ierr;
2231cb5b572fSBarry Smith 
2232cb5b572fSBarry Smith   PetscFunctionBegin;
223333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
223433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2235be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2236be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2237be6bf707SBarry Smith 
2238700c5bfcSBarry 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");
2239d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2240cb5b572fSBarry Smith   } else {
2241cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2242cb5b572fSBarry Smith   }
2243cb5b572fSBarry Smith   PetscFunctionReturn(0);
2244cb5b572fSBarry Smith }
2245cb5b572fSBarry Smith 
22464a2ae208SSatish Balay #undef __FUNCT__
22474a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
2248dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A)
2249273d9f13SBarry Smith {
2250dfbe8321SBarry Smith   PetscErrorCode ierr;
2251273d9f13SBarry Smith 
2252273d9f13SBarry Smith   PetscFunctionBegin;
2253ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2254273d9f13SBarry Smith   PetscFunctionReturn(0);
2255273d9f13SBarry Smith }
2256273d9f13SBarry Smith 
22574a2ae208SSatish Balay #undef __FUNCT__
22584a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2259a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
22606c0721eeSBarry Smith {
22616c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
22626c0721eeSBarry Smith   PetscFunctionBegin;
22636c0721eeSBarry Smith   *array = a->a;
22646c0721eeSBarry Smith   PetscFunctionReturn(0);
22656c0721eeSBarry Smith }
22666c0721eeSBarry Smith 
22674a2ae208SSatish Balay #undef __FUNCT__
22684a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2269dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
22706c0721eeSBarry Smith {
22716c0721eeSBarry Smith   PetscFunctionBegin;
22726c0721eeSBarry Smith   PetscFunctionReturn(0);
22736c0721eeSBarry Smith }
2274273d9f13SBarry Smith 
2275ee4f033dSBarry Smith #undef __FUNCT__
2276ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2277dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2278ee4f033dSBarry Smith {
22796849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
22806849ba73SBarry Smith   PetscErrorCode ierr;
228197f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2282efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
228387828ca2SBarry Smith   PetscScalar    *vscale_array;
2284ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2285ee4f033dSBarry Smith   Vec            w1,w2,w3;
2286ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2287ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2288ee4f033dSBarry Smith 
2289ee4f033dSBarry Smith   PetscFunctionBegin;
2290ee4f033dSBarry Smith   if (!coloring->w1) {
2291ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
229252e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2293ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
229452e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2295ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
229652e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2297ee4f033dSBarry Smith   }
2298ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2299ee4f033dSBarry Smith 
2300ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2301acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2302ee4f033dSBarry Smith   if (flg) {
2303ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2304ee4f033dSBarry Smith   } else {
2305ace3abfcSBarry Smith     PetscBool  assembled;
23060b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
23070b9b6f31SBarry Smith     if (assembled) {
2308ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2309ee4f033dSBarry Smith     }
23100b9b6f31SBarry Smith   }
2311ee4f033dSBarry Smith 
2312ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2313ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2314ee4f033dSBarry Smith 
2315ee4f033dSBarry Smith   /*
2316ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
2317ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
2318ee4f033dSBarry Smith   */
2319ee4f033dSBarry Smith   if (coloring->F) {
2320ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2321ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2322ee4f033dSBarry Smith     if (m1 != m2) {
2323ee4f033dSBarry Smith       coloring->F = 0;
2324ee4f033dSBarry Smith     }
2325ee4f033dSBarry Smith   }
2326ee4f033dSBarry Smith 
2327ee4f033dSBarry Smith   if (coloring->F) {
2328ee4f033dSBarry Smith     w1          = coloring->F;
2329ee4f033dSBarry Smith     coloring->F = 0;
2330ee4f033dSBarry Smith   } else {
233166f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2332ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
233366f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2334ee4f033dSBarry Smith   }
2335ee4f033dSBarry Smith 
2336ee4f033dSBarry Smith   /*
2337ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2338ee4f033dSBarry Smith   */
23391ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
23401ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2341ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2342ee4f033dSBarry Smith     /*
2343ee4f033dSBarry Smith        Loop over each column associated with color adding the
2344ee4f033dSBarry Smith        perturbation to the vector w3.
2345ee4f033dSBarry Smith     */
2346ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2347ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2348ee4f033dSBarry Smith       dx  = xx[col];
2349ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2350ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2351ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2352ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2353ee4f033dSBarry Smith #else
2354ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2355ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2356ee4f033dSBarry Smith #endif
2357ee4f033dSBarry Smith       dx                *= epsilon;
2358ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2359ee4f033dSBarry Smith     }
2360ee4f033dSBarry Smith   }
23611ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2362ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2363ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2364ee4f033dSBarry Smith 
2365ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2366ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2367ee4f033dSBarry Smith 
2368ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2369ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2370ee4f033dSBarry Smith 
23711ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2372ee4f033dSBarry Smith   /*
2373ee4f033dSBarry Smith       Loop over each color
2374ee4f033dSBarry Smith   */
2375ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
237649b058dcSBarry Smith     coloring->currentcolor = k;
2377ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
23781ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2379ee4f033dSBarry Smith     /*
2380ee4f033dSBarry Smith        Loop over each column associated with color adding the
2381ee4f033dSBarry Smith        perturbation to the vector w3.
2382ee4f033dSBarry Smith     */
2383ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2384ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2385ee4f033dSBarry Smith       dx  = xx[col];
23865b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2387ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2388ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2389ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2390ee4f033dSBarry Smith #else
2391ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2392ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2393ee4f033dSBarry Smith #endif
2394ee4f033dSBarry Smith       dx            *= epsilon;
2395e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2396ee4f033dSBarry Smith       w3_array[col] += dx;
2397ee4f033dSBarry Smith     }
23981ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2399ee4f033dSBarry Smith 
2400ee4f033dSBarry Smith     /*
2401ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2402ee4f033dSBarry Smith     */
2403ee4f033dSBarry Smith 
240466f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2405ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
240666f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2407efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2408ee4f033dSBarry Smith 
2409ee4f033dSBarry Smith     /*
2410ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2411ee4f033dSBarry Smith     */
24121ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2413ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2414ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2415ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2416ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2417ee4f033dSBarry Smith       srow   = row + start;
2418ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2419ee4f033dSBarry Smith     }
24201ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2421ee4f033dSBarry Smith   }
242249b058dcSBarry Smith   coloring->currentcolor = k;
24231ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
24241ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2425ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2426ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2427ee4f033dSBarry Smith   PetscFunctionReturn(0);
2428ee4f033dSBarry Smith }
2429ee4f033dSBarry Smith 
24308229c054SShri Abhyankar /*
24318229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
24328229c054SShri Abhyankar    have different nonzero structure.
24338229c054SShri Abhyankar */
2434ac90fabeSBarry Smith #undef __FUNCT__
24358229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
24368229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2437ec7775f6SShri Abhyankar {
24388229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2439ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2440ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2441ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2442ec7775f6SShri Abhyankar 
2443ec7775f6SShri Abhyankar   PetscFunctionBegin;
2444ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2445ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
24468af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
24478af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
24488af7cee1SJed Brown     nnz[i] = 0;
24498af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
24508af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
24518af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
24528af7cee1SJed Brown       nnz[i]++;
24538af7cee1SJed Brown     }
24548af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2455ec7775f6SShri Abhyankar   }
2456ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2457ec7775f6SShri Abhyankar }
2458ec7775f6SShri Abhyankar 
2459ec7775f6SShri Abhyankar #undef __FUNCT__
2460ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2461f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2462ac90fabeSBarry Smith {
2463dfbe8321SBarry Smith   PetscErrorCode ierr;
246497f1f81fSBarry Smith   PetscInt       i;
2465ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
24660805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2467ac90fabeSBarry Smith 
2468ac90fabeSBarry Smith   PetscFunctionBegin;
2469ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2470f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2471f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
2472c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2473a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2474a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
2475a30b2313SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
2476a30b2313SHong Zhang     }
2477a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2478d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2479a30b2313SHong Zhang       y->XtoY = X;
2480407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2481c537a176SHong Zhang     }
2482f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
24831e2582c4SBarry 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);
2484ac90fabeSBarry Smith   } else {
24858229c054SShri Abhyankar     Mat      B;
24868229c054SShri Abhyankar     PetscInt *nnz;
248716b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2488ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2489bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
24904aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2491ec7775f6SShri Abhyankar     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
24928229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
24938229c054SShri Abhyankar     ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr);
2494ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2495ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
24968229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2497ac90fabeSBarry Smith   }
2498ac90fabeSBarry Smith   PetscFunctionReturn(0);
2499ac90fabeSBarry Smith }
2500ac90fabeSBarry Smith 
2501521d7252SBarry Smith #undef __FUNCT__
2502521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ"
2503521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs)
2504521d7252SBarry Smith {
250541c166b1SJed Brown   PetscErrorCode ierr;
250641c166b1SJed Brown 
2507521d7252SBarry Smith   PetscFunctionBegin;
250841c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr);
250941c166b1SJed Brown   ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr);
2510521d7252SBarry Smith   PetscFunctionReturn(0);
2511521d7252SBarry Smith }
2512521d7252SBarry Smith 
2513354c94deSBarry Smith #undef __FUNCT__
2514354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
25157087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2516354c94deSBarry Smith {
2517354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2518354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2519354c94deSBarry Smith   PetscInt    i,nz;
2520354c94deSBarry Smith   PetscScalar *a;
2521354c94deSBarry Smith 
2522354c94deSBarry Smith   PetscFunctionBegin;
2523354c94deSBarry Smith   nz = aij->nz;
2524354c94deSBarry Smith   a  = aij->a;
2525354c94deSBarry Smith   for (i=0; i<nz; i++) {
2526354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2527354c94deSBarry Smith   }
2528354c94deSBarry Smith #else
2529354c94deSBarry Smith   PetscFunctionBegin;
2530354c94deSBarry Smith #endif
2531354c94deSBarry Smith   PetscFunctionReturn(0);
2532354c94deSBarry Smith }
2533354c94deSBarry Smith 
2534e34fafa9SBarry Smith #undef __FUNCT__
2535985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2536985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2537e34fafa9SBarry Smith {
2538e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2539e34fafa9SBarry Smith   PetscErrorCode ierr;
2540d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2541e34fafa9SBarry Smith   PetscReal      atmp;
2542985db425SBarry Smith   PetscScalar    *x;
2543e34fafa9SBarry Smith   MatScalar      *aa;
2544e34fafa9SBarry Smith 
2545e34fafa9SBarry Smith   PetscFunctionBegin;
2546e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2547e34fafa9SBarry Smith   aa   = a->a;
2548e34fafa9SBarry Smith   ai   = a->i;
2549e34fafa9SBarry Smith   aj   = a->j;
2550e34fafa9SBarry Smith 
2551985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2552e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2553e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2554e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2555e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2556e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
25579189402eSHong Zhang     x[i] = 0.0;
2558e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2559985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2560985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2561985db425SBarry Smith       aa++; aj++;
2562985db425SBarry Smith     }
2563985db425SBarry Smith   }
2564985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2565985db425SBarry Smith   PetscFunctionReturn(0);
2566985db425SBarry Smith }
2567985db425SBarry Smith 
2568985db425SBarry Smith #undef __FUNCT__
2569985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2570985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2571985db425SBarry Smith {
2572985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2573985db425SBarry Smith   PetscErrorCode ierr;
2574d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2575985db425SBarry Smith   PetscScalar    *x;
2576985db425SBarry Smith   MatScalar      *aa;
2577985db425SBarry Smith 
2578985db425SBarry Smith   PetscFunctionBegin;
2579e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2580985db425SBarry Smith   aa   = a->a;
2581985db425SBarry Smith   ai   = a->i;
2582985db425SBarry Smith   aj   = a->j;
2583985db425SBarry Smith 
2584985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2585985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2586985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2587e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2588985db425SBarry Smith   for (i=0; i<m; i++) {
2589985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2590d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2591985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2592985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2593985db425SBarry Smith       x[i] = 0.0;
2594985db425SBarry Smith       if (idx) {
2595985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2596985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2597985db425SBarry Smith           if (aj[j] > j) {
2598985db425SBarry Smith             idx[i] = j;
2599985db425SBarry Smith             break;
2600985db425SBarry Smith           }
2601985db425SBarry Smith         }
2602985db425SBarry Smith       }
2603985db425SBarry Smith     }
2604985db425SBarry Smith     for (j=0; j<ncols; j++){
2605985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2606985db425SBarry Smith       aa++; aj++;
2607985db425SBarry Smith     }
2608985db425SBarry Smith   }
2609985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2610985db425SBarry Smith   PetscFunctionReturn(0);
2611985db425SBarry Smith }
2612985db425SBarry Smith 
2613985db425SBarry Smith #undef __FUNCT__
2614c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2615c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2616c87e5d42SMatthew Knepley {
2617c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2618c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2619c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2620c87e5d42SMatthew Knepley   PetscReal      atmp;
2621c87e5d42SMatthew Knepley   PetscScalar    *x;
2622c87e5d42SMatthew Knepley   MatScalar      *aa;
2623c87e5d42SMatthew Knepley 
2624c87e5d42SMatthew Knepley   PetscFunctionBegin;
2625e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2626c87e5d42SMatthew Knepley   aa   = a->a;
2627c87e5d42SMatthew Knepley   ai   = a->i;
2628c87e5d42SMatthew Knepley   aj   = a->j;
2629c87e5d42SMatthew Knepley 
2630c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2631c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2632c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2633e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2634c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2635c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2636289a08f5SMatthew Knepley     if (ncols) {
2637289a08f5SMatthew Knepley       /* Get first nonzero */
2638289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2639289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2640289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2641289a08f5SMatthew Knepley       }
2642289a08f5SMatthew Knepley       if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;}
2643289a08f5SMatthew Knepley     } else {
2644289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2645289a08f5SMatthew Knepley     }
2646c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2647c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2648289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2649c87e5d42SMatthew Knepley       aa++; aj++;
2650c87e5d42SMatthew Knepley     }
2651c87e5d42SMatthew Knepley   }
2652c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2653c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2654c87e5d42SMatthew Knepley }
2655c87e5d42SMatthew Knepley 
2656c87e5d42SMatthew Knepley #undef __FUNCT__
2657985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2658985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2659985db425SBarry Smith {
2660985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2661985db425SBarry Smith   PetscErrorCode ierr;
2662d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2663985db425SBarry Smith   PetscScalar    *x;
2664985db425SBarry Smith   MatScalar      *aa;
2665985db425SBarry Smith 
2666985db425SBarry Smith   PetscFunctionBegin;
2667e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2668985db425SBarry Smith   aa   = a->a;
2669985db425SBarry Smith   ai   = a->i;
2670985db425SBarry Smith   aj   = a->j;
2671985db425SBarry Smith 
2672985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2673985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2674985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2675e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2676985db425SBarry Smith   for (i=0; i<m; i++) {
2677985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2678d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2679985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2680985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2681985db425SBarry Smith       x[i] = 0.0;
2682985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2683985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2684985db425SBarry Smith         for (j=0;j<ncols;j++) {
2685985db425SBarry Smith           if (aj[j] > j) {
2686985db425SBarry Smith             idx[i] = j;
2687985db425SBarry Smith             break;
2688985db425SBarry Smith           }
2689985db425SBarry Smith         }
2690985db425SBarry Smith       }
2691985db425SBarry Smith     }
2692985db425SBarry Smith     for (j=0; j<ncols; j++){
2693985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2694985db425SBarry Smith       aa++; aj++;
2695e34fafa9SBarry Smith     }
2696e34fafa9SBarry Smith   }
2697e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2698e34fafa9SBarry Smith   PetscFunctionReturn(0);
2699e34fafa9SBarry Smith }
27007087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2701682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
27020a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2703cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2704cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2705cb5b572fSBarry Smith        MatMult_SeqAIJ,
270697304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
27077c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
27087c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2709db4efbfdSBarry Smith        0,
2710db4efbfdSBarry Smith        0,
2711db4efbfdSBarry Smith        0,
2712db4efbfdSBarry Smith /*10*/ 0,
2713cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2714cb5b572fSBarry Smith        0,
271541f059aeSBarry Smith        MatSOR_SeqAIJ,
271617ab2063SBarry Smith        MatTranspose_SeqAIJ,
271797304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2718cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2719cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2720cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2721cb5b572fSBarry Smith        MatNorm_SeqAIJ,
272297304618SKris Buschelman /*20*/ 0,
2723cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2724cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2725cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2726d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2727db4efbfdSBarry Smith        0,
2728db4efbfdSBarry Smith        0,
2729db4efbfdSBarry Smith        0,
2730db4efbfdSBarry Smith        0,
2731d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ,
2732db4efbfdSBarry Smith        0,
2733db4efbfdSBarry Smith        0,
27346c0721eeSBarry Smith        MatGetArray_SeqAIJ,
27356c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2736d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2737cb5b572fSBarry Smith        0,
2738cb5b572fSBarry Smith        0,
2739cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2740cb5b572fSBarry Smith        0,
2741d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
2742cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2743cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2744cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2745cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2746d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
2747cb5b572fSBarry Smith        MatScale_SeqAIJ,
2748cb5b572fSBarry Smith        0,
274979299369SBarry Smith        MatDiagonalSet_SeqAIJ,
27506e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
2751d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ,
27523b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
27533b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
27543b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2755a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2756d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
2757b9617806SBarry Smith        0,
27580513a670SBarry Smith        0,
2759cda55fadSBarry Smith        MatPermute_SeqAIJ,
2760cda55fadSBarry Smith        0,
2761d519adbfSMatthew Knepley /*59*/ 0,
2762b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2763b9b97703SBarry Smith        MatView_SeqAIJ,
2764357abbc8SBarry Smith        0,
2765ee4f033dSBarry Smith        0,
2766d519adbfSMatthew Knepley /*64*/ 0,
2767ee4f033dSBarry Smith        0,
2768ee4f033dSBarry Smith        0,
2769ee4f033dSBarry Smith        0,
2770ee4f033dSBarry Smith        0,
2771d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
2772c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
2773ee4f033dSBarry Smith        0,
2774ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2775dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2776ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2777dcf5cc72SBarry Smith #else
2778dcf5cc72SBarry Smith        0,
2779dcf5cc72SBarry Smith #endif
2780d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
27813acb8795SBarry Smith        MatFDColoringApply_AIJ,
278297304618SKris Buschelman        0,
278397304618SKris Buschelman        0,
278497304618SKris Buschelman        0,
27856ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
278697304618SKris Buschelman        0,
278797304618SKris Buschelman        0,
278897304618SKris Buschelman        0,
2789bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2790d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
27911cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
27926284ec50SHong Zhang        0,
27936284ec50SHong Zhang        0,
2794bc011b1eSHong Zhang        0,
2795d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
279626be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
279726be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
2798d439da42SKris Buschelman        MatPtAP_Basic,
27997ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
2800d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
2801bc011b1eSHong Zhang        MatMatMultTranspose_SeqAIJ_SeqAIJ,
2802bc011b1eSHong Zhang        MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ,
2803bc011b1eSHong Zhang        MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ,
28047ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
2805d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
2806609c6c4dSKris Buschelman        0,
2807609c6c4dSKris Buschelman        0,
280887d4246cSBarry Smith        MatConjugate_SeqAIJ,
280987d4246cSBarry Smith        0,
2810d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
281199cafbc1SBarry Smith        MatRealPart_SeqAIJ,
2812f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
2813f5edf698SHong Zhang        0,
28142bebee5dSHong Zhang        0,
2815cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
2816985db425SBarry Smith        0,
28172af78befSBarry Smith        MatGetRowMin_SeqAIJ,
28182af78befSBarry Smith        0,
2819599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
2820d519adbfSMatthew Knepley /*114*/0,
2821599ef60dSHong Zhang        0,
28223c2a7987SHong Zhang        0,
2823fe97e370SBarry Smith        0,
2824fbdbba38SShri Abhyankar        0,
2825fbdbba38SShri Abhyankar /*119*/0,
2826fbdbba38SShri Abhyankar        0,
2827fbdbba38SShri Abhyankar        0,
282882d44351SHong Zhang        0,
2829b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
2830b3a44c85SBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ
28319e29f15eSvictorle };
283217ab2063SBarry Smith 
2833fb2e594dSBarry Smith EXTERN_C_BEGIN
28344a2ae208SSatish Balay #undef __FUNCT__
28354a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
28367087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
2837bef8e0ddSBarry Smith {
2838bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
283997f1f81fSBarry Smith   PetscInt   i,nz,n;
2840bef8e0ddSBarry Smith 
2841bef8e0ddSBarry Smith   PetscFunctionBegin;
2842bef8e0ddSBarry Smith 
2843bef8e0ddSBarry Smith   nz = aij->maxnz;
2844d0f46423SBarry Smith   n  = mat->rmap->n;
2845bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2846bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2847bef8e0ddSBarry Smith   }
2848bef8e0ddSBarry Smith   aij->nz = nz;
2849bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2850bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2851bef8e0ddSBarry Smith   }
2852bef8e0ddSBarry Smith 
2853bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2854bef8e0ddSBarry Smith }
2855fb2e594dSBarry Smith EXTERN_C_END
2856bef8e0ddSBarry Smith 
28574a2ae208SSatish Balay #undef __FUNCT__
28584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2859bef8e0ddSBarry Smith /*@
2860bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2861bef8e0ddSBarry Smith        in the matrix.
2862bef8e0ddSBarry Smith 
2863bef8e0ddSBarry Smith   Input Parameters:
2864bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2865bef8e0ddSBarry Smith -  indices - the column indices
2866bef8e0ddSBarry Smith 
286715091d37SBarry Smith   Level: advanced
286815091d37SBarry Smith 
2869bef8e0ddSBarry Smith   Notes:
2870bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2871bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2872bef8e0ddSBarry Smith   of the MatSetValues() operation.
2873bef8e0ddSBarry Smith 
2874bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2875d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
2876bef8e0ddSBarry Smith 
2877bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2878bef8e0ddSBarry Smith 
2879b9617806SBarry Smith     The indices should start with zero, not one.
2880b9617806SBarry Smith 
2881bef8e0ddSBarry Smith @*/
28827087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
2883bef8e0ddSBarry Smith {
28844ac538c5SBarry Smith   PetscErrorCode ierr;
2885bef8e0ddSBarry Smith 
2886bef8e0ddSBarry Smith   PetscFunctionBegin;
28870700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
28884482741eSBarry Smith   PetscValidPointer(indices,2);
28894ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
2890bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2891bef8e0ddSBarry Smith }
2892bef8e0ddSBarry Smith 
2893be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2894be6bf707SBarry Smith 
2895fb2e594dSBarry Smith EXTERN_C_BEGIN
28964a2ae208SSatish Balay #undef __FUNCT__
28974a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
28987087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
2899be6bf707SBarry Smith {
2900be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
29016849ba73SBarry Smith   PetscErrorCode ierr;
2902d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
2903be6bf707SBarry Smith 
2904be6bf707SBarry Smith   PetscFunctionBegin;
2905be6bf707SBarry Smith   if (aij->nonew != 1) {
2906e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2907be6bf707SBarry Smith   }
2908be6bf707SBarry Smith 
2909be6bf707SBarry Smith   /* allocate space for values if not already there */
2910be6bf707SBarry Smith   if (!aij->saved_values) {
291187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
29129518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
2913be6bf707SBarry Smith   }
2914be6bf707SBarry Smith 
2915be6bf707SBarry Smith   /* copy values over */
291687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2917be6bf707SBarry Smith   PetscFunctionReturn(0);
2918be6bf707SBarry Smith }
2919fb2e594dSBarry Smith EXTERN_C_END
2920be6bf707SBarry Smith 
29214a2ae208SSatish Balay #undef __FUNCT__
2922b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2923be6bf707SBarry Smith /*@
2924be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2925be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2926be6bf707SBarry Smith        nonlinear portion.
2927be6bf707SBarry Smith 
2928be6bf707SBarry Smith    Collect on Mat
2929be6bf707SBarry Smith 
2930be6bf707SBarry Smith   Input Parameters:
29310e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
2932be6bf707SBarry Smith 
293315091d37SBarry Smith   Level: advanced
293415091d37SBarry Smith 
2935be6bf707SBarry Smith   Common Usage, with SNESSolve():
2936be6bf707SBarry Smith $    Create Jacobian matrix
2937be6bf707SBarry Smith $    Set linear terms into matrix
2938be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2939be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2940be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2941512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2942be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2943be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2944be6bf707SBarry Smith $    In your Jacobian routine
2945be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2946be6bf707SBarry Smith $      Set nonlinear terms in matrix
2947be6bf707SBarry Smith 
2948be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2949be6bf707SBarry Smith $    // build linear portion of Jacobian
2950512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
2951be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2952be6bf707SBarry Smith $    loop over nonlinear iterations
2953be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2954be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2955be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2956be6bf707SBarry Smith $       Solve linear system with Jacobian
2957be6bf707SBarry Smith $    endloop
2958be6bf707SBarry Smith 
2959be6bf707SBarry Smith   Notes:
2960be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2961512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
2962be6bf707SBarry Smith     calling this routine.
2963be6bf707SBarry Smith 
29640c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
29650c468ba9SBarry Smith     and does not allocated additional space.
29660c468ba9SBarry Smith 
2967be6bf707SBarry Smith .seealso: MatRetrieveValues()
2968be6bf707SBarry Smith 
2969be6bf707SBarry Smith @*/
29707087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
2971be6bf707SBarry Smith {
29724ac538c5SBarry Smith   PetscErrorCode ierr;
2973be6bf707SBarry Smith 
2974be6bf707SBarry Smith   PetscFunctionBegin;
29750700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2976e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2977e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
29784ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
2979be6bf707SBarry Smith   PetscFunctionReturn(0);
2980be6bf707SBarry Smith }
2981be6bf707SBarry Smith 
2982fb2e594dSBarry Smith EXTERN_C_BEGIN
29834a2ae208SSatish Balay #undef __FUNCT__
29844a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
29857087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
2986be6bf707SBarry Smith {
2987be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
29886849ba73SBarry Smith   PetscErrorCode ierr;
2989d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
2990be6bf707SBarry Smith 
2991be6bf707SBarry Smith   PetscFunctionBegin;
2992be6bf707SBarry Smith   if (aij->nonew != 1) {
2993e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
2994be6bf707SBarry Smith   }
2995be6bf707SBarry Smith   if (!aij->saved_values) {
2996e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
2997be6bf707SBarry Smith   }
2998be6bf707SBarry Smith   /* copy values over */
299987828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3000be6bf707SBarry Smith   PetscFunctionReturn(0);
3001be6bf707SBarry Smith }
3002fb2e594dSBarry Smith EXTERN_C_END
3003be6bf707SBarry Smith 
30044a2ae208SSatish Balay #undef __FUNCT__
30054a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3006be6bf707SBarry Smith /*@
3007be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3008be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3009be6bf707SBarry Smith        nonlinear portion.
3010be6bf707SBarry Smith 
3011be6bf707SBarry Smith    Collect on Mat
3012be6bf707SBarry Smith 
3013be6bf707SBarry Smith   Input Parameters:
3014be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3015be6bf707SBarry Smith 
301615091d37SBarry Smith   Level: advanced
301715091d37SBarry Smith 
3018be6bf707SBarry Smith .seealso: MatStoreValues()
3019be6bf707SBarry Smith 
3020be6bf707SBarry Smith @*/
30217087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3022be6bf707SBarry Smith {
30234ac538c5SBarry Smith   PetscErrorCode ierr;
3024be6bf707SBarry Smith 
3025be6bf707SBarry Smith   PetscFunctionBegin;
30260700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3027e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3028e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
30294ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3030be6bf707SBarry Smith   PetscFunctionReturn(0);
3031be6bf707SBarry Smith }
3032be6bf707SBarry Smith 
3033f83d6046SBarry Smith 
3034be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
30354a2ae208SSatish Balay #undef __FUNCT__
30364a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
303717ab2063SBarry Smith /*@C
3038682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
30390d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
30406e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
304151c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
30422bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
304317ab2063SBarry Smith 
3044db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3045db81eaa0SLois Curfman McInnes 
304617ab2063SBarry Smith    Input Parameters:
3047db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
304817ab2063SBarry Smith .  m - number of rows
304917ab2063SBarry Smith .  n - number of columns
305017ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
305151c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
30522bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
305317ab2063SBarry Smith 
305417ab2063SBarry Smith    Output Parameter:
3055416022c9SBarry Smith .  A - the matrix
305617ab2063SBarry Smith 
3057175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3058ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3059175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3060175b88e8SBarry Smith 
3061b259b22eSLois Curfman McInnes    Notes:
306249a6f317SBarry Smith    If nnz is given then nz is ignored
306349a6f317SBarry Smith 
306417ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
306517ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
30660002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
306744cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
306817ab2063SBarry Smith 
306917ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3070a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
30713d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
30726da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
307317ab2063SBarry Smith 
3074682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
30754fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3076682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
30776c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
30786c7ebb05SLois Curfman McInnes 
30796c7ebb05SLois Curfman McInnes    Options Database Keys:
3080698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
30819db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
308217ab2063SBarry Smith 
3083027ccd11SLois Curfman McInnes    Level: intermediate
3084027ccd11SLois Curfman McInnes 
308536db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
308636db0b34SBarry Smith 
308717ab2063SBarry Smith @*/
30887087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
308917ab2063SBarry Smith {
3090dfbe8321SBarry Smith   PetscErrorCode ierr;
30916945ee14SBarry Smith 
30923a40ed3dSBarry Smith   PetscFunctionBegin;
3093f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3094117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3095c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3096d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3097273d9f13SBarry Smith   PetscFunctionReturn(0);
3098273d9f13SBarry Smith }
3099273d9f13SBarry Smith 
31004a2ae208SSatish Balay #undef __FUNCT__
31014a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3102273d9f13SBarry Smith /*@C
3103273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3104273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3105273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3106273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3107273d9f13SBarry Smith 
3108273d9f13SBarry Smith    Collective on MPI_Comm
3109273d9f13SBarry Smith 
3110273d9f13SBarry Smith    Input Parameters:
3111117016b1SBarry Smith +  B - The matrix-free
3112273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3113273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3114273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3115273d9f13SBarry Smith 
3116273d9f13SBarry Smith    Notes:
311749a6f317SBarry Smith      If nnz is given then nz is ignored
311849a6f317SBarry Smith 
3119273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3120273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3121273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3122273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3123273d9f13SBarry Smith 
3124273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3125273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3126273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3127273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3128273d9f13SBarry Smith 
3129aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3130aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3131aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3132aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3133aa95bbe8SBarry Smith 
3134a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3135a96a251dSBarry Smith    entries or columns indices
3136a96a251dSBarry Smith 
3137273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3138273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3139273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3140273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3141273d9f13SBarry Smith 
3142273d9f13SBarry Smith    Options Database Keys:
3143698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3144698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3145273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3146273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3147273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3148273d9f13SBarry Smith 
3149273d9f13SBarry Smith    Level: intermediate
3150273d9f13SBarry Smith 
3151aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3152273d9f13SBarry Smith 
3153273d9f13SBarry Smith @*/
31547087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3155273d9f13SBarry Smith {
31564ac538c5SBarry Smith   PetscErrorCode ierr;
3157a23d5eceSKris Buschelman 
3158a23d5eceSKris Buschelman   PetscFunctionBegin;
31594ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3160a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3161a23d5eceSKris Buschelman }
3162a23d5eceSKris Buschelman 
3163a23d5eceSKris Buschelman EXTERN_C_BEGIN
3164a23d5eceSKris Buschelman #undef __FUNCT__
3165a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
31667087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3167a23d5eceSKris Buschelman {
3168273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3169ace3abfcSBarry Smith   PetscBool      skipallocation = PETSC_FALSE;
31706849ba73SBarry Smith   PetscErrorCode ierr;
317197f1f81fSBarry Smith   PetscInt       i;
3172273d9f13SBarry Smith 
3173273d9f13SBarry Smith   PetscFunctionBegin;
3174d5d45c9bSBarry Smith 
3175a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3176c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3177c461c341SBarry Smith     nz             = 0;
3178c461c341SBarry Smith   }
3179c461c341SBarry Smith 
318026283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr);
318126283091SBarry Smith   ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr);
318226283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
318326283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3184899cda47SBarry Smith 
3185435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3186e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3187b73539f3SBarry Smith   if (nnz) {
3188d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3189e32f2f54SBarry 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]);
3190e32f2f54SBarry 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);
3191b73539f3SBarry Smith     }
3192b73539f3SBarry Smith   }
3193b73539f3SBarry Smith 
3194273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3195273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3196273d9f13SBarry Smith 
3197ab93d7beSBarry Smith   if (!skipallocation) {
31982ee49352SLisandro Dalcin     if (!b->imax) {
3199d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3200d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
32012ee49352SLisandro Dalcin     }
3202273d9f13SBarry Smith     if (!nnz) {
3203435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3204c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3205d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3206d0f46423SBarry Smith       nz = nz*B->rmap->n;
3207273d9f13SBarry Smith     } else {
3208273d9f13SBarry Smith       nz = 0;
3209d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3210273d9f13SBarry Smith     }
3211ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3212d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3213ab93d7beSBarry Smith 
3214273d9f13SBarry Smith     /* allocate the matrix space */
32152ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3216d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3217d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3218bfeeae90SHong Zhang     b->i[0] = 0;
3219d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
32205da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
32215da197adSKris Buschelman     }
3222273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3223e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3224e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3225c461c341SBarry Smith   } else {
3226e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3227e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3228c461c341SBarry Smith   }
3229273d9f13SBarry Smith 
3230273d9f13SBarry Smith   b->nz                = 0;
3231273d9f13SBarry Smith   b->maxnz             = nz;
3232273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
3233273d9f13SBarry Smith   PetscFunctionReturn(0);
3234273d9f13SBarry Smith }
3235a23d5eceSKris Buschelman EXTERN_C_END
3236273d9f13SBarry Smith 
3237a1661176SMatthew Knepley #undef  __FUNCT__
3238a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
323958d36128SBarry Smith /*@
3240a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3241a1661176SMatthew Knepley 
3242a1661176SMatthew Knepley    Input Parameters:
3243a1661176SMatthew Knepley +  B - the matrix
3244a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3245a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3246a1661176SMatthew Knepley -  v - optional values in the matrix
3247a1661176SMatthew Knepley 
3248a1661176SMatthew Knepley    Level: developer
3249a1661176SMatthew Knepley 
325058d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
325158d36128SBarry Smith 
3252a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3253a1661176SMatthew Knepley 
3254a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3255a1661176SMatthew Knepley @*/
3256a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3257a1661176SMatthew Knepley {
3258a1661176SMatthew Knepley   PetscErrorCode ierr;
3259a1661176SMatthew Knepley 
3260a1661176SMatthew Knepley   PetscFunctionBegin;
32610700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
32624ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3263a1661176SMatthew Knepley   PetscFunctionReturn(0);
3264a1661176SMatthew Knepley }
3265a1661176SMatthew Knepley 
3266a1661176SMatthew Knepley EXTERN_C_BEGIN
3267a1661176SMatthew Knepley #undef  __FUNCT__
3268a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
32697087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3270a1661176SMatthew Knepley {
3271a1661176SMatthew Knepley   PetscInt       i;
3272a1661176SMatthew Knepley   PetscInt       m,n;
3273a1661176SMatthew Knepley   PetscInt       nz;
3274a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3275a1661176SMatthew Knepley   PetscScalar    *values;
3276a1661176SMatthew Knepley   PetscErrorCode ierr;
3277a1661176SMatthew Knepley 
3278a1661176SMatthew Knepley   PetscFunctionBegin;
3279a1661176SMatthew Knepley   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3280a1661176SMatthew Knepley 
328165e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3282a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3283a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3284b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3285a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
328665e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3287a1661176SMatthew Knepley     nnz[i] = nz;
3288a1661176SMatthew Knepley   }
3289a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3290a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3291a1661176SMatthew Knepley 
3292a1661176SMatthew Knepley   if (v) {
3293a1661176SMatthew Knepley     values = (PetscScalar*) v;
3294a1661176SMatthew Knepley   } else {
32950e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3296a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3297a1661176SMatthew Knepley   }
3298a1661176SMatthew Knepley 
3299a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3300b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3301b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3302a1661176SMatthew Knepley   }
3303a1661176SMatthew Knepley 
3304a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3305a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3306a1661176SMatthew Knepley 
3307a1661176SMatthew Knepley   if (!v) {
3308a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3309a1661176SMatthew Knepley   }
3310a1661176SMatthew Knepley   PetscFunctionReturn(0);
3311a1661176SMatthew Knepley }
3312a1661176SMatthew Knepley EXTERN_C_END
3313a1661176SMatthew Knepley 
3314c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3315c6db04a5SJed Brown #include <private/petscaxpy.h>
3316170fe5c8SBarry Smith 
3317170fe5c8SBarry Smith #undef __FUNCT__
3318170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3319170fe5c8SBarry Smith /*
3320170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3321170fe5c8SBarry Smith 
3322170fe5c8SBarry Smith                n                       p                          p
3323170fe5c8SBarry Smith         (              )       (              )         (                  )
3324170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3325170fe5c8SBarry Smith         (              )       (              )         (                  )
3326170fe5c8SBarry Smith 
3327170fe5c8SBarry Smith */
3328170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3329170fe5c8SBarry Smith {
3330170fe5c8SBarry Smith   PetscErrorCode     ierr;
3331170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3332170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3333170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
33341de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3335170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3336170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3337170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3338170fe5c8SBarry Smith 
3339170fe5c8SBarry Smith   PetscFunctionBegin;
3340d0f46423SBarry Smith   m = A->rmap->n;
3341d0f46423SBarry Smith   n = A->cmap->n;
3342d0f46423SBarry Smith   p = B->cmap->n;
3343170fe5c8SBarry Smith   a = sub_a->v;
3344170fe5c8SBarry Smith   b = sub_b->a;
3345170fe5c8SBarry Smith   c = sub_c->v;
3346170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3347170fe5c8SBarry Smith 
3348170fe5c8SBarry Smith   ii  = sub_b->i;
3349170fe5c8SBarry Smith   idx = sub_b->j;
3350170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3351170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3352170fe5c8SBarry Smith     while (q-->0) {
3353170fe5c8SBarry Smith       c_q = c + m*(*idx);
3354170fe5c8SBarry Smith       a_q = a + m*i;
3355be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3356170fe5c8SBarry Smith       idx++;
3357170fe5c8SBarry Smith       b++;
3358170fe5c8SBarry Smith     }
3359170fe5c8SBarry Smith   }
3360170fe5c8SBarry Smith   PetscFunctionReturn(0);
3361170fe5c8SBarry Smith }
3362170fe5c8SBarry Smith 
3363170fe5c8SBarry Smith #undef __FUNCT__
3364170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3365170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3366170fe5c8SBarry Smith {
3367170fe5c8SBarry Smith   PetscErrorCode ierr;
3368d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3369170fe5c8SBarry Smith   Mat            Cmat;
3370170fe5c8SBarry Smith 
3371170fe5c8SBarry Smith   PetscFunctionBegin;
3372e32f2f54SBarry 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);
337339804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3374170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3375170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3376170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3377170fe5c8SBarry Smith   Cmat->assembled = PETSC_TRUE;
3378170fe5c8SBarry Smith   *C = Cmat;
3379170fe5c8SBarry Smith   PetscFunctionReturn(0);
3380170fe5c8SBarry Smith }
3381170fe5c8SBarry Smith 
3382170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3383170fe5c8SBarry Smith #undef __FUNCT__
3384170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3385170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3386170fe5c8SBarry Smith {
3387170fe5c8SBarry Smith   PetscErrorCode ierr;
3388170fe5c8SBarry Smith 
3389170fe5c8SBarry Smith   PetscFunctionBegin;
3390170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3391170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3392170fe5c8SBarry Smith   }
3393170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3394170fe5c8SBarry Smith   PetscFunctionReturn(0);
3395170fe5c8SBarry Smith }
3396170fe5c8SBarry Smith 
3397170fe5c8SBarry Smith 
33980bad9183SKris Buschelman /*MC
3399fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
34000bad9183SKris Buschelman    based on compressed sparse row format.
34010bad9183SKris Buschelman 
34020bad9183SKris Buschelman    Options Database Keys:
34030bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
34040bad9183SKris Buschelman 
34050bad9183SKris Buschelman   Level: beginner
34060bad9183SKris Buschelman 
3407f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
34080bad9183SKris Buschelman M*/
34090bad9183SKris Buschelman 
3410a6175056SHong Zhang EXTERN_C_BEGIN
3411b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3412b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3413b5e56a35SBarry Smith #endif
3414*ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3415af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3416af1023dbSSatish Balay #endif
34177087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
34187087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
34197087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
34207087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3421611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
34227087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3423611f576cSBarry Smith #endif
3424611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
34257087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3426611f576cSBarry Smith #endif
3427f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3428f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3429f3c0ef26SHong Zhang #endif
3430611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
34317087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3432611f576cSBarry Smith #endif
3433eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
34347087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3435eb3b5408SSatish Balay #endif
3436586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
34377087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3438586621ddSJed Brown #endif
3439719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
34407087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3441719d5645SBarry Smith #endif
3442b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
34437087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
34447087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
34457087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3446b3866ffcSBarry Smith #endif
344717667f90SBarry Smith EXTERN_C_END
344817667f90SBarry Smith 
3449b24902e0SBarry Smith 
345017667f90SBarry Smith EXTERN_C_BEGIN
34514a2ae208SSatish Balay #undef __FUNCT__
34524a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
34537087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3454273d9f13SBarry Smith {
3455273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3456dfbe8321SBarry Smith   PetscErrorCode ierr;
345738baddfdSBarry Smith   PetscMPIInt    size;
3458273d9f13SBarry Smith 
3459273d9f13SBarry Smith   PetscFunctionBegin;
34607adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3461e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3462273d9f13SBarry Smith 
346338f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3464b0a32e0cSBarry Smith   B->data             = (void*)b;
3465549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3466416022c9SBarry Smith   b->row              = 0;
3467416022c9SBarry Smith   b->col              = 0;
346882bf6240SBarry Smith   b->icol             = 0;
3469b810aeb4SBarry Smith   b->reallocs         = 0;
347036db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3471f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3472416022c9SBarry Smith   b->nonew             = 0;
3473416022c9SBarry Smith   b->diag              = 0;
3474416022c9SBarry Smith   b->solve_work        = 0;
34752a1b7f2aSHong Zhang   B->spptr             = 0;
3476be6bf707SBarry Smith   b->saved_values      = 0;
3477d7f994e1SBarry Smith   b->idiag             = 0;
347871f1c65dSBarry Smith   b->mdiag             = 0;
347971f1c65dSBarry Smith   b->ssor_work         = 0;
348071f1c65dSBarry Smith   b->omega             = 1.0;
348171f1c65dSBarry Smith   b->fshift            = 0.0;
348271f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3483a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3484a30b2313SHong Zhang   b->xtoy              = 0;
3485a30b2313SHong Zhang   b->XtoY              = 0;
348688e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
348717ab2063SBarry Smith 
348835d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3489b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3490700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3491b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3492b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3493b3866ffcSBarry Smith #endif
3494b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3495700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3496b5e56a35SBarry Smith #endif
3497*ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3498700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3499719d5645SBarry Smith #endif
3500611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3501700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3502611f576cSBarry Smith #endif
3503f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3504700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3505f3c0ef26SHong Zhang #endif
3506611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3507700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3508611f576cSBarry Smith #endif
3509611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3510700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3511611f576cSBarry Smith #endif
3512eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3513700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3514eb3b5408SSatish Balay #endif
3515586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3516700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3517586621ddSJed Brown #endif
3518719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3519700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3520719d5645SBarry Smith #endif
3521700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3522700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3523700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3524700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3525700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3526700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3527700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3528700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3529700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3530700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3531700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3532700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3533700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3534700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3535700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3536700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3537700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3538700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
35394108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
354017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
35413a40ed3dSBarry Smith   PetscFunctionReturn(0);
354217ab2063SBarry Smith }
3543273d9f13SBarry Smith EXTERN_C_END
354417ab2063SBarry Smith 
35454a2ae208SSatish Balay #undef __FUNCT__
3546b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3547b24902e0SBarry Smith /*
3548b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3549b24902e0SBarry Smith */
3550ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
355117ab2063SBarry Smith {
3552416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
35536849ba73SBarry Smith   PetscErrorCode ierr;
3554d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
355517ab2063SBarry Smith 
35563a40ed3dSBarry Smith   PetscFunctionBegin;
3557273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3558273d9f13SBarry Smith 
3559d5f3da31SBarry Smith   C->factortype     = A->factortype;
3560416022c9SBarry Smith   c->row            = 0;
3561416022c9SBarry Smith   c->col            = 0;
356282bf6240SBarry Smith   c->icol           = 0;
35636ad4291fSHong Zhang   c->reallocs       = 0;
356417ab2063SBarry Smith 
35656ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
356617ab2063SBarry Smith 
356726283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->rmap,1);CHKERRQ(ierr);
356826283091SBarry Smith   ierr = PetscLayoutSetBlockSize(C->cmap,1);CHKERRQ(ierr);
356926283091SBarry Smith   ierr = PetscLayoutSetUp(C->rmap);CHKERRQ(ierr);
357026283091SBarry Smith   ierr = PetscLayoutSetUp(C->cmap);CHKERRQ(ierr);
3571eec197d1SBarry Smith 
357233b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
35739518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
357417ab2063SBarry Smith   for (i=0; i<m; i++) {
3575416022c9SBarry Smith     c->imax[i] = a->imax[i];
3576416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
357717ab2063SBarry Smith   }
357817ab2063SBarry Smith 
357917ab2063SBarry Smith   /* allocate the matrix space */
3580f77e22a1SHong Zhang   if (mallocmatspace){
3581a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
35829518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3583f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
358497f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
358517ab2063SBarry Smith     if (m > 0) {
358697f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3587be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3588bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3589be6bf707SBarry Smith       } else {
3590bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
359117ab2063SBarry Smith       }
359208480c60SBarry Smith     }
3593f77e22a1SHong Zhang   }
359417ab2063SBarry Smith 
35956ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3596416022c9SBarry Smith   c->roworiented       = a->roworiented;
3597416022c9SBarry Smith   c->nonew             = a->nonew;
3598416022c9SBarry Smith   if (a->diag) {
359997f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
360052e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
360117ab2063SBarry Smith     for (i=0; i<m; i++) {
3602416022c9SBarry Smith       c->diag[i] = a->diag[i];
360317ab2063SBarry Smith     }
36043a40ed3dSBarry Smith   } else c->diag           = 0;
36056ad4291fSHong Zhang   c->solve_work            = 0;
36066ad4291fSHong Zhang   c->saved_values          = 0;
36076ad4291fSHong Zhang   c->idiag                 = 0;
360871f1c65dSBarry Smith   c->ssor_work             = 0;
3609a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3610e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3611e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
36126ad4291fSHong Zhang   c->xtoy                  = 0;
36136ad4291fSHong Zhang   c->XtoY                  = 0;
36146ad4291fSHong Zhang 
3615416022c9SBarry Smith   c->nz                 = a->nz;
36168ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3617273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3618754ec7b1SSatish Balay 
36196ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
36206ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3621cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3622cd6b891eSBarry Smith   if (a->compressedrow.use){
36236ad4291fSHong Zhang     i = a->compressedrow.nrows;
36240e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
36256ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
36266ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
362727ea64f8SHong Zhang   } else {
362827ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
362927ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
363027ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
36316ad4291fSHong Zhang   }
363288e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
36334108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
36344846f1f5SKris Buschelman 
36357adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
36363a40ed3dSBarry Smith   PetscFunctionReturn(0);
363717ab2063SBarry Smith }
363817ab2063SBarry Smith 
36394a2ae208SSatish Balay #undef __FUNCT__
3640b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3641b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3642b24902e0SBarry Smith {
3643b24902e0SBarry Smith   PetscErrorCode ierr;
3644b24902e0SBarry Smith 
3645b24902e0SBarry Smith   PetscFunctionBegin;
3646b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
36474b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3648b24902e0SBarry Smith   ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr);
3649f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3650b24902e0SBarry Smith   PetscFunctionReturn(0);
3651b24902e0SBarry Smith }
3652b24902e0SBarry Smith 
3653b24902e0SBarry Smith #undef __FUNCT__
36544a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3655112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3656fbdbba38SShri Abhyankar {
3657fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3658fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3659fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3660fbdbba38SShri Abhyankar   int            fd;
3661fbdbba38SShri Abhyankar   PetscMPIInt    size;
3662fbdbba38SShri Abhyankar   MPI_Comm       comm;
3663fbdbba38SShri Abhyankar 
3664fbdbba38SShri Abhyankar   PetscFunctionBegin;
3665fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3666fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3667fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3668fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3669fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3670fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3671fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3672fbdbba38SShri Abhyankar 
3673fbdbba38SShri Abhyankar   if (nz < 0) {
3674fbdbba38SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3675fbdbba38SShri Abhyankar   }
3676fbdbba38SShri Abhyankar 
3677fbdbba38SShri Abhyankar   /* read in row lengths */
3678fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3679fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3680fbdbba38SShri Abhyankar 
3681fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3682fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3683fbdbba38SShri 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);
3684fbdbba38SShri Abhyankar 
3685fbdbba38SShri Abhyankar   /* set global size if not set already*/
3686f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3687fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3688aabbc4fbSShri Abhyankar   } else {
3689fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3690fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
3691f501eaabSShri 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);
3692aabbc4fbSShri Abhyankar   }
3693fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3694fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3695fbdbba38SShri Abhyankar 
3696fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3697fbdbba38SShri Abhyankar 
3698fbdbba38SShri Abhyankar   /* read in nonzero values */
3699fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3700fbdbba38SShri Abhyankar 
3701fbdbba38SShri Abhyankar   /* set matrix "i" values */
3702fbdbba38SShri Abhyankar   a->i[0] = 0;
3703fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3704fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3705fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3706fbdbba38SShri Abhyankar   }
3707fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3708fbdbba38SShri Abhyankar 
3709fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3710fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3711fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3712fbdbba38SShri Abhyankar }
3713fbdbba38SShri Abhyankar 
3714fbdbba38SShri Abhyankar #undef __FUNCT__
3715b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3716ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
37177264ac53SSatish Balay {
37187264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3719dfbe8321SBarry Smith   PetscErrorCode ierr;
3720eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3721eeffb40dSHong Zhang   PetscInt k;
3722eeffb40dSHong Zhang #endif
37237264ac53SSatish Balay 
37243a40ed3dSBarry Smith   PetscFunctionBegin;
3725bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3726d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
3727ca44d042SBarry Smith     *flg = PETSC_FALSE;
3728ca44d042SBarry Smith     PetscFunctionReturn(0);
3729bcd2baecSBarry Smith   }
37307264ac53SSatish Balay 
37317264ac53SSatish Balay   /* if the a->i are the same */
3732d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3733abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
37347264ac53SSatish Balay 
37357264ac53SSatish Balay   /* if a->j are the same */
373697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3737abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3738bcd2baecSBarry Smith 
3739bcd2baecSBarry Smith   /* if a->a are the same */
3740eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3741eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
3742eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
3743eeffb40dSHong Zhang       *flg = PETSC_FALSE;
37443a40ed3dSBarry Smith       PetscFunctionReturn(0);
3745eeffb40dSHong Zhang     }
3746eeffb40dSHong Zhang   }
3747eeffb40dSHong Zhang #else
3748eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
3749eeffb40dSHong Zhang #endif
3750eeffb40dSHong Zhang   PetscFunctionReturn(0);
37517264ac53SSatish Balay }
375236db0b34SBarry Smith 
37534a2ae208SSatish Balay #undef __FUNCT__
37544a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
375505869f15SSatish Balay /*@
375636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
375736db0b34SBarry Smith               provided by the user.
375836db0b34SBarry Smith 
3759c75a6043SHong Zhang       Collective on MPI_Comm
376036db0b34SBarry Smith 
376136db0b34SBarry Smith    Input Parameters:
376236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
376336db0b34SBarry Smith .   m - number of rows
376436db0b34SBarry Smith .   n - number of columns
376536db0b34SBarry Smith .   i - row indices
376636db0b34SBarry Smith .   j - column indices
376736db0b34SBarry Smith -   a - matrix values
376836db0b34SBarry Smith 
376936db0b34SBarry Smith    Output Parameter:
377036db0b34SBarry Smith .   mat - the matrix
377136db0b34SBarry Smith 
377236db0b34SBarry Smith    Level: intermediate
377336db0b34SBarry Smith 
377436db0b34SBarry Smith    Notes:
37750551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
3776292fb18eSBarry Smith     once the matrix is destroyed and not before
377736db0b34SBarry Smith 
377836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
377936db0b34SBarry Smith 
3780bfeeae90SHong Zhang        The i and j indices are 0 based
378136db0b34SBarry Smith 
3782a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
3783a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
3784a4552177SSatish Balay     as shown:
3785a4552177SSatish Balay 
3786a4552177SSatish Balay         1 0 0
3787a4552177SSatish Balay         2 0 3
3788a4552177SSatish Balay         4 5 6
3789a4552177SSatish Balay 
3790a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
37919985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
3792a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
3793a4552177SSatish Balay 
37949985e31cSBarry Smith 
37952fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
379636db0b34SBarry Smith 
379736db0b34SBarry Smith @*/
37987087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
379936db0b34SBarry Smith {
3800dfbe8321SBarry Smith   PetscErrorCode ierr;
3801cbcfb4deSHong Zhang   PetscInt       ii;
380236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
3803cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
3804cbcfb4deSHong Zhang   PetscInt       jj;
3805cbcfb4deSHong Zhang #endif
380636db0b34SBarry Smith 
380736db0b34SBarry Smith   PetscFunctionBegin;
3808a96a251dSBarry Smith   if (i[0]) {
3809e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
381036db0b34SBarry Smith   }
3811f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3812f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
3813ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
3814ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
3815ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
3816ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
3817ab93d7beSBarry Smith 
381836db0b34SBarry Smith   aij->i = i;
381936db0b34SBarry Smith   aij->j = j;
382036db0b34SBarry Smith   aij->a = a;
382136db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
382236db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
3823e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
3824e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
382536db0b34SBarry Smith 
382636db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
382736db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
38282515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
3829e32f2f54SBarry 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]);
38309985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
3831e32f2f54SBarry 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);
3832e32f2f54SBarry 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);
38339985e31cSBarry Smith     }
383436db0b34SBarry Smith #endif
383536db0b34SBarry Smith   }
38362515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
383736db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
3838e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
3839e32f2f54SBarry 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]);
384036db0b34SBarry Smith   }
384136db0b34SBarry Smith #endif
384236db0b34SBarry Smith 
3843b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3844b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
384536db0b34SBarry Smith   PetscFunctionReturn(0);
384636db0b34SBarry Smith }
384736db0b34SBarry Smith 
3848cc8ba8e1SBarry Smith #undef __FUNCT__
3849ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
3850dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
3851cc8ba8e1SBarry Smith {
3852dfbe8321SBarry Smith   PetscErrorCode ierr;
3853cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
385436db0b34SBarry Smith 
3855cc8ba8e1SBarry Smith   PetscFunctionBegin;
38568ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
3857cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
3858cc8ba8e1SBarry Smith     a->coloring = coloring;
385912c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
386097f1f81fSBarry Smith     PetscInt             i,*larray;
386112c595b3SBarry Smith     ISColoring      ocoloring;
386208b6dcc0SBarry Smith     ISColoringValue *colors;
386312c595b3SBarry Smith 
386412c595b3SBarry Smith     /* set coloring for diagonal portion */
38650e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
3866d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
386712c595b3SBarry Smith       larray[i] = i;
386812c595b3SBarry Smith     }
3869784ac674SJed Brown     ierr = ISGlobalToLocalMappingApply(A->cmapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
38700e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
3871d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
387212c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
387312c595b3SBarry Smith     }
387412c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
3875d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
387612c595b3SBarry Smith     a->coloring = ocoloring;
387712c595b3SBarry Smith   }
3878cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3879cc8ba8e1SBarry Smith }
3880cc8ba8e1SBarry Smith 
3881dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3882ee4f033dSBarry Smith EXTERN_C_BEGIN
3883c6db04a5SJed Brown #include <adic/ad_utils.h>
3884ee4f033dSBarry Smith EXTERN_C_END
3885cc8ba8e1SBarry Smith 
3886cc8ba8e1SBarry Smith #undef __FUNCT__
3887ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3888dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3889cc8ba8e1SBarry Smith {
3890cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3891d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
38924440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
389308b6dcc0SBarry Smith   ISColoringValue *color;
3894cc8ba8e1SBarry Smith 
3895cc8ba8e1SBarry Smith   PetscFunctionBegin;
3896e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
38974440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
3898cc8ba8e1SBarry Smith   color = a->coloring->colors;
3899cc8ba8e1SBarry Smith   /* loop over rows */
3900cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3901cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3902cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
3903cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3904cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3905cc8ba8e1SBarry Smith     }
39064440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
3907ee4f033dSBarry Smith   }
3908ee4f033dSBarry Smith   PetscFunctionReturn(0);
3909ee4f033dSBarry Smith }
3910ee4f033dSBarry Smith #endif
3911ee4f033dSBarry Smith 
3912ee4f033dSBarry Smith #undef __FUNCT__
3913ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
391497f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
3915ee4f033dSBarry Smith {
3916ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3917d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
391854f21887SBarry Smith   MatScalar       *v = a->a;
391954f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
392008b6dcc0SBarry Smith   ISColoringValue *color;
3921ee4f033dSBarry Smith 
3922ee4f033dSBarry Smith   PetscFunctionBegin;
3923e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
3924ee4f033dSBarry Smith   color = a->coloring->colors;
3925ee4f033dSBarry Smith   /* loop over rows */
3926ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3927ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3928ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3929ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3930ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3931ee4f033dSBarry Smith     }
3932ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3933cc8ba8e1SBarry Smith   }
3934cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3935cc8ba8e1SBarry Smith }
393636db0b34SBarry Smith 
393781824310SBarry Smith /*
393881824310SBarry Smith     Special version for direct calls from Fortran
393981824310SBarry Smith */
3940c6db04a5SJed Brown #include <private/fortranimpl.h>
394181824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
394281824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
394381824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
394481824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
394581824310SBarry Smith #endif
394681824310SBarry Smith 
394781824310SBarry Smith /* Change these macros so can be used in void function */
394881824310SBarry Smith #undef CHKERRQ
39497adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
395081824310SBarry Smith #undef SETERRQ2
3951e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
395281824310SBarry Smith 
395381824310SBarry Smith EXTERN_C_BEGIN
395481824310SBarry Smith #undef __FUNCT__
395581824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
39561f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
395781824310SBarry Smith {
395881824310SBarry Smith   Mat            A = *AA;
395981824310SBarry Smith   PetscInt       m = *mm, n = *nn;
396081824310SBarry Smith   InsertMode     is = *isis;
396181824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
396281824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
396381824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
396481824310SBarry Smith   PetscErrorCode ierr;
396581824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
396654f21887SBarry Smith   MatScalar      *ap,value,*aa;
3967ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
3968ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
396981824310SBarry Smith 
397081824310SBarry Smith   PetscFunctionBegin;
3971d9e2c085SLisandro Dalcin   ierr = MatPreallocated(A);CHKERRQ(ierr);
397281824310SBarry Smith   imax = a->imax;
397381824310SBarry Smith   ai = a->i;
397481824310SBarry Smith   ailen = a->ilen;
397581824310SBarry Smith   aj = a->j;
397681824310SBarry Smith   aa = a->a;
397781824310SBarry Smith 
397881824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
397981824310SBarry Smith     row  = im[k];
398081824310SBarry Smith     if (row < 0) continue;
398181824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3982d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
398381824310SBarry Smith #endif
398481824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
398581824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
398681824310SBarry Smith     low  = 0;
398781824310SBarry Smith     high = nrow;
398881824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
398981824310SBarry Smith       if (in[l] < 0) continue;
399081824310SBarry Smith #if defined(PETSC_USE_DEBUG)
3991d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
399281824310SBarry Smith #endif
399381824310SBarry Smith       col = in[l];
399481824310SBarry Smith       if (roworiented) {
399581824310SBarry Smith         value = v[l + k*n];
399681824310SBarry Smith       } else {
399781824310SBarry Smith         value = v[k + l*m];
399881824310SBarry Smith       }
399981824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
400081824310SBarry Smith 
400181824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
400281824310SBarry Smith       lastcol = col;
400381824310SBarry Smith       while (high-low > 5) {
400481824310SBarry Smith         t = (low+high)/2;
400581824310SBarry Smith         if (rp[t] > col) high = t;
400681824310SBarry Smith         else             low  = t;
400781824310SBarry Smith       }
400881824310SBarry Smith       for (i=low; i<high; i++) {
400981824310SBarry Smith         if (rp[i] > col) break;
401081824310SBarry Smith         if (rp[i] == col) {
401181824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
401281824310SBarry Smith           else                  ap[i] = value;
401381824310SBarry Smith           goto noinsert;
401481824310SBarry Smith         }
401581824310SBarry Smith       }
401681824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
401781824310SBarry Smith       if (nonew == 1) goto noinsert;
40187adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4019fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
402081824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
402181824310SBarry Smith       /* shift up all the later entries in this row */
402281824310SBarry Smith       for (ii=N; ii>=i; ii--) {
402381824310SBarry Smith         rp[ii+1] = rp[ii];
402481824310SBarry Smith         ap[ii+1] = ap[ii];
402581824310SBarry Smith       }
402681824310SBarry Smith       rp[i] = col;
402781824310SBarry Smith       ap[i] = value;
402881824310SBarry Smith       noinsert:;
402981824310SBarry Smith       low = i + 1;
403081824310SBarry Smith     }
403181824310SBarry Smith     ailen[row] = nrow;
403281824310SBarry Smith   }
403381824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
403481824310SBarry Smith   PetscFunctionReturnVoid();
403581824310SBarry Smith }
403681824310SBarry Smith EXTERN_C_END
403762298a1eSBarry Smith 
4038