xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 1814747fb326b169892d9cf81384a03be6494bc6)
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>
11d441b888SJed Brown #include <../src/mat/blocktranspose.h>
120716a85fSBarry Smith 
130716a85fSBarry Smith #undef __FUNCT__
140716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
150716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
160716a85fSBarry Smith {
170716a85fSBarry Smith   PetscErrorCode ierr;
180716a85fSBarry Smith   PetscInt       i,m,n;
190716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
200716a85fSBarry Smith 
210716a85fSBarry Smith   PetscFunctionBegin;
220716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
230716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
240716a85fSBarry Smith   if (type == NORM_2) {
250716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
260716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
270716a85fSBarry Smith     }
280716a85fSBarry Smith   } else if (type == NORM_1) {
290716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
300716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
310716a85fSBarry Smith     }
320716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
330716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
340716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
350716a85fSBarry Smith     }
360716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
370716a85fSBarry Smith 
380716a85fSBarry Smith   if (type == NORM_2) {
398f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
400716a85fSBarry Smith   }
410716a85fSBarry Smith   PetscFunctionReturn(0);
420716a85fSBarry Smith }
430716a85fSBarry Smith 
444a2ae208SSatish Balay #undef __FUNCT__
45f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
46f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
476ce1633cSBarry Smith {
486ce1633cSBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
496ce1633cSBarry Smith   const MatScalar   *aa = a->a;
506ce1633cSBarry Smith   PetscInt          i,m=A->rmap->n,cnt = 0;
516ce1633cSBarry Smith   const PetscInt    *jj = a->j,*diag;
526ce1633cSBarry Smith   PetscInt          *rows;
536ce1633cSBarry Smith   PetscErrorCode    ierr;
546ce1633cSBarry Smith 
556ce1633cSBarry Smith   PetscFunctionBegin;
566ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
576ce1633cSBarry Smith   diag = a->diag;
586ce1633cSBarry Smith   for (i=0; i<m; i++) {
596ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
606ce1633cSBarry Smith       cnt++;
616ce1633cSBarry Smith     }
626ce1633cSBarry Smith   }
636ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr);
646ce1633cSBarry Smith   cnt  = 0;
656ce1633cSBarry Smith   for (i=0; i<m; i++) {
666ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
676ce1633cSBarry Smith       rows[cnt++] = i;
686ce1633cSBarry Smith     }
696ce1633cSBarry Smith   }
70f1f41ecbSJed Brown   *nrows = cnt;
71f1f41ecbSJed Brown   *zrows = rows;
72f1f41ecbSJed Brown   PetscFunctionReturn(0);
73f1f41ecbSJed Brown }
74f1f41ecbSJed Brown 
75f1f41ecbSJed Brown #undef __FUNCT__
76f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
77f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
78f1f41ecbSJed Brown {
79f1f41ecbSJed Brown   PetscInt       nrows,*rows;
80f1f41ecbSJed Brown   PetscErrorCode ierr;
81f1f41ecbSJed Brown 
82f1f41ecbSJed Brown   PetscFunctionBegin;
83f1f41ecbSJed Brown   *zrows = PETSC_NULL;
84f1f41ecbSJed Brown   ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
85f1f41ecbSJed Brown   ierr = ISCreateGeneral(((PetscObject)A)->comm,nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
866ce1633cSBarry Smith   PetscFunctionReturn(0);
876ce1633cSBarry Smith }
886ce1633cSBarry Smith 
896ce1633cSBarry Smith #undef __FUNCT__
90b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
91b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
92b3a44c85SBarry Smith {
93b3a44c85SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
94b3a44c85SBarry Smith   const MatScalar   *aa;
95b3a44c85SBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
96b3a44c85SBarry Smith   const PetscInt    *ii;
97b3a44c85SBarry Smith   PetscInt          n,i,j,*rows;
98b3a44c85SBarry Smith   PetscErrorCode    ierr;
99b3a44c85SBarry Smith 
100b3a44c85SBarry Smith   PetscFunctionBegin;
101b3a44c85SBarry Smith   *keptrows = 0;
102b3a44c85SBarry Smith   ii        = a->i;
103b3a44c85SBarry Smith   for (i=0; i<m; i++) {
104b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
105b3a44c85SBarry Smith     if (!n) {
106b3a44c85SBarry Smith       cnt++;
107b3a44c85SBarry Smith       goto ok1;
108b3a44c85SBarry Smith     }
109b3a44c85SBarry Smith     aa  = a->a + ii[i];
110b3a44c85SBarry Smith     for (j=0; j<n; j++) {
111b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
112b3a44c85SBarry Smith     }
113b3a44c85SBarry Smith     cnt++;
114b3a44c85SBarry Smith     ok1:;
115b3a44c85SBarry Smith   }
116b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
117b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
118b3a44c85SBarry Smith   cnt  = 0;
119b3a44c85SBarry Smith   for (i=0; i<m; i++) {
120b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
121b3a44c85SBarry Smith     if (!n) continue;
122b3a44c85SBarry Smith     aa  = a->a + ii[i];
123b3a44c85SBarry Smith     for (j=0; j<n; j++) {
124b3a44c85SBarry Smith       if (aa[j] != 0.0) {
125b3a44c85SBarry Smith         rows[cnt++] = i;
126b3a44c85SBarry Smith         break;
127b3a44c85SBarry Smith       }
128b3a44c85SBarry Smith     }
129b3a44c85SBarry Smith   }
130b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
131b3a44c85SBarry Smith   PetscFunctionReturn(0);
132b3a44c85SBarry Smith }
133b3a44c85SBarry Smith 
134b3a44c85SBarry Smith #undef __FUNCT__
13579299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1367087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
13779299369SBarry Smith {
13879299369SBarry Smith   PetscErrorCode ierr;
13979299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
140d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
14154f21887SBarry Smith   MatScalar      *aa = aij->a;
14254f21887SBarry Smith   PetscScalar    *v;
143ace3abfcSBarry Smith   PetscBool      missing;
14479299369SBarry Smith 
14579299369SBarry Smith   PetscFunctionBegin;
14609f38230SBarry Smith   if (Y->assembled) {
14709f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
14809f38230SBarry Smith     if (!missing) {
14979299369SBarry Smith       diag = aij->diag;
15079299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
15179299369SBarry Smith       if (is == INSERT_VALUES) {
15279299369SBarry Smith 	for (i=0; i<m; i++) {
15379299369SBarry Smith 	  aa[diag[i]] = v[i];
15479299369SBarry Smith 	}
15579299369SBarry Smith       } else {
15679299369SBarry Smith 	for (i=0; i<m; i++) {
15779299369SBarry Smith 	  aa[diag[i]] += v[i];
15879299369SBarry Smith 	}
15979299369SBarry Smith       }
16079299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
16179299369SBarry Smith       PetscFunctionReturn(0);
16279299369SBarry Smith     }
1630847f33cSJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
16409f38230SBarry Smith   }
16509f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
16609f38230SBarry Smith   PetscFunctionReturn(0);
16709f38230SBarry Smith }
16879299369SBarry Smith 
16979299369SBarry Smith #undef __FUNCT__
1704a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
171ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
17217ab2063SBarry Smith {
173416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
174dfbe8321SBarry Smith   PetscErrorCode ierr;
17597f1f81fSBarry Smith   PetscInt       i,ishift;
17617ab2063SBarry Smith 
1773a40ed3dSBarry Smith   PetscFunctionBegin;
178d0f46423SBarry Smith   *m     = A->rmap->n;
1793a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
180bfeeae90SHong Zhang   ishift = 0;
18153e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
182d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
183bfeeae90SHong Zhang   } else if (oshift == 1) {
184d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1853b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
186d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
187d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
188ecc77c7aSBarry Smith     if (ja) {
18997f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
1903b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
191ecc77c7aSBarry Smith     }
1926945ee14SBarry Smith   } else {
193ecc77c7aSBarry Smith     *ia = a->i;
194ecc77c7aSBarry Smith     if (ja) *ja = a->j;
195a2ce50c7SBarry Smith   }
1963a40ed3dSBarry Smith   PetscFunctionReturn(0);
197a2744918SBarry Smith }
198a2744918SBarry Smith 
1994a2ae208SSatish Balay #undef __FUNCT__
2004a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
201ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2026945ee14SBarry Smith {
203dfbe8321SBarry Smith   PetscErrorCode ierr;
2046945ee14SBarry Smith 
2053a40ed3dSBarry Smith   PetscFunctionBegin;
2063a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
207bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
208606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
209ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
210bcd2baecSBarry Smith   }
2113a40ed3dSBarry Smith   PetscFunctionReturn(0);
21217ab2063SBarry Smith }
21317ab2063SBarry Smith 
2144a2ae208SSatish Balay #undef __FUNCT__
2154a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
216ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2173b2fbd54SBarry Smith {
2183b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
219dfbe8321SBarry Smith   PetscErrorCode ierr;
220d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
22197f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2223b2fbd54SBarry Smith 
2233a40ed3dSBarry Smith   PetscFunctionBegin;
224899cda47SBarry Smith   *nn = n;
2253a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2263b2fbd54SBarry Smith   if (symmetric) {
227d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2283b2fbd54SBarry Smith   } else {
22997f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
23097f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
23197f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
23297f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
2333b2fbd54SBarry Smith     jj = a->j;
2343b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
235bfeeae90SHong Zhang       collengths[jj[i]]++;
2363b2fbd54SBarry Smith     }
2373b2fbd54SBarry Smith     cia[0] = oshift;
2383b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2393b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2403b2fbd54SBarry Smith     }
24197f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2423b2fbd54SBarry Smith     jj   = a->j;
243a93ec695SBarry Smith     for (row=0; row<m; row++) {
244a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
245a93ec695SBarry Smith       for (i=0; i<mr; i++) {
246bfeeae90SHong Zhang         col = *jj++;
2473b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2483b2fbd54SBarry Smith       }
2493b2fbd54SBarry Smith     }
250606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2513b2fbd54SBarry Smith     *ia = cia; *ja = cja;
2523b2fbd54SBarry Smith   }
2533a40ed3dSBarry Smith   PetscFunctionReturn(0);
2543b2fbd54SBarry Smith }
2553b2fbd54SBarry Smith 
2564a2ae208SSatish Balay #undef __FUNCT__
2574a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
258ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2593b2fbd54SBarry Smith {
260dfbe8321SBarry Smith   PetscErrorCode ierr;
261606d414cSSatish Balay 
2623a40ed3dSBarry Smith   PetscFunctionBegin;
2633a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2643b2fbd54SBarry Smith 
265606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
266606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2673b2fbd54SBarry Smith 
2683a40ed3dSBarry Smith   PetscFunctionReturn(0);
2693b2fbd54SBarry Smith }
2703b2fbd54SBarry Smith 
27187d4246cSBarry Smith #undef __FUNCT__
27287d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
27387d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
27487d4246cSBarry Smith {
27587d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
27687d4246cSBarry Smith   PetscInt       *ai = a->i;
27787d4246cSBarry Smith   PetscErrorCode ierr;
27887d4246cSBarry Smith 
27987d4246cSBarry Smith   PetscFunctionBegin;
28087d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
28187d4246cSBarry Smith   PetscFunctionReturn(0);
28287d4246cSBarry Smith }
28387d4246cSBarry Smith 
2844a2ae208SSatish Balay #undef __FUNCT__
2854a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
28697f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
28717ab2063SBarry Smith {
288416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
289e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
29097f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
2916849ba73SBarry Smith   PetscErrorCode ierr;
292e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
29354f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
294ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
295ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
29617ab2063SBarry Smith 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
29871fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
29917ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
300416022c9SBarry Smith     row  = im[k];
3015ef9f2a5SBarry Smith     if (row < 0) continue;
3022515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
303e32f2f54SBarry 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);
3043b2fbd54SBarry Smith #endif
305bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
30617ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
307416022c9SBarry Smith     low  = 0;
308c71e6ed7SBarry Smith     high = nrow;
30917ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3105ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3112515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
312e32f2f54SBarry 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);
3133b2fbd54SBarry Smith #endif
314bfeeae90SHong Zhang       col = in[l];
31516371a99SBarry Smith       if (v) {
3164b0e389bSBarry Smith 	if (roworiented) {
3175ef9f2a5SBarry Smith 	  value = v[l + k*n];
318bef8e0ddSBarry Smith 	} else {
3194b0e389bSBarry Smith 	  value = v[k + l*m];
3204b0e389bSBarry Smith 	}
32116371a99SBarry Smith       } else {
32275567043SBarry Smith         value = 0.;
32316371a99SBarry Smith       }
324abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
32536db0b34SBarry Smith 
3267cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
327e2ee6c50SBarry Smith       lastcol = col;
328416022c9SBarry Smith       while (high-low > 5) {
329416022c9SBarry Smith         t = (low+high)/2;
330416022c9SBarry Smith         if (rp[t] > col) high = t;
331416022c9SBarry Smith         else             low  = t;
33217ab2063SBarry Smith       }
333416022c9SBarry Smith       for (i=low; i<high; i++) {
33417ab2063SBarry Smith         if (rp[i] > col) break;
33517ab2063SBarry Smith         if (rp[i] == col) {
336416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
33717ab2063SBarry Smith           else                  ap[i] = value;
338e44c0bd4SBarry Smith           low = i + 1;
33917ab2063SBarry Smith           goto noinsert;
34017ab2063SBarry Smith         }
34117ab2063SBarry Smith       }
342abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
343c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
344e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
345fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
346c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
347416022c9SBarry Smith       /* shift up all the later entries in this row */
348416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
34917ab2063SBarry Smith         rp[ii+1] = rp[ii];
35017ab2063SBarry Smith         ap[ii+1] = ap[ii];
35117ab2063SBarry Smith       }
35217ab2063SBarry Smith       rp[i] = col;
35317ab2063SBarry Smith       ap[i] = value;
354416022c9SBarry Smith       low   = i + 1;
355e44c0bd4SBarry Smith       noinsert:;
35617ab2063SBarry Smith     }
35717ab2063SBarry Smith     ailen[row] = nrow;
35817ab2063SBarry Smith   }
35988e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
3603a40ed3dSBarry Smith   PetscFunctionReturn(0);
36117ab2063SBarry Smith }
36217ab2063SBarry Smith 
36381824310SBarry Smith 
3644a2ae208SSatish Balay #undef __FUNCT__
3654a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
366a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
3677eb43aa7SLois Curfman McInnes {
3687eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
36997f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
37097f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
37154f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
3727eb43aa7SLois Curfman McInnes 
3733a40ed3dSBarry Smith   PetscFunctionBegin;
3747eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
3757eb43aa7SLois Curfman McInnes     row  = im[k];
376e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
377e32f2f54SBarry 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);
378bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
3797eb43aa7SLois Curfman McInnes     nrow = ailen[row];
3807eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
381e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
382e32f2f54SBarry 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);
383bfeeae90SHong Zhang       col = in[l] ;
3847eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
3857eb43aa7SLois Curfman McInnes       while (high-low > 5) {
3867eb43aa7SLois Curfman McInnes         t = (low+high)/2;
3877eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
3887eb43aa7SLois Curfman McInnes         else             low  = t;
3897eb43aa7SLois Curfman McInnes       }
3907eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
3917eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
3927eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
393b49de8d1SLois Curfman McInnes           *v++ = ap[i];
3947eb43aa7SLois Curfman McInnes           goto finished;
3957eb43aa7SLois Curfman McInnes         }
3967eb43aa7SLois Curfman McInnes       }
39797e567efSBarry Smith       *v++ = 0.0;
3987eb43aa7SLois Curfman McInnes       finished:;
3997eb43aa7SLois Curfman McInnes     }
4007eb43aa7SLois Curfman McInnes   }
4013a40ed3dSBarry Smith   PetscFunctionReturn(0);
4027eb43aa7SLois Curfman McInnes }
4037eb43aa7SLois Curfman McInnes 
40417ab2063SBarry Smith 
4054a2ae208SSatish Balay #undef __FUNCT__
4064a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
407dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
40817ab2063SBarry Smith {
409416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4106849ba73SBarry Smith   PetscErrorCode ierr;
4116f69ff64SBarry Smith   PetscInt       i,*col_lens;
4126f69ff64SBarry Smith   int            fd;
41317ab2063SBarry Smith 
4143a40ed3dSBarry Smith   PetscFunctionBegin;
415b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
416d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4170700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
418d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
419d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
420416022c9SBarry Smith   col_lens[3] = a->nz;
421416022c9SBarry Smith 
422416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
423d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
424416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
42517ab2063SBarry Smith   }
426d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
427606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
428416022c9SBarry Smith 
429416022c9SBarry Smith   /* store column indices (zero start index) */
4306f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
431416022c9SBarry Smith 
432416022c9SBarry Smith   /* store nonzero values */
4336f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
4343a40ed3dSBarry Smith   PetscFunctionReturn(0);
43517ab2063SBarry Smith }
436416022c9SBarry Smith 
43709573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
438cd155464SBarry Smith 
4394a2ae208SSatish Balay #undef __FUNCT__
4404a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
441dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
442416022c9SBarry Smith {
443416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
444dfbe8321SBarry Smith   PetscErrorCode    ierr;
445d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
446e060cb09SBarry Smith   const char        *name;
447f3ef73ceSBarry Smith   PetscViewerFormat format;
44817ab2063SBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
450b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
45171c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
45297f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
453d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
454d00d2cf4SBarry Smith       nofinalvalue = 1;
455d00d2cf4SBarry Smith     }
456d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
457d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
45877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
45977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
460b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
46117ab2063SBarry Smith 
46217ab2063SBarry Smith     for (i=0; i<m; i++) {
463416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
464aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46577431f27SBarry 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);
46617ab2063SBarry Smith #else
46777431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
46817ab2063SBarry Smith #endif
46917ab2063SBarry Smith       }
47017ab2063SBarry Smith     }
471d00d2cf4SBarry Smith     if (nofinalvalue) {
472d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
473d00d2cf4SBarry Smith     }
474317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
475fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
476d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
47768369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
478cd155464SBarry Smith      PetscFunctionReturn(0);
479fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
480d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4817566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
48244cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
48377431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
48444cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
485aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
48636db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
487a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
48836db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
489a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
49036db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
491a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
4926831982aSBarry Smith         }
49344cd7ae7SLois Curfman McInnes #else
494a83599f4SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
49544cd7ae7SLois Curfman McInnes #endif
49644cd7ae7SLois Curfman McInnes       }
497b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
49844cd7ae7SLois Curfman McInnes     }
499d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
500fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
50197f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
502d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5037566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
50497f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
505496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
506496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
507496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
508496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
509aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
51036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
511496be53dSLois Curfman McInnes #else
512496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
513496be53dSLois Curfman McInnes #endif
514496be53dSLois Curfman McInnes         }
515496be53dSLois Curfman McInnes       }
516496be53dSLois Curfman McInnes     }
5172e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
51877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5192e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
52077431f27SBarry 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);}
52177431f27SBarry 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);}
52277431f27SBarry 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);}
52377431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
52477431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
52577431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
526496be53dSLois Curfman McInnes     }
527b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
528606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
529496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
530496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
53177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
532496be53dSLois Curfman McInnes       }
533b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
534496be53dSLois Curfman McInnes     }
535b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
536496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
537496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
538496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
539aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
54036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
541b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
5426831982aSBarry Smith           }
543496be53dSLois Curfman McInnes #else
544b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
545496be53dSLois Curfman McInnes #endif
546496be53dSLois Curfman McInnes         }
547496be53dSLois Curfman McInnes       }
548b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
549496be53dSLois Curfman McInnes     }
550d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
551fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
55297f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
55387828ca2SBarry Smith     PetscScalar value;
55402594712SBarry Smith 
555d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5567566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
55702594712SBarry Smith     for (i=0; i<m; i++) {
55802594712SBarry Smith       jcnt = 0;
559d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
560e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
56102594712SBarry Smith           value = a->a[cnt++];
562e24b481bSBarry Smith           jcnt++;
56302594712SBarry Smith         } else {
56402594712SBarry Smith           value = 0.0;
56502594712SBarry Smith         }
566aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
567b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
56802594712SBarry Smith #else
569b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
57002594712SBarry Smith #endif
57102594712SBarry Smith       }
572b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57302594712SBarry Smith     }
574d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5753c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
576d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5777566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
5783c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5793c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
5803c215bfdSMatthew Knepley #else
5813c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
5823c215bfdSMatthew Knepley #endif
583d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
5843c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
5853c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5863c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5873c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
5883c215bfdSMatthew 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);
5893c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
5903c215bfdSMatthew 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);
5913c215bfdSMatthew Knepley         } else {
5923c215bfdSMatthew Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5933c215bfdSMatthew Knepley         }
5943c215bfdSMatthew Knepley #else
5953c215bfdSMatthew Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr);
5963c215bfdSMatthew Knepley #endif
5973c215bfdSMatthew Knepley       }
5983c215bfdSMatthew Knepley     }
599d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6003a40ed3dSBarry Smith   } else {
601d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
6027566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
603d5f3da31SBarry Smith     if (A->factortype){
60416cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
60516cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
60616cd7e1dSShri Abhyankar         /* L part */
60716cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
60816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
60916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
61016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
61116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
61216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
61316cd7e1dSShri Abhyankar           } else {
61416cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
61516cd7e1dSShri Abhyankar           }
61616cd7e1dSShri Abhyankar #else
61716cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
61816cd7e1dSShri Abhyankar #endif
61916cd7e1dSShri Abhyankar         }
62016cd7e1dSShri Abhyankar 	/* diagonal */
62116cd7e1dSShri Abhyankar 	j = a->diag[i];
62216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
62316cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
6242c990fa1SHong Zhang             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
62516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
6262c990fa1SHong Zhang             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
62716cd7e1dSShri Abhyankar           } else {
6282c990fa1SHong Zhang             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
62916cd7e1dSShri Abhyankar           }
63016cd7e1dSShri Abhyankar #else
6312c990fa1SHong Zhang           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,1.0/a->a[j]);CHKERRQ(ierr);
63216cd7e1dSShri Abhyankar #endif
63316cd7e1dSShri Abhyankar 
63416cd7e1dSShri Abhyankar 	/* U part */
63516cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
63616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
63716cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
63816cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
63916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
64016cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64116cd7e1dSShri Abhyankar           } else {
64216cd7e1dSShri Abhyankar             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
64316cd7e1dSShri Abhyankar           }
64416cd7e1dSShri Abhyankar #else
64516cd7e1dSShri Abhyankar           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
64616cd7e1dSShri Abhyankar #endif
64716cd7e1dSShri Abhyankar }
64816cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
64916cd7e1dSShri Abhyankar         }
65016cd7e1dSShri Abhyankar     } else {
65117ab2063SBarry Smith       for (i=0; i<m; i++) {
65277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
653416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
654aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
65536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
656a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
65736db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
658a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6593a40ed3dSBarry Smith           } else {
660a83599f4SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
66117ab2063SBarry Smith           }
66217ab2063SBarry Smith #else
663a83599f4SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
66417ab2063SBarry Smith #endif
66517ab2063SBarry Smith         }
666b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
66717ab2063SBarry Smith       }
66816cd7e1dSShri Abhyankar     }
669d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
67017ab2063SBarry Smith   }
671b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6723a40ed3dSBarry Smith   PetscFunctionReturn(0);
673416022c9SBarry Smith }
674416022c9SBarry Smith 
6754a2ae208SSatish Balay #undef __FUNCT__
6764a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
677dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
678416022c9SBarry Smith {
679480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
680416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
681dfbe8321SBarry Smith   PetscErrorCode    ierr;
682d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
68336db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
684b0a32e0cSBarry Smith   PetscViewer       viewer;
685f3ef73ceSBarry Smith   PetscViewerFormat format;
686cddf8d76SBarry Smith 
6873a40ed3dSBarry Smith   PetscFunctionBegin;
688480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
689b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
69019bcc07fSBarry Smith 
691b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
692416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
6930513a670SBarry Smith 
694fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
6950513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
696b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
697416022c9SBarry Smith     for (i=0; i<m; i++) {
698cddf8d76SBarry 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;
701aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
703cddf8d76SBarry Smith #else
704cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
705cddf8d76SBarry Smith #endif
706b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
707cddf8d76SBarry Smith       }
708cddf8d76SBarry Smith     }
709b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
710cddf8d76SBarry Smith     for (i=0; i<m; i++) {
711cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
712bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
713bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
714cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
715b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
716cddf8d76SBarry Smith       }
717cddf8d76SBarry Smith     }
718b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
719cddf8d76SBarry Smith     for (i=0; i<m; i++) {
720cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
721bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
722bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
723aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
72436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
725cddf8d76SBarry Smith #else
726cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
727cddf8d76SBarry Smith #endif
728b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
729416022c9SBarry Smith       }
730416022c9SBarry Smith     }
7310513a670SBarry Smith   } else {
7320513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
7330513a670SBarry Smith     /* first determine max of all nonzero values */
73497f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
735b0a32e0cSBarry Smith     PetscDraw   popup;
73636db0b34SBarry Smith     PetscReal scale;
7370513a670SBarry Smith 
7380513a670SBarry Smith     for (i=0; i<nz; i++) {
7390513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
7400513a670SBarry Smith     }
741b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
742b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
743b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
7440513a670SBarry Smith     count = 0;
7450513a670SBarry Smith     for (i=0; i<m; i++) {
7460513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
747bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
748bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
74997f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
750b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
7510513a670SBarry Smith         count++;
7520513a670SBarry Smith       }
7530513a670SBarry Smith     }
7540513a670SBarry Smith   }
755480ef9eaSBarry Smith   PetscFunctionReturn(0);
756480ef9eaSBarry Smith }
757cddf8d76SBarry Smith 
7584a2ae208SSatish Balay #undef __FUNCT__
7594a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
760dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
761480ef9eaSBarry Smith {
762dfbe8321SBarry Smith   PetscErrorCode ierr;
763b0a32e0cSBarry Smith   PetscDraw      draw;
76436db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
765ace3abfcSBarry Smith   PetscBool      isnull;
766480ef9eaSBarry Smith 
767480ef9eaSBarry Smith   PetscFunctionBegin;
768b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
769b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
770480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
771480ef9eaSBarry Smith 
772480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
773d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
774480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
775b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
776b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
777480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7783a40ed3dSBarry Smith   PetscFunctionReturn(0);
779416022c9SBarry Smith }
780416022c9SBarry Smith 
7814a2ae208SSatish Balay #undef __FUNCT__
7824a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
783dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
784416022c9SBarry Smith {
785dfbe8321SBarry Smith   PetscErrorCode ierr;
786ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
787416022c9SBarry Smith 
7883a40ed3dSBarry Smith   PetscFunctionBegin;
789251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
790251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
791251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
792c45a1595SBarry Smith   if (iascii) {
7933a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7940f5bd95cSBarry Smith   } else if (isbinary) {
7953a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
7960f5bd95cSBarry Smith   } else if (isdraw) {
7973a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
798913ac41fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
7994108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8003a40ed3dSBarry Smith   PetscFunctionReturn(0);
80117ab2063SBarry Smith }
80219bcc07fSBarry Smith 
8034a2ae208SSatish Balay #undef __FUNCT__
8044a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
805dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
80617ab2063SBarry Smith {
807416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8086849ba73SBarry Smith   PetscErrorCode ierr;
80997f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
810d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
81154f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
8123447b6efSHong Zhang   PetscReal      ratio=0.6;
81317ab2063SBarry Smith 
8143a40ed3dSBarry Smith   PetscFunctionBegin;
8153a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
81617ab2063SBarry Smith 
81743ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
81817ab2063SBarry Smith   for (i=1; i<m; i++) {
819416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
82017ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
82194a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
82217ab2063SBarry Smith     if (fshift) {
823bfeeae90SHong Zhang       ip = aj + ai[i] ;
824bfeeae90SHong Zhang       ap = aa + ai[i] ;
82517ab2063SBarry Smith       N  = ailen[i];
82617ab2063SBarry Smith       for (j=0; j<N; j++) {
82717ab2063SBarry Smith         ip[j-fshift] = ip[j];
82817ab2063SBarry Smith         ap[j-fshift] = ap[j];
82917ab2063SBarry Smith       }
83017ab2063SBarry Smith     }
83117ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
83217ab2063SBarry Smith   }
83317ab2063SBarry Smith   if (m) {
83417ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
83517ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
83617ab2063SBarry Smith   }
83717ab2063SBarry Smith   /* reset ilen and imax for each row */
83817ab2063SBarry Smith   for (i=0; i<m; i++) {
83917ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
84017ab2063SBarry Smith   }
841bfeeae90SHong Zhang   a->nz = ai[m];
84265e19b50SBarry 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);
84317ab2063SBarry Smith 
84409f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
845d0f46423SBarry 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);
846ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
847ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
8488e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
849dd5f02e7SSatish Balay   a->reallocs          = 0;
8504e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
85136db0b34SBarry Smith   a->rmax              = rmax;
8524e220ebcSLois Curfman McInnes 
853cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
85488e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
85571c2f376SKris Buschelman 
8564108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
85771f1c65dSBarry Smith 
8580847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
8593a40ed3dSBarry Smith   PetscFunctionReturn(0);
86017ab2063SBarry Smith }
86117ab2063SBarry Smith 
8624a2ae208SSatish Balay #undef __FUNCT__
86399cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
86499cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
86599cafbc1SBarry Smith {
86699cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
86799cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
86854f21887SBarry Smith   MatScalar      *aa = a->a;
8690847f33cSJed Brown   PetscErrorCode ierr;
87099cafbc1SBarry Smith 
87199cafbc1SBarry Smith   PetscFunctionBegin;
87299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
8730847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
87499cafbc1SBarry Smith   PetscFunctionReturn(0);
87599cafbc1SBarry Smith }
87699cafbc1SBarry Smith 
87799cafbc1SBarry Smith #undef __FUNCT__
87899cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
87999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
88099cafbc1SBarry Smith {
88199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
88299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
88354f21887SBarry Smith   MatScalar      *aa = a->a;
8840847f33cSJed Brown   PetscErrorCode ierr;
88599cafbc1SBarry Smith 
88699cafbc1SBarry Smith   PetscFunctionBegin;
88799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
8880847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
88999cafbc1SBarry Smith   PetscFunctionReturn(0);
89099cafbc1SBarry Smith }
89199cafbc1SBarry Smith 
89299cafbc1SBarry Smith #undef __FUNCT__
8934a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
894dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
89517ab2063SBarry Smith {
896416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
897dfbe8321SBarry Smith   PetscErrorCode ierr;
8983a40ed3dSBarry Smith 
8993a40ed3dSBarry Smith   PetscFunctionBegin;
900d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
9010847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9023a40ed3dSBarry Smith   PetscFunctionReturn(0);
90317ab2063SBarry Smith }
904416022c9SBarry Smith 
9054a2ae208SSatish Balay #undef __FUNCT__
9064a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
907dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
90817ab2063SBarry Smith {
909416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
910dfbe8321SBarry Smith   PetscErrorCode ierr;
911d5d45c9bSBarry Smith 
9123a40ed3dSBarry Smith   PetscFunctionBegin;
913aa482453SBarry Smith #if defined(PETSC_USE_LOG)
914d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
91517ab2063SBarry Smith #endif
916e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
9176bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
9186bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
91905b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
920d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
92105b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
92271f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
92305b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
9246bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
92505b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
9266bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
92705b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
9286bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
929cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
9300b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
931a30b2313SHong Zhang 
9324108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
933bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
934901853e0SKris Buschelman 
935dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
936901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
937901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
938901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
939901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
940901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
9415a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
942901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
943901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
944a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
945901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
9463a40ed3dSBarry Smith   PetscFunctionReturn(0);
94717ab2063SBarry Smith }
94817ab2063SBarry Smith 
9494a2ae208SSatish Balay #undef __FUNCT__
9504a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
951ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
95217ab2063SBarry Smith {
953416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9544846f1f5SKris Buschelman   PetscErrorCode ierr;
9553a40ed3dSBarry Smith 
9563a40ed3dSBarry Smith   PetscFunctionBegin;
957a65d3064SKris Buschelman   switch (op) {
958a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
9594e0d8c25SBarry Smith       a->roworiented       = flg;
960a65d3064SKris Buschelman       break;
961a9817697SBarry Smith     case MAT_KEEP_NONZERO_PATTERN:
962a9817697SBarry Smith       a->keepnonzeropattern    = flg;
963a65d3064SKris Buschelman       break;
964512a5fc5SBarry Smith     case MAT_NEW_NONZERO_LOCATIONS:
965512a5fc5SBarry Smith       a->nonew             = (flg ? 0 : 1);
966a65d3064SKris Buschelman       break;
967a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
9684e0d8c25SBarry Smith       a->nonew             = (flg ? -1 : 0);
969a65d3064SKris Buschelman       break;
970a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
9714e0d8c25SBarry Smith       a->nonew             = (flg ? -2 : 0);
972a65d3064SKris Buschelman       break;
97328b2fa4aSMatthew Knepley     case MAT_UNUSED_NONZERO_LOCATION_ERR:
97428b2fa4aSMatthew Knepley       a->nounused          = (flg ? -1 : 0);
97528b2fa4aSMatthew Knepley       break;
976a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
9774e0d8c25SBarry Smith       a->ignorezeroentries = flg;
9780df259c2SBarry Smith       break;
979cd6b891eSBarry Smith     case MAT_CHECK_COMPRESSED_ROW:
980cd6b891eSBarry Smith       a->compressedrow.check = flg;
981d487561eSHong Zhang       break;
9823d472b54SHong Zhang     case MAT_SPD:
9833d472b54SHong Zhang       A->spd_set                         = PETSC_TRUE;
9843d472b54SHong Zhang       A->spd                             = flg;
9853d472b54SHong Zhang       if (flg) {
9863d472b54SHong Zhang         A->symmetric                     = PETSC_TRUE;
9873d472b54SHong Zhang         A->structurally_symmetric        = PETSC_TRUE;
9883d472b54SHong Zhang         A->symmetric_set                 = PETSC_TRUE;
9893d472b54SHong Zhang         A->structurally_symmetric_set    = PETSC_TRUE;
9903d472b54SHong Zhang       }
9913d472b54SHong Zhang       break;
992b1646e73SJed Brown     case MAT_SYMMETRIC:
993b1646e73SJed Brown     case MAT_STRUCTURALLY_SYMMETRIC:
994b1646e73SJed Brown     case MAT_HERMITIAN:
995b1646e73SJed Brown     case MAT_SYMMETRY_ETERNAL:
9964e0d8c25SBarry Smith     case MAT_NEW_DIAGONALS:
997a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
998a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
999290bbb0aSBarry Smith       ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1000a65d3064SKris Buschelman       break;
1001b87ac2d8SJed Brown     case MAT_USE_INODES:
1002b87ac2d8SJed Brown       /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1003b87ac2d8SJed Brown       break;
1004a65d3064SKris Buschelman     default:
1005e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1006a65d3064SKris Buschelman   }
10074108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
10083a40ed3dSBarry Smith   PetscFunctionReturn(0);
100917ab2063SBarry Smith }
101017ab2063SBarry Smith 
10114a2ae208SSatish Balay #undef __FUNCT__
10124a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1013dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
101417ab2063SBarry Smith {
1015416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10166849ba73SBarry Smith   PetscErrorCode ierr;
1017d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
101835e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
101917ab2063SBarry Smith 
10203a40ed3dSBarry Smith   PetscFunctionBegin;
1021d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1022e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
102335e7444dSHong Zhang 
1024d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
1025d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
102635e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
10272c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
102835e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
102935e7444dSHong Zhang     PetscFunctionReturn(0);
103035e7444dSHong Zhang   }
103135e7444dSHong Zhang 
10322dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
10331ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
103435e7444dSHong Zhang   for (i=0; i<n; i++) {
103535e7444dSHong Zhang     nz = ai[i+1] - ai[i];
10362f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
103735e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
103835e7444dSHong Zhang       if (aj[j] == i) {
103935e7444dSHong Zhang         x[i] = aa[j];
104017ab2063SBarry Smith         break;
104117ab2063SBarry Smith       }
104217ab2063SBarry Smith     }
104317ab2063SBarry Smith   }
10441ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
10453a40ed3dSBarry Smith   PetscFunctionReturn(0);
104617ab2063SBarry Smith }
104717ab2063SBarry Smith 
1048c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10494a2ae208SSatish Balay #undef __FUNCT__
10504a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1051dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
105217ab2063SBarry Smith {
1053416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
10545c897100SBarry Smith   PetscScalar       *x,*y;
1055dfbe8321SBarry Smith   PetscErrorCode    ierr;
1056d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
10575c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1058a77337e4SBarry Smith   MatScalar         *v;
1059a77337e4SBarry Smith   PetscScalar       alpha;
106004fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
10613447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
1062ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
10635c897100SBarry Smith #endif
106417ab2063SBarry Smith 
10653a40ed3dSBarry Smith   PetscFunctionBegin;
10662e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
10671ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
10681ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10695c897100SBarry Smith 
10705c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1071bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
10725c897100SBarry Smith #else
10733447b6efSHong Zhang   if (usecprow){
10743447b6efSHong Zhang     m    = cprow.nrows;
10753447b6efSHong Zhang     ii   = cprow.i;
10767b2bb3b9SHong Zhang     ridx = cprow.rindex;
10773447b6efSHong Zhang   } else {
10783447b6efSHong Zhang     ii = a->i;
10793447b6efSHong Zhang   }
108017ab2063SBarry Smith   for (i=0; i<m; i++) {
10813447b6efSHong Zhang     idx   = a->j + ii[i] ;
10823447b6efSHong Zhang     v     = a->a + ii[i] ;
10833447b6efSHong Zhang     n     = ii[i+1] - ii[i];
10843447b6efSHong Zhang     if (usecprow){
10857b2bb3b9SHong Zhang       alpha = x[ridx[i]];
10863447b6efSHong Zhang     } else {
108717ab2063SBarry Smith       alpha = x[i];
10883447b6efSHong Zhang     }
108904fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
109017ab2063SBarry Smith   }
10915c897100SBarry Smith #endif
1092dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
10931ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
10941ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
10953a40ed3dSBarry Smith   PetscFunctionReturn(0);
109617ab2063SBarry Smith }
109717ab2063SBarry Smith 
10984a2ae208SSatish Balay #undef __FUNCT__
10995c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1100dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
11015c897100SBarry Smith {
1102dfbe8321SBarry Smith   PetscErrorCode ierr;
11035c897100SBarry Smith 
11045c897100SBarry Smith   PetscFunctionBegin;
1105170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
11065c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
11075c897100SBarry Smith   PetscFunctionReturn(0);
11085c897100SBarry Smith }
11095c897100SBarry Smith 
1110c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11115c897100SBarry Smith #undef __FUNCT__
11124a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1113dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
111417ab2063SBarry Smith {
1115416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1116d9fead3dSBarry Smith   PetscScalar       *y;
111754f21887SBarry Smith   const PetscScalar *x;
111854f21887SBarry Smith   const MatScalar   *aa;
1119dfbe8321SBarry Smith   PetscErrorCode    ierr;
1120003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1121003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
11228aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1123362ced78SSatish Balay   PetscScalar       sum;
1124ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
112517ab2063SBarry Smith 
1126b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
112797952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1128fee21e36SBarry Smith #endif
1129fee21e36SBarry Smith 
11303a40ed3dSBarry Smith   PetscFunctionBegin;
11313649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11321ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
113397952fefSHong Zhang   aj  = a->j;
113497952fefSHong Zhang   aa  = a->a;
1135416022c9SBarry Smith   ii  = a->i;
11364eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
113797952fefSHong Zhang     m    = a->compressedrow.nrows;
113897952fefSHong Zhang     ii   = a->compressedrow.i;
113997952fefSHong Zhang     ridx = a->compressedrow.rindex;
114097952fefSHong Zhang     for (i=0; i<m; i++){
114197952fefSHong Zhang       n   = ii[i+1] - ii[i];
114297952fefSHong Zhang       aj  = a->j + ii[i];
114397952fefSHong Zhang       aa  = a->a + ii[i];
114497952fefSHong Zhang       sum = 0.0;
1145a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1146003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1147003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
114897952fefSHong Zhang       y[*ridx++] = sum;
114997952fefSHong Zhang     }
115097952fefSHong Zhang   } else { /* do not use compressed row format */
1151b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1152b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1153b05257ddSBarry Smith #else
115417ab2063SBarry Smith     for (i=0; i<m; i++) {
1155003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1156003131ecSBarry Smith       aj  = a->j + ii[i];
1157003131ecSBarry Smith       aa  = a->a + ii[i];
115817ab2063SBarry Smith       sum  = 0.0;
1159a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1160003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
116117ab2063SBarry Smith       y[i] = sum;
116217ab2063SBarry Smith     }
11638d195f9aSBarry Smith #endif
1164b05257ddSBarry Smith   }
1165dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
11663649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11671ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11683a40ed3dSBarry Smith   PetscFunctionReturn(0);
116917ab2063SBarry Smith }
117017ab2063SBarry Smith 
1171c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
11724a2ae208SSatish Balay #undef __FUNCT__
11734a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1174dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
117517ab2063SBarry Smith {
1176416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1177f15663dcSBarry Smith   PetscScalar       *y,*z;
1178f15663dcSBarry Smith   const PetscScalar *x;
117954f21887SBarry Smith   const MatScalar   *aa;
1180dfbe8321SBarry Smith   PetscErrorCode    ierr;
1181d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
1182f15663dcSBarry Smith   PetscInt          n,i,*ridx=PETSC_NULL;
1183362ced78SSatish Balay   PetscScalar       sum;
1184ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
11859ea0dfa2SSatish Balay 
11863a40ed3dSBarry Smith   PetscFunctionBegin;
1187f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11881ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11892e8a6d31SBarry Smith   if (zz != yy) {
11901ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
11912e8a6d31SBarry Smith   } else {
11922e8a6d31SBarry Smith     z = y;
11932e8a6d31SBarry Smith   }
1194bfeeae90SHong Zhang 
119597952fefSHong Zhang   aj  = a->j;
119697952fefSHong Zhang   aa  = a->a;
1197cddf8d76SBarry Smith   ii  = a->i;
11984eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
11994eb6d288SHong Zhang     if (zz != yy){
12004eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
12014eb6d288SHong Zhang     }
120297952fefSHong Zhang     m    = a->compressedrow.nrows;
120397952fefSHong Zhang     ii   = a->compressedrow.i;
120497952fefSHong Zhang     ridx = a->compressedrow.rindex;
120597952fefSHong Zhang     for (i=0; i<m; i++){
120697952fefSHong Zhang       n  = ii[i+1] - ii[i];
120797952fefSHong Zhang       aj  = a->j + ii[i];
120897952fefSHong Zhang       aa  = a->a + ii[i];
120997952fefSHong Zhang       sum = y[*ridx];
1210f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
121197952fefSHong Zhang       z[*ridx++] = sum;
121297952fefSHong Zhang     }
121397952fefSHong Zhang   } else { /* do not use compressed row format */
1214f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1215f15663dcSBarry Smith   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1216f15663dcSBarry Smith #else
121717ab2063SBarry Smith     for (i=0; i<m; i++) {
1218f15663dcSBarry Smith       n    = ii[i+1] - ii[i];
1219f15663dcSBarry Smith       aj  = a->j + ii[i];
1220f15663dcSBarry Smith       aa  = a->a + ii[i];
122117ab2063SBarry Smith       sum  = y[i];
1222f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
122317ab2063SBarry Smith       z[i] = sum;
122417ab2063SBarry Smith     }
122502ab625aSSatish Balay #endif
1226f15663dcSBarry Smith   }
1227dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1228f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12291ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12302e8a6d31SBarry Smith   if (zz != yy) {
12311ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
12322e8a6d31SBarry Smith   }
12338154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
12346b375ea7SVictor Minden   /*
1235918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1236918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1237918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
12386b375ea7SVictor Minden   */
1239918e98c3SVictor Minden #endif
12403a40ed3dSBarry Smith   PetscFunctionReturn(0);
124117ab2063SBarry Smith }
124217ab2063SBarry Smith 
124317ab2063SBarry Smith /*
124417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
124517ab2063SBarry Smith */
12464a2ae208SSatish Balay #undef __FUNCT__
12474a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1248dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
124917ab2063SBarry Smith {
1250416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12516849ba73SBarry Smith   PetscErrorCode ierr;
1252d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
125317ab2063SBarry Smith 
12543a40ed3dSBarry Smith   PetscFunctionBegin;
125509f38230SBarry Smith   if (!a->diag) {
125609f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
12579518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
125809f38230SBarry Smith   }
1259d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
126009f38230SBarry Smith     a->diag[i] = a->i[i+1];
1261bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1262bfeeae90SHong Zhang       if (a->j[j] == i) {
126309f38230SBarry Smith         a->diag[i] = j;
126417ab2063SBarry Smith         break;
126517ab2063SBarry Smith       }
126617ab2063SBarry Smith     }
126717ab2063SBarry Smith   }
12683a40ed3dSBarry Smith   PetscFunctionReturn(0);
126917ab2063SBarry Smith }
127017ab2063SBarry Smith 
1271be5855fcSBarry Smith /*
1272be5855fcSBarry Smith      Checks for missing diagonals
1273be5855fcSBarry Smith */
12744a2ae208SSatish Balay #undef __FUNCT__
12754a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1276ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1277be5855fcSBarry Smith {
1278be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
127997f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1280be5855fcSBarry Smith 
1281be5855fcSBarry Smith   PetscFunctionBegin;
128209f38230SBarry Smith   *missing = PETSC_FALSE;
1283d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
128409f38230SBarry Smith     *missing  = PETSC_TRUE;
128509f38230SBarry Smith     if (d) *d = 0;
1286358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
128709f38230SBarry Smith   } else {
1288f1e2ffcdSBarry Smith     diag = a->diag;
1289d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1290bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
129109f38230SBarry Smith 	*missing = PETSC_TRUE;
129209f38230SBarry Smith 	if (d) *d = i;
129309f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1294358d2f5dSShri Abhyankar 	break;
129509f38230SBarry Smith       }
1296be5855fcSBarry Smith     }
1297be5855fcSBarry Smith   }
1298be5855fcSBarry Smith   PetscFunctionReturn(0);
1299be5855fcSBarry Smith }
1300be5855fcSBarry Smith 
130171f1c65dSBarry Smith EXTERN_C_BEGIN
130271f1c65dSBarry Smith #undef __FUNCT__
130371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
13047087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
130571f1c65dSBarry Smith {
130671f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
130771f1c65dSBarry Smith   PetscErrorCode ierr;
1308d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
130954f21887SBarry Smith   MatScalar      *v = a->a;
131054f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
131171f1c65dSBarry Smith 
131271f1c65dSBarry Smith   PetscFunctionBegin;
131371f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
131471f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
131571f1c65dSBarry Smith   diag = a->diag;
131671f1c65dSBarry Smith   if (!a->idiag) {
131771f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
131871f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
131971f1c65dSBarry Smith     v        = a->a;
132071f1c65dSBarry Smith   }
132171f1c65dSBarry Smith   mdiag = a->mdiag;
132271f1c65dSBarry Smith   idiag = a->idiag;
132371f1c65dSBarry Smith 
1324028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
132571f1c65dSBarry Smith     for (i=0; i<m; i++) {
132671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1327e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
132871f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
132971f1c65dSBarry Smith     }
133071f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
133171f1c65dSBarry Smith   } else {
133271f1c65dSBarry Smith     for (i=0; i<m; i++) {
133371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
133471f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
133571f1c65dSBarry Smith     }
1336dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
133771f1c65dSBarry Smith   }
133871f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
133971f1c65dSBarry Smith   PetscFunctionReturn(0);
134071f1c65dSBarry Smith }
13415a9745a3SMatthew Knepley EXTERN_C_END
134271f1c65dSBarry Smith 
1343c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
13444a2ae208SSatish Balay #undef __FUNCT__
134541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
134641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
134717ab2063SBarry Smith {
1348416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1349e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1350e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
135154f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1352dfbe8321SBarry Smith   PetscErrorCode     ierr;
1353d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
135497f1f81fSBarry Smith   const PetscInt     *idx,*diag;
135517ab2063SBarry Smith 
13563a40ed3dSBarry Smith   PetscFunctionBegin;
1357b965ef7fSBarry Smith   its = its*lits;
135891723122SBarry Smith 
135971f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
136071f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
136171f1c65dSBarry Smith   a->fshift = fshift;
136271f1c65dSBarry Smith   a->omega  = omega;
1363ed480e8bSBarry Smith 
136471f1c65dSBarry Smith   diag = a->diag;
136571f1c65dSBarry Smith   t     = a->ssor_work;
1366ed480e8bSBarry Smith   idiag = a->idiag;
136771f1c65dSBarry Smith   mdiag = a->mdiag;
1368ed480e8bSBarry Smith 
13691ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
13703649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
137171f1c65dSBarry Smith   CHKMEMQ;
1372ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
137317ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
137417ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1375ed480e8bSBarry Smith     bs = b;
137617ab2063SBarry Smith     for (i=0; i<m; i++) {
137771f1c65dSBarry Smith         d    = fshift + mdiag[i];
1378416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1379ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1380ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
138117ab2063SBarry Smith         sum  = b[i]*d/omega;
1382003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
138317ab2063SBarry Smith         x[i] = sum;
138417ab2063SBarry Smith     }
13851ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13863649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1387efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
13883a40ed3dSBarry Smith     PetscFunctionReturn(0);
138917ab2063SBarry Smith   }
1390c783ea89SBarry Smith 
139148af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1392e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
13933a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
139417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1395887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
139617ab2063SBarry Smith 
139717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
139817ab2063SBarry Smith 
1399887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
140017ab2063SBarry Smith     */
140117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
140217ab2063SBarry Smith 
140317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
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  = b[i];
1409e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1410ed480e8bSBarry Smith       x[i] = sum*idiag[i];
141117ab2063SBarry Smith     }
141217ab2063SBarry Smith 
141317ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1414416022c9SBarry Smith     v = a->a;
1415ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
141617ab2063SBarry Smith 
141717ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1418ed480e8bSBarry Smith     ts = t;
1419416022c9SBarry Smith     diag = a->diag;
142017ab2063SBarry Smith     for (i=0; i<m; i++) {
1421416022c9SBarry Smith       n    = diag[i] - a->i[i];
1422ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1423ed480e8bSBarry Smith       v    = a->a + a->i[i];
142417ab2063SBarry Smith       sum  = t[i];
1425003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1426ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1427733d66baSBarry Smith       /*  x = x + t */
1428733d66baSBarry Smith       x[i] += t[i];
142917ab2063SBarry Smith     }
143017ab2063SBarry Smith 
1431dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
14321ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14333649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
14343a40ed3dSBarry Smith     PetscFunctionReturn(0);
143517ab2063SBarry Smith   }
143617ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
143717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
143817ab2063SBarry Smith       for (i=0; i<m; i++) {
1439416022c9SBarry Smith         n    = diag[i] - a->i[i];
1440ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1441ed480e8bSBarry Smith         v    = a->a + a->i[i];
144217ab2063SBarry Smith         sum  = b[i];
1443e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
14445c99c7daSBarry Smith         t[i] = sum;
1445ed480e8bSBarry Smith         x[i] = sum*idiag[i];
144617ab2063SBarry Smith       }
14475c99c7daSBarry Smith       xb = t;
1448efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
14493a40ed3dSBarry Smith     } else xb = b;
145017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
145117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1452416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1453ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1454ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
145517ab2063SBarry Smith         sum  = xb[i];
1456e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
14575c99c7daSBarry Smith         if (xb == b) {
1458ed480e8bSBarry Smith           x[i] = sum*idiag[i];
14595c99c7daSBarry Smith         } else {
14605c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
146117ab2063SBarry Smith         }
14625c99c7daSBarry Smith       }
1463efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
146417ab2063SBarry Smith     }
146517ab2063SBarry Smith     its--;
146617ab2063SBarry Smith   }
146717ab2063SBarry Smith   while (its--) {
146817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
146917ab2063SBarry Smith       for (i=0; i<m; i++) {
1470416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1471ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1472ed480e8bSBarry Smith         v    = a->a + a->i[i];
147317ab2063SBarry Smith         sum  = b[i];
1474e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1475ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
147617ab2063SBarry Smith       }
14779f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
147817ab2063SBarry Smith     }
147917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
148017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1481416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1482ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1483ed480e8bSBarry Smith         v    = a->a + a->i[i];
148417ab2063SBarry Smith         sum  = b[i];
1485e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1486ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
148717ab2063SBarry Smith       }
14889f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
148917ab2063SBarry Smith     }
149017ab2063SBarry Smith   }
14911ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
14923649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
149371f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
149417ab2063SBarry Smith }
149517ab2063SBarry Smith 
14962af78befSBarry Smith 
14974a2ae208SSatish Balay #undef __FUNCT__
14984a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1499dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
150017ab2063SBarry Smith {
1501416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
15024e220ebcSLois Curfman McInnes 
15033a40ed3dSBarry Smith   PetscFunctionBegin;
15044e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
15054e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
15064e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
15074e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
15084e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
15098e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
15107adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1511d5f3da31SBarry Smith   if (A->factortype) {
15124e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
15134e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
15144e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
15154e220ebcSLois Curfman McInnes   } else {
15164e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
15174e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
15184e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
15194e220ebcSLois Curfman McInnes   }
15203a40ed3dSBarry Smith   PetscFunctionReturn(0);
152117ab2063SBarry Smith }
152217ab2063SBarry Smith 
15234a2ae208SSatish Balay #undef __FUNCT__
15244a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
15252b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
152617ab2063SBarry Smith {
1527416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
15283b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
15296849ba73SBarry Smith   PetscErrorCode    ierr;
153097b48c8fSBarry Smith   const PetscScalar *xx;
153197b48c8fSBarry Smith   PetscScalar       *bb;
1532ace3abfcSBarry Smith   PetscBool         missing;
153317ab2063SBarry Smith 
15343a40ed3dSBarry Smith   PetscFunctionBegin;
153597b48c8fSBarry Smith   if (x && b) {
153697b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
153797b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
153897b48c8fSBarry Smith     for (i=0; i<N; i++) {
153997b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
154097b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
154197b48c8fSBarry Smith     }
154297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
154397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
154497b48c8fSBarry Smith   }
154597b48c8fSBarry Smith 
1546a9817697SBarry Smith   if (a->keepnonzeropattern) {
1547f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1548e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1549bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1550f1e2ffcdSBarry Smith     }
1551f4df32b1SMatthew Knepley     if (diag != 0.0) {
155209f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1553e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1554f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1555f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1556f1e2ffcdSBarry Smith       }
1557f1e2ffcdSBarry Smith     }
155888e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1559f1e2ffcdSBarry Smith   } else {
1560f4df32b1SMatthew Knepley     if (diag != 0.0) {
156117ab2063SBarry Smith       for (i=0; i<N; i++) {
1562e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
15637ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1564416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1565f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1566bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
15677ae801bdSBarry Smith         } else { /* in case row was completely empty */
1568f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
156917ab2063SBarry Smith         }
157017ab2063SBarry Smith       }
15713a40ed3dSBarry Smith     } else {
157217ab2063SBarry Smith       for (i=0; i<N; i++) {
1573e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1574416022c9SBarry Smith         a->ilen[rows[i]] = 0;
157517ab2063SBarry Smith       }
157617ab2063SBarry Smith     }
157788e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1578f1e2ffcdSBarry Smith   }
157943a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15803a40ed3dSBarry Smith   PetscFunctionReturn(0);
158117ab2063SBarry Smith }
158217ab2063SBarry Smith 
15834a2ae208SSatish Balay #undef __FUNCT__
15846e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
15856e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15866e169961SBarry Smith {
15876e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
15886e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
15896e169961SBarry Smith   PetscErrorCode    ierr;
15902b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
15916e169961SBarry Smith   const PetscScalar *xx;
15926e169961SBarry Smith   PetscScalar       *bb;
15936e169961SBarry Smith 
15946e169961SBarry Smith   PetscFunctionBegin;
15956e169961SBarry Smith   if (x && b) {
15966e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
15976e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15982b40b63fSBarry Smith     vecs = PETSC_TRUE;
15996e169961SBarry Smith   }
16006e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
16016e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
16026e169961SBarry Smith   for (i=0; i<N; i++) {
16036e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
16046e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
16056e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
16066e169961SBarry Smith   }
16076e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
16086e169961SBarry Smith     if (!zeroed[i]) {
16096e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
16106e169961SBarry Smith         if (zeroed[a->j[j]]) {
16112b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
16126e169961SBarry Smith           a->a[j] = 0.0;
16136e169961SBarry Smith         }
16146e169961SBarry Smith       }
16152b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
16166e169961SBarry Smith   }
16176e169961SBarry Smith   if (x && b) {
16186e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
16196e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
16206e169961SBarry Smith   }
16216e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
16226e169961SBarry Smith   if (diag != 0.0) {
16236e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
16246e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
16256e169961SBarry Smith     for (i=0; i<N; i++) {
16266e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
16276e169961SBarry Smith     }
16286e169961SBarry Smith   }
16296e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
16306e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16316e169961SBarry Smith   PetscFunctionReturn(0);
16326e169961SBarry Smith }
16336e169961SBarry Smith 
16346e169961SBarry Smith #undef __FUNCT__
16354a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1636a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
163717ab2063SBarry Smith {
1638416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
163997f1f81fSBarry Smith   PetscInt   *itmp;
164017ab2063SBarry Smith 
16413a40ed3dSBarry Smith   PetscFunctionBegin;
1642e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
164317ab2063SBarry Smith 
1644416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1645bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
164617ab2063SBarry Smith   if (idx) {
1647bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1648bfeeae90SHong Zhang     if (*nz) {
16494e093b46SBarry Smith       *idx = itmp;
165017ab2063SBarry Smith     }
165117ab2063SBarry Smith     else *idx = 0;
165217ab2063SBarry Smith   }
16533a40ed3dSBarry Smith   PetscFunctionReturn(0);
165417ab2063SBarry Smith }
165517ab2063SBarry Smith 
1656bfeeae90SHong Zhang /* remove this function? */
16574a2ae208SSatish Balay #undef __FUNCT__
16584a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1659a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
166017ab2063SBarry Smith {
16613a40ed3dSBarry Smith   PetscFunctionBegin;
16623a40ed3dSBarry Smith   PetscFunctionReturn(0);
166317ab2063SBarry Smith }
166417ab2063SBarry Smith 
16654a2ae208SSatish Balay #undef __FUNCT__
16664a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1667dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
166817ab2063SBarry Smith {
1669416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
167054f21887SBarry Smith   MatScalar      *v = a->a;
167136db0b34SBarry Smith   PetscReal      sum = 0.0;
16726849ba73SBarry Smith   PetscErrorCode ierr;
167397f1f81fSBarry Smith   PetscInt       i,j;
167417ab2063SBarry Smith 
16753a40ed3dSBarry Smith   PetscFunctionBegin;
167617ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1677416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1678aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
167936db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
168017ab2063SBarry Smith #else
168117ab2063SBarry Smith       sum += (*v)*(*v); v++;
168217ab2063SBarry Smith #endif
168317ab2063SBarry Smith     }
16848f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
16853a40ed3dSBarry Smith   } else if (type == NORM_1) {
168636db0b34SBarry Smith     PetscReal *tmp;
168797f1f81fSBarry Smith     PetscInt    *jj = a->j;
1688d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1689d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1690064f8208SBarry Smith     *nrm = 0.0;
1691416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1692bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
169317ab2063SBarry Smith     }
1694d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1695064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
169617ab2063SBarry Smith     }
1697606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
16983a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1699064f8208SBarry Smith     *nrm = 0.0;
1700d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1701bfeeae90SHong Zhang       v = a->a + a->i[j];
170217ab2063SBarry Smith       sum = 0.0;
1703416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1704cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
170517ab2063SBarry Smith       }
1706064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
170717ab2063SBarry Smith     }
17083a40ed3dSBarry Smith   } else {
1709e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
171017ab2063SBarry Smith   }
17113a40ed3dSBarry Smith   PetscFunctionReturn(0);
171217ab2063SBarry Smith }
171317ab2063SBarry Smith 
17144e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
17154e938277SHong Zhang #undef __FUNCT__
17164e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
17174e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
17184e938277SHong Zhang {
17194e938277SHong Zhang   PetscErrorCode ierr;
17204e938277SHong Zhang   PetscInt       i,j,anzj;
17214e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ *)A->data,*b;
17224e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
17234e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
17244e938277SHong Zhang 
17254e938277SHong Zhang   PetscFunctionBegin;
17264e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
17274e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
17284e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
17294e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
17304e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
17314e938277SHong Zhang 
17324e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
17334e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
17344e938277SHong Zhang   for (i=0;i<ai[am];i++) {
17354e938277SHong Zhang     ati[aj[i]+1] += 1;
17364e938277SHong Zhang   }
17374e938277SHong Zhang   /* Form ati for csr format of A^T. */
17384e938277SHong Zhang   for (i=0;i<an;i++) {
17394e938277SHong Zhang     ati[i+1] += ati[i];
17404e938277SHong Zhang   }
17414e938277SHong Zhang 
17424e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
17434e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
17444e938277SHong Zhang 
17454e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
17464e938277SHong Zhang   for (i=0;i<am;i++) {
17474e938277SHong Zhang     anzj = ai[i+1] - ai[i];
17484e938277SHong Zhang     for (j=0;j<anzj;j++) {
17494e938277SHong Zhang       atj[atfill[*aj]] = i;
17504e938277SHong Zhang       atfill[*aj++]   += 1;
17514e938277SHong Zhang     }
17524e938277SHong Zhang   }
17534e938277SHong Zhang 
17544e938277SHong Zhang   /* Clean up temporary space and complete requests. */
17554e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
17564e938277SHong Zhang   ierr = MatCreateSeqAIJWithArrays(((PetscObject)A)->comm,an,am,ati,atj,PETSC_NULL,B);CHKERRQ(ierr);
1757a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
1758a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
1759a2f3521dSMark F. Adams 
17604e938277SHong Zhang   b = (Mat_SeqAIJ *)((*B)->data);
17614e938277SHong Zhang   b->free_a   = PETSC_FALSE;
17624e938277SHong Zhang   b->free_ij  = PETSC_TRUE;
17634e938277SHong Zhang   b->nonew    = 0;
17644e938277SHong Zhang   PetscFunctionReturn(0);
17654e938277SHong Zhang }
17664e938277SHong Zhang 
17674a2ae208SSatish Balay #undef __FUNCT__
17684a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1769fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
177017ab2063SBarry Smith {
1771416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1772416022c9SBarry Smith   Mat            C;
17736849ba73SBarry Smith   PetscErrorCode ierr;
1774d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
177554f21887SBarry Smith   MatScalar      *array = a->a;
177617ab2063SBarry Smith 
17773a40ed3dSBarry Smith   PetscFunctionBegin;
1778e32f2f54SBarry 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");
1779fc4dec0aSBarry Smith 
1780fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1781d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1782d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1783bfeeae90SHong Zhang 
1784bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
17857adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1786d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
1787a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
17887adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1789ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1790606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1791a541d17aSBarry Smith   } else {
1792a541d17aSBarry Smith     C = *B;
1793a541d17aSBarry Smith   }
1794a541d17aSBarry Smith 
179517ab2063SBarry Smith   for (i=0; i<m; i++) {
179617ab2063SBarry Smith     len    = ai[i+1]-ai[i];
179787d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1798b9b97703SBarry Smith     array += len;
1799b9b97703SBarry Smith     aj    += len;
180017ab2063SBarry Smith   }
18016d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18026d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
180317ab2063SBarry Smith 
1804815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1805416022c9SBarry Smith     *B = C;
180617ab2063SBarry Smith   } else {
1807eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
180817ab2063SBarry Smith   }
18093a40ed3dSBarry Smith   PetscFunctionReturn(0);
181017ab2063SBarry Smith }
181117ab2063SBarry Smith 
1812cd0d46ebSvictorle EXTERN_C_BEGIN
1813cd0d46ebSvictorle #undef __FUNCT__
18145fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
18157087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1816cd0d46ebSvictorle {
1817cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
181854f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
181954f21887SBarry Smith   MatScalar      *va,*vb;
18206849ba73SBarry Smith   PetscErrorCode ierr;
182197f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1822cd0d46ebSvictorle 
1823cd0d46ebSvictorle   PetscFunctionBegin;
1824cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1825cd0d46ebSvictorle 
1826cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1827cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
18285485867bSBarry Smith   if (ma!=nb || na!=mb){
18295485867bSBarry Smith     *f = PETSC_FALSE;
18305485867bSBarry Smith     PetscFunctionReturn(0);
18315485867bSBarry Smith   }
1832cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1833cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1834cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
183597f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
183697f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1837cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1838cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1839cd0d46ebSvictorle 
1840cd0d46ebSvictorle   *f = PETSC_TRUE;
1841cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1842cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
184397f1f81fSBarry Smith       PetscInt         idc,idr;
18445485867bSBarry Smith       PetscScalar vc,vr;
1845cd0d46ebSvictorle       /* column/row index/value */
18465485867bSBarry Smith       idc = adx[aptr[i]];
18475485867bSBarry Smith       idr = bdx[bptr[idc]];
18485485867bSBarry Smith       vc  = va[aptr[i]];
18495485867bSBarry Smith       vr  = vb[bptr[idc]];
18505485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
18515485867bSBarry Smith         *f = PETSC_FALSE;
18525485867bSBarry Smith         goto done;
1853cd0d46ebSvictorle       } else {
18545485867bSBarry Smith         aptr[i]++;
18555485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1856cd0d46ebSvictorle       }
1857cd0d46ebSvictorle     }
1858cd0d46ebSvictorle   }
1859cd0d46ebSvictorle  done:
1860cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
18613aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
1862cd0d46ebSvictorle   PetscFunctionReturn(0);
1863cd0d46ebSvictorle }
1864cd0d46ebSvictorle EXTERN_C_END
1865cd0d46ebSvictorle 
18661cbb95d3SBarry Smith EXTERN_C_BEGIN
18671cbb95d3SBarry Smith #undef __FUNCT__
18681cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
18697087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
18701cbb95d3SBarry Smith {
18711cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
187254f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
187354f21887SBarry Smith   MatScalar      *va,*vb;
18741cbb95d3SBarry Smith   PetscErrorCode ierr;
18751cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
18761cbb95d3SBarry Smith 
18771cbb95d3SBarry Smith   PetscFunctionBegin;
18781cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
18791cbb95d3SBarry Smith 
18801cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
18811cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
18821cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
18831cbb95d3SBarry Smith     *f = PETSC_FALSE;
18841cbb95d3SBarry Smith     PetscFunctionReturn(0);
18851cbb95d3SBarry Smith   }
18861cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
18871cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
18881cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
18891cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
18901cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
18911cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
18921cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
18931cbb95d3SBarry Smith 
18941cbb95d3SBarry Smith   *f = PETSC_TRUE;
18951cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
18961cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
18971cbb95d3SBarry Smith       PetscInt         idc,idr;
18981cbb95d3SBarry Smith       PetscScalar vc,vr;
18991cbb95d3SBarry Smith       /* column/row index/value */
19001cbb95d3SBarry Smith       idc = adx[aptr[i]];
19011cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
19021cbb95d3SBarry Smith       vc  = va[aptr[i]];
19031cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
19041cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
19051cbb95d3SBarry Smith         *f = PETSC_FALSE;
19061cbb95d3SBarry Smith         goto done;
19071cbb95d3SBarry Smith       } else {
19081cbb95d3SBarry Smith         aptr[i]++;
19091cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
19101cbb95d3SBarry Smith       }
19111cbb95d3SBarry Smith     }
19121cbb95d3SBarry Smith   }
19131cbb95d3SBarry Smith  done:
19141cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
19151cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
19161cbb95d3SBarry Smith   PetscFunctionReturn(0);
19171cbb95d3SBarry Smith }
19181cbb95d3SBarry Smith EXTERN_C_END
19191cbb95d3SBarry Smith 
19209e29f15eSvictorle #undef __FUNCT__
19219e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
1922ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
19239e29f15eSvictorle {
1924dfbe8321SBarry Smith   PetscErrorCode ierr;
19259e29f15eSvictorle   PetscFunctionBegin;
19265485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
19279e29f15eSvictorle   PetscFunctionReturn(0);
19289e29f15eSvictorle }
19299e29f15eSvictorle 
19304a2ae208SSatish Balay #undef __FUNCT__
19311cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
1932ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
19331cbb95d3SBarry Smith {
19341cbb95d3SBarry Smith   PetscErrorCode ierr;
19351cbb95d3SBarry Smith   PetscFunctionBegin;
19361cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
19371cbb95d3SBarry Smith   PetscFunctionReturn(0);
19381cbb95d3SBarry Smith }
19391cbb95d3SBarry Smith 
19401cbb95d3SBarry Smith #undef __FUNCT__
19414a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
1942dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
194317ab2063SBarry Smith {
1944416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
194554f21887SBarry Smith   PetscScalar    *l,*r,x;
194654f21887SBarry Smith   MatScalar      *v;
1947dfbe8321SBarry Smith   PetscErrorCode ierr;
1948d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
194917ab2063SBarry Smith 
19503a40ed3dSBarry Smith   PetscFunctionBegin;
195117ab2063SBarry Smith   if (ll) {
19523ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
19533ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1954e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1955e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
19561ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1957416022c9SBarry Smith     v = a->a;
195817ab2063SBarry Smith     for (i=0; i<m; i++) {
195917ab2063SBarry Smith       x = l[i];
1960416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
196117ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
196217ab2063SBarry Smith     }
19631ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1964efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
196517ab2063SBarry Smith   }
196617ab2063SBarry Smith   if (rr) {
1967e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1968e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
19691ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1970416022c9SBarry Smith     v = a->a; jj = a->j;
197117ab2063SBarry Smith     for (i=0; i<nz; i++) {
1972bfeeae90SHong Zhang       (*v++) *= r[*jj++];
197317ab2063SBarry Smith     }
19741ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1975efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
197617ab2063SBarry Smith   }
19770847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
19783a40ed3dSBarry Smith   PetscFunctionReturn(0);
197917ab2063SBarry Smith }
198017ab2063SBarry Smith 
19814a2ae208SSatish Balay #undef __FUNCT__
19824a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
198397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
198417ab2063SBarry Smith {
1985db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
19866849ba73SBarry Smith   PetscErrorCode ierr;
1987d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
198897f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
19895d0c19d7SBarry Smith   const PetscInt *irow,*icol;
19905d0c19d7SBarry Smith   PetscInt       nrows,ncols;
199197f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
199254f21887SBarry Smith   MatScalar      *a_new,*mat_a;
1993416022c9SBarry Smith   Mat            C;
1994ace3abfcSBarry Smith   PetscBool      stride,sorted;
199517ab2063SBarry Smith 
19963a40ed3dSBarry Smith   PetscFunctionBegin;
199714ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
1998e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
199914ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2000e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
200199141d43SSatish Balay 
200217ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2003b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2004b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
200517ab2063SBarry Smith 
2006fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2007251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2008fee21e36SBarry Smith   if (stride && step == 1) {
200902834360SBarry Smith     /* special case of contiguous rows */
20100e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
201102834360SBarry Smith     /* loop over new rows determining lens and starting points */
201202834360SBarry Smith     for (i=0; i<nrows; i++) {
2013bfeeae90SHong Zhang       kstart  = ai[irow[i]];
2014a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
201502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2016bfeeae90SHong Zhang         if (aj[k] >= first) {
201702834360SBarry Smith           starts[i] = k;
201802834360SBarry Smith           break;
201902834360SBarry Smith 	}
202002834360SBarry Smith       }
2021a2744918SBarry Smith       sum = 0;
202202834360SBarry Smith       while (k < kend) {
2023bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2024a2744918SBarry Smith         sum++;
202502834360SBarry Smith       }
2026a2744918SBarry Smith       lens[i] = sum;
202702834360SBarry Smith     }
202802834360SBarry Smith     /* create submatrix */
2029cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
203097f1f81fSBarry Smith       PetscInt n_cols,n_rows;
203108480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2032e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2033d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
203408480c60SBarry Smith       C = *B;
20353a40ed3dSBarry Smith     } else {
20363bef6203SJed Brown       PetscInt rbs,cbs;
20377adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2038f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
20393bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
20403bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
20413bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
20427adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2043ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
204408480c60SBarry Smith     }
2045db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2046db02288aSLois Curfman McInnes 
204702834360SBarry Smith     /* loop over rows inserting into submatrix */
2048db02288aSLois Curfman McInnes     a_new    = c->a;
2049db02288aSLois Curfman McInnes     j_new    = c->j;
2050db02288aSLois Curfman McInnes     i_new    = c->i;
2051bfeeae90SHong Zhang 
205202834360SBarry Smith     for (i=0; i<nrows; i++) {
2053a2744918SBarry Smith       ii    = starts[i];
2054a2744918SBarry Smith       lensi = lens[i];
2055a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2056a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
205702834360SBarry Smith       }
205887828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2059a2744918SBarry Smith       a_new      += lensi;
2060a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
2061a2744918SBarry Smith       c->ilen[i]  = lensi;
206202834360SBarry Smith     }
20630e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
20643a40ed3dSBarry Smith   } else {
206502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
20660e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
206797f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
20680e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
20694dcab191SBarry Smith     for (i=0; i<ncols; i++) {
20704dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
20714dcab191SBarry Smith       if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols);
20724dcab191SBarry Smith #endif
20734dcab191SBarry Smith       smap[icol[i]] = i+1;
20744dcab191SBarry Smith     }
20754dcab191SBarry Smith 
207602834360SBarry Smith     /* determine lens of each row */
207702834360SBarry Smith     for (i=0; i<nrows; i++) {
2078bfeeae90SHong Zhang       kstart  = ai[irow[i]];
207902834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
208002834360SBarry Smith       lens[i] = 0;
208102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2082bfeeae90SHong Zhang         if (smap[aj[k]]) {
208302834360SBarry Smith           lens[i]++;
208402834360SBarry Smith         }
208502834360SBarry Smith       }
208602834360SBarry Smith     }
208717ab2063SBarry Smith     /* Create and fill new matrix */
2088a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2089ace3abfcSBarry Smith       PetscBool  equal;
20900f5bd95cSBarry Smith 
209199141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
2092e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2093d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
20940f5bd95cSBarry Smith       if (!equal) {
2095e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
209699141d43SSatish Balay       }
2097d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
209808480c60SBarry Smith       C = *B;
20993a40ed3dSBarry Smith     } else {
21003bef6203SJed Brown       PetscInt rbs,cbs;
21017adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2102f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
21033bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
21043bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
21053bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
21067adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2107ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
210808480c60SBarry Smith     }
210999141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
211017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
211199141d43SSatish Balay       row    = irow[i];
2112bfeeae90SHong Zhang       kstart = ai[row];
211399141d43SSatish Balay       kend   = kstart + a->ilen[row];
2114bfeeae90SHong Zhang       mat_i  = c->i[i];
211599141d43SSatish Balay       mat_j  = c->j + mat_i;
211699141d43SSatish Balay       mat_a  = c->a + mat_i;
211799141d43SSatish Balay       mat_ilen = c->ilen + i;
211817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2119bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2120ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
212199141d43SSatish Balay           *mat_a++ = a->a[k];
212299141d43SSatish Balay           (*mat_ilen)++;
212399141d43SSatish Balay 
212417ab2063SBarry Smith         }
212517ab2063SBarry Smith       }
212617ab2063SBarry Smith     }
212702834360SBarry Smith     /* Free work space */
212802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2129606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2130606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
213102834360SBarry Smith   }
21326d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21336d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
213417ab2063SBarry Smith 
213517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2136416022c9SBarry Smith   *B = C;
21373a40ed3dSBarry Smith   PetscFunctionReturn(0);
213817ab2063SBarry Smith }
213917ab2063SBarry Smith 
21401df811f5SHong Zhang #undef __FUNCT__
214182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2142fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat* subMat)
214382d44351SHong Zhang {
214482d44351SHong Zhang   PetscErrorCode ierr;
214582d44351SHong Zhang   Mat            B;
214682d44351SHong Zhang 
214782d44351SHong Zhang   PetscFunctionBegin;
214882d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
214982d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2150a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs); CHKERRQ(ierr);
215182d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
215282d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
215382d44351SHong Zhang   *subMat = B;
215482d44351SHong Zhang   PetscFunctionReturn(0);
215582d44351SHong Zhang }
215682d44351SHong Zhang 
215782d44351SHong Zhang #undef __FUNCT__
21584a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
21590481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2160a871dcd8SBarry Smith {
216163b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2162dfbe8321SBarry Smith   PetscErrorCode ierr;
216363b91edcSBarry Smith   Mat            outA;
2164ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
216563b91edcSBarry Smith 
21663a40ed3dSBarry Smith   PetscFunctionBegin;
2167e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
21681df811f5SHong Zhang 
2169b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2170b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2171a871dcd8SBarry Smith 
217263b91edcSBarry Smith   outA              = inA;
2173d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2174c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
21756bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2176c3122656SLisandro Dalcin   a->row = row;
2177c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
21786bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2179c3122656SLisandro Dalcin   a->col = col;
218063b91edcSBarry Smith 
218136db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
21826bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
21834c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
218452e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2185f0ec6fceSSatish Balay 
218694a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2187d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2188d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
218994a9d846SBarry Smith   }
219063b91edcSBarry Smith 
2191f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2192137fb511SHong Zhang   if (row_identity && col_identity) {
2193ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2194137fb511SHong Zhang   } else {
2195719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2196137fb511SHong Zhang   }
21973a40ed3dSBarry Smith   PetscFunctionReturn(0);
2198a871dcd8SBarry Smith }
2199a871dcd8SBarry Smith 
22004a2ae208SSatish Balay #undef __FUNCT__
22014a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2202f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2203f0b747eeSBarry Smith {
2204f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2205f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2206efee365bSSatish Balay   PetscErrorCode ierr;
22070805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
22083a40ed3dSBarry Smith 
22093a40ed3dSBarry Smith   PetscFunctionBegin;
2210f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2211efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
22120847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
22133a40ed3dSBarry Smith   PetscFunctionReturn(0);
2214f0b747eeSBarry Smith }
2215f0b747eeSBarry Smith 
22164a2ae208SSatish Balay #undef __FUNCT__
22174a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
221897f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2219cddf8d76SBarry Smith {
2220dfbe8321SBarry Smith   PetscErrorCode ierr;
222197f1f81fSBarry Smith   PetscInt       i;
2222cddf8d76SBarry Smith 
22233a40ed3dSBarry Smith   PetscFunctionBegin;
2224cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2225b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2226cddf8d76SBarry Smith   }
2227cddf8d76SBarry Smith 
2228cddf8d76SBarry Smith   for (i=0; i<n; i++) {
22296a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2230cddf8d76SBarry Smith   }
22313a40ed3dSBarry Smith   PetscFunctionReturn(0);
2232cddf8d76SBarry Smith }
2233cddf8d76SBarry Smith 
22344a2ae208SSatish Balay #undef __FUNCT__
22354a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
223697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
22374dcbc457SBarry Smith {
2238e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
22396849ba73SBarry Smith   PetscErrorCode ierr;
22405d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
22415d0c19d7SBarry Smith   const PetscInt *idx;
224297f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2243f1af5d2fSBarry Smith   PetscBT        table;
2244bbd702dbSSatish Balay 
22453a40ed3dSBarry Smith   PetscFunctionBegin;
2246d0f46423SBarry Smith   m     = A->rmap->n;
2247e4d965acSSatish Balay   ai    = a->i;
2248bfeeae90SHong Zhang   aj    = a->j;
22498a047759SSatish Balay 
2250e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
225106763907SSatish Balay 
225297f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
225353b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
225406763907SSatish Balay 
2255e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2256b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2257e4d965acSSatish Balay     isz  = 0;
22586831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2259e4d965acSSatish Balay 
2260e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
22614dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2262b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2263e4d965acSSatish Balay 
2264dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2265e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2266f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
22674dcbc457SBarry Smith     }
226806763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
22696bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2270e4d965acSSatish Balay 
227104a348a9SBarry Smith     k = 0;
227204a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
227304a348a9SBarry Smith       n = isz;
227406763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2275e4d965acSSatish Balay         row   = nidx[k];
2276e4d965acSSatish Balay         start = ai[row];
2277e4d965acSSatish Balay         end   = ai[row+1];
227804a348a9SBarry Smith         for (l = start; l<end ; l++){
2279efb16452SHong Zhang           val = aj[l] ;
2280f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2281e4d965acSSatish Balay         }
2282e4d965acSSatish Balay       }
2283e4d965acSSatish Balay     }
228470b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2285e4d965acSSatish Balay   }
228694bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2287606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
22883a40ed3dSBarry Smith   PetscFunctionReturn(0);
22894dcbc457SBarry Smith }
229017ab2063SBarry Smith 
22910513a670SBarry Smith /* -------------------------------------------------------------- */
22924a2ae208SSatish Balay #undef __FUNCT__
22934a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2294dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
22950513a670SBarry Smith {
22960513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
22976849ba73SBarry Smith   PetscErrorCode ierr;
22983b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
22995d0c19d7SBarry Smith   const PetscInt *row,*col;
23005d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
230156cd22aeSBarry Smith   IS             icolp,irowp;
23023b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
23033b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
23040513a670SBarry Smith 
23053a40ed3dSBarry Smith   PetscFunctionBegin;
23064c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
230756cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
23084c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
230956cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
23100513a670SBarry Smith 
23110513a670SBarry Smith   /* determine lengths of permuted rows */
231297f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
23130513a670SBarry Smith   for (i=0; i<m; i++) {
23140513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
23150513a670SBarry Smith   }
23167adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2317f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2318a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
23197adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2320ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2321606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
23220513a670SBarry Smith 
232397f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
23240513a670SBarry Smith   for (i=0; i<m; i++) {
232532ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
23260513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2327cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
232832ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
23290513a670SBarry Smith   }
2330606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
23313c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
23320513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23330513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
233456cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
233556cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
23366bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
23376bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
23383a40ed3dSBarry Smith   PetscFunctionReturn(0);
23390513a670SBarry Smith }
23400513a670SBarry Smith 
23414a2ae208SSatish Balay #undef __FUNCT__
23424a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2343dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2344cb5b572fSBarry Smith {
2345dfbe8321SBarry Smith   PetscErrorCode ierr;
2346cb5b572fSBarry Smith 
2347cb5b572fSBarry Smith   PetscFunctionBegin;
234833f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
234933f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2350be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2351be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2352be6bf707SBarry Smith 
2353700c5bfcSBarry 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");
2354d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2355cb5b572fSBarry Smith   } else {
2356cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2357cb5b572fSBarry Smith   }
2358cb5b572fSBarry Smith   PetscFunctionReturn(0);
2359cb5b572fSBarry Smith }
2360cb5b572fSBarry Smith 
23614a2ae208SSatish Balay #undef __FUNCT__
23624994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
23634994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2364273d9f13SBarry Smith {
2365dfbe8321SBarry Smith   PetscErrorCode ierr;
2366273d9f13SBarry Smith 
2367273d9f13SBarry Smith   PetscFunctionBegin;
2368ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2369273d9f13SBarry Smith   PetscFunctionReturn(0);
2370273d9f13SBarry Smith }
2371273d9f13SBarry Smith 
23724a2ae208SSatish Balay #undef __FUNCT__
23734a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
2374a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[])
23756c0721eeSBarry Smith {
23766c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
23776c0721eeSBarry Smith   PetscFunctionBegin;
23786c0721eeSBarry Smith   *array = a->a;
23796c0721eeSBarry Smith   PetscFunctionReturn(0);
23806c0721eeSBarry Smith }
23816c0721eeSBarry Smith 
23824a2ae208SSatish Balay #undef __FUNCT__
23834a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
2384dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
23856c0721eeSBarry Smith {
23866c0721eeSBarry Smith   PetscFunctionBegin;
23876c0721eeSBarry Smith   PetscFunctionReturn(0);
23886c0721eeSBarry Smith }
2389273d9f13SBarry Smith 
2390ee4f033dSBarry Smith #undef __FUNCT__
2391ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2392dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2393ee4f033dSBarry Smith {
23946849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
23956849ba73SBarry Smith   PetscErrorCode ierr;
239697f1f81fSBarry Smith   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
2397efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
239887828ca2SBarry Smith   PetscScalar    *vscale_array;
2399ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2400ee4f033dSBarry Smith   Vec            w1,w2,w3;
2401ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2402ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2403ee4f033dSBarry Smith 
2404ee4f033dSBarry Smith   PetscFunctionBegin;
2405ee4f033dSBarry Smith   if (!coloring->w1) {
2406ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
240752e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2408ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
240952e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2410ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
241152e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2412ee4f033dSBarry Smith   }
2413ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2414ee4f033dSBarry Smith 
2415ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2416acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2417ee4f033dSBarry Smith   if (flg) {
2418ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2419ee4f033dSBarry Smith   } else {
2420ace3abfcSBarry Smith     PetscBool  assembled;
24210b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
24220b9b6f31SBarry Smith     if (assembled) {
2423ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2424ee4f033dSBarry Smith     }
24250b9b6f31SBarry Smith   }
2426ee4f033dSBarry Smith 
2427ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2428ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2429ee4f033dSBarry Smith 
2430ee4f033dSBarry Smith   /*
243198bf7241SBarry Smith        This is a horrible, horrible, hack.
2432ee4f033dSBarry Smith   */
2433ee4f033dSBarry Smith   if (coloring->F) {
2434ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
2435ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
2436ee4f033dSBarry Smith     if (m1 != m2) {
2437ee4f033dSBarry Smith       coloring->F = 0;
2438ee4f033dSBarry Smith     }
2439ee4f033dSBarry Smith   }
2440ee4f033dSBarry Smith 
2441ee4f033dSBarry Smith   if (coloring->F) {
2442ee4f033dSBarry Smith     w1          = coloring->F;
2443ee4f033dSBarry Smith     coloring->F = 0;
2444ee4f033dSBarry Smith   } else {
244566f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2446ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
244766f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2448ee4f033dSBarry Smith   }
2449ee4f033dSBarry Smith 
2450ee4f033dSBarry Smith   /*
2451ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2452ee4f033dSBarry Smith   */
24531ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
24541ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2455ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2456ee4f033dSBarry Smith     /*
2457ee4f033dSBarry Smith        Loop over each column associated with color adding the
2458ee4f033dSBarry Smith        perturbation to the vector w3.
2459ee4f033dSBarry Smith     */
2460ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2461ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2462ee4f033dSBarry Smith       dx  = xx[col];
2463ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2464ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2465ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2466ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2467ee4f033dSBarry Smith #else
2468ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2469ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2470ee4f033dSBarry Smith #endif
2471ee4f033dSBarry Smith       dx                *= epsilon;
2472ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2473ee4f033dSBarry Smith     }
2474ee4f033dSBarry Smith   }
24751ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2476ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2477ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2478ee4f033dSBarry Smith 
2479ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2480ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2481ee4f033dSBarry Smith 
2482ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2483ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2484ee4f033dSBarry Smith 
24851ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2486ee4f033dSBarry Smith   /*
2487ee4f033dSBarry Smith       Loop over each color
2488ee4f033dSBarry Smith   */
2489ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
249049b058dcSBarry Smith     coloring->currentcolor = k;
2491ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
24921ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2493ee4f033dSBarry Smith     /*
2494ee4f033dSBarry Smith        Loop over each column associated with color adding the
2495ee4f033dSBarry Smith        perturbation to the vector w3.
2496ee4f033dSBarry Smith     */
2497ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2498ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2499ee4f033dSBarry Smith       dx  = xx[col];
25005b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2501ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2502ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2503ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2504ee4f033dSBarry Smith #else
2505ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2506ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2507ee4f033dSBarry Smith #endif
2508ee4f033dSBarry Smith       dx            *= epsilon;
2509e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2510ee4f033dSBarry Smith       w3_array[col] += dx;
2511ee4f033dSBarry Smith     }
25121ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2513ee4f033dSBarry Smith 
2514ee4f033dSBarry Smith     /*
2515ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2516ee4f033dSBarry Smith     */
2517ee4f033dSBarry Smith 
251866f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2519ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
252066f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2521efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2522ee4f033dSBarry Smith 
2523ee4f033dSBarry Smith     /*
2524ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2525ee4f033dSBarry Smith     */
25261ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2527ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2528ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2529ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2530ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2531ee4f033dSBarry Smith       srow   = row + start;
2532ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2533ee4f033dSBarry Smith     }
25341ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2535ee4f033dSBarry Smith   }
253649b058dcSBarry Smith   coloring->currentcolor = k;
25371ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
25381ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2539ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2540ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2541ee4f033dSBarry Smith   PetscFunctionReturn(0);
2542ee4f033dSBarry Smith }
2543ee4f033dSBarry Smith 
25448229c054SShri Abhyankar /*
25458229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
25468229c054SShri Abhyankar    have different nonzero structure.
25478229c054SShri Abhyankar */
2548ac90fabeSBarry Smith #undef __FUNCT__
25498229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
25508229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2551ec7775f6SShri Abhyankar {
25528229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2553ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2554ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2555ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2556ec7775f6SShri Abhyankar 
2557ec7775f6SShri Abhyankar   PetscFunctionBegin;
2558ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2559ec7775f6SShri Abhyankar   for(i=0; i<m; i++) {
25608af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
25618af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
25628af7cee1SJed Brown     nnz[i] = 0;
25638af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
25648af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
25658af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
25668af7cee1SJed Brown       nnz[i]++;
25678af7cee1SJed Brown     }
25688af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2569ec7775f6SShri Abhyankar   }
2570ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2571ec7775f6SShri Abhyankar }
2572ec7775f6SShri Abhyankar 
2573ec7775f6SShri Abhyankar #undef __FUNCT__
2574ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2575f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2576ac90fabeSBarry Smith {
2577dfbe8321SBarry Smith   PetscErrorCode ierr;
257897f1f81fSBarry Smith   PetscInt       i;
2579ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
25800805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2581ac90fabeSBarry Smith 
2582ac90fabeSBarry Smith   PetscFunctionBegin;
2583ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2584f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2585f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
25860847f33cSJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2587c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2588a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2589a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
25906bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2591a30b2313SHong Zhang     }
2592a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2593d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2594a30b2313SHong Zhang       y->XtoY = X;
2595407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2596c537a176SHong Zhang     }
2597f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
25988644d96aSMark F. Adams     ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/(y->nz+1));CHKERRQ(ierr);
2599ac90fabeSBarry Smith   } else {
26008229c054SShri Abhyankar     Mat      B;
26018229c054SShri Abhyankar     PetscInt *nnz;
260216b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2603ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2604bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
26054aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2606a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2607176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
26088229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2609ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2610ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2611ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
26128229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2613ac90fabeSBarry Smith   }
2614ac90fabeSBarry Smith   PetscFunctionReturn(0);
2615ac90fabeSBarry Smith }
2616ac90fabeSBarry Smith 
2617521d7252SBarry Smith #undef __FUNCT__
2618354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
26197087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2620354c94deSBarry Smith {
2621354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2622354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2623354c94deSBarry Smith   PetscInt    i,nz;
2624354c94deSBarry Smith   PetscScalar *a;
2625354c94deSBarry Smith 
2626354c94deSBarry Smith   PetscFunctionBegin;
2627354c94deSBarry Smith   nz = aij->nz;
2628354c94deSBarry Smith   a  = aij->a;
2629354c94deSBarry Smith   for (i=0; i<nz; i++) {
2630354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2631354c94deSBarry Smith   }
2632354c94deSBarry Smith #else
2633354c94deSBarry Smith   PetscFunctionBegin;
2634354c94deSBarry Smith #endif
2635354c94deSBarry Smith   PetscFunctionReturn(0);
2636354c94deSBarry Smith }
2637354c94deSBarry Smith 
2638e34fafa9SBarry Smith #undef __FUNCT__
2639985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2640985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2641e34fafa9SBarry Smith {
2642e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2643e34fafa9SBarry Smith   PetscErrorCode ierr;
2644d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2645e34fafa9SBarry Smith   PetscReal      atmp;
2646985db425SBarry Smith   PetscScalar    *x;
2647e34fafa9SBarry Smith   MatScalar      *aa;
2648e34fafa9SBarry Smith 
2649e34fafa9SBarry Smith   PetscFunctionBegin;
2650e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2651e34fafa9SBarry Smith   aa   = a->a;
2652e34fafa9SBarry Smith   ai   = a->i;
2653e34fafa9SBarry Smith   aj   = a->j;
2654e34fafa9SBarry Smith 
2655985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2656e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2657e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2658e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2659e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2660e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
26619189402eSHong Zhang     x[i] = 0.0;
2662e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2663985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2664985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2665985db425SBarry Smith       aa++; aj++;
2666985db425SBarry Smith     }
2667985db425SBarry Smith   }
2668985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2669985db425SBarry Smith   PetscFunctionReturn(0);
2670985db425SBarry Smith }
2671985db425SBarry Smith 
2672985db425SBarry Smith #undef __FUNCT__
2673985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2674985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2675985db425SBarry Smith {
2676985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2677985db425SBarry Smith   PetscErrorCode ierr;
2678d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2679985db425SBarry Smith   PetscScalar    *x;
2680985db425SBarry Smith   MatScalar      *aa;
2681985db425SBarry Smith 
2682985db425SBarry Smith   PetscFunctionBegin;
2683e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2684985db425SBarry Smith   aa   = a->a;
2685985db425SBarry Smith   ai   = a->i;
2686985db425SBarry Smith   aj   = a->j;
2687985db425SBarry Smith 
2688985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2689985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2690985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2691e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2692985db425SBarry Smith   for (i=0; i<m; i++) {
2693985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2694d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2695985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2696985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2697985db425SBarry Smith       x[i] = 0.0;
2698985db425SBarry Smith       if (idx) {
2699985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2700985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2701985db425SBarry Smith           if (aj[j] > j) {
2702985db425SBarry Smith             idx[i] = j;
2703985db425SBarry Smith             break;
2704985db425SBarry Smith           }
2705985db425SBarry Smith         }
2706985db425SBarry Smith       }
2707985db425SBarry Smith     }
2708985db425SBarry Smith     for (j=0; j<ncols; j++){
2709985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2710985db425SBarry Smith       aa++; aj++;
2711985db425SBarry Smith     }
2712985db425SBarry Smith   }
2713985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2714985db425SBarry Smith   PetscFunctionReturn(0);
2715985db425SBarry Smith }
2716985db425SBarry Smith 
2717985db425SBarry Smith #undef __FUNCT__
2718c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2719c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2720c87e5d42SMatthew Knepley {
2721c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2722c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2723c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2724c87e5d42SMatthew Knepley   PetscReal      atmp;
2725c87e5d42SMatthew Knepley   PetscScalar    *x;
2726c87e5d42SMatthew Knepley   MatScalar      *aa;
2727c87e5d42SMatthew Knepley 
2728c87e5d42SMatthew Knepley   PetscFunctionBegin;
2729e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2730c87e5d42SMatthew Knepley   aa   = a->a;
2731c87e5d42SMatthew Knepley   ai   = a->i;
2732c87e5d42SMatthew Knepley   aj   = a->j;
2733c87e5d42SMatthew Knepley 
2734c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2735c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2736c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
27373bb78c5cSMatthew G Knepley   if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %d vs. %d rows", A->rmap->n, n);
2738c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2739c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2740289a08f5SMatthew Knepley     if (ncols) {
2741289a08f5SMatthew Knepley       /* Get first nonzero */
2742289a08f5SMatthew Knepley       for(j = 0; j < ncols; j++) {
2743289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2744289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2745289a08f5SMatthew Knepley       }
274612431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2747289a08f5SMatthew Knepley     } else {
2748289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2749289a08f5SMatthew Knepley     }
2750c87e5d42SMatthew Knepley     for(j = 0; j < ncols; j++) {
2751c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2752289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2753c87e5d42SMatthew Knepley       aa++; aj++;
2754c87e5d42SMatthew Knepley     }
2755c87e5d42SMatthew Knepley   }
2756c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2757c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2758c87e5d42SMatthew Knepley }
2759c87e5d42SMatthew Knepley 
2760c87e5d42SMatthew Knepley #undef __FUNCT__
2761985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2762985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2763985db425SBarry Smith {
2764985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2765985db425SBarry Smith   PetscErrorCode ierr;
2766d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2767985db425SBarry Smith   PetscScalar    *x;
2768985db425SBarry Smith   MatScalar      *aa;
2769985db425SBarry Smith 
2770985db425SBarry Smith   PetscFunctionBegin;
2771e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2772985db425SBarry Smith   aa   = a->a;
2773985db425SBarry Smith   ai   = a->i;
2774985db425SBarry Smith   aj   = a->j;
2775985db425SBarry Smith 
2776985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2777985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2778985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2779e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2780985db425SBarry Smith   for (i=0; i<m; i++) {
2781985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2782d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2783985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2784985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2785985db425SBarry Smith       x[i] = 0.0;
2786985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2787985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2788985db425SBarry Smith         for (j=0;j<ncols;j++) {
2789985db425SBarry Smith           if (aj[j] > j) {
2790985db425SBarry Smith             idx[i] = j;
2791985db425SBarry Smith             break;
2792985db425SBarry Smith           }
2793985db425SBarry Smith         }
2794985db425SBarry Smith       }
2795985db425SBarry Smith     }
2796985db425SBarry Smith     for (j=0; j<ncols; j++){
2797985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2798985db425SBarry Smith       aa++; aj++;
2799e34fafa9SBarry Smith     }
2800e34fafa9SBarry Smith   }
2801e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2802e34fafa9SBarry Smith   PetscFunctionReturn(0);
2803e34fafa9SBarry Smith }
2804bbead8a2SBarry Smith 
2805bbead8a2SBarry Smith #include <petscblaslapack.h>
2806bbead8a2SBarry Smith #include <../src/mat/blockinvert.h>
2807bbead8a2SBarry Smith 
2808bbead8a2SBarry Smith #undef __FUNCT__
2809bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2810713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2811bbead8a2SBarry Smith {
2812bbead8a2SBarry Smith   Mat_SeqAIJ    *a = (Mat_SeqAIJ*) A->data;
2813bbead8a2SBarry Smith   PetscErrorCode ierr;
281434fc4b71SJed Brown   PetscInt       i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2815bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2816bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2817bbead8a2SBarry Smith 
2818bbead8a2SBarry Smith   PetscFunctionBegin;
28194a0d0026SBarry Smith   if (a->ibdiagvalid) {
28204a0d0026SBarry Smith     if (values) *values = a->ibdiag;
28214a0d0026SBarry Smith     PetscFunctionReturn(0);
28224a0d0026SBarry Smith   }
2823bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2824bbead8a2SBarry Smith   if (!a->ibdiag) {
2825bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr);
2826bbead8a2SBarry Smith     ierr = PetscLogObjectMemory(A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2827bbead8a2SBarry Smith   }
2828bbead8a2SBarry Smith   diag    = a->ibdiag;
2829bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2830bbead8a2SBarry Smith   /* factor and invert each block */
2831bbead8a2SBarry Smith   switch (bs){
2832bbead8a2SBarry Smith     case 1:
2833bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2834bbead8a2SBarry Smith         ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2835bbead8a2SBarry Smith         diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2836bbead8a2SBarry Smith       }
2837bbead8a2SBarry Smith       break;
2838bbead8a2SBarry Smith     case 2:
2839bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2840bbead8a2SBarry Smith         ij[0] = 2*i; ij[1] = 2*i + 1;
2841bbead8a2SBarry Smith         ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
284296b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
284396b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2844bbead8a2SBarry Smith 	diag  += 4;
2845bbead8a2SBarry Smith       }
2846bbead8a2SBarry Smith       break;
2847bbead8a2SBarry Smith     case 3:
2848bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2849bbead8a2SBarry Smith         ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2850bbead8a2SBarry Smith         ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
285196b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
285296b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2853bbead8a2SBarry Smith 	diag    += 9;
2854bbead8a2SBarry Smith       }
2855bbead8a2SBarry Smith       break;
2856bbead8a2SBarry Smith     case 4:
2857bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2858bbead8a2SBarry Smith         ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2859bbead8a2SBarry Smith         ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
286096b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
286196b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2862bbead8a2SBarry Smith 	diag  += 16;
2863bbead8a2SBarry Smith       }
2864bbead8a2SBarry Smith       break;
2865bbead8a2SBarry Smith     case 5:
2866bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2867bbead8a2SBarry Smith         ij[0] = 5*i; ij[1] = 5*i + 1; ij[2] = 5*i + 2; ij[3] = 5*i + 3; ij[4] = 5*i + 4;
2868bbead8a2SBarry Smith         ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
286996b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
287096b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2871bbead8a2SBarry Smith 	diag  += 25;
2872bbead8a2SBarry Smith       }
2873bbead8a2SBarry Smith       break;
2874bbead8a2SBarry Smith     case 6:
2875bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2876bbead8a2SBarry Smith         ij[0] = 6*i; ij[1] = 6*i + 1; ij[2] = 6*i + 2; ij[3] = 6*i + 3; ij[4] = 6*i + 4; ij[5] = 6*i + 5;
2877bbead8a2SBarry Smith         ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
287896b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
287996b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2880bbead8a2SBarry Smith 	diag  += 36;
2881bbead8a2SBarry Smith       }
2882bbead8a2SBarry Smith       break;
2883bbead8a2SBarry Smith     case 7:
2884bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2885bbead8a2SBarry Smith         ij[0] = 7*i; ij[1] = 7*i + 1; ij[2] = 7*i + 2; ij[3] = 7*i + 3; ij[4] = 7*i + 4; ij[5] = 7*i + 5; ij[5] = 7*i + 6;
2886bbead8a2SBarry Smith         ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
288796b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
288896b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
2889bbead8a2SBarry Smith 	diag  += 49;
2890bbead8a2SBarry Smith       }
2891bbead8a2SBarry Smith       break;
2892bbead8a2SBarry Smith     default:
2893bbead8a2SBarry Smith       ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr);
2894bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2895bbead8a2SBarry Smith         for (j=0; j<bs; j++) {
2896bbead8a2SBarry Smith           IJ[j] = bs*i + j;
2897bbead8a2SBarry Smith         }
2898bbead8a2SBarry Smith         ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
289996b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
290096b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
2901bbead8a2SBarry Smith 	diag  += bs2;
2902bbead8a2SBarry Smith       }
2903bbead8a2SBarry Smith       ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
2904bbead8a2SBarry Smith   }
2905bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
2906bbead8a2SBarry Smith   PetscFunctionReturn(0);
2907bbead8a2SBarry Smith }
2908bbead8a2SBarry Smith 
29097087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
2910682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
29110a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2912cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2913cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2914cb5b572fSBarry Smith        MatMult_SeqAIJ,
291597304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
29167c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
29177c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2918db4efbfdSBarry Smith        0,
2919db4efbfdSBarry Smith        0,
2920db4efbfdSBarry Smith        0,
2921db4efbfdSBarry Smith /*10*/ 0,
2922cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2923cb5b572fSBarry Smith        0,
292441f059aeSBarry Smith        MatSOR_SeqAIJ,
292517ab2063SBarry Smith        MatTranspose_SeqAIJ,
292697304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
2927cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2928cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2929cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2930cb5b572fSBarry Smith        MatNorm_SeqAIJ,
293197304618SKris Buschelman /*20*/ 0,
2932cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
2933cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2934cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2935d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
2936db4efbfdSBarry Smith        0,
2937db4efbfdSBarry Smith        0,
2938db4efbfdSBarry Smith        0,
2939db4efbfdSBarry Smith        0,
29404994cf47SJed Brown /*29*/ MatSetUp_SeqAIJ,
2941db4efbfdSBarry Smith        0,
2942db4efbfdSBarry Smith        0,
29436c0721eeSBarry Smith        MatGetArray_SeqAIJ,
29446c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2945d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
2946cb5b572fSBarry Smith        0,
2947cb5b572fSBarry Smith        0,
2948cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2949cb5b572fSBarry Smith        0,
2950d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
2951cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2952cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2953cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2954cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2955d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
2956cb5b572fSBarry Smith        MatScale_SeqAIJ,
2957cb5b572fSBarry Smith        0,
295879299369SBarry Smith        MatDiagonalSet_SeqAIJ,
29596e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
2960f73d5cc4SBarry Smith /*49*/ 0,
29613b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
29623b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
29633b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2964a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2965d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
2966b9617806SBarry Smith        0,
29670513a670SBarry Smith        0,
2968cda55fadSBarry Smith        MatPermute_SeqAIJ,
2969cda55fadSBarry Smith        0,
2970d519adbfSMatthew Knepley /*59*/ 0,
2971b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2972b9b97703SBarry Smith        MatView_SeqAIJ,
2973357abbc8SBarry Smith        0,
2974ee4f033dSBarry Smith        0,
2975d519adbfSMatthew Knepley /*64*/ 0,
2976ee4f033dSBarry Smith        0,
2977ee4f033dSBarry Smith        0,
2978ee4f033dSBarry Smith        0,
2979ee4f033dSBarry Smith        0,
2980d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
2981c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
2982ee4f033dSBarry Smith        0,
2983ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2984dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
2985ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2986dcf5cc72SBarry Smith #else
2987dcf5cc72SBarry Smith        0,
2988dcf5cc72SBarry Smith #endif
2989d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
29903acb8795SBarry Smith        MatFDColoringApply_AIJ,
299197304618SKris Buschelman        0,
299297304618SKris Buschelman        0,
299397304618SKris Buschelman        0,
29946ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
299597304618SKris Buschelman        0,
299697304618SKris Buschelman        0,
299797304618SKris Buschelman        0,
2998bc011b1eSHong Zhang        MatLoad_SeqAIJ,
2999d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
30001cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
30016284ec50SHong Zhang        0,
30026284ec50SHong Zhang        0,
3003bc011b1eSHong Zhang        0,
3004d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
300526be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
300626be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
3007d439da42SKris Buschelman        MatPtAP_Basic,
30087ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
3009d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
30106fc122caSHong Zhang        MatMatTransposeMult_SeqAIJ_SeqAIJ,
30116fc122caSHong Zhang        MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
30126fc122caSHong Zhang        MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
30137ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
3014d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
3015609c6c4dSKris Buschelman        0,
3016609c6c4dSKris Buschelman        0,
301787d4246cSBarry Smith        MatConjugate_SeqAIJ,
301887d4246cSBarry Smith        0,
3019d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
302099cafbc1SBarry Smith        MatRealPart_SeqAIJ,
3021f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
3022f5edf698SHong Zhang        0,
30232bebee5dSHong Zhang        0,
3024cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
3025985db425SBarry Smith        0,
30262af78befSBarry Smith        MatGetRowMin_SeqAIJ,
30272af78befSBarry Smith        0,
3028599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
3029d519adbfSMatthew Knepley /*114*/0,
3030599ef60dSHong Zhang        0,
30313c2a7987SHong Zhang        0,
3032fe97e370SBarry Smith        0,
3033fbdbba38SShri Abhyankar        0,
3034fbdbba38SShri Abhyankar /*119*/0,
3035fbdbba38SShri Abhyankar        0,
3036fbdbba38SShri Abhyankar        0,
303782d44351SHong Zhang        0,
3038b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
30390716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ,
3040bbead8a2SBarry Smith        MatGetColumnNorms_SeqAIJ,
304137868618SMatthew G Knepley        MatInvertBlockDiagonal_SeqAIJ,
304237868618SMatthew G Knepley        0,
304337868618SMatthew G Knepley        0,
30445df89d91SHong Zhang /*129*/0,
304575648e8dSHong Zhang        MatTransposeMatMult_SeqAIJ_SeqAIJ,
304675648e8dSHong Zhang        MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
304775648e8dSHong Zhang        MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3048b9af6bddSHong Zhang        MatTransposeColoringCreate_SeqAIJ,
3049b9af6bddSHong Zhang /*134*/MatTransColoringApplySpToDen_SeqAIJ,
30502b8ad9a3SHong Zhang        MatTransColoringApplyDenToSp_SeqAIJ,
30512b8ad9a3SHong Zhang        MatRARt_SeqAIJ_SeqAIJ,
30522b8ad9a3SHong Zhang        MatRARtSymbolic_SeqAIJ_SeqAIJ,
30532b8ad9a3SHong Zhang        MatRARtNumeric_SeqAIJ_SeqAIJ
30549e29f15eSvictorle };
305517ab2063SBarry Smith 
3056fb2e594dSBarry Smith EXTERN_C_BEGIN
30574a2ae208SSatish Balay #undef __FUNCT__
30584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
30597087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3060bef8e0ddSBarry Smith {
3061bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
306297f1f81fSBarry Smith   PetscInt   i,nz,n;
3063bef8e0ddSBarry Smith 
3064bef8e0ddSBarry Smith   PetscFunctionBegin;
3065bef8e0ddSBarry Smith 
3066bef8e0ddSBarry Smith   nz = aij->maxnz;
3067d0f46423SBarry Smith   n  = mat->rmap->n;
3068bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3069bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3070bef8e0ddSBarry Smith   }
3071bef8e0ddSBarry Smith   aij->nz = nz;
3072bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3073bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3074bef8e0ddSBarry Smith   }
3075bef8e0ddSBarry Smith 
3076bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3077bef8e0ddSBarry Smith }
3078fb2e594dSBarry Smith EXTERN_C_END
3079bef8e0ddSBarry Smith 
30804a2ae208SSatish Balay #undef __FUNCT__
30814a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3082bef8e0ddSBarry Smith /*@
3083bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3084bef8e0ddSBarry Smith        in the matrix.
3085bef8e0ddSBarry Smith 
3086bef8e0ddSBarry Smith   Input Parameters:
3087bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3088bef8e0ddSBarry Smith -  indices - the column indices
3089bef8e0ddSBarry Smith 
309015091d37SBarry Smith   Level: advanced
309115091d37SBarry Smith 
3092bef8e0ddSBarry Smith   Notes:
3093bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3094bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3095bef8e0ddSBarry Smith   of the MatSetValues() operation.
3096bef8e0ddSBarry Smith 
3097bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3098d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3099bef8e0ddSBarry Smith 
3100bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3101bef8e0ddSBarry Smith 
3102b9617806SBarry Smith     The indices should start with zero, not one.
3103b9617806SBarry Smith 
3104bef8e0ddSBarry Smith @*/
31057087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3106bef8e0ddSBarry Smith {
31074ac538c5SBarry Smith   PetscErrorCode ierr;
3108bef8e0ddSBarry Smith 
3109bef8e0ddSBarry Smith   PetscFunctionBegin;
31100700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
31114482741eSBarry Smith   PetscValidPointer(indices,2);
31124ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
3113bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3114bef8e0ddSBarry Smith }
3115bef8e0ddSBarry Smith 
3116be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3117be6bf707SBarry Smith 
3118fb2e594dSBarry Smith EXTERN_C_BEGIN
31194a2ae208SSatish Balay #undef __FUNCT__
31204a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
31217087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3122be6bf707SBarry Smith {
3123be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
31246849ba73SBarry Smith   PetscErrorCode ierr;
3125d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3126be6bf707SBarry Smith 
3127be6bf707SBarry Smith   PetscFunctionBegin;
3128be6bf707SBarry Smith   if (aij->nonew != 1) {
3129e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3130be6bf707SBarry Smith   }
3131be6bf707SBarry Smith 
3132be6bf707SBarry Smith   /* allocate space for values if not already there */
3133be6bf707SBarry Smith   if (!aij->saved_values) {
313487828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
31359518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3136be6bf707SBarry Smith   }
3137be6bf707SBarry Smith 
3138be6bf707SBarry Smith   /* copy values over */
313987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3140be6bf707SBarry Smith   PetscFunctionReturn(0);
3141be6bf707SBarry Smith }
3142fb2e594dSBarry Smith EXTERN_C_END
3143be6bf707SBarry Smith 
31444a2ae208SSatish Balay #undef __FUNCT__
3145b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3146be6bf707SBarry Smith /*@
3147be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3148be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3149be6bf707SBarry Smith        nonlinear portion.
3150be6bf707SBarry Smith 
3151be6bf707SBarry Smith    Collect on Mat
3152be6bf707SBarry Smith 
3153be6bf707SBarry Smith   Input Parameters:
31540e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3155be6bf707SBarry Smith 
315615091d37SBarry Smith   Level: advanced
315715091d37SBarry Smith 
3158be6bf707SBarry Smith   Common Usage, with SNESSolve():
3159be6bf707SBarry Smith $    Create Jacobian matrix
3160be6bf707SBarry Smith $    Set linear terms into matrix
3161be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3162be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3163be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3164512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3165be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3166be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3167be6bf707SBarry Smith $    In your Jacobian routine
3168be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3169be6bf707SBarry Smith $      Set nonlinear terms in matrix
3170be6bf707SBarry Smith 
3171be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3172be6bf707SBarry Smith $    // build linear portion of Jacobian
3173512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3174be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3175be6bf707SBarry Smith $    loop over nonlinear iterations
3176be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3177be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3178be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3179be6bf707SBarry Smith $       Solve linear system with Jacobian
3180be6bf707SBarry Smith $    endloop
3181be6bf707SBarry Smith 
3182be6bf707SBarry Smith   Notes:
3183be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3184512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3185be6bf707SBarry Smith     calling this routine.
3186be6bf707SBarry Smith 
31870c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
31880c468ba9SBarry Smith     and does not allocated additional space.
31890c468ba9SBarry Smith 
3190be6bf707SBarry Smith .seealso: MatRetrieveValues()
3191be6bf707SBarry Smith 
3192be6bf707SBarry Smith @*/
31937087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3194be6bf707SBarry Smith {
31954ac538c5SBarry Smith   PetscErrorCode ierr;
3196be6bf707SBarry Smith 
3197be6bf707SBarry Smith   PetscFunctionBegin;
31980700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3199e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3200e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32014ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3202be6bf707SBarry Smith   PetscFunctionReturn(0);
3203be6bf707SBarry Smith }
3204be6bf707SBarry Smith 
3205fb2e594dSBarry Smith EXTERN_C_BEGIN
32064a2ae208SSatish Balay #undef __FUNCT__
32074a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
32087087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3209be6bf707SBarry Smith {
3210be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
32116849ba73SBarry Smith   PetscErrorCode ierr;
3212d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3213be6bf707SBarry Smith 
3214be6bf707SBarry Smith   PetscFunctionBegin;
3215be6bf707SBarry Smith   if (aij->nonew != 1) {
3216e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3217be6bf707SBarry Smith   }
3218be6bf707SBarry Smith   if (!aij->saved_values) {
3219e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3220be6bf707SBarry Smith   }
3221be6bf707SBarry Smith   /* copy values over */
322287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3223be6bf707SBarry Smith   PetscFunctionReturn(0);
3224be6bf707SBarry Smith }
3225fb2e594dSBarry Smith EXTERN_C_END
3226be6bf707SBarry Smith 
32274a2ae208SSatish Balay #undef __FUNCT__
32284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3229be6bf707SBarry Smith /*@
3230be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3231be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3232be6bf707SBarry Smith        nonlinear portion.
3233be6bf707SBarry Smith 
3234be6bf707SBarry Smith    Collect on Mat
3235be6bf707SBarry Smith 
3236be6bf707SBarry Smith   Input Parameters:
3237be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3238be6bf707SBarry Smith 
323915091d37SBarry Smith   Level: advanced
324015091d37SBarry Smith 
3241be6bf707SBarry Smith .seealso: MatStoreValues()
3242be6bf707SBarry Smith 
3243be6bf707SBarry Smith @*/
32447087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3245be6bf707SBarry Smith {
32464ac538c5SBarry Smith   PetscErrorCode ierr;
3247be6bf707SBarry Smith 
3248be6bf707SBarry Smith   PetscFunctionBegin;
32490700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3250e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3251e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32524ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3253be6bf707SBarry Smith   PetscFunctionReturn(0);
3254be6bf707SBarry Smith }
3255be6bf707SBarry Smith 
3256f83d6046SBarry Smith 
3257be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
32584a2ae208SSatish Balay #undef __FUNCT__
32594a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
326017ab2063SBarry Smith /*@C
3261682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
32620d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
32636e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
326451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
32652bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
326617ab2063SBarry Smith 
3267db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3268db81eaa0SLois Curfman McInnes 
326917ab2063SBarry Smith    Input Parameters:
3270db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
327117ab2063SBarry Smith .  m - number of rows
327217ab2063SBarry Smith .  n - number of columns
327317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
327451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
32752bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
327617ab2063SBarry Smith 
327717ab2063SBarry Smith    Output Parameter:
3278416022c9SBarry Smith .  A - the matrix
327917ab2063SBarry Smith 
3280175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3281ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3282175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3283175b88e8SBarry Smith 
3284b259b22eSLois Curfman McInnes    Notes:
328549a6f317SBarry Smith    If nnz is given then nz is ignored
328649a6f317SBarry Smith 
328717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
328817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
32890002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
329044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
329117ab2063SBarry Smith 
329217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3293a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
32943d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
32956da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
329617ab2063SBarry Smith 
3297682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
32984fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3299682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
33006c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
33016c7ebb05SLois Curfman McInnes 
33026c7ebb05SLois Curfman McInnes    Options Database Keys:
3303698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
33049db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
330517ab2063SBarry Smith 
3306027ccd11SLois Curfman McInnes    Level: intermediate
3307027ccd11SLois Curfman McInnes 
330869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
330936db0b34SBarry Smith 
331017ab2063SBarry Smith @*/
33117087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
331217ab2063SBarry Smith {
3313dfbe8321SBarry Smith   PetscErrorCode ierr;
33146945ee14SBarry Smith 
33153a40ed3dSBarry Smith   PetscFunctionBegin;
3316f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3317117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3318c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3319d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3320273d9f13SBarry Smith   PetscFunctionReturn(0);
3321273d9f13SBarry Smith }
3322273d9f13SBarry Smith 
33234a2ae208SSatish Balay #undef __FUNCT__
33244a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3325273d9f13SBarry Smith /*@C
3326273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3327273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3328273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3329273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3330273d9f13SBarry Smith 
3331273d9f13SBarry Smith    Collective on MPI_Comm
3332273d9f13SBarry Smith 
3333273d9f13SBarry Smith    Input Parameters:
3334117016b1SBarry Smith +  B - The matrix-free
3335273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3336273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3337273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3338273d9f13SBarry Smith 
3339273d9f13SBarry Smith    Notes:
334049a6f317SBarry Smith      If nnz is given then nz is ignored
334149a6f317SBarry Smith 
3342273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3343273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3344273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3345273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3346273d9f13SBarry Smith 
3347273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3348273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3349273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3350273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3351273d9f13SBarry Smith 
3352aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3353aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3354aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3355aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3356aa95bbe8SBarry Smith 
3357a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3358a96a251dSBarry Smith    entries or columns indices
3359a96a251dSBarry Smith 
3360273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3361273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3362273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3363273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3364273d9f13SBarry Smith 
3365273d9f13SBarry Smith    Options Database Keys:
3366698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3367698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3368273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3369273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3370273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3371273d9f13SBarry Smith 
3372273d9f13SBarry Smith    Level: intermediate
3373273d9f13SBarry Smith 
337469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3375273d9f13SBarry Smith 
3376273d9f13SBarry Smith @*/
33777087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3378273d9f13SBarry Smith {
33794ac538c5SBarry Smith   PetscErrorCode ierr;
3380a23d5eceSKris Buschelman 
3381a23d5eceSKris Buschelman   PetscFunctionBegin;
33826ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
33836ba663aaSJed Brown   PetscValidType(B,1);
33844ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3385a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3386a23d5eceSKris Buschelman }
3387a23d5eceSKris Buschelman 
3388a23d5eceSKris Buschelman EXTERN_C_BEGIN
3389a23d5eceSKris Buschelman #undef __FUNCT__
3390a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
33917087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3392a23d5eceSKris Buschelman {
3393273d9f13SBarry Smith   Mat_SeqAIJ     *b;
33942576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
33956849ba73SBarry Smith   PetscErrorCode ierr;
339697f1f81fSBarry Smith   PetscInt       i;
3397273d9f13SBarry Smith 
3398273d9f13SBarry Smith   PetscFunctionBegin;
33992576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3400a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3401c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3402c461c341SBarry Smith     nz             = 0;
3403c461c341SBarry Smith   }
3404c461c341SBarry Smith 
340526283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
340626283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3407899cda47SBarry Smith 
3408435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3409e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3410b73539f3SBarry Smith   if (nnz) {
3411d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3412e32f2f54SBarry 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]);
3413e32f2f54SBarry 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);
3414b73539f3SBarry Smith     }
3415b73539f3SBarry Smith   }
3416b73539f3SBarry Smith 
3417273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3418273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3419273d9f13SBarry Smith 
3420ab93d7beSBarry Smith   if (!skipallocation) {
34212ee49352SLisandro Dalcin     if (!b->imax) {
3422d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3423d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
34242ee49352SLisandro Dalcin     }
3425273d9f13SBarry Smith     if (!nnz) {
3426435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3427c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3428d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3429d0f46423SBarry Smith       nz = nz*B->rmap->n;
3430273d9f13SBarry Smith     } else {
3431273d9f13SBarry Smith       nz = 0;
3432d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3433273d9f13SBarry Smith     }
3434ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3435d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3436ab93d7beSBarry Smith 
3437273d9f13SBarry Smith     /* allocate the matrix space */
34382ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3439d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3440d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3441bfeeae90SHong Zhang     b->i[0] = 0;
3442d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
34435da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
34445da197adSKris Buschelman     }
3445273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3446e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3447e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3448c461c341SBarry Smith   } else {
3449e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3450e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3451c461c341SBarry Smith   }
3452273d9f13SBarry Smith 
3453273d9f13SBarry Smith   b->nz                = 0;
3454273d9f13SBarry Smith   b->maxnz             = nz;
3455273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
34562576faa2SJed Brown   if (realalloc) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);}
3457273d9f13SBarry Smith   PetscFunctionReturn(0);
3458273d9f13SBarry Smith }
3459a23d5eceSKris Buschelman EXTERN_C_END
3460273d9f13SBarry Smith 
3461a1661176SMatthew Knepley #undef  __FUNCT__
3462a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
346358d36128SBarry Smith /*@
3464a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3465a1661176SMatthew Knepley 
3466a1661176SMatthew Knepley    Input Parameters:
3467a1661176SMatthew Knepley +  B - the matrix
3468a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3469a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3470a1661176SMatthew Knepley -  v - optional values in the matrix
3471a1661176SMatthew Knepley 
3472a1661176SMatthew Knepley    Level: developer
3473a1661176SMatthew Knepley 
347458d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
347558d36128SBarry Smith 
3476a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3477a1661176SMatthew Knepley 
3478a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3479a1661176SMatthew Knepley @*/
3480a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3481a1661176SMatthew Knepley {
3482a1661176SMatthew Knepley   PetscErrorCode ierr;
3483a1661176SMatthew Knepley 
3484a1661176SMatthew Knepley   PetscFunctionBegin;
34850700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
34866ba663aaSJed Brown   PetscValidType(B,1);
34874ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3488a1661176SMatthew Knepley   PetscFunctionReturn(0);
3489a1661176SMatthew Knepley }
3490a1661176SMatthew Knepley 
3491a1661176SMatthew Knepley EXTERN_C_BEGIN
3492a1661176SMatthew Knepley #undef  __FUNCT__
3493a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
34947087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3495a1661176SMatthew Knepley {
3496a1661176SMatthew Knepley   PetscInt       i;
3497a1661176SMatthew Knepley   PetscInt       m,n;
3498a1661176SMatthew Knepley   PetscInt       nz;
3499a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3500a1661176SMatthew Knepley   PetscScalar    *values;
3501a1661176SMatthew Knepley   PetscErrorCode ierr;
3502a1661176SMatthew Knepley 
3503a1661176SMatthew Knepley   PetscFunctionBegin;
350465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3505779a8d59SSatish Balay 
3506779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3507779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3508779a8d59SSatish Balay 
3509779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3510a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3511a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3512b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3513a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
351465e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3515a1661176SMatthew Knepley     nnz[i] = nz;
3516a1661176SMatthew Knepley   }
3517a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3518a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3519a1661176SMatthew Knepley 
3520a1661176SMatthew Knepley   if (v) {
3521a1661176SMatthew Knepley     values = (PetscScalar*) v;
3522a1661176SMatthew Knepley   } else {
35230e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3524a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3525a1661176SMatthew Knepley   }
3526a1661176SMatthew Knepley 
3527a1661176SMatthew Knepley   for(i = 0; i < m; i++) {
3528b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3529b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3530a1661176SMatthew Knepley   }
3531a1661176SMatthew Knepley 
3532a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3533a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3534a1661176SMatthew Knepley 
3535a1661176SMatthew Knepley   if (!v) {
3536a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3537a1661176SMatthew Knepley   }
35387827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3539a1661176SMatthew Knepley   PetscFunctionReturn(0);
3540a1661176SMatthew Knepley }
3541a1661176SMatthew Knepley EXTERN_C_END
3542a1661176SMatthew Knepley 
3543c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3544b45d2f2cSJed Brown #include <petsc-private/petscaxpy.h>
3545170fe5c8SBarry Smith 
3546170fe5c8SBarry Smith #undef __FUNCT__
3547170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3548170fe5c8SBarry Smith /*
3549170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3550170fe5c8SBarry Smith 
3551170fe5c8SBarry Smith                n                       p                          p
3552170fe5c8SBarry Smith         (              )       (              )         (                  )
3553170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3554170fe5c8SBarry Smith         (              )       (              )         (                  )
3555170fe5c8SBarry Smith 
3556170fe5c8SBarry Smith */
3557170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3558170fe5c8SBarry Smith {
3559170fe5c8SBarry Smith   PetscErrorCode     ierr;
3560170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3561170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3562170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
35631de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3564170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3565170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3566170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3567170fe5c8SBarry Smith 
3568170fe5c8SBarry Smith   PetscFunctionBegin;
3569d0f46423SBarry Smith   m = A->rmap->n;
3570d0f46423SBarry Smith   n = A->cmap->n;
3571d0f46423SBarry Smith   p = B->cmap->n;
3572170fe5c8SBarry Smith   a = sub_a->v;
3573170fe5c8SBarry Smith   b = sub_b->a;
3574170fe5c8SBarry Smith   c = sub_c->v;
3575170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3576170fe5c8SBarry Smith 
3577170fe5c8SBarry Smith   ii  = sub_b->i;
3578170fe5c8SBarry Smith   idx = sub_b->j;
3579170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3580170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3581170fe5c8SBarry Smith     while (q-->0) {
3582170fe5c8SBarry Smith       c_q = c + m*(*idx);
3583170fe5c8SBarry Smith       a_q = a + m*i;
3584be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3585170fe5c8SBarry Smith       idx++;
3586170fe5c8SBarry Smith       b++;
3587170fe5c8SBarry Smith     }
3588170fe5c8SBarry Smith   }
3589170fe5c8SBarry Smith   PetscFunctionReturn(0);
3590170fe5c8SBarry Smith }
3591170fe5c8SBarry Smith 
3592170fe5c8SBarry Smith #undef __FUNCT__
3593170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3594170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3595170fe5c8SBarry Smith {
3596170fe5c8SBarry Smith   PetscErrorCode ierr;
3597d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3598170fe5c8SBarry Smith   Mat            Cmat;
3599170fe5c8SBarry Smith 
3600170fe5c8SBarry Smith   PetscFunctionBegin;
3601e32f2f54SBarry 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);
360239804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3603170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3604a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3605170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3606170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3607170fe5c8SBarry Smith   Cmat->assembled    = PETSC_TRUE;
36088cdbd757SHong Zhang   Cmat->ops->matmult = MatMatMult_SeqDense_SeqAIJ;
3609170fe5c8SBarry Smith   *C = Cmat;
3610170fe5c8SBarry Smith   PetscFunctionReturn(0);
3611170fe5c8SBarry Smith }
3612170fe5c8SBarry Smith 
3613170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3614170fe5c8SBarry Smith #undef __FUNCT__
3615170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3616170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3617170fe5c8SBarry Smith {
3618170fe5c8SBarry Smith   PetscErrorCode ierr;
3619170fe5c8SBarry Smith 
3620170fe5c8SBarry Smith   PetscFunctionBegin;
3621170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3622170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3623170fe5c8SBarry Smith   }
3624170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3625170fe5c8SBarry Smith   PetscFunctionReturn(0);
3626170fe5c8SBarry Smith }
3627170fe5c8SBarry Smith 
3628170fe5c8SBarry Smith 
36290bad9183SKris Buschelman /*MC
3630fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
36310bad9183SKris Buschelman    based on compressed sparse row format.
36320bad9183SKris Buschelman 
36330bad9183SKris Buschelman    Options Database Keys:
36340bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
36350bad9183SKris Buschelman 
36360bad9183SKris Buschelman   Level: beginner
36370bad9183SKris Buschelman 
3638f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
36390bad9183SKris Buschelman M*/
36400bad9183SKris Buschelman 
3641a6175056SHong Zhang EXTERN_C_BEGIN
3642b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3643b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3644b5e56a35SBarry Smith #endif
3645ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3646af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3647af1023dbSSatish Balay #endif
36487087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
36497087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
36507087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
36517087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3652611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
36537087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3654611f576cSBarry Smith #endif
3655611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
36567087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3657611f576cSBarry Smith #endif
3658f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3659f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3660f3c0ef26SHong Zhang #endif
3661611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
36627087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*);
3663611f576cSBarry Smith #endif
3664eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
36657087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3666eb3b5408SSatish Balay #endif
3667586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
36687087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3669586621ddSJed Brown #endif
3670719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
36717087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3672719d5645SBarry Smith #endif
3673b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
36747087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
36757087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
36767087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3677b3866ffcSBarry Smith #endif
367817667f90SBarry Smith EXTERN_C_END
367917667f90SBarry Smith 
3680c0c8ee5eSDmitry Karpeev 
368117667f90SBarry Smith EXTERN_C_BEGIN
36824a2ae208SSatish Balay #undef __FUNCT__
36834a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
36847087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3685273d9f13SBarry Smith {
3686273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3687dfbe8321SBarry Smith   PetscErrorCode ierr;
368838baddfdSBarry Smith   PetscMPIInt    size;
3689273d9f13SBarry Smith 
3690273d9f13SBarry Smith   PetscFunctionBegin;
36917adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3692e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3693273d9f13SBarry Smith 
369438f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3695b0a32e0cSBarry Smith   B->data             = (void*)b;
3696549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3697416022c9SBarry Smith   b->row              = 0;
3698416022c9SBarry Smith   b->col              = 0;
369982bf6240SBarry Smith   b->icol             = 0;
3700b810aeb4SBarry Smith   b->reallocs         = 0;
370136db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3702f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3703416022c9SBarry Smith   b->nonew             = 0;
3704416022c9SBarry Smith   b->diag              = 0;
3705416022c9SBarry Smith   b->solve_work        = 0;
37062a1b7f2aSHong Zhang   B->spptr             = 0;
3707be6bf707SBarry Smith   b->saved_values      = 0;
3708d7f994e1SBarry Smith   b->idiag             = 0;
370971f1c65dSBarry Smith   b->mdiag             = 0;
371071f1c65dSBarry Smith   b->ssor_work         = 0;
371171f1c65dSBarry Smith   b->omega             = 1.0;
371271f1c65dSBarry Smith   b->fshift            = 0.0;
371371f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3714bbead8a2SBarry Smith   b->ibdiagvalid       = PETSC_FALSE;
3715a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3716a30b2313SHong Zhang   b->xtoy              = 0;
3717a30b2313SHong Zhang   b->XtoY              = 0;
371888e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
371917ab2063SBarry Smith 
372035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3721b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3722700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3723b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3724b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3725b3866ffcSBarry Smith #endif
3726b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3727700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3728b5e56a35SBarry Smith #endif
3729ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3730700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3731719d5645SBarry Smith #endif
3732611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3733700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3734611f576cSBarry Smith #endif
3735f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3736700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3737f3c0ef26SHong Zhang #endif
3738611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES)
3739700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr);
3740611f576cSBarry Smith #endif
3741611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3742700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3743611f576cSBarry Smith #endif
3744eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3745700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3746eb3b5408SSatish Balay #endif
3747586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3748700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3749586621ddSJed Brown #endif
3750719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
3751700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3752719d5645SBarry Smith #endif
3753700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3754700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3755700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3756700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3757700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3758700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3759700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3760700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3761700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3762700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3763700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3764700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3765700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3766700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3767700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3768700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3769700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3770700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
37714108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
377217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
37733a40ed3dSBarry Smith   PetscFunctionReturn(0);
377417ab2063SBarry Smith }
3775273d9f13SBarry Smith EXTERN_C_END
377617ab2063SBarry Smith 
37774a2ae208SSatish Balay #undef __FUNCT__
3778b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
3779b24902e0SBarry Smith /*
3780b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3781b24902e0SBarry Smith */
3782ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
378317ab2063SBarry Smith {
3784416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
37856849ba73SBarry Smith   PetscErrorCode ierr;
3786d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
378717ab2063SBarry Smith 
37883a40ed3dSBarry Smith   PetscFunctionBegin;
3789273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3790273d9f13SBarry Smith 
3791d5f3da31SBarry Smith   C->factortype     = A->factortype;
3792416022c9SBarry Smith   c->row            = 0;
3793416022c9SBarry Smith   c->col            = 0;
379482bf6240SBarry Smith   c->icol           = 0;
37956ad4291fSHong Zhang   c->reallocs       = 0;
379617ab2063SBarry Smith 
37976ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
379817ab2063SBarry Smith 
3799aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3800aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3801eec197d1SBarry Smith 
380233b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
38039518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
380417ab2063SBarry Smith   for (i=0; i<m; i++) {
3805416022c9SBarry Smith     c->imax[i] = a->imax[i];
3806416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
380717ab2063SBarry Smith   }
380817ab2063SBarry Smith 
380917ab2063SBarry Smith   /* allocate the matrix space */
3810f77e22a1SHong Zhang   if (mallocmatspace){
3811a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
38129518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
3813f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
381497f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
381517ab2063SBarry Smith     if (m > 0) {
381697f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3817be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3818bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3819be6bf707SBarry Smith       } else {
3820bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
382117ab2063SBarry Smith       }
382208480c60SBarry Smith     }
3823f77e22a1SHong Zhang   }
382417ab2063SBarry Smith 
38256ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3826416022c9SBarry Smith   c->roworiented       = a->roworiented;
3827416022c9SBarry Smith   c->nonew             = a->nonew;
3828416022c9SBarry Smith   if (a->diag) {
382997f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
383052e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
383117ab2063SBarry Smith     for (i=0; i<m; i++) {
3832416022c9SBarry Smith       c->diag[i] = a->diag[i];
383317ab2063SBarry Smith     }
38343a40ed3dSBarry Smith   } else c->diag           = 0;
38356ad4291fSHong Zhang   c->solve_work            = 0;
38366ad4291fSHong Zhang   c->saved_values          = 0;
38376ad4291fSHong Zhang   c->idiag                 = 0;
383871f1c65dSBarry Smith   c->ssor_work             = 0;
3839a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
3840e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
3841e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
38426ad4291fSHong Zhang   c->xtoy                  = 0;
38436ad4291fSHong Zhang   c->XtoY                  = 0;
38446ad4291fSHong Zhang 
3845893ad86cSHong Zhang   c->rmax               = a->rmax;
3846416022c9SBarry Smith   c->nz                 = a->nz;
38478ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
3848273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
3849754ec7b1SSatish Balay 
38506ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
38516ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
3852cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
3853cd6b891eSBarry Smith   if (a->compressedrow.use){
38546ad4291fSHong Zhang     i = a->compressedrow.nrows;
38550e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
38566ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
38576ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
385827ea64f8SHong Zhang   } else {
385927ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
386027ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
386127ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
38626ad4291fSHong Zhang   }
386388e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
38644108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
38654846f1f5SKris Buschelman 
38667adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
38673a40ed3dSBarry Smith   PetscFunctionReturn(0);
386817ab2063SBarry Smith }
386917ab2063SBarry Smith 
38704a2ae208SSatish Balay #undef __FUNCT__
3871b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
3872b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3873b24902e0SBarry Smith {
3874b24902e0SBarry Smith   PetscErrorCode ierr;
3875b24902e0SBarry Smith 
3876b24902e0SBarry Smith   PetscFunctionBegin;
3877b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
38784b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3879a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
3880a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
3881f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3882b24902e0SBarry Smith   PetscFunctionReturn(0);
3883b24902e0SBarry Smith }
3884b24902e0SBarry Smith 
3885b24902e0SBarry Smith #undef __FUNCT__
38864a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
3887112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3888fbdbba38SShri Abhyankar {
3889fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3890fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3891fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3892fbdbba38SShri Abhyankar   int            fd;
3893fbdbba38SShri Abhyankar   PetscMPIInt    size;
3894fbdbba38SShri Abhyankar   MPI_Comm       comm;
3895bbead8a2SBarry Smith   PetscInt       bs = 1;
3896fbdbba38SShri Abhyankar 
3897fbdbba38SShri Abhyankar   PetscFunctionBegin;
3898fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3899fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3900fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3901bbead8a2SBarry Smith 
3902bbead8a2SBarry Smith   ierr = PetscOptionsBegin(comm,PETSC_NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
3903bbead8a2SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,PETSC_NULL);CHKERRQ(ierr);
3904bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3905*1814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
3906bbead8a2SBarry Smith 
3907fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3908fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
3909fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
3910fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
3911fbdbba38SShri Abhyankar 
3912bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
3913fbdbba38SShri Abhyankar 
3914fbdbba38SShri Abhyankar   /* read in row lengths */
3915fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
3916fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
3917fbdbba38SShri Abhyankar 
3918fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
3919fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
3920fbdbba38SShri 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);
3921fbdbba38SShri Abhyankar 
3922fbdbba38SShri Abhyankar   /* set global size if not set already*/
3923f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
3924fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3925aabbc4fbSShri Abhyankar   } else {
3926fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
3927fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
39284c5b953cSHong Zhang     if (rows < 0 && cols < 0){ /* user might provide local size instead of global size */
39294c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
39304c5b953cSHong Zhang     }
3931f501eaabSShri 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);
3932aabbc4fbSShri Abhyankar   }
3933fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
3934fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
3935fbdbba38SShri Abhyankar 
3936fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
3937fbdbba38SShri Abhyankar 
3938fbdbba38SShri Abhyankar   /* read in nonzero values */
3939fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
3940fbdbba38SShri Abhyankar 
3941fbdbba38SShri Abhyankar   /* set matrix "i" values */
3942fbdbba38SShri Abhyankar   a->i[0] = 0;
3943fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
3944fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
3945fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
3946fbdbba38SShri Abhyankar   }
3947fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
3948fbdbba38SShri Abhyankar 
3949fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3950fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3951fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
3952fbdbba38SShri Abhyankar }
3953fbdbba38SShri Abhyankar 
3954fbdbba38SShri Abhyankar #undef __FUNCT__
3955b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
3956ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
39577264ac53SSatish Balay {
39587264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
3959dfbe8321SBarry Smith   PetscErrorCode ierr;
3960eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3961eeffb40dSHong Zhang   PetscInt k;
3962eeffb40dSHong Zhang #endif
39637264ac53SSatish Balay 
39643a40ed3dSBarry Smith   PetscFunctionBegin;
3965bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
3966d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
3967ca44d042SBarry Smith     *flg = PETSC_FALSE;
3968ca44d042SBarry Smith     PetscFunctionReturn(0);
3969bcd2baecSBarry Smith   }
39707264ac53SSatish Balay 
39717264ac53SSatish Balay   /* if the a->i are the same */
3972d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3973abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
39747264ac53SSatish Balay 
39757264ac53SSatish Balay   /* if a->j are the same */
397697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
3977abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
3978bcd2baecSBarry Smith 
3979bcd2baecSBarry Smith   /* if a->a are the same */
3980eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
3981eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
3982eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
3983eeffb40dSHong Zhang       *flg = PETSC_FALSE;
39843a40ed3dSBarry Smith       PetscFunctionReturn(0);
3985eeffb40dSHong Zhang     }
3986eeffb40dSHong Zhang   }
3987eeffb40dSHong Zhang #else
3988eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
3989eeffb40dSHong Zhang #endif
3990eeffb40dSHong Zhang   PetscFunctionReturn(0);
39917264ac53SSatish Balay }
399236db0b34SBarry Smith 
39934a2ae208SSatish Balay #undef __FUNCT__
39944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
399505869f15SSatish Balay /*@
399636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
399736db0b34SBarry Smith               provided by the user.
399836db0b34SBarry Smith 
3999c75a6043SHong Zhang       Collective on MPI_Comm
400036db0b34SBarry Smith 
400136db0b34SBarry Smith    Input Parameters:
400236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
400336db0b34SBarry Smith .   m - number of rows
400436db0b34SBarry Smith .   n - number of columns
400536db0b34SBarry Smith .   i - row indices
400636db0b34SBarry Smith .   j - column indices
400736db0b34SBarry Smith -   a - matrix values
400836db0b34SBarry Smith 
400936db0b34SBarry Smith    Output Parameter:
401036db0b34SBarry Smith .   mat - the matrix
401136db0b34SBarry Smith 
401236db0b34SBarry Smith    Level: intermediate
401336db0b34SBarry Smith 
401436db0b34SBarry Smith    Notes:
40150551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4016292fb18eSBarry Smith     once the matrix is destroyed and not before
401736db0b34SBarry Smith 
401836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
401936db0b34SBarry Smith 
4020bfeeae90SHong Zhang        The i and j indices are 0 based
402136db0b34SBarry Smith 
4022a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4023a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4024a4552177SSatish Balay     as shown:
4025a4552177SSatish Balay 
4026a4552177SSatish Balay         1 0 0
4027a4552177SSatish Balay         2 0 3
4028a4552177SSatish Balay         4 5 6
4029a4552177SSatish Balay 
4030a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
40319985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4032a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4033a4552177SSatish Balay 
40349985e31cSBarry Smith 
403569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
403636db0b34SBarry Smith 
403736db0b34SBarry Smith @*/
40387087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
403936db0b34SBarry Smith {
4040dfbe8321SBarry Smith   PetscErrorCode ierr;
4041cbcfb4deSHong Zhang   PetscInt       ii;
404236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4043cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4044cbcfb4deSHong Zhang   PetscInt       jj;
4045cbcfb4deSHong Zhang #endif
404636db0b34SBarry Smith 
404736db0b34SBarry Smith   PetscFunctionBegin;
4048a96a251dSBarry Smith   if (i[0]) {
4049e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
405036db0b34SBarry Smith   }
4051f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4052f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4053a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4054ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4055ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4056ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4057ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4058ab93d7beSBarry Smith 
405936db0b34SBarry Smith   aij->i = i;
406036db0b34SBarry Smith   aij->j = j;
406136db0b34SBarry Smith   aij->a = a;
406236db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
406336db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4064e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4065e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
406636db0b34SBarry Smith 
406736db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
406836db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
40692515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4070e32f2f54SBarry 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]);
40719985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4072e32f2f54SBarry 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);
4073e32f2f54SBarry 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);
40749985e31cSBarry Smith     }
407536db0b34SBarry Smith #endif
407636db0b34SBarry Smith   }
40772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
407836db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4079e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4080e32f2f54SBarry 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]);
408136db0b34SBarry Smith   }
408236db0b34SBarry Smith #endif
408336db0b34SBarry Smith 
4084b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4085b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
408636db0b34SBarry Smith   PetscFunctionReturn(0);
408736db0b34SBarry Smith }
40888a0b0e6bSVictor Minden #undef __FUNCT__
40898a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
409080ef6e79SMatthew G Knepley /*@C
4091d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
40928a0b0e6bSVictor Minden               provided by the user.
40938a0b0e6bSVictor Minden 
40948a0b0e6bSVictor Minden       Collective on MPI_Comm
40958a0b0e6bSVictor Minden 
40968a0b0e6bSVictor Minden    Input Parameters:
40978a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
40988a0b0e6bSVictor Minden .   m   - number of rows
40998a0b0e6bSVictor Minden .   n   - number of columns
41008a0b0e6bSVictor Minden .   i   - row indices
41018a0b0e6bSVictor Minden .   j   - column indices
41021230e6d1SVictor Minden .   a   - matrix values
41031230e6d1SVictor Minden .   nz  - number of nonzeros
41041230e6d1SVictor Minden -   idx - 0 or 1 based
41058a0b0e6bSVictor Minden 
41068a0b0e6bSVictor Minden    Output Parameter:
41078a0b0e6bSVictor Minden .   mat - the matrix
41088a0b0e6bSVictor Minden 
41098a0b0e6bSVictor Minden    Level: intermediate
41108a0b0e6bSVictor Minden 
41118a0b0e6bSVictor Minden    Notes:
41128a0b0e6bSVictor Minden        The i and j indices are 0 based
41138a0b0e6bSVictor Minden 
41148a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
41158a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
41168a0b0e6bSVictor Minden     as shown:
41178a0b0e6bSVictor Minden 
41188a0b0e6bSVictor Minden         1 0 0
41198a0b0e6bSVictor Minden         2 0 3
41208a0b0e6bSVictor Minden         4 5 6
41218a0b0e6bSVictor Minden 
41228a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
41238a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
41248a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
41258a0b0e6bSVictor Minden 
41268a0b0e6bSVictor Minden 
412769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
41288a0b0e6bSVictor Minden 
41298a0b0e6bSVictor Minden @*/
41301230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
41318a0b0e6bSVictor Minden {
41328a0b0e6bSVictor Minden   PetscErrorCode ierr;
4133d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
41348a0b0e6bSVictor Minden 
41358a0b0e6bSVictor Minden 
41368a0b0e6bSVictor Minden   PetscFunctionBegin;
4137d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
41381230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
41391230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++){
41401230e6d1SVictor Minden     nnz[i[ii]] += 1;
41411230e6d1SVictor Minden   }
41428a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
41438a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4144a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
41458a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
41461230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
41471230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++){
41481230e6d1SVictor Minden     if (idx){
41491230e6d1SVictor Minden       row = i[ii] - 1;
41501230e6d1SVictor Minden       col = j[ii] - 1;
41511230e6d1SVictor Minden     } else {
41521230e6d1SVictor Minden       row = i[ii];
41531230e6d1SVictor Minden       col = j[ii];
41548a0b0e6bSVictor Minden     }
41551230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
41568a0b0e6bSVictor Minden   }
41578a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
41588a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4159d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
41608a0b0e6bSVictor Minden   PetscFunctionReturn(0);
41618a0b0e6bSVictor Minden }
416236db0b34SBarry Smith 
4163cc8ba8e1SBarry Smith #undef __FUNCT__
4164ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4165dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4166cc8ba8e1SBarry Smith {
4167dfbe8321SBarry Smith   PetscErrorCode ierr;
4168cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
416936db0b34SBarry Smith 
4170cc8ba8e1SBarry Smith   PetscFunctionBegin;
41718ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4172cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4173cc8ba8e1SBarry Smith     a->coloring = coloring;
417412c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
417597f1f81fSBarry Smith     PetscInt             i,*larray;
417612c595b3SBarry Smith     ISColoring      ocoloring;
417708b6dcc0SBarry Smith     ISColoringValue *colors;
417812c595b3SBarry Smith 
417912c595b3SBarry Smith     /* set coloring for diagonal portion */
41800e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
4181d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
418212c595b3SBarry Smith       larray[i] = i;
418312c595b3SBarry Smith     }
4184992144d0SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
41850e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
4186d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
418712c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
418812c595b3SBarry Smith     }
418912c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
4190d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
419112c595b3SBarry Smith     a->coloring = ocoloring;
419212c595b3SBarry Smith   }
4193cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4194cc8ba8e1SBarry Smith }
4195cc8ba8e1SBarry Smith 
4196dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
4197ee4f033dSBarry Smith EXTERN_C_BEGIN
4198c6db04a5SJed Brown #include <adic/ad_utils.h>
4199ee4f033dSBarry Smith EXTERN_C_END
4200cc8ba8e1SBarry Smith 
4201cc8ba8e1SBarry Smith #undef __FUNCT__
4202ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
4203dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
4204cc8ba8e1SBarry Smith {
4205cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4206d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
42074440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
420808b6dcc0SBarry Smith   ISColoringValue *color;
4209cc8ba8e1SBarry Smith 
4210cc8ba8e1SBarry Smith   PetscFunctionBegin;
4211e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
42124440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
4213cc8ba8e1SBarry Smith   color = a->coloring->colors;
4214cc8ba8e1SBarry Smith   /* loop over rows */
4215cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
4216cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
4217cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
4218cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
4219cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
4220cc8ba8e1SBarry Smith     }
42214440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
4222ee4f033dSBarry Smith   }
4223ee4f033dSBarry Smith   PetscFunctionReturn(0);
4224ee4f033dSBarry Smith }
4225ee4f033dSBarry Smith #endif
4226ee4f033dSBarry Smith 
4227ee4f033dSBarry Smith #undef __FUNCT__
4228ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
422997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4230ee4f033dSBarry Smith {
4231ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4232d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
423354f21887SBarry Smith   MatScalar       *v = a->a;
423454f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
423508b6dcc0SBarry Smith   ISColoringValue *color;
4236ee4f033dSBarry Smith 
4237ee4f033dSBarry Smith   PetscFunctionBegin;
4238e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4239ee4f033dSBarry Smith   color = a->coloring->colors;
4240ee4f033dSBarry Smith   /* loop over rows */
4241ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4242ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4243ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
4244ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
4245ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
4246ee4f033dSBarry Smith     }
4247ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4248cc8ba8e1SBarry Smith   }
4249cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4250cc8ba8e1SBarry Smith }
425136db0b34SBarry Smith 
42520847f33cSJed Brown #undef __FUNCT__
42530847f33cSJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
42540847f33cSJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
42550847f33cSJed Brown {
42560847f33cSJed Brown   Mat_SeqAIJ      *a=(Mat_SeqAIJ*)A->data;
42570847f33cSJed Brown   PetscErrorCode ierr;
42580847f33cSJed Brown 
42590847f33cSJed Brown   PetscFunctionBegin;
42600847f33cSJed Brown   a->idiagvalid = PETSC_FALSE;
42610847f33cSJed Brown   a->ibdiagvalid = PETSC_FALSE;
42620847f33cSJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
42630847f33cSJed Brown   PetscFunctionReturn(0);
42640847f33cSJed Brown }
42650847f33cSJed Brown 
426681824310SBarry Smith /*
426781824310SBarry Smith     Special version for direct calls from Fortran
426881824310SBarry Smith */
4269b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
427081824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
427181824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
427281824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
427381824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
427481824310SBarry Smith #endif
427581824310SBarry Smith 
427681824310SBarry Smith /* Change these macros so can be used in void function */
427781824310SBarry Smith #undef CHKERRQ
42787adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
427981824310SBarry Smith #undef SETERRQ2
4280e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
42814994cf47SJed Brown #undef SETERRQ3
42824994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
428381824310SBarry Smith 
428481824310SBarry Smith EXTERN_C_BEGIN
428581824310SBarry Smith #undef __FUNCT__
428681824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
42871f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
428881824310SBarry Smith {
428981824310SBarry Smith   Mat            A = *AA;
429081824310SBarry Smith   PetscInt       m = *mm, n = *nn;
429181824310SBarry Smith   InsertMode     is = *isis;
429281824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
429381824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
429481824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
429581824310SBarry Smith   PetscErrorCode ierr;
429681824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
429754f21887SBarry Smith   MatScalar      *ap,value,*aa;
4298ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4299ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
430081824310SBarry Smith 
430181824310SBarry Smith   PetscFunctionBegin;
43024994cf47SJed Brown   MatCheckPreallocated(A,1);
430381824310SBarry Smith   imax = a->imax;
430481824310SBarry Smith   ai = a->i;
430581824310SBarry Smith   ailen = a->ilen;
430681824310SBarry Smith   aj = a->j;
430781824310SBarry Smith   aa = a->a;
430881824310SBarry Smith 
430981824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
431081824310SBarry Smith     row  = im[k];
431181824310SBarry Smith     if (row < 0) continue;
431281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4313d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
431481824310SBarry Smith #endif
431581824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
431681824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
431781824310SBarry Smith     low  = 0;
431881824310SBarry Smith     high = nrow;
431981824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
432081824310SBarry Smith       if (in[l] < 0) continue;
432181824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4322d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
432381824310SBarry Smith #endif
432481824310SBarry Smith       col = in[l];
432581824310SBarry Smith       if (roworiented) {
432681824310SBarry Smith         value = v[l + k*n];
432781824310SBarry Smith       } else {
432881824310SBarry Smith         value = v[k + l*m];
432981824310SBarry Smith       }
433081824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
433181824310SBarry Smith 
433281824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
433381824310SBarry Smith       lastcol = col;
433481824310SBarry Smith       while (high-low > 5) {
433581824310SBarry Smith         t = (low+high)/2;
433681824310SBarry Smith         if (rp[t] > col) high = t;
433781824310SBarry Smith         else             low  = t;
433881824310SBarry Smith       }
433981824310SBarry Smith       for (i=low; i<high; i++) {
434081824310SBarry Smith         if (rp[i] > col) break;
434181824310SBarry Smith         if (rp[i] == col) {
434281824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
434381824310SBarry Smith           else                  ap[i] = value;
434481824310SBarry Smith           goto noinsert;
434581824310SBarry Smith         }
434681824310SBarry Smith       }
434781824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
434881824310SBarry Smith       if (nonew == 1) goto noinsert;
43497adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4350fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
435181824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
435281824310SBarry Smith       /* shift up all the later entries in this row */
435381824310SBarry Smith       for (ii=N; ii>=i; ii--) {
435481824310SBarry Smith         rp[ii+1] = rp[ii];
435581824310SBarry Smith         ap[ii+1] = ap[ii];
435681824310SBarry Smith       }
435781824310SBarry Smith       rp[i] = col;
435881824310SBarry Smith       ap[i] = value;
435981824310SBarry Smith       noinsert:;
436081824310SBarry Smith       low = i + 1;
436181824310SBarry Smith     }
436281824310SBarry Smith     ailen[row] = nrow;
436381824310SBarry Smith   }
436481824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
436581824310SBarry Smith   PetscFunctionReturnVoid();
436681824310SBarry Smith }
436781824310SBarry Smith EXTERN_C_END
436862298a1eSBarry Smith 
4369