xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 5021d80f6fafe3c479cce7b9a948571cf63b4162)
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>
1278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1378b84d54SShri Abhyankar #include <petscthreadcomm.h>
1478b84d54SShri Abhyankar #endif
150716a85fSBarry Smith 
160716a85fSBarry Smith #undef __FUNCT__
170716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
180716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
190716a85fSBarry Smith {
200716a85fSBarry Smith   PetscErrorCode ierr;
210716a85fSBarry Smith   PetscInt       i,m,n;
220716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
230716a85fSBarry Smith 
240716a85fSBarry Smith   PetscFunctionBegin;
250716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
260716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
270716a85fSBarry Smith   if (type == NORM_2) {
280716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
290716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
300716a85fSBarry Smith     }
310716a85fSBarry Smith   } else if (type == NORM_1) {
320716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
330716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
340716a85fSBarry Smith     }
350716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
360716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
370716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
380716a85fSBarry Smith     }
390716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
400716a85fSBarry Smith 
410716a85fSBarry Smith   if (type == NORM_2) {
428f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
430716a85fSBarry Smith   }
440716a85fSBarry Smith   PetscFunctionReturn(0);
450716a85fSBarry Smith }
460716a85fSBarry Smith 
474a2ae208SSatish Balay #undef __FUNCT__
48f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
49f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
506ce1633cSBarry Smith {
516ce1633cSBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
526ce1633cSBarry Smith   const MatScalar   *aa = a->a;
536ce1633cSBarry Smith   PetscInt          i,m=A->rmap->n,cnt = 0;
546ce1633cSBarry Smith   const PetscInt    *jj = a->j,*diag;
556ce1633cSBarry Smith   PetscInt          *rows;
566ce1633cSBarry Smith   PetscErrorCode    ierr;
576ce1633cSBarry Smith 
586ce1633cSBarry Smith   PetscFunctionBegin;
596ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
606ce1633cSBarry Smith   diag = a->diag;
616ce1633cSBarry Smith   for (i=0; i<m; i++) {
626ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
636ce1633cSBarry Smith       cnt++;
646ce1633cSBarry Smith     }
656ce1633cSBarry Smith   }
666ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr);
676ce1633cSBarry Smith   cnt  = 0;
686ce1633cSBarry Smith   for (i=0; i<m; i++) {
696ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
706ce1633cSBarry Smith       rows[cnt++] = i;
716ce1633cSBarry Smith     }
726ce1633cSBarry Smith   }
73f1f41ecbSJed Brown   *nrows = cnt;
74f1f41ecbSJed Brown   *zrows = rows;
75f1f41ecbSJed Brown   PetscFunctionReturn(0);
76f1f41ecbSJed Brown }
77f1f41ecbSJed Brown 
78f1f41ecbSJed Brown #undef __FUNCT__
79f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
80f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
81f1f41ecbSJed Brown {
82f1f41ecbSJed Brown   PetscInt       nrows,*rows;
83f1f41ecbSJed Brown   PetscErrorCode ierr;
84f1f41ecbSJed Brown 
85f1f41ecbSJed Brown   PetscFunctionBegin;
86f1f41ecbSJed Brown   *zrows = PETSC_NULL;
87f1f41ecbSJed Brown   ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
88f1f41ecbSJed Brown   ierr = ISCreateGeneral(((PetscObject)A)->comm,nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
896ce1633cSBarry Smith   PetscFunctionReturn(0);
906ce1633cSBarry Smith }
916ce1633cSBarry Smith 
926ce1633cSBarry Smith #undef __FUNCT__
93b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
94b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
95b3a44c85SBarry Smith {
96b3a44c85SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
97b3a44c85SBarry Smith   const MatScalar   *aa;
98b3a44c85SBarry Smith   PetscInt          m=A->rmap->n,cnt = 0;
99b3a44c85SBarry Smith   const PetscInt    *ii;
100b3a44c85SBarry Smith   PetscInt          n,i,j,*rows;
101b3a44c85SBarry Smith   PetscErrorCode    ierr;
102b3a44c85SBarry Smith 
103b3a44c85SBarry Smith   PetscFunctionBegin;
104b3a44c85SBarry Smith   *keptrows = 0;
105b3a44c85SBarry Smith   ii        = a->i;
106b3a44c85SBarry Smith   for (i=0; i<m; i++) {
107b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
108b3a44c85SBarry Smith     if (!n) {
109b3a44c85SBarry Smith       cnt++;
110b3a44c85SBarry Smith       goto ok1;
111b3a44c85SBarry Smith     }
112b3a44c85SBarry Smith     aa  = a->a + ii[i];
113b3a44c85SBarry Smith     for (j=0; j<n; j++) {
114b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
115b3a44c85SBarry Smith     }
116b3a44c85SBarry Smith     cnt++;
117b3a44c85SBarry Smith     ok1:;
118b3a44c85SBarry Smith   }
119b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
120b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
121b3a44c85SBarry Smith   cnt  = 0;
122b3a44c85SBarry Smith   for (i=0; i<m; i++) {
123b3a44c85SBarry Smith     n   = ii[i+1] - ii[i];
124b3a44c85SBarry Smith     if (!n) continue;
125b3a44c85SBarry Smith     aa  = a->a + ii[i];
126b3a44c85SBarry Smith     for (j=0; j<n; j++) {
127b3a44c85SBarry Smith       if (aa[j] != 0.0) {
128b3a44c85SBarry Smith         rows[cnt++] = i;
129b3a44c85SBarry Smith         break;
130b3a44c85SBarry Smith       }
131b3a44c85SBarry Smith     }
132b3a44c85SBarry Smith   }
133b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
134b3a44c85SBarry Smith   PetscFunctionReturn(0);
135b3a44c85SBarry Smith }
136b3a44c85SBarry Smith 
137b3a44c85SBarry Smith #undef __FUNCT__
13879299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1397087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
14079299369SBarry Smith {
14179299369SBarry Smith   PetscErrorCode ierr;
14279299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
143d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
14454f21887SBarry Smith   MatScalar      *aa = aij->a;
14554f21887SBarry Smith   PetscScalar    *v;
146ace3abfcSBarry Smith   PetscBool      missing;
14779299369SBarry Smith 
14879299369SBarry Smith   PetscFunctionBegin;
14909f38230SBarry Smith   if (Y->assembled) {
15009f38230SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr);
15109f38230SBarry Smith     if (!missing) {
15279299369SBarry Smith       diag = aij->diag;
15379299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
15479299369SBarry Smith       if (is == INSERT_VALUES) {
15579299369SBarry Smith 	for (i=0; i<m; i++) {
15679299369SBarry Smith 	  aa[diag[i]] = v[i];
15779299369SBarry Smith 	}
15879299369SBarry Smith       } else {
15979299369SBarry Smith 	for (i=0; i<m; i++) {
16079299369SBarry Smith 	  aa[diag[i]] += v[i];
16179299369SBarry Smith 	}
16279299369SBarry Smith       }
16379299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
16479299369SBarry Smith       PetscFunctionReturn(0);
16579299369SBarry Smith     }
16686c113feSBarry Smith     aij->idiagvalid  = PETSC_FALSE;
16786c113feSBarry Smith     aij->ibdiagvalid = PETSC_FALSE;
16809f38230SBarry Smith   }
16909f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
17009f38230SBarry Smith   PetscFunctionReturn(0);
17109f38230SBarry Smith }
17279299369SBarry Smith 
17379299369SBarry Smith #undef __FUNCT__
1744a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
175ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
17617ab2063SBarry Smith {
177416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
178dfbe8321SBarry Smith   PetscErrorCode ierr;
17997f1f81fSBarry Smith   PetscInt       i,ishift;
18017ab2063SBarry Smith 
1813a40ed3dSBarry Smith   PetscFunctionBegin;
182d0f46423SBarry Smith   *m     = A->rmap->n;
1833a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
184bfeeae90SHong Zhang   ishift = 0;
18553e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
186d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
187bfeeae90SHong Zhang   } else if (oshift == 1) {
188d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1893b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
190d0f46423SBarry Smith     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr);
191d0f46423SBarry Smith     for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1;
192ecc77c7aSBarry Smith     if (ja) {
19397f1f81fSBarry Smith       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr);
1943b2fbd54SBarry Smith       for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
195ecc77c7aSBarry Smith     }
1966945ee14SBarry Smith   } else {
197ecc77c7aSBarry Smith     *ia = a->i;
198ecc77c7aSBarry Smith     if (ja) *ja = a->j;
199a2ce50c7SBarry Smith   }
2003a40ed3dSBarry Smith   PetscFunctionReturn(0);
201a2744918SBarry Smith }
202a2744918SBarry Smith 
2034a2ae208SSatish Balay #undef __FUNCT__
2044a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
205ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2066945ee14SBarry Smith {
207dfbe8321SBarry Smith   PetscErrorCode ierr;
2086945ee14SBarry Smith 
2093a40ed3dSBarry Smith   PetscFunctionBegin;
2103a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
211bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
212606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
213ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
214bcd2baecSBarry Smith   }
2153a40ed3dSBarry Smith   PetscFunctionReturn(0);
21617ab2063SBarry Smith }
21717ab2063SBarry Smith 
2184a2ae208SSatish Balay #undef __FUNCT__
2194a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
220ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2213b2fbd54SBarry Smith {
2223b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
223dfbe8321SBarry Smith   PetscErrorCode ierr;
224d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
22597f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2263b2fbd54SBarry Smith 
2273a40ed3dSBarry Smith   PetscFunctionBegin;
228899cda47SBarry Smith   *nn = n;
2293a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2303b2fbd54SBarry Smith   if (symmetric) {
231d0f46423SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2323b2fbd54SBarry Smith   } else {
23397f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
23497f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
23597f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
23697f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
2373b2fbd54SBarry Smith     jj = a->j;
2383b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
239bfeeae90SHong Zhang       collengths[jj[i]]++;
2403b2fbd54SBarry Smith     }
2413b2fbd54SBarry Smith     cia[0] = oshift;
2423b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2433b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2443b2fbd54SBarry Smith     }
24597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2463b2fbd54SBarry Smith     jj   = a->j;
247a93ec695SBarry Smith     for (row=0; row<m; row++) {
248a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
249a93ec695SBarry Smith       for (i=0; i<mr; i++) {
250bfeeae90SHong Zhang         col = *jj++;
2513b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2523b2fbd54SBarry Smith       }
2533b2fbd54SBarry Smith     }
254606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2553b2fbd54SBarry Smith     *ia = cia; *ja = cja;
2563b2fbd54SBarry Smith   }
2573a40ed3dSBarry Smith   PetscFunctionReturn(0);
2583b2fbd54SBarry Smith }
2593b2fbd54SBarry Smith 
2604a2ae208SSatish Balay #undef __FUNCT__
2614a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
262ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool  *done)
2633b2fbd54SBarry Smith {
264dfbe8321SBarry Smith   PetscErrorCode ierr;
265606d414cSSatish Balay 
2663a40ed3dSBarry Smith   PetscFunctionBegin;
2673a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2683b2fbd54SBarry Smith 
269606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
270606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2713b2fbd54SBarry Smith 
2723a40ed3dSBarry Smith   PetscFunctionReturn(0);
2733b2fbd54SBarry Smith }
2743b2fbd54SBarry Smith 
27587d4246cSBarry Smith #undef __FUNCT__
27687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
27787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
27887d4246cSBarry Smith {
27987d4246cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
28087d4246cSBarry Smith   PetscInt       *ai = a->i;
28187d4246cSBarry Smith   PetscErrorCode ierr;
28287d4246cSBarry Smith 
28387d4246cSBarry Smith   PetscFunctionBegin;
28487d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
28587d4246cSBarry Smith   PetscFunctionReturn(0);
28687d4246cSBarry Smith }
28787d4246cSBarry Smith 
2884a2ae208SSatish Balay #undef __FUNCT__
2894a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
29097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
29117ab2063SBarry Smith {
292416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
293e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
29497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
2956849ba73SBarry Smith   PetscErrorCode ierr;
296e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
29754f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
298ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
299ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
30017ab2063SBarry Smith 
3013a40ed3dSBarry Smith   PetscFunctionBegin;
30271fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
30317ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
304416022c9SBarry Smith     row  = im[k];
3055ef9f2a5SBarry Smith     if (row < 0) continue;
3062515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
307e32f2f54SBarry 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);
3083b2fbd54SBarry Smith #endif
309bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
31017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
311416022c9SBarry Smith     low  = 0;
312c71e6ed7SBarry Smith     high = nrow;
31317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3145ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
316e32f2f54SBarry 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);
3173b2fbd54SBarry Smith #endif
318bfeeae90SHong Zhang       col = in[l];
31916371a99SBarry Smith       if (v) {
3204b0e389bSBarry Smith 	if (roworiented) {
3215ef9f2a5SBarry Smith 	  value = v[l + k*n];
322bef8e0ddSBarry Smith 	} else {
3234b0e389bSBarry Smith 	  value = v[k + l*m];
3244b0e389bSBarry Smith 	}
32516371a99SBarry Smith       } else {
32675567043SBarry Smith         value = 0.;
32716371a99SBarry Smith       }
328abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
32936db0b34SBarry Smith 
3307cd84e04SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
331e2ee6c50SBarry Smith       lastcol = col;
332416022c9SBarry Smith       while (high-low > 5) {
333416022c9SBarry Smith         t = (low+high)/2;
334416022c9SBarry Smith         if (rp[t] > col) high = t;
335416022c9SBarry Smith         else             low  = t;
33617ab2063SBarry Smith       }
337416022c9SBarry Smith       for (i=low; i<high; i++) {
33817ab2063SBarry Smith         if (rp[i] > col) break;
33917ab2063SBarry Smith         if (rp[i] == col) {
340416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
34117ab2063SBarry Smith           else                  ap[i] = value;
342e44c0bd4SBarry Smith           low = i + 1;
34317ab2063SBarry Smith           goto noinsert;
34417ab2063SBarry Smith         }
34517ab2063SBarry Smith       }
346abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
347c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
348e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
349fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
350c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
351416022c9SBarry Smith       /* shift up all the later entries in this row */
352416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
35317ab2063SBarry Smith         rp[ii+1] = rp[ii];
35417ab2063SBarry Smith         ap[ii+1] = ap[ii];
35517ab2063SBarry Smith       }
35617ab2063SBarry Smith       rp[i] = col;
35717ab2063SBarry Smith       ap[i] = value;
358416022c9SBarry Smith       low   = i + 1;
359e44c0bd4SBarry Smith       noinsert:;
36017ab2063SBarry Smith     }
36117ab2063SBarry Smith     ailen[row] = nrow;
36217ab2063SBarry Smith   }
36388e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
3643a40ed3dSBarry Smith   PetscFunctionReturn(0);
36517ab2063SBarry Smith }
36617ab2063SBarry Smith 
36781824310SBarry Smith 
3684a2ae208SSatish Balay #undef __FUNCT__
3694a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
370a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
3717eb43aa7SLois Curfman McInnes {
3727eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
37397f1f81fSBarry Smith   PetscInt     *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
37497f1f81fSBarry Smith   PetscInt     *ai = a->i,*ailen = a->ilen;
37554f21887SBarry Smith   MatScalar    *ap,*aa = a->a;
3767eb43aa7SLois Curfman McInnes 
3773a40ed3dSBarry Smith   PetscFunctionBegin;
3787eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
3797eb43aa7SLois Curfman McInnes     row  = im[k];
380e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
381e32f2f54SBarry 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);
382bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
3837eb43aa7SLois Curfman McInnes     nrow = ailen[row];
3847eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
385e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
386e32f2f54SBarry 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);
387bfeeae90SHong Zhang       col = in[l] ;
3887eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
3897eb43aa7SLois Curfman McInnes       while (high-low > 5) {
3907eb43aa7SLois Curfman McInnes         t = (low+high)/2;
3917eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
3927eb43aa7SLois Curfman McInnes         else             low  = t;
3937eb43aa7SLois Curfman McInnes       }
3947eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
3957eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
3967eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
397b49de8d1SLois Curfman McInnes           *v++ = ap[i];
3987eb43aa7SLois Curfman McInnes           goto finished;
3997eb43aa7SLois Curfman McInnes         }
4007eb43aa7SLois Curfman McInnes       }
40197e567efSBarry Smith       *v++ = 0.0;
4027eb43aa7SLois Curfman McInnes       finished:;
4037eb43aa7SLois Curfman McInnes     }
4047eb43aa7SLois Curfman McInnes   }
4053a40ed3dSBarry Smith   PetscFunctionReturn(0);
4067eb43aa7SLois Curfman McInnes }
4077eb43aa7SLois Curfman McInnes 
40817ab2063SBarry Smith 
4094a2ae208SSatish Balay #undef __FUNCT__
4104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
411dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
41217ab2063SBarry Smith {
413416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4146849ba73SBarry Smith   PetscErrorCode ierr;
4156f69ff64SBarry Smith   PetscInt       i,*col_lens;
4166f69ff64SBarry Smith   int            fd;
417b37d52dbSMark F. Adams   FILE           *file;
41817ab2063SBarry Smith 
4193a40ed3dSBarry Smith   PetscFunctionBegin;
420b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
421d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4220700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
423d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
424d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
425416022c9SBarry Smith   col_lens[3] = a->nz;
426416022c9SBarry Smith 
427416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
428d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
429416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
43017ab2063SBarry Smith   }
431d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
432606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
433416022c9SBarry Smith 
434416022c9SBarry Smith   /* store column indices (zero start index) */
4356f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
436416022c9SBarry Smith 
437416022c9SBarry Smith   /* store nonzero values */
4386f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
439b37d52dbSMark F. Adams 
440b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
441b37d52dbSMark F. Adams   if (file) {
442b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
443b37d52dbSMark F. Adams   }
444b37d52dbSMark F. Adams 
4453a40ed3dSBarry Smith   PetscFunctionReturn(0);
44617ab2063SBarry Smith }
447416022c9SBarry Smith 
44809573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
449cd155464SBarry Smith 
4504a2ae208SSatish Balay #undef __FUNCT__
4514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
452dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
453416022c9SBarry Smith {
454416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
455dfbe8321SBarry Smith   PetscErrorCode    ierr;
456d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
457e060cb09SBarry Smith   const char        *name;
458f3ef73ceSBarry Smith   PetscViewerFormat format;
45917ab2063SBarry Smith 
4603a40ed3dSBarry Smith   PetscFunctionBegin;
461b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
46271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
46397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
464d0f46423SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) {
465d00d2cf4SBarry Smith       nofinalvalue = 1;
466d00d2cf4SBarry Smith     }
467d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
468d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
46977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
47077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
471b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
47217ab2063SBarry Smith 
47317ab2063SBarry Smith     for (i=0; i<m; i++) {
474416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
475aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
47677431f27SBarry 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);
47717ab2063SBarry Smith #else
47877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
47917ab2063SBarry Smith #endif
48017ab2063SBarry Smith       }
48117ab2063SBarry Smith     }
482d00d2cf4SBarry Smith     if (nofinalvalue) {
483d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
484d00d2cf4SBarry Smith     }
485317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
486fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
487d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
48868369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
489cd155464SBarry Smith      PetscFunctionReturn(0);
490fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
491d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
4927566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
49344cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
49477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
49544cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
496aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
49736db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
498ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
49936db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
500ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
50136db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
502ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5036831982aSBarry Smith         }
50444cd7ae7SLois Curfman McInnes #else
505ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
50644cd7ae7SLois Curfman McInnes #endif
50744cd7ae7SLois Curfman McInnes       }
508b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
50944cd7ae7SLois Curfman McInnes     }
510d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
511fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
51297f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
513d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5147566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
51597f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
516496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
517496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
518496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
519496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
520aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
52136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
522496be53dSLois Curfman McInnes #else
523496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
524496be53dSLois Curfman McInnes #endif
525496be53dSLois Curfman McInnes         }
526496be53dSLois Curfman McInnes       }
527496be53dSLois Curfman McInnes     }
5282e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
52977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5302e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
53177431f27SBarry 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);}
53277431f27SBarry 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);}
53377431f27SBarry 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);}
53477431f27SBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
53577431f27SBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
53677431f27SBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);}
537496be53dSLois Curfman McInnes     }
538b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
539606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
540496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
541496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
54277431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
543496be53dSLois Curfman McInnes       }
544b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
545496be53dSLois Curfman McInnes     }
546b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
547496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
548496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
549496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
550aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
55136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
552b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
5536831982aSBarry Smith           }
554496be53dSLois Curfman McInnes #else
555b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
556496be53dSLois Curfman McInnes #endif
557496be53dSLois Curfman McInnes         }
558496be53dSLois Curfman McInnes       }
559b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
560496be53dSLois Curfman McInnes     }
561d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
562fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
56397f1f81fSBarry Smith     PetscInt         cnt = 0,jcnt;
56487828ca2SBarry Smith     PetscScalar value;
56502594712SBarry Smith 
566d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5677566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
56802594712SBarry Smith     for (i=0; i<m; i++) {
56902594712SBarry Smith       jcnt = 0;
570d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
571e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
57202594712SBarry Smith           value = a->a[cnt++];
573e24b481bSBarry Smith           jcnt++;
57402594712SBarry Smith         } else {
57502594712SBarry Smith           value = 0.0;
57602594712SBarry Smith         }
577aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
578b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
57902594712SBarry Smith #else
580b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
58102594712SBarry Smith #endif
58202594712SBarry Smith       }
583b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
58402594712SBarry Smith     }
585d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5863c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
587d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5887566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
5893c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5903c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
5913c215bfdSMatthew Knepley #else
5923c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
5933c215bfdSMatthew Knepley #endif
594d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
5953c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
5963c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5973c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
5983c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
599ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6003c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
601ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6023c215bfdSMatthew Knepley         } else {
603ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6043c215bfdSMatthew Knepley         }
6053c215bfdSMatthew Knepley #else
606ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr);
6073c215bfdSMatthew Knepley #endif
6083c215bfdSMatthew Knepley       }
6093c215bfdSMatthew Knepley     }
610d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6113a40ed3dSBarry Smith   } else {
612d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
6137566de4bSShri Abhyankar     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr);
614d5f3da31SBarry Smith     if (A->factortype){
61516cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
61616cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
61716cd7e1dSShri Abhyankar         /* L part */
61816cd7e1dSShri Abhyankar 	for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
61916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
62016cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
621ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62216cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
623ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62416cd7e1dSShri Abhyankar           } else {
625ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
62616cd7e1dSShri Abhyankar           }
62716cd7e1dSShri Abhyankar #else
628ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
62916cd7e1dSShri Abhyankar #endif
63016cd7e1dSShri Abhyankar         }
63116cd7e1dSShri Abhyankar 	/* diagonal */
63216cd7e1dSShri Abhyankar 	j = a->diag[i];
63316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
63416cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
635ba0e910bSBarry Smith             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);
63616cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
637ba0e910bSBarry Smith             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);
63816cd7e1dSShri Abhyankar           } else {
639ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
64016cd7e1dSShri Abhyankar           }
64116cd7e1dSShri Abhyankar #else
642ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
64316cd7e1dSShri Abhyankar #endif
64416cd7e1dSShri Abhyankar 
64516cd7e1dSShri Abhyankar 	/* U part */
64616cd7e1dSShri Abhyankar 	for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
64716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
64816cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
649ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
65016cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
651ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
65216cd7e1dSShri Abhyankar           } else {
653ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
65416cd7e1dSShri Abhyankar           }
65516cd7e1dSShri Abhyankar #else
656ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
65716cd7e1dSShri Abhyankar #endif
65816cd7e1dSShri Abhyankar }
65916cd7e1dSShri Abhyankar 	  ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
66016cd7e1dSShri Abhyankar         }
66116cd7e1dSShri Abhyankar     } else {
66217ab2063SBarry Smith       for (i=0; i<m; i++) {
66377431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
664416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
665aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
667ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
66836db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
669ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6703a40ed3dSBarry Smith           } else {
671ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
67217ab2063SBarry Smith           }
67317ab2063SBarry Smith #else
674ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
67517ab2063SBarry Smith #endif
67617ab2063SBarry Smith         }
677b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
67817ab2063SBarry Smith       }
67916cd7e1dSShri Abhyankar     }
680d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
68117ab2063SBarry Smith   }
682b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6833a40ed3dSBarry Smith   PetscFunctionReturn(0);
684416022c9SBarry Smith }
685416022c9SBarry Smith 
6864a2ae208SSatish Balay #undef __FUNCT__
6874a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
688dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
689416022c9SBarry Smith {
690480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
691416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
692dfbe8321SBarry Smith   PetscErrorCode    ierr;
693d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
69436db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
695b0a32e0cSBarry Smith   PetscViewer       viewer;
696f3ef73ceSBarry Smith   PetscViewerFormat format;
697cddf8d76SBarry Smith 
6983a40ed3dSBarry Smith   PetscFunctionBegin;
699480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
700b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
70119bcc07fSBarry Smith 
702b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
703416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7040513a670SBarry Smith 
705fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7060513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
707b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
708416022c9SBarry Smith     for (i=0; i<m; i++) {
709cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
710bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
711bfeeae90SHong Zhang         x_l = a->j[j] ; x_r = x_l + 1.0;
712aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
71336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
714cddf8d76SBarry Smith #else
715cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
716cddf8d76SBarry Smith #endif
717b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
718cddf8d76SBarry Smith       }
719cddf8d76SBarry Smith     }
720b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
721cddf8d76SBarry Smith     for (i=0; i<m; i++) {
722cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
723bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
724bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
725cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
726b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
727cddf8d76SBarry Smith       }
728cddf8d76SBarry Smith     }
729b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
730cddf8d76SBarry Smith     for (i=0; i<m; i++) {
731cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
732bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
733bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
734aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
736cddf8d76SBarry Smith #else
737cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
738cddf8d76SBarry Smith #endif
739b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
740416022c9SBarry Smith       }
741416022c9SBarry Smith     }
7420513a670SBarry Smith   } else {
7430513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
7440513a670SBarry Smith     /* first determine max of all nonzero values */
74597f1f81fSBarry Smith     PetscInt    nz = a->nz,count;
746b0a32e0cSBarry Smith     PetscDraw   popup;
74736db0b34SBarry Smith     PetscReal scale;
7480513a670SBarry Smith 
7490513a670SBarry Smith     for (i=0; i<nz; i++) {
7500513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
7510513a670SBarry Smith     }
752b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
753b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
754b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
7550513a670SBarry Smith     count = 0;
7560513a670SBarry Smith     for (i=0; i<m; i++) {
7570513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
758bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
759bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
76097f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
761b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
7620513a670SBarry Smith         count++;
7630513a670SBarry Smith       }
7640513a670SBarry Smith     }
7650513a670SBarry Smith   }
766480ef9eaSBarry Smith   PetscFunctionReturn(0);
767480ef9eaSBarry Smith }
768cddf8d76SBarry Smith 
7694a2ae208SSatish Balay #undef __FUNCT__
7704a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
771dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
772480ef9eaSBarry Smith {
773dfbe8321SBarry Smith   PetscErrorCode ierr;
774b0a32e0cSBarry Smith   PetscDraw      draw;
77536db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
776ace3abfcSBarry Smith   PetscBool      isnull;
777480ef9eaSBarry Smith 
778480ef9eaSBarry Smith   PetscFunctionBegin;
779b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
780b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
781480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
782480ef9eaSBarry Smith 
783480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
784d0f46423SBarry Smith   xr  = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
785480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
786b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
787b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
788480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7893a40ed3dSBarry Smith   PetscFunctionReturn(0);
790416022c9SBarry Smith }
791416022c9SBarry Smith 
7924a2ae208SSatish Balay #undef __FUNCT__
7934a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
794dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
795416022c9SBarry Smith {
796dfbe8321SBarry Smith   PetscErrorCode ierr;
797ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
798416022c9SBarry Smith 
7993a40ed3dSBarry Smith   PetscFunctionBegin;
800251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
801251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
802251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
803c45a1595SBarry Smith   if (iascii) {
8043a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8050f5bd95cSBarry Smith   } else if (isbinary) {
8063a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8070f5bd95cSBarry Smith   } else if (isdraw) {
8083a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
809913ac41fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
8104108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8113a40ed3dSBarry Smith   PetscFunctionReturn(0);
81217ab2063SBarry Smith }
81319bcc07fSBarry Smith 
8144a2ae208SSatish Balay #undef __FUNCT__
8154a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
816dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
81717ab2063SBarry Smith {
818416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8196849ba73SBarry Smith   PetscErrorCode ierr;
82097f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
821d0f46423SBarry Smith   PetscInt       m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
82254f21887SBarry Smith   MatScalar      *aa = a->a,*ap;
8233447b6efSHong Zhang   PetscReal      ratio=0.6;
82417ab2063SBarry Smith 
8253a40ed3dSBarry Smith   PetscFunctionBegin;
8263a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
82717ab2063SBarry Smith 
82843ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
82917ab2063SBarry Smith   for (i=1; i<m; i++) {
830416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
83117ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
83294a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
83317ab2063SBarry Smith     if (fshift) {
834bfeeae90SHong Zhang       ip = aj + ai[i] ;
835bfeeae90SHong Zhang       ap = aa + ai[i] ;
83617ab2063SBarry Smith       N  = ailen[i];
83717ab2063SBarry Smith       for (j=0; j<N; j++) {
83817ab2063SBarry Smith         ip[j-fshift] = ip[j];
83917ab2063SBarry Smith         ap[j-fshift] = ap[j];
84017ab2063SBarry Smith       }
84117ab2063SBarry Smith     }
84217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
84317ab2063SBarry Smith   }
84417ab2063SBarry Smith   if (m) {
84517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
84617ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
84717ab2063SBarry Smith   }
84817ab2063SBarry Smith   /* reset ilen and imax for each row */
84917ab2063SBarry Smith   for (i=0; i<m; i++) {
85017ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
85117ab2063SBarry Smith   }
852bfeeae90SHong Zhang   a->nz = ai[m];
85365e19b50SBarry 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);
85417ab2063SBarry Smith 
85509f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
856d0f46423SBarry 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);
857ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
858ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
8598e58a170SBarry Smith   A->info.mallocs     += a->reallocs;
860dd5f02e7SSatish Balay   a->reallocs          = 0;
8614e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
86236db0b34SBarry Smith   a->rmax              = rmax;
8634e220ebcSLois Curfman McInnes 
864cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
86588e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
86671c2f376SKris Buschelman 
8674108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
86871f1c65dSBarry Smith 
86971f1c65dSBarry Smith   a->idiagvalid  = PETSC_FALSE;
870bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_FALSE;
8713a40ed3dSBarry Smith   PetscFunctionReturn(0);
87217ab2063SBarry Smith }
87317ab2063SBarry Smith 
8744a2ae208SSatish Balay #undef __FUNCT__
87599cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
87699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
87799cafbc1SBarry Smith {
87899cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
87999cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
88054f21887SBarry Smith   MatScalar      *aa = a->a;
88199cafbc1SBarry Smith 
88299cafbc1SBarry Smith   PetscFunctionBegin;
88399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
88486c113feSBarry Smith   a->idiagvalid  = PETSC_FALSE;
88586c113feSBarry Smith   a->ibdiagvalid = PETSC_FALSE;
88699cafbc1SBarry Smith   PetscFunctionReturn(0);
88799cafbc1SBarry Smith }
88899cafbc1SBarry Smith 
88999cafbc1SBarry Smith #undef __FUNCT__
89099cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
89199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
89299cafbc1SBarry Smith {
89399cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
89499cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
89554f21887SBarry Smith   MatScalar      *aa = a->a;
89699cafbc1SBarry Smith 
89799cafbc1SBarry Smith   PetscFunctionBegin;
89899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
89986c113feSBarry Smith   a->idiagvalid  = PETSC_FALSE;
90086c113feSBarry Smith   a->ibdiagvalid = PETSC_FALSE;
90199cafbc1SBarry Smith   PetscFunctionReturn(0);
90299cafbc1SBarry Smith }
90399cafbc1SBarry Smith 
90478b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
90578b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
90678b84d54SShri Abhyankar {
90778b84d54SShri Abhyankar   PetscErrorCode ierr;
90878b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
90978b84d54SShri Abhyankar   PetscInt       n,start,end;
91078b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
91178b84d54SShri Abhyankar 
91278b84d54SShri Abhyankar   start = trstarts[thread_id];
91378b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
91478b84d54SShri Abhyankar   n     = end - start;
91578b84d54SShri Abhyankar   ierr = PetscMemzero(a->a+start,n*sizeof(PetscScalar));CHKERRQ(ierr);
91678b84d54SShri Abhyankar   return 0;
91778b84d54SShri Abhyankar }
91878b84d54SShri Abhyankar 
91978b84d54SShri Abhyankar #undef __FUNCT__
92078b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
92178b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
92278b84d54SShri Abhyankar {
92378b84d54SShri Abhyankar   PetscErrorCode ierr;
92478b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
92578b84d54SShri Abhyankar 
92678b84d54SShri Abhyankar   PetscFunctionBegin;
92778b84d54SShri Abhyankar   ierr = PetscThreadCommRunKernel(((PetscObject)A)->comm,(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
92878b84d54SShri Abhyankar   a->idiagvalid = PETSC_FALSE;
92978b84d54SShri Abhyankar   a->ibdiagvalid = PETSC_FALSE;
93078b84d54SShri Abhyankar   PetscFunctionReturn(0);
93178b84d54SShri Abhyankar }
93278b84d54SShri Abhyankar #else
93399cafbc1SBarry Smith #undef __FUNCT__
9344a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
935dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
93617ab2063SBarry Smith {
937416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
938dfbe8321SBarry Smith   PetscErrorCode ierr;
9393a40ed3dSBarry Smith 
9403a40ed3dSBarry Smith   PetscFunctionBegin;
941d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
94286c113feSBarry Smith   a->idiagvalid  = PETSC_FALSE;
94386c113feSBarry Smith   a->ibdiagvalid = PETSC_FALSE;
9443a40ed3dSBarry Smith   PetscFunctionReturn(0);
94517ab2063SBarry Smith }
94678b84d54SShri Abhyankar #endif
947416022c9SBarry Smith 
9484a2ae208SSatish Balay #undef __FUNCT__
9494a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
950dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
95117ab2063SBarry Smith {
952416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
953dfbe8321SBarry Smith   PetscErrorCode ierr;
954d5d45c9bSBarry Smith 
9553a40ed3dSBarry Smith   PetscFunctionBegin;
956aa482453SBarry Smith #if defined(PETSC_USE_LOG)
957d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
95817ab2063SBarry Smith #endif
959e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
9606bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
9616bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
96205b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
963d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
96405b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
96571f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
96605b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
9676bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
96805b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
9696bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
97005b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
9716bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
972cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
9730b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
974a30b2313SHong Zhang 
9754108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
976bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
977901853e0SKris Buschelman 
978dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
979901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr);
980901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr);
981901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr);
982901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr);
983901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr);
9845a11e1b2SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr);
985901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr);
986901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr);
987a1661176SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr);
988901853e0SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr);
9893a40ed3dSBarry Smith   PetscFunctionReturn(0);
99017ab2063SBarry Smith }
99117ab2063SBarry Smith 
9924a2ae208SSatish Balay #undef __FUNCT__
9934a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
994ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool  flg)
99517ab2063SBarry Smith {
996416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9974846f1f5SKris Buschelman   PetscErrorCode ierr;
9983a40ed3dSBarry Smith 
9993a40ed3dSBarry Smith   PetscFunctionBegin;
1000a65d3064SKris Buschelman   switch (op) {
1001a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10024e0d8c25SBarry Smith     a->roworiented       = flg;
1003a65d3064SKris Buschelman     break;
1004a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1005a9817697SBarry Smith     a->keepnonzeropattern    = flg;
1006a65d3064SKris Buschelman     break;
1007512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1008512a5fc5SBarry Smith     a->nonew             = (flg ? 0 : 1);
1009a65d3064SKris Buschelman     break;
1010a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10114e0d8c25SBarry Smith     a->nonew             = (flg ? -1 : 0);
1012a65d3064SKris Buschelman     break;
1013a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10144e0d8c25SBarry Smith     a->nonew             = (flg ? -2 : 0);
1015a65d3064SKris Buschelman     break;
101628b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
101728b2fa4aSMatthew Knepley     a->nounused          = (flg ? -1 : 0);
101828b2fa4aSMatthew Knepley     break;
1019a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10204e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10210df259c2SBarry Smith     break;
1022cd6b891eSBarry Smith   case MAT_CHECK_COMPRESSED_ROW:
1023cd6b891eSBarry Smith     a->compressedrow.check = flg;
1024d487561eSHong Zhang     break;
10253d472b54SHong Zhang   case MAT_SPD:
1026b1646e73SJed Brown   case MAT_SYMMETRIC:
1027b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1028b1646e73SJed Brown   case MAT_HERMITIAN:
1029b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1030*5021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
1031*5021d80fSJed Brown     break;
10324e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1033a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1034a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1035290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1036a65d3064SKris Buschelman     break;
1037b87ac2d8SJed Brown   case MAT_USE_INODES:
1038b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1039b87ac2d8SJed Brown     break;
1040a65d3064SKris Buschelman   default:
1041e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1042a65d3064SKris Buschelman   }
10434108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
10443a40ed3dSBarry Smith   PetscFunctionReturn(0);
104517ab2063SBarry Smith }
104617ab2063SBarry Smith 
10474a2ae208SSatish Balay #undef __FUNCT__
10484a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1049dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
105017ab2063SBarry Smith {
1051416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10526849ba73SBarry Smith   PetscErrorCode ierr;
1053d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
105435e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
105517ab2063SBarry Smith 
10563a40ed3dSBarry Smith   PetscFunctionBegin;
1057d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1058e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
105935e7444dSHong Zhang 
1060d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){
1061d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
106235e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
10632c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
106435e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
106535e7444dSHong Zhang     PetscFunctionReturn(0);
106635e7444dSHong Zhang   }
106735e7444dSHong Zhang 
10682dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
10691ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
107035e7444dSHong Zhang   for (i=0; i<n; i++) {
107135e7444dSHong Zhang     nz = ai[i+1] - ai[i];
10722f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
107335e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++){
107435e7444dSHong Zhang       if (aj[j] == i) {
107535e7444dSHong Zhang         x[i] = aa[j];
107617ab2063SBarry Smith         break;
107717ab2063SBarry Smith       }
107817ab2063SBarry Smith     }
107917ab2063SBarry Smith   }
10801ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
10813a40ed3dSBarry Smith   PetscFunctionReturn(0);
108217ab2063SBarry Smith }
108317ab2063SBarry Smith 
1084c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
10854a2ae208SSatish Balay #undef __FUNCT__
10864a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1087dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
108817ab2063SBarry Smith {
1089416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
10905c897100SBarry Smith   PetscScalar       *x,*y;
1091dfbe8321SBarry Smith   PetscErrorCode    ierr;
1092d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
10935c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1094a77337e4SBarry Smith   MatScalar         *v;
1095a77337e4SBarry Smith   PetscScalar       alpha;
109604fbf559SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=PETSC_NULL;
10973447b6efSHong Zhang   Mat_CompressedRow cprow = a->compressedrow;
1098ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
10995c897100SBarry Smith #endif
110017ab2063SBarry Smith 
11013a40ed3dSBarry Smith   PetscFunctionBegin;
11022e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11031ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11041ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11055c897100SBarry Smith 
11065c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1107bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11085c897100SBarry Smith #else
11093447b6efSHong Zhang   if (usecprow){
11103447b6efSHong Zhang     m    = cprow.nrows;
11113447b6efSHong Zhang     ii   = cprow.i;
11127b2bb3b9SHong Zhang     ridx = cprow.rindex;
11133447b6efSHong Zhang   } else {
11143447b6efSHong Zhang     ii = a->i;
11153447b6efSHong Zhang   }
111617ab2063SBarry Smith   for (i=0; i<m; i++) {
11173447b6efSHong Zhang     idx   = a->j + ii[i] ;
11183447b6efSHong Zhang     v     = a->a + ii[i] ;
11193447b6efSHong Zhang     n     = ii[i+1] - ii[i];
11203447b6efSHong Zhang     if (usecprow){
11217b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11223447b6efSHong Zhang     } else {
112317ab2063SBarry Smith       alpha = x[i];
11243447b6efSHong Zhang     }
112504fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
112617ab2063SBarry Smith   }
11275c897100SBarry Smith #endif
1128dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11291ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11301ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11313a40ed3dSBarry Smith   PetscFunctionReturn(0);
113217ab2063SBarry Smith }
113317ab2063SBarry Smith 
11344a2ae208SSatish Balay #undef __FUNCT__
11355c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1136dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
11375c897100SBarry Smith {
1138dfbe8321SBarry Smith   PetscErrorCode ierr;
11395c897100SBarry Smith 
11405c897100SBarry Smith   PetscFunctionBegin;
1141170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
11425c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
11435c897100SBarry Smith   PetscFunctionReturn(0);
11445c897100SBarry Smith }
11455c897100SBarry Smith 
1146c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
114778b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
114878b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
114978b84d54SShri Abhyankar {
115078b84d54SShri Abhyankar   PetscErrorCode    ierr;
115178b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
115278b84d54SShri Abhyankar   PetscScalar       *y;
115378b84d54SShri Abhyankar   const PetscScalar *x;
115478b84d54SShri Abhyankar   const MatScalar   *aa;
115578b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
115678b84d54SShri Abhyankar   PetscInt          n,start,end,i;
115778b84d54SShri Abhyankar   const PetscInt   *aj,*ai;
115878b84d54SShri Abhyankar   PetscScalar      sum;
115978b84d54SShri Abhyankar 
116078b84d54SShri Abhyankar   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
116178b84d54SShri Abhyankar   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
116278b84d54SShri Abhyankar   start = trstarts[thread_id];
116378b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
116478b84d54SShri Abhyankar   aj    = a->j;
116578b84d54SShri Abhyankar   aa    = a->a;
116678b84d54SShri Abhyankar   ai    = a->i;
116778b84d54SShri Abhyankar   for (i=start;i<end;i++) {
116878b84d54SShri Abhyankar     n = ai[i+1] - ai[i];
116978b84d54SShri Abhyankar     aj = a->j + ai[i];
117078b84d54SShri Abhyankar     aa = a->a + ai[i];
117178b84d54SShri Abhyankar     sum = 0.0;
117278b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
117378b84d54SShri Abhyankar     y[i] = sum;
117478b84d54SShri Abhyankar   }
117578b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
117678b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
117778b84d54SShri Abhyankar   return 0;
117878b84d54SShri Abhyankar }
117978b84d54SShri Abhyankar 
118078b84d54SShri Abhyankar #undef __FUNCT__
118178b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
118278b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
118378b84d54SShri Abhyankar {
118478b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
118578b84d54SShri Abhyankar   PetscScalar       *y;
118678b84d54SShri Abhyankar   const PetscScalar *x;
118778b84d54SShri Abhyankar   const MatScalar   *aa;
118878b84d54SShri Abhyankar   PetscErrorCode    ierr;
118978b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
119078b84d54SShri Abhyankar   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
119178b84d54SShri Abhyankar   PetscInt          n,i,nonzerorow=0;
119278b84d54SShri Abhyankar   PetscScalar       sum;
119378b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
119478b84d54SShri Abhyankar 
119578b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
119678b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
119778b84d54SShri Abhyankar #endif
119878b84d54SShri Abhyankar 
119978b84d54SShri Abhyankar   PetscFunctionBegin;
120078b84d54SShri Abhyankar   aj  = a->j;
120178b84d54SShri Abhyankar   aa  = a->a;
120278b84d54SShri Abhyankar   ii  = a->i;
120378b84d54SShri Abhyankar   if (usecprow){ /* use compressed row format */
120478b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
120578b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
120678b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
120778b84d54SShri Abhyankar     ii   = a->compressedrow.i;
120878b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
120978b84d54SShri Abhyankar     for (i=0; i<m; i++){
121078b84d54SShri Abhyankar       n   = ii[i+1] - ii[i];
121178b84d54SShri Abhyankar       aj  = a->j + ii[i];
121278b84d54SShri Abhyankar       aa  = a->a + ii[i];
121378b84d54SShri Abhyankar       sum = 0.0;
121478b84d54SShri Abhyankar       nonzerorow += (n>0);
121578b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
121678b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
121778b84d54SShri Abhyankar       y[*ridx++] = sum;
121878b84d54SShri Abhyankar     }
121978b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
122078b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
122178b84d54SShri Abhyankar   } else { /* do not use compressed row format */
122278b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
122378b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
122478b84d54SShri Abhyankar #else
122578b84d54SShri Abhyankar     ierr = PetscThreadCommRunKernel(((PetscObject)A)->comm,(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
122678b84d54SShri Abhyankar #endif
122778b84d54SShri Abhyankar   }
122878b84d54SShri Abhyankar   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
122978b84d54SShri Abhyankar   PetscFunctionReturn(0);
123078b84d54SShri Abhyankar }
123178b84d54SShri Abhyankar #else
12325c897100SBarry Smith #undef __FUNCT__
12334a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1234dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
123517ab2063SBarry Smith {
1236416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1237d9fead3dSBarry Smith   PetscScalar       *y;
123854f21887SBarry Smith   const PetscScalar *x;
123954f21887SBarry Smith   const MatScalar   *aa;
1240dfbe8321SBarry Smith   PetscErrorCode    ierr;
1241003131ecSBarry Smith   PetscInt          m=A->rmap->n;
1242003131ecSBarry Smith   const PetscInt    *aj,*ii,*ridx=PETSC_NULL;
12438aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1244362ced78SSatish Balay   PetscScalar       sum;
1245ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
124617ab2063SBarry Smith 
1247b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
124897952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1249fee21e36SBarry Smith #endif
1250fee21e36SBarry Smith 
12513a40ed3dSBarry Smith   PetscFunctionBegin;
12523649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12531ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
125497952fefSHong Zhang   aj  = a->j;
125597952fefSHong Zhang   aa  = a->a;
1256416022c9SBarry Smith   ii  = a->i;
12574eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
125897952fefSHong Zhang     m    = a->compressedrow.nrows;
125997952fefSHong Zhang     ii   = a->compressedrow.i;
126097952fefSHong Zhang     ridx = a->compressedrow.rindex;
126197952fefSHong Zhang     for (i=0; i<m; i++){
126297952fefSHong Zhang       n   = ii[i+1] - ii[i];
126397952fefSHong Zhang       aj  = a->j + ii[i];
126497952fefSHong Zhang       aa  = a->a + ii[i];
126597952fefSHong Zhang       sum = 0.0;
1266a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1267003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1268003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
126997952fefSHong Zhang       y[*ridx++] = sum;
127097952fefSHong Zhang     }
127197952fefSHong Zhang   } else { /* do not use compressed row format */
1272b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1273b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1274b05257ddSBarry Smith #else
127578b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
127678b84d54SShri Abhyankar     ierr = PetscThreadCommRunKernel(((PetscObject)A)->comm,(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
127778b84d54SShri Abhyankar #else
127817ab2063SBarry Smith     for (i=0; i<m; i++) {
1279003131ecSBarry Smith       n   = ii[i+1] - ii[i];
1280003131ecSBarry Smith       aj  = a->j + ii[i];
1281003131ecSBarry Smith       aa  = a->a + ii[i];
128217ab2063SBarry Smith       sum  = 0.0;
1283a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1284003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128517ab2063SBarry Smith       y[i] = sum;
128617ab2063SBarry Smith     }
12878d195f9aSBarry Smith #endif
128878b84d54SShri Abhyankar #endif
1289b05257ddSBarry Smith   }
1290dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
12913649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12921ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12933a40ed3dSBarry Smith   PetscFunctionReturn(0);
129417ab2063SBarry Smith }
129578b84d54SShri Abhyankar #endif
129617ab2063SBarry Smith 
1297c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
12984a2ae208SSatish Balay #undef __FUNCT__
12994a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1300dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
130117ab2063SBarry Smith {
1302416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1303f15663dcSBarry Smith   PetscScalar       *y,*z;
1304f15663dcSBarry Smith   const PetscScalar *x;
130554f21887SBarry Smith   const MatScalar   *aa;
1306dfbe8321SBarry Smith   PetscErrorCode    ierr;
1307d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
1308f15663dcSBarry Smith   PetscInt          n,i,*ridx=PETSC_NULL;
1309362ced78SSatish Balay   PetscScalar       sum;
1310ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
13119ea0dfa2SSatish Balay 
13123a40ed3dSBarry Smith   PetscFunctionBegin;
1313f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13141ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
13152e8a6d31SBarry Smith   if (zz != yy) {
13161ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
13172e8a6d31SBarry Smith   } else {
13182e8a6d31SBarry Smith     z = y;
13192e8a6d31SBarry Smith   }
1320bfeeae90SHong Zhang 
132197952fefSHong Zhang   aj  = a->j;
132297952fefSHong Zhang   aa  = a->a;
1323cddf8d76SBarry Smith   ii  = a->i;
13244eb6d288SHong Zhang   if (usecprow){ /* use compressed row format */
13254eb6d288SHong Zhang     if (zz != yy){
13264eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
13274eb6d288SHong Zhang     }
132897952fefSHong Zhang     m    = a->compressedrow.nrows;
132997952fefSHong Zhang     ii   = a->compressedrow.i;
133097952fefSHong Zhang     ridx = a->compressedrow.rindex;
133197952fefSHong Zhang     for (i=0; i<m; i++){
133297952fefSHong Zhang       n  = ii[i+1] - ii[i];
133397952fefSHong Zhang       aj  = a->j + ii[i];
133497952fefSHong Zhang       aa  = a->a + ii[i];
133597952fefSHong Zhang       sum = y[*ridx];
1336f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
133797952fefSHong Zhang       z[*ridx++] = sum;
133897952fefSHong Zhang     }
133997952fefSHong Zhang   } else { /* do not use compressed row format */
1340f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1341f15663dcSBarry Smith   fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1342f15663dcSBarry Smith #else
134317ab2063SBarry Smith     for (i=0; i<m; i++) {
1344f15663dcSBarry Smith       n    = ii[i+1] - ii[i];
1345f15663dcSBarry Smith       aj  = a->j + ii[i];
1346f15663dcSBarry Smith       aa  = a->a + ii[i];
134717ab2063SBarry Smith       sum  = y[i];
1348f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
134917ab2063SBarry Smith       z[i] = sum;
135017ab2063SBarry Smith     }
135102ab625aSSatish Balay #endif
1352f15663dcSBarry Smith   }
1353dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1354f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13551ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13562e8a6d31SBarry Smith   if (zz != yy) {
13571ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
13582e8a6d31SBarry Smith   }
13598154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
13606b375ea7SVictor Minden   /*
1361918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1362918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1363918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
13646b375ea7SVictor Minden   */
1365918e98c3SVictor Minden #endif
13663a40ed3dSBarry Smith   PetscFunctionReturn(0);
136717ab2063SBarry Smith }
136817ab2063SBarry Smith 
136917ab2063SBarry Smith /*
137017ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
137117ab2063SBarry Smith */
13724a2ae208SSatish Balay #undef __FUNCT__
13734a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1374dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
137517ab2063SBarry Smith {
1376416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
13776849ba73SBarry Smith   PetscErrorCode ierr;
1378d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
137917ab2063SBarry Smith 
13803a40ed3dSBarry Smith   PetscFunctionBegin;
138109f38230SBarry Smith   if (!a->diag) {
138209f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
13839518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr);
138409f38230SBarry Smith   }
1385d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
138609f38230SBarry Smith     a->diag[i] = a->i[i+1];
1387bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1388bfeeae90SHong Zhang       if (a->j[j] == i) {
138909f38230SBarry Smith         a->diag[i] = j;
139017ab2063SBarry Smith         break;
139117ab2063SBarry Smith       }
139217ab2063SBarry Smith     }
139317ab2063SBarry Smith   }
13943a40ed3dSBarry Smith   PetscFunctionReturn(0);
139517ab2063SBarry Smith }
139617ab2063SBarry Smith 
1397be5855fcSBarry Smith /*
1398be5855fcSBarry Smith      Checks for missing diagonals
1399be5855fcSBarry Smith */
14004a2ae208SSatish Balay #undef __FUNCT__
14014a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1402ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1403be5855fcSBarry Smith {
1404be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
140597f1f81fSBarry Smith   PetscInt       *diag,*jj = a->j,i;
1406be5855fcSBarry Smith 
1407be5855fcSBarry Smith   PetscFunctionBegin;
140809f38230SBarry Smith   *missing = PETSC_FALSE;
1409d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
141009f38230SBarry Smith     *missing  = PETSC_TRUE;
141109f38230SBarry Smith     if (d) *d = 0;
1412358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
141309f38230SBarry Smith   } else {
1414f1e2ffcdSBarry Smith     diag = a->diag;
1415d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1416bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
141709f38230SBarry Smith 	*missing = PETSC_TRUE;
141809f38230SBarry Smith 	if (d) *d = i;
141909f38230SBarry Smith 	PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1420358d2f5dSShri Abhyankar 	break;
142109f38230SBarry Smith       }
1422be5855fcSBarry Smith     }
1423be5855fcSBarry Smith   }
1424be5855fcSBarry Smith   PetscFunctionReturn(0);
1425be5855fcSBarry Smith }
1426be5855fcSBarry Smith 
142771f1c65dSBarry Smith EXTERN_C_BEGIN
142871f1c65dSBarry Smith #undef __FUNCT__
142971f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
14307087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
143171f1c65dSBarry Smith {
143271f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
143371f1c65dSBarry Smith   PetscErrorCode ierr;
1434d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
143554f21887SBarry Smith   MatScalar      *v = a->a;
143654f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
143771f1c65dSBarry Smith 
143871f1c65dSBarry Smith   PetscFunctionBegin;
143971f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
144071f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
144171f1c65dSBarry Smith   diag = a->diag;
144271f1c65dSBarry Smith   if (!a->idiag) {
144371f1c65dSBarry Smith     ierr     = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
144471f1c65dSBarry Smith     ierr     = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
144571f1c65dSBarry Smith     v        = a->a;
144671f1c65dSBarry Smith   }
144771f1c65dSBarry Smith   mdiag = a->mdiag;
144871f1c65dSBarry Smith   idiag = a->idiag;
144971f1c65dSBarry Smith 
1450028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
145171f1c65dSBarry Smith     for (i=0; i<m; i++) {
145271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1453e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
145471f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
145571f1c65dSBarry Smith     }
145671f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
145771f1c65dSBarry Smith   } else {
145871f1c65dSBarry Smith     for (i=0; i<m; i++) {
145971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
146071f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
146171f1c65dSBarry Smith     }
1462dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
146371f1c65dSBarry Smith   }
146471f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
146571f1c65dSBarry Smith   PetscFunctionReturn(0);
146671f1c65dSBarry Smith }
14675a9745a3SMatthew Knepley EXTERN_C_END
146871f1c65dSBarry Smith 
1469c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
14704a2ae208SSatish Balay #undef __FUNCT__
147141f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
147241f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
147317ab2063SBarry Smith {
1474416022c9SBarry Smith   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
1475e6d1f457SBarry Smith   PetscScalar        *x,d,sum,*t,scale;
1476e6d1f457SBarry Smith   const MatScalar    *v = a->a,*idiag=0,*mdiag;
147754f21887SBarry Smith   const PetscScalar  *b, *bs,*xb, *ts;
1478dfbe8321SBarry Smith   PetscErrorCode     ierr;
1479d0f46423SBarry Smith   PetscInt           n = A->cmap->n,m = A->rmap->n,i;
148097f1f81fSBarry Smith   const PetscInt     *idx,*diag;
148117ab2063SBarry Smith 
14823a40ed3dSBarry Smith   PetscFunctionBegin;
1483b965ef7fSBarry Smith   its = its*lits;
148491723122SBarry Smith 
148571f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
148671f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
148771f1c65dSBarry Smith   a->fshift = fshift;
148871f1c65dSBarry Smith   a->omega  = omega;
1489ed480e8bSBarry Smith 
149071f1c65dSBarry Smith   diag = a->diag;
149171f1c65dSBarry Smith   t     = a->ssor_work;
1492ed480e8bSBarry Smith   idiag = a->idiag;
149371f1c65dSBarry Smith   mdiag = a->mdiag;
1494ed480e8bSBarry Smith 
14951ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
14963649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
149771f1c65dSBarry Smith   CHKMEMQ;
1498ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
149917ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
150017ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
1501ed480e8bSBarry Smith     bs = b;
150217ab2063SBarry Smith     for (i=0; i<m; i++) {
150371f1c65dSBarry Smith         d    = fshift + mdiag[i];
1504416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1505ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1506ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
150717ab2063SBarry Smith         sum  = b[i]*d/omega;
1508003131ecSBarry Smith         PetscSparseDensePlusDot(sum,bs,v,idx,n);
150917ab2063SBarry Smith         x[i] = sum;
151017ab2063SBarry Smith     }
15111ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
15123649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1513efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
15143a40ed3dSBarry Smith     PetscFunctionReturn(0);
151517ab2063SBarry Smith   }
1516c783ea89SBarry Smith 
151748af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1518e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
15193a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
152017ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1521887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
152217ab2063SBarry Smith 
152317ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
152417ab2063SBarry Smith 
1525887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
152617ab2063SBarry Smith     */
152717ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
152817ab2063SBarry Smith 
152917ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
153017ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1531416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1532ed480e8bSBarry Smith       idx  = a->j + diag[i] + 1;
1533ed480e8bSBarry Smith       v    = a->a + diag[i] + 1;
153417ab2063SBarry Smith       sum  = b[i];
1535e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1536ed480e8bSBarry Smith       x[i] = sum*idiag[i];
153717ab2063SBarry Smith     }
153817ab2063SBarry Smith 
153917ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1540416022c9SBarry Smith     v = a->a;
1541ed480e8bSBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; }
154217ab2063SBarry Smith 
154317ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1544ed480e8bSBarry Smith     ts = t;
1545416022c9SBarry Smith     diag = a->diag;
154617ab2063SBarry Smith     for (i=0; i<m; i++) {
1547416022c9SBarry Smith       n    = diag[i] - a->i[i];
1548ed480e8bSBarry Smith       idx  = a->j + a->i[i];
1549ed480e8bSBarry Smith       v    = a->a + a->i[i];
155017ab2063SBarry Smith       sum  = t[i];
1551003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1552ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1553733d66baSBarry Smith       /*  x = x + t */
1554733d66baSBarry Smith       x[i] += t[i];
155517ab2063SBarry Smith     }
155617ab2063SBarry Smith 
1557dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
15581ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
15593649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
15603a40ed3dSBarry Smith     PetscFunctionReturn(0);
156117ab2063SBarry Smith   }
156217ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
156317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
156417ab2063SBarry Smith       for (i=0; i<m; i++) {
1565416022c9SBarry Smith         n    = diag[i] - a->i[i];
1566ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1567ed480e8bSBarry Smith         v    = a->a + a->i[i];
156817ab2063SBarry Smith         sum  = b[i];
1569e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
15705c99c7daSBarry Smith         t[i] = sum;
1571ed480e8bSBarry Smith         x[i] = sum*idiag[i];
157217ab2063SBarry Smith       }
15735c99c7daSBarry Smith       xb = t;
1574efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
15753a40ed3dSBarry Smith     } else xb = b;
157617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
157717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1578416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1579ed480e8bSBarry Smith         idx  = a->j + diag[i] + 1;
1580ed480e8bSBarry Smith         v    = a->a + diag[i] + 1;
158117ab2063SBarry Smith         sum  = xb[i];
1582e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
15835c99c7daSBarry Smith         if (xb == b) {
1584ed480e8bSBarry Smith           x[i] = sum*idiag[i];
15855c99c7daSBarry Smith         } else {
15865c99c7daSBarry Smith           x[i] = (1-omega)*x[i] + sum*idiag[i];
158717ab2063SBarry Smith         }
15885c99c7daSBarry Smith       }
1589efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
159017ab2063SBarry Smith     }
159117ab2063SBarry Smith     its--;
159217ab2063SBarry Smith   }
159317ab2063SBarry Smith   while (its--) {
159417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
159517ab2063SBarry Smith       for (i=0; i<m; i++) {
1596416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1597ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1598ed480e8bSBarry Smith         v    = a->a + a->i[i];
159917ab2063SBarry Smith         sum  = b[i];
1600e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1601ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
160217ab2063SBarry Smith       }
16039f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
160417ab2063SBarry Smith     }
160517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
160617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1607416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1608ed480e8bSBarry Smith         idx  = a->j + a->i[i];
1609ed480e8bSBarry Smith         v    = a->a + a->i[i];
161017ab2063SBarry Smith         sum  = b[i];
1611e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1612ed480e8bSBarry Smith         x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
161317ab2063SBarry Smith       }
16149f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
161517ab2063SBarry Smith     }
161617ab2063SBarry Smith   }
16171ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16183649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
161971f1c65dSBarry Smith   CHKMEMQ;  PetscFunctionReturn(0);
162017ab2063SBarry Smith }
162117ab2063SBarry Smith 
16222af78befSBarry Smith 
16234a2ae208SSatish Balay #undef __FUNCT__
16244a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1625dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
162617ab2063SBarry Smith {
1627416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
16284e220ebcSLois Curfman McInnes 
16293a40ed3dSBarry Smith   PetscFunctionBegin;
16304e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
16314e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
16324e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
16334e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
16344e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
16358e58a170SBarry Smith   info->mallocs        = (double)A->info.mallocs;
16367adad957SLisandro Dalcin   info->memory         = ((PetscObject)A)->mem;
1637d5f3da31SBarry Smith   if (A->factortype) {
16384e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
16394e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
16404e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
16414e220ebcSLois Curfman McInnes   } else {
16424e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
16434e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
16444e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
16454e220ebcSLois Curfman McInnes   }
16463a40ed3dSBarry Smith   PetscFunctionReturn(0);
164717ab2063SBarry Smith }
164817ab2063SBarry Smith 
16494a2ae208SSatish Balay #undef __FUNCT__
16504a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
16512b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
165217ab2063SBarry Smith {
1653416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
16543b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
16556849ba73SBarry Smith   PetscErrorCode    ierr;
165697b48c8fSBarry Smith   const PetscScalar *xx;
165797b48c8fSBarry Smith   PetscScalar       *bb;
1658ace3abfcSBarry Smith   PetscBool         missing;
165917ab2063SBarry Smith 
16603a40ed3dSBarry Smith   PetscFunctionBegin;
166197b48c8fSBarry Smith   if (x && b) {
166297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
166397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
166497b48c8fSBarry Smith     for (i=0; i<N; i++) {
166597b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
166697b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
166797b48c8fSBarry Smith     }
166897b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
166997b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
167097b48c8fSBarry Smith   }
167197b48c8fSBarry Smith 
1672a9817697SBarry Smith   if (a->keepnonzeropattern) {
1673f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1674e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1675bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1676f1e2ffcdSBarry Smith     }
1677f4df32b1SMatthew Knepley     if (diag != 0.0) {
167809f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1679e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1680f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1681f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1682f1e2ffcdSBarry Smith       }
1683f1e2ffcdSBarry Smith     }
168488e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1685f1e2ffcdSBarry Smith   } else {
1686f4df32b1SMatthew Knepley     if (diag != 0.0) {
168717ab2063SBarry Smith       for (i=0; i<N; i++) {
1688e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
16897ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1690416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1691f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1692bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
16937ae801bdSBarry Smith         } else { /* in case row was completely empty */
1694f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
169517ab2063SBarry Smith         }
169617ab2063SBarry Smith       }
16973a40ed3dSBarry Smith     } else {
169817ab2063SBarry Smith       for (i=0; i<N; i++) {
1699e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1700416022c9SBarry Smith         a->ilen[rows[i]] = 0;
170117ab2063SBarry Smith       }
170217ab2063SBarry Smith     }
170388e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1704f1e2ffcdSBarry Smith   }
170543a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17063a40ed3dSBarry Smith   PetscFunctionReturn(0);
170717ab2063SBarry Smith }
170817ab2063SBarry Smith 
17094a2ae208SSatish Balay #undef __FUNCT__
17106e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
17116e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17126e169961SBarry Smith {
17136e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
17146e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
17156e169961SBarry Smith   PetscErrorCode    ierr;
17162b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
17176e169961SBarry Smith   const PetscScalar *xx;
17186e169961SBarry Smith   PetscScalar       *bb;
17196e169961SBarry Smith 
17206e169961SBarry Smith   PetscFunctionBegin;
17216e169961SBarry Smith   if (x && b) {
17226e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
17236e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17242b40b63fSBarry Smith     vecs = PETSC_TRUE;
17256e169961SBarry Smith   }
17266e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
17276e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
17286e169961SBarry Smith   for (i=0; i<N; i++) {
17296e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17306e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
17316e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
17326e169961SBarry Smith   }
17336e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
17346e169961SBarry Smith     if (!zeroed[i]) {
17356e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
17366e169961SBarry Smith         if (zeroed[a->j[j]]) {
17372b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
17386e169961SBarry Smith           a->a[j] = 0.0;
17396e169961SBarry Smith         }
17406e169961SBarry Smith       }
17412b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
17426e169961SBarry Smith   }
17436e169961SBarry Smith   if (x && b) {
17446e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
17456e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
17466e169961SBarry Smith   }
17476e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
17486e169961SBarry Smith   if (diag != 0.0) {
17496e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
17506e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
17516e169961SBarry Smith     for (i=0; i<N; i++) {
17526e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
17536e169961SBarry Smith     }
17546e169961SBarry Smith   }
17556e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
17566e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17576e169961SBarry Smith   PetscFunctionReturn(0);
17586e169961SBarry Smith }
17596e169961SBarry Smith 
17606e169961SBarry Smith #undef __FUNCT__
17614a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1762a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
176317ab2063SBarry Smith {
1764416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
176597f1f81fSBarry Smith   PetscInt   *itmp;
176617ab2063SBarry Smith 
17673a40ed3dSBarry Smith   PetscFunctionBegin;
1768e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
176917ab2063SBarry Smith 
1770416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1771bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
177217ab2063SBarry Smith   if (idx) {
1773bfeeae90SHong Zhang     itmp = a->j + a->i[row];
1774bfeeae90SHong Zhang     if (*nz) {
17754e093b46SBarry Smith       *idx = itmp;
177617ab2063SBarry Smith     }
177717ab2063SBarry Smith     else *idx = 0;
177817ab2063SBarry Smith   }
17793a40ed3dSBarry Smith   PetscFunctionReturn(0);
178017ab2063SBarry Smith }
178117ab2063SBarry Smith 
1782bfeeae90SHong Zhang /* remove this function? */
17834a2ae208SSatish Balay #undef __FUNCT__
17844a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1785a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
178617ab2063SBarry Smith {
17873a40ed3dSBarry Smith   PetscFunctionBegin;
17883a40ed3dSBarry Smith   PetscFunctionReturn(0);
178917ab2063SBarry Smith }
179017ab2063SBarry Smith 
17914a2ae208SSatish Balay #undef __FUNCT__
17924a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1793dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
179417ab2063SBarry Smith {
1795416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
179654f21887SBarry Smith   MatScalar      *v = a->a;
179736db0b34SBarry Smith   PetscReal      sum = 0.0;
17986849ba73SBarry Smith   PetscErrorCode ierr;
179997f1f81fSBarry Smith   PetscInt       i,j;
180017ab2063SBarry Smith 
18013a40ed3dSBarry Smith   PetscFunctionBegin;
180217ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1803416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1804aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
180536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
180617ab2063SBarry Smith #else
180717ab2063SBarry Smith       sum += (*v)*(*v); v++;
180817ab2063SBarry Smith #endif
180917ab2063SBarry Smith     }
18108f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
18113a40ed3dSBarry Smith   } else if (type == NORM_1) {
181236db0b34SBarry Smith     PetscReal *tmp;
181397f1f81fSBarry Smith     PetscInt    *jj = a->j;
1814d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1815d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
1816064f8208SBarry Smith     *nrm = 0.0;
1817416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1818bfeeae90SHong Zhang         tmp[*jj++] += PetscAbsScalar(*v);  v++;
181917ab2063SBarry Smith     }
1820d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1821064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
182217ab2063SBarry Smith     }
1823606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
18243a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1825064f8208SBarry Smith     *nrm = 0.0;
1826d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1827bfeeae90SHong Zhang       v = a->a + a->i[j];
182817ab2063SBarry Smith       sum = 0.0;
1829416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1830cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
183117ab2063SBarry Smith       }
1832064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
183317ab2063SBarry Smith     }
18343a40ed3dSBarry Smith   } else {
1835e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
183617ab2063SBarry Smith   }
18373a40ed3dSBarry Smith   PetscFunctionReturn(0);
183817ab2063SBarry Smith }
183917ab2063SBarry Smith 
18404e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
18414e938277SHong Zhang #undef __FUNCT__
18424e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
18434e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
18444e938277SHong Zhang {
18454e938277SHong Zhang   PetscErrorCode ierr;
18464e938277SHong Zhang   PetscInt       i,j,anzj;
18474e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ *)A->data,*b;
18484e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
18494e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
18504e938277SHong Zhang 
18514e938277SHong Zhang   PetscFunctionBegin;
18524e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
18534e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
18544e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
18554e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
18564e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
18574e938277SHong Zhang 
18584e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
18594e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
18604e938277SHong Zhang   for (i=0;i<ai[am];i++) {
18614e938277SHong Zhang     ati[aj[i]+1] += 1;
18624e938277SHong Zhang   }
18634e938277SHong Zhang   /* Form ati for csr format of A^T. */
18644e938277SHong Zhang   for (i=0;i<an;i++) {
18654e938277SHong Zhang     ati[i+1] += ati[i];
18664e938277SHong Zhang   }
18674e938277SHong Zhang 
18684e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
18694e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
18704e938277SHong Zhang 
18714e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
18724e938277SHong Zhang   for (i=0;i<am;i++) {
18734e938277SHong Zhang     anzj = ai[i+1] - ai[i];
18744e938277SHong Zhang     for (j=0;j<anzj;j++) {
18754e938277SHong Zhang       atj[atfill[*aj]] = i;
18764e938277SHong Zhang       atfill[*aj++]   += 1;
18774e938277SHong Zhang     }
18784e938277SHong Zhang   }
18794e938277SHong Zhang 
18804e938277SHong Zhang   /* Clean up temporary space and complete requests. */
18814e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
18824e938277SHong Zhang   ierr = MatCreateSeqAIJWithArrays(((PetscObject)A)->comm,an,am,ati,atj,PETSC_NULL,B);CHKERRQ(ierr);
1883a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
1884a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
1885a2f3521dSMark F. Adams 
18864e938277SHong Zhang   b = (Mat_SeqAIJ *)((*B)->data);
18874e938277SHong Zhang   b->free_a   = PETSC_FALSE;
18884e938277SHong Zhang   b->free_ij  = PETSC_TRUE;
18894e938277SHong Zhang   b->nonew    = 0;
18904e938277SHong Zhang   PetscFunctionReturn(0);
18914e938277SHong Zhang }
18924e938277SHong Zhang 
18934a2ae208SSatish Balay #undef __FUNCT__
18944a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
1895fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
189617ab2063SBarry Smith {
1897416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1898416022c9SBarry Smith   Mat            C;
18996849ba73SBarry Smith   PetscErrorCode ierr;
1900d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
190154f21887SBarry Smith   MatScalar      *array = a->a;
190217ab2063SBarry Smith 
19033a40ed3dSBarry Smith   PetscFunctionBegin;
1904e32f2f54SBarry 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");
1905fc4dec0aSBarry Smith 
1906fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
1907d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
1908d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
1909bfeeae90SHong Zhang 
1910bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
19117adad957SLisandro Dalcin     ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
1912d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
1913a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
19147adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1915ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1916606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1917a541d17aSBarry Smith   } else {
1918a541d17aSBarry Smith     C = *B;
1919a541d17aSBarry Smith   }
1920a541d17aSBarry Smith 
192117ab2063SBarry Smith   for (i=0; i<m; i++) {
192217ab2063SBarry Smith     len    = ai[i+1]-ai[i];
192387d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1924b9b97703SBarry Smith     array += len;
1925b9b97703SBarry Smith     aj    += len;
192617ab2063SBarry Smith   }
19276d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19286d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
192917ab2063SBarry Smith 
1930815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
1931416022c9SBarry Smith     *B = C;
193217ab2063SBarry Smith   } else {
1933eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
193417ab2063SBarry Smith   }
19353a40ed3dSBarry Smith   PetscFunctionReturn(0);
193617ab2063SBarry Smith }
193717ab2063SBarry Smith 
1938cd0d46ebSvictorle EXTERN_C_BEGIN
1939cd0d46ebSvictorle #undef __FUNCT__
19405fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
19417087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
1942cd0d46ebSvictorle {
1943cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
194454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
194554f21887SBarry Smith   MatScalar      *va,*vb;
19466849ba73SBarry Smith   PetscErrorCode ierr;
194797f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
1948cd0d46ebSvictorle 
1949cd0d46ebSvictorle   PetscFunctionBegin;
1950cd0d46ebSvictorle   bij = (Mat_SeqAIJ *) B->data;
1951cd0d46ebSvictorle 
1952cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
1953cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
19545485867bSBarry Smith   if (ma!=nb || na!=mb){
19555485867bSBarry Smith     *f = PETSC_FALSE;
19565485867bSBarry Smith     PetscFunctionReturn(0);
19575485867bSBarry Smith   }
1958cd0d46ebSvictorle   aii = aij->i; bii = bij->i;
1959cd0d46ebSvictorle   adx = aij->j; bdx = bij->j;
1960cd0d46ebSvictorle   va  = aij->a; vb = bij->a;
196197f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
196297f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
1963cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
1964cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
1965cd0d46ebSvictorle 
1966cd0d46ebSvictorle   *f = PETSC_TRUE;
1967cd0d46ebSvictorle   for (i=0; i<ma; i++) {
1968cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
196997f1f81fSBarry Smith       PetscInt         idc,idr;
19705485867bSBarry Smith       PetscScalar vc,vr;
1971cd0d46ebSvictorle       /* column/row index/value */
19725485867bSBarry Smith       idc = adx[aptr[i]];
19735485867bSBarry Smith       idr = bdx[bptr[idc]];
19745485867bSBarry Smith       vc  = va[aptr[i]];
19755485867bSBarry Smith       vr  = vb[bptr[idc]];
19765485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
19775485867bSBarry Smith         *f = PETSC_FALSE;
19785485867bSBarry Smith         goto done;
1979cd0d46ebSvictorle       } else {
19805485867bSBarry Smith         aptr[i]++;
19815485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
1982cd0d46ebSvictorle       }
1983cd0d46ebSvictorle     }
1984cd0d46ebSvictorle   }
1985cd0d46ebSvictorle  done:
1986cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
19873aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
1988cd0d46ebSvictorle   PetscFunctionReturn(0);
1989cd0d46ebSvictorle }
1990cd0d46ebSvictorle EXTERN_C_END
1991cd0d46ebSvictorle 
19921cbb95d3SBarry Smith EXTERN_C_BEGIN
19931cbb95d3SBarry Smith #undef __FUNCT__
19941cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
19957087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
19961cbb95d3SBarry Smith {
19971cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data;
199854f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
199954f21887SBarry Smith   MatScalar      *va,*vb;
20001cbb95d3SBarry Smith   PetscErrorCode ierr;
20011cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20021cbb95d3SBarry Smith 
20031cbb95d3SBarry Smith   PetscFunctionBegin;
20041cbb95d3SBarry Smith   bij = (Mat_SeqAIJ *) B->data;
20051cbb95d3SBarry Smith 
20061cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20071cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20081cbb95d3SBarry Smith   if (ma!=nb || na!=mb){
20091cbb95d3SBarry Smith     *f = PETSC_FALSE;
20101cbb95d3SBarry Smith     PetscFunctionReturn(0);
20111cbb95d3SBarry Smith   }
20121cbb95d3SBarry Smith   aii = aij->i; bii = bij->i;
20131cbb95d3SBarry Smith   adx = aij->j; bdx = bij->j;
20141cbb95d3SBarry Smith   va  = aij->a; vb = bij->a;
20151cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
20161cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
20171cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20181cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20191cbb95d3SBarry Smith 
20201cbb95d3SBarry Smith   *f = PETSC_TRUE;
20211cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20221cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
20231cbb95d3SBarry Smith       PetscInt         idc,idr;
20241cbb95d3SBarry Smith       PetscScalar vc,vr;
20251cbb95d3SBarry Smith       /* column/row index/value */
20261cbb95d3SBarry Smith       idc = adx[aptr[i]];
20271cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
20281cbb95d3SBarry Smith       vc  = va[aptr[i]];
20291cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
20301cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
20311cbb95d3SBarry Smith         *f = PETSC_FALSE;
20321cbb95d3SBarry Smith         goto done;
20331cbb95d3SBarry Smith       } else {
20341cbb95d3SBarry Smith         aptr[i]++;
20351cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
20361cbb95d3SBarry Smith       }
20371cbb95d3SBarry Smith     }
20381cbb95d3SBarry Smith   }
20391cbb95d3SBarry Smith  done:
20401cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
20411cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
20421cbb95d3SBarry Smith   PetscFunctionReturn(0);
20431cbb95d3SBarry Smith }
20441cbb95d3SBarry Smith EXTERN_C_END
20451cbb95d3SBarry Smith 
20469e29f15eSvictorle #undef __FUNCT__
20479e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2048ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20499e29f15eSvictorle {
2050dfbe8321SBarry Smith   PetscErrorCode ierr;
20519e29f15eSvictorle   PetscFunctionBegin;
20525485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
20539e29f15eSvictorle   PetscFunctionReturn(0);
20549e29f15eSvictorle }
20559e29f15eSvictorle 
20564a2ae208SSatish Balay #undef __FUNCT__
20571cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2058ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
20591cbb95d3SBarry Smith {
20601cbb95d3SBarry Smith   PetscErrorCode ierr;
20611cbb95d3SBarry Smith   PetscFunctionBegin;
20621cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
20631cbb95d3SBarry Smith   PetscFunctionReturn(0);
20641cbb95d3SBarry Smith }
20651cbb95d3SBarry Smith 
20661cbb95d3SBarry Smith #undef __FUNCT__
20674a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2068dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
206917ab2063SBarry Smith {
2070416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
207154f21887SBarry Smith   PetscScalar    *l,*r,x;
207254f21887SBarry Smith   MatScalar      *v;
2073dfbe8321SBarry Smith   PetscErrorCode ierr;
2074d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
207517ab2063SBarry Smith 
20763a40ed3dSBarry Smith   PetscFunctionBegin;
207717ab2063SBarry Smith   if (ll) {
20783ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
20793ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2080e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2081e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
20821ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2083416022c9SBarry Smith     v = a->a;
208417ab2063SBarry Smith     for (i=0; i<m; i++) {
208517ab2063SBarry Smith       x = l[i];
2086416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
208717ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
208817ab2063SBarry Smith     }
20891ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2090efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
209117ab2063SBarry Smith   }
209217ab2063SBarry Smith   if (rr) {
2093e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2094e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
20951ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2096416022c9SBarry Smith     v = a->a; jj = a->j;
209717ab2063SBarry Smith     for (i=0; i<nz; i++) {
2098bfeeae90SHong Zhang       (*v++) *= r[*jj++];
209917ab2063SBarry Smith     }
21001ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2101efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
210217ab2063SBarry Smith   }
210386c113feSBarry Smith   a->idiagvalid  = PETSC_FALSE;
210486c113feSBarry Smith   a->ibdiagvalid = PETSC_FALSE;
21053a40ed3dSBarry Smith   PetscFunctionReturn(0);
210617ab2063SBarry Smith }
210717ab2063SBarry Smith 
21084a2ae208SSatish Balay #undef __FUNCT__
21094a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
211097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
211117ab2063SBarry Smith {
2112db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21136849ba73SBarry Smith   PetscErrorCode ierr;
2114d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
211597f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21165d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21175d0c19d7SBarry Smith   PetscInt       nrows,ncols;
211897f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
211954f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2120416022c9SBarry Smith   Mat            C;
2121ace3abfcSBarry Smith   PetscBool      stride,sorted;
212217ab2063SBarry Smith 
21233a40ed3dSBarry Smith   PetscFunctionBegin;
212414ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2125e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
212614ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2127e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
212899141d43SSatish Balay 
212917ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2130b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2131b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
213217ab2063SBarry Smith 
2133fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2134251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2135fee21e36SBarry Smith   if (stride && step == 1) {
213602834360SBarry Smith     /* special case of contiguous rows */
21370e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
213802834360SBarry Smith     /* loop over new rows determining lens and starting points */
213902834360SBarry Smith     for (i=0; i<nrows; i++) {
2140bfeeae90SHong Zhang       kstart  = ai[irow[i]];
2141a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
214202834360SBarry Smith       for (k=kstart; k<kend; k++) {
2143bfeeae90SHong Zhang         if (aj[k] >= first) {
214402834360SBarry Smith           starts[i] = k;
214502834360SBarry Smith           break;
214602834360SBarry Smith 	}
214702834360SBarry Smith       }
2148a2744918SBarry Smith       sum = 0;
214902834360SBarry Smith       while (k < kend) {
2150bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2151a2744918SBarry Smith         sum++;
215202834360SBarry Smith       }
2153a2744918SBarry Smith       lens[i] = sum;
215402834360SBarry Smith     }
215502834360SBarry Smith     /* create submatrix */
2156cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
215797f1f81fSBarry Smith       PetscInt n_cols,n_rows;
215808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2159e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2160d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
216108480c60SBarry Smith       C = *B;
21623a40ed3dSBarry Smith     } else {
21633bef6203SJed Brown       PetscInt rbs,cbs;
21647adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2165f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
21663bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
21673bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
21683bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
21697adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2170ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
217108480c60SBarry Smith     }
2172db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2173db02288aSLois Curfman McInnes 
217402834360SBarry Smith     /* loop over rows inserting into submatrix */
2175db02288aSLois Curfman McInnes     a_new    = c->a;
2176db02288aSLois Curfman McInnes     j_new    = c->j;
2177db02288aSLois Curfman McInnes     i_new    = c->i;
2178bfeeae90SHong Zhang 
217902834360SBarry Smith     for (i=0; i<nrows; i++) {
2180a2744918SBarry Smith       ii    = starts[i];
2181a2744918SBarry Smith       lensi = lens[i];
2182a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2183a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
218402834360SBarry Smith       }
218587828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2186a2744918SBarry Smith       a_new      += lensi;
2187a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
2188a2744918SBarry Smith       c->ilen[i]  = lensi;
218902834360SBarry Smith     }
21900e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
21913a40ed3dSBarry Smith   } else {
219202834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
21930e83c824SBarry Smith     ierr  = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
219497f1f81fSBarry Smith     ierr  = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
21950e83c824SBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
21964dcab191SBarry Smith     for (i=0; i<ncols; i++) {
21974dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
21984dcab191SBarry 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);
21994dcab191SBarry Smith #endif
22004dcab191SBarry Smith       smap[icol[i]] = i+1;
22014dcab191SBarry Smith     }
22024dcab191SBarry Smith 
220302834360SBarry Smith     /* determine lens of each row */
220402834360SBarry Smith     for (i=0; i<nrows; i++) {
2205bfeeae90SHong Zhang       kstart  = ai[irow[i]];
220602834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
220702834360SBarry Smith       lens[i] = 0;
220802834360SBarry Smith       for (k=kstart; k<kend; k++) {
2209bfeeae90SHong Zhang         if (smap[aj[k]]) {
221002834360SBarry Smith           lens[i]++;
221102834360SBarry Smith         }
221202834360SBarry Smith       }
221302834360SBarry Smith     }
221417ab2063SBarry Smith     /* Create and fill new matrix */
2215a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2216ace3abfcSBarry Smith       PetscBool  equal;
22170f5bd95cSBarry Smith 
221899141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
2219e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2220d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
22210f5bd95cSBarry Smith       if (!equal) {
2222e32f2f54SBarry Smith         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
222399141d43SSatish Balay       }
2224d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
222508480c60SBarry Smith       C = *B;
22263a40ed3dSBarry Smith     } else {
22273bef6203SJed Brown       PetscInt rbs,cbs;
22287adad957SLisandro Dalcin       ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr);
2229f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22303bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22313bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22323bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22337adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2234ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
223508480c60SBarry Smith     }
223699141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
223717ab2063SBarry Smith     for (i=0; i<nrows; i++) {
223899141d43SSatish Balay       row    = irow[i];
2239bfeeae90SHong Zhang       kstart = ai[row];
224099141d43SSatish Balay       kend   = kstart + a->ilen[row];
2241bfeeae90SHong Zhang       mat_i  = c->i[i];
224299141d43SSatish Balay       mat_j  = c->j + mat_i;
224399141d43SSatish Balay       mat_a  = c->a + mat_i;
224499141d43SSatish Balay       mat_ilen = c->ilen + i;
224517ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2246bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2247ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
224899141d43SSatish Balay           *mat_a++ = a->a[k];
224999141d43SSatish Balay           (*mat_ilen)++;
225099141d43SSatish Balay 
225117ab2063SBarry Smith         }
225217ab2063SBarry Smith       }
225317ab2063SBarry Smith     }
225402834360SBarry Smith     /* Free work space */
225502834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2256606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2257606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
225802834360SBarry Smith   }
22596d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22606d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
226117ab2063SBarry Smith 
226217ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2263416022c9SBarry Smith   *B = C;
22643a40ed3dSBarry Smith   PetscFunctionReturn(0);
226517ab2063SBarry Smith }
226617ab2063SBarry Smith 
22671df811f5SHong Zhang #undef __FUNCT__
226882d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2269fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat* subMat)
227082d44351SHong Zhang {
227182d44351SHong Zhang   PetscErrorCode ierr;
227282d44351SHong Zhang   Mat            B;
227382d44351SHong Zhang 
227482d44351SHong Zhang   PetscFunctionBegin;
227582d44351SHong Zhang   ierr = MatCreate(subComm,&B);CHKERRQ(ierr);
227682d44351SHong Zhang   ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2277a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs); CHKERRQ(ierr);
227882d44351SHong Zhang   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
227982d44351SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
228082d44351SHong Zhang   *subMat = B;
228182d44351SHong Zhang   PetscFunctionReturn(0);
228282d44351SHong Zhang }
228382d44351SHong Zhang 
228482d44351SHong Zhang #undef __FUNCT__
22854a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
22860481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2287a871dcd8SBarry Smith {
228863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2289dfbe8321SBarry Smith   PetscErrorCode ierr;
229063b91edcSBarry Smith   Mat            outA;
2291ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
229263b91edcSBarry Smith 
22933a40ed3dSBarry Smith   PetscFunctionBegin;
2294e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
22951df811f5SHong Zhang 
2296b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2297b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2298a871dcd8SBarry Smith 
229963b91edcSBarry Smith   outA              = inA;
2300d5f3da31SBarry Smith   outA->factortype  = MAT_FACTOR_LU;
2301c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23026bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
2303c3122656SLisandro Dalcin   a->row = row;
2304c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23056bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
2306c3122656SLisandro Dalcin   a->col = col;
230763b91edcSBarry Smith 
230836db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23096bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23104c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
231152e6d16bSBarry Smith   ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr);
2312f0ec6fceSSatish Balay 
231394a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2314d0f46423SBarry Smith      ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
2315d0f46423SBarry Smith      ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
231694a9d846SBarry Smith   }
231763b91edcSBarry Smith 
2318f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2319137fb511SHong Zhang   if (row_identity && col_identity) {
2320ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2321137fb511SHong Zhang   } else {
2322719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2323137fb511SHong Zhang   }
23243a40ed3dSBarry Smith   PetscFunctionReturn(0);
2325a871dcd8SBarry Smith }
2326a871dcd8SBarry Smith 
23274a2ae208SSatish Balay #undef __FUNCT__
23284a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2329f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2330f0b747eeSBarry Smith {
2331f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2332f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2333efee365bSSatish Balay   PetscErrorCode ierr;
23340805154bSBarry Smith   PetscBLASInt   one = 1,bnz = PetscBLASIntCast(a->nz);
23353a40ed3dSBarry Smith 
23363a40ed3dSBarry Smith   PetscFunctionBegin;
2337f4df32b1SMatthew Knepley   BLASscal_(&bnz,&oalpha,a->a,&one);
2338efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
233986c113feSBarry Smith   a->idiagvalid  = PETSC_FALSE;
234086c113feSBarry Smith   a->ibdiagvalid = PETSC_FALSE;
23413a40ed3dSBarry Smith   PetscFunctionReturn(0);
2342f0b747eeSBarry Smith }
2343f0b747eeSBarry Smith 
23444a2ae208SSatish Balay #undef __FUNCT__
23454a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
234697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2347cddf8d76SBarry Smith {
2348dfbe8321SBarry Smith   PetscErrorCode ierr;
234997f1f81fSBarry Smith   PetscInt       i;
2350cddf8d76SBarry Smith 
23513a40ed3dSBarry Smith   PetscFunctionBegin;
2352cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2353b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2354cddf8d76SBarry Smith   }
2355cddf8d76SBarry Smith 
2356cddf8d76SBarry Smith   for (i=0; i<n; i++) {
23576a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2358cddf8d76SBarry Smith   }
23593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2360cddf8d76SBarry Smith }
2361cddf8d76SBarry Smith 
23624a2ae208SSatish Balay #undef __FUNCT__
23634a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
236497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
23654dcbc457SBarry Smith {
2366e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
23676849ba73SBarry Smith   PetscErrorCode ierr;
23685d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
23695d0c19d7SBarry Smith   const PetscInt *idx;
237097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2371f1af5d2fSBarry Smith   PetscBT        table;
2372bbd702dbSSatish Balay 
23733a40ed3dSBarry Smith   PetscFunctionBegin;
2374d0f46423SBarry Smith   m     = A->rmap->n;
2375e4d965acSSatish Balay   ai    = a->i;
2376bfeeae90SHong Zhang   aj    = a->j;
23778a047759SSatish Balay 
2378e32f2f54SBarry Smith   if (ov < 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
237906763907SSatish Balay 
238097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
238153b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
238206763907SSatish Balay 
2383e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2384b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2385e4d965acSSatish Balay     isz  = 0;
23866831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2387e4d965acSSatish Balay 
2388e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
23894dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2390b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2391e4d965acSSatish Balay 
2392dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2393e4d965acSSatish Balay     for (j=0; j<n ; ++j){
2394f1af5d2fSBarry Smith       if (!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
23954dcbc457SBarry Smith     }
239606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
23976bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2398e4d965acSSatish Balay 
239904a348a9SBarry Smith     k = 0;
240004a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
240104a348a9SBarry Smith       n = isz;
240206763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
2403e4d965acSSatish Balay         row   = nidx[k];
2404e4d965acSSatish Balay         start = ai[row];
2405e4d965acSSatish Balay         end   = ai[row+1];
240604a348a9SBarry Smith         for (l = start; l<end ; l++){
2407efb16452SHong Zhang           val = aj[l] ;
2408f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
2409e4d965acSSatish Balay         }
2410e4d965acSSatish Balay       }
2411e4d965acSSatish Balay     }
241270b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2413e4d965acSSatish Balay   }
241494bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2415606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
24163a40ed3dSBarry Smith   PetscFunctionReturn(0);
24174dcbc457SBarry Smith }
241817ab2063SBarry Smith 
24190513a670SBarry Smith /* -------------------------------------------------------------- */
24204a2ae208SSatish Balay #undef __FUNCT__
24214a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2422dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
24230513a670SBarry Smith {
24240513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24256849ba73SBarry Smith   PetscErrorCode ierr;
24263b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
24275d0c19d7SBarry Smith   const PetscInt *row,*col;
24285d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
242956cd22aeSBarry Smith   IS             icolp,irowp;
24303b98c0a2SBarry Smith   PetscInt       *cwork = PETSC_NULL;
24313b98c0a2SBarry Smith   PetscScalar    *vwork = PETSC_NULL;
24320513a670SBarry Smith 
24333a40ed3dSBarry Smith   PetscFunctionBegin;
24344c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
243556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
24364c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
243756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
24380513a670SBarry Smith 
24390513a670SBarry Smith   /* determine lengths of permuted rows */
244097f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
24410513a670SBarry Smith   for (i=0; i<m; i++) {
24420513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
24430513a670SBarry Smith   }
24447adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
2445f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2446a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
24477adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2448ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2449606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
24500513a670SBarry Smith 
245197f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
24520513a670SBarry Smith   for (i=0; i<m; i++) {
245332ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24540513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
2455cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
245632ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
24570513a670SBarry Smith   }
2458606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
24593c7d62e4SBarry Smith   (*B)->assembled     = PETSC_FALSE;
24600513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24610513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
246256cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
246356cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
24646bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
24656bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
24663a40ed3dSBarry Smith   PetscFunctionReturn(0);
24670513a670SBarry Smith }
24680513a670SBarry Smith 
24694a2ae208SSatish Balay #undef __FUNCT__
24704a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2471dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2472cb5b572fSBarry Smith {
2473dfbe8321SBarry Smith   PetscErrorCode ierr;
2474cb5b572fSBarry Smith 
2475cb5b572fSBarry Smith   PetscFunctionBegin;
247633f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
247733f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2478be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2479be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2480be6bf707SBarry Smith 
2481700c5bfcSBarry 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");
2482d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2483cb5b572fSBarry Smith   } else {
2484cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2485cb5b572fSBarry Smith   }
2486cb5b572fSBarry Smith   PetscFunctionReturn(0);
2487cb5b572fSBarry Smith }
2488cb5b572fSBarry Smith 
24894a2ae208SSatish Balay #undef __FUNCT__
24904994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
24914994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2492273d9f13SBarry Smith {
2493dfbe8321SBarry Smith   PetscErrorCode ierr;
2494273d9f13SBarry Smith 
2495273d9f13SBarry Smith   PetscFunctionBegin;
2496ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2497273d9f13SBarry Smith   PetscFunctionReturn(0);
2498273d9f13SBarry Smith }
2499273d9f13SBarry Smith 
25004a2ae208SSatish Balay #undef __FUNCT__
25018c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
25028c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
25036c0721eeSBarry Smith {
25046c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
25056c0721eeSBarry Smith   PetscFunctionBegin;
25066c0721eeSBarry Smith   *array = a->a;
25076c0721eeSBarry Smith   PetscFunctionReturn(0);
25086c0721eeSBarry Smith }
25096c0721eeSBarry Smith 
25104a2ae208SSatish Balay #undef __FUNCT__
25118c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
25128c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
25136c0721eeSBarry Smith {
25146c0721eeSBarry Smith   PetscFunctionBegin;
25156c0721eeSBarry Smith   PetscFunctionReturn(0);
25166c0721eeSBarry Smith }
2517273d9f13SBarry Smith 
2518ee4f033dSBarry Smith #undef __FUNCT__
2519ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2520dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2521ee4f033dSBarry Smith {
25226849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f;
25236849ba73SBarry Smith   PetscErrorCode ierr;
25244e269d77SPeter Brune   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow;
2525efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
252687828ca2SBarry Smith   PetscScalar    *vscale_array;
2527ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2528ee4f033dSBarry Smith   Vec            w1,w2,w3;
2529ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2530ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2531ee4f033dSBarry Smith 
2532ee4f033dSBarry Smith   PetscFunctionBegin;
2533ee4f033dSBarry Smith   if (!coloring->w1) {
2534ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
253552e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr);
2536ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
253752e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr);
2538ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
253952e6d16bSBarry Smith     ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr);
2540ee4f033dSBarry Smith   }
2541ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2542ee4f033dSBarry Smith 
2543ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2544acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr);
2545ee4f033dSBarry Smith   if (flg) {
2546ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2547ee4f033dSBarry Smith   } else {
2548ace3abfcSBarry Smith     PetscBool  assembled;
25490b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
25500b9b6f31SBarry Smith     if (assembled) {
2551ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2552ee4f033dSBarry Smith     }
25530b9b6f31SBarry Smith   }
2554ee4f033dSBarry Smith 
2555ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2556ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2557ee4f033dSBarry Smith 
25584e269d77SPeter Brune   if (!coloring->fset) {
255966f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2560ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
256166f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
25624e269d77SPeter Brune   } else {
25634e269d77SPeter Brune     coloring->fset = PETSC_FALSE;
2564ee4f033dSBarry Smith   }
2565ee4f033dSBarry Smith 
2566ee4f033dSBarry Smith   /*
2567ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2568ee4f033dSBarry Smith   */
25691ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
25701ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2571ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2572ee4f033dSBarry Smith     /*
2573ee4f033dSBarry Smith        Loop over each column associated with color adding the
2574ee4f033dSBarry Smith        perturbation to the vector w3.
2575ee4f033dSBarry Smith     */
2576ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2577ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2578ee4f033dSBarry Smith       dx  = xx[col];
2579ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2580ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2581ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2582ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2583ee4f033dSBarry Smith #else
2584ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2585ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2586ee4f033dSBarry Smith #endif
2587ee4f033dSBarry Smith       dx                *= epsilon;
2588ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2589ee4f033dSBarry Smith     }
2590ee4f033dSBarry Smith   }
25911ebc52fbSHong Zhang   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2592ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2593ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2594ee4f033dSBarry Smith 
2595ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2596ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2597ee4f033dSBarry Smith 
2598ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2599ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2600ee4f033dSBarry Smith 
26011ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2602ee4f033dSBarry Smith   /*
2603ee4f033dSBarry Smith       Loop over each color
2604ee4f033dSBarry Smith   */
2605ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
260649b058dcSBarry Smith     coloring->currentcolor = k;
2607ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
26081ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2609ee4f033dSBarry Smith     /*
2610ee4f033dSBarry Smith        Loop over each column associated with color adding the
2611ee4f033dSBarry Smith        perturbation to the vector w3.
2612ee4f033dSBarry Smith     */
2613ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2614ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2615ee4f033dSBarry Smith       dx  = xx[col];
26165b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2617ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2618ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2619ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2620ee4f033dSBarry Smith #else
2621ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2622ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2623ee4f033dSBarry Smith #endif
2624ee4f033dSBarry Smith       dx            *= epsilon;
2625e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2626ee4f033dSBarry Smith       w3_array[col] += dx;
2627ee4f033dSBarry Smith     }
26281ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2629ee4f033dSBarry Smith 
2630ee4f033dSBarry Smith     /*
2631ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2632ee4f033dSBarry Smith     */
2633ee4f033dSBarry Smith 
263466f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2635ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
263666f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2637efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2638ee4f033dSBarry Smith 
2639ee4f033dSBarry Smith     /*
2640ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2641ee4f033dSBarry Smith     */
26421ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2643ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2644ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2645ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2646ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2647ee4f033dSBarry Smith       srow   = row + start;
2648ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2649ee4f033dSBarry Smith     }
26501ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2651ee4f033dSBarry Smith   }
265249b058dcSBarry Smith   coloring->currentcolor = k;
26531ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
26541ebc52fbSHong Zhang   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2655ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2656ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2657ee4f033dSBarry Smith   PetscFunctionReturn(0);
2658ee4f033dSBarry Smith }
2659ee4f033dSBarry Smith 
26608229c054SShri Abhyankar /*
26618229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26628229c054SShri Abhyankar    have different nonzero structure.
26638229c054SShri Abhyankar */
2664ac90fabeSBarry Smith #undef __FUNCT__
26658229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
26668229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz)
2667ec7775f6SShri Abhyankar {
26688229c054SShri Abhyankar   PetscInt          i,m=Y->rmap->N;
2669ec7775f6SShri Abhyankar   Mat_SeqAIJ        *x = (Mat_SeqAIJ*)X->data;
2670ec7775f6SShri Abhyankar   Mat_SeqAIJ        *y = (Mat_SeqAIJ*)Y->data;
2671ec7775f6SShri Abhyankar   const PetscInt    *xi = x->i,*yi = y->i;
2672ec7775f6SShri Abhyankar 
2673ec7775f6SShri Abhyankar   PetscFunctionBegin;
2674ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2675ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
26768af7cee1SJed Brown     PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
26778af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
26788af7cee1SJed Brown     nnz[i] = 0;
26798af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
26808af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
26818af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
26828af7cee1SJed Brown       nnz[i]++;
26838af7cee1SJed Brown     }
26848af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2685ec7775f6SShri Abhyankar   }
2686ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2687ec7775f6SShri Abhyankar }
2688ec7775f6SShri Abhyankar 
2689ec7775f6SShri Abhyankar #undef __FUNCT__
2690ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2691f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2692ac90fabeSBarry Smith {
2693dfbe8321SBarry Smith   PetscErrorCode ierr;
269497f1f81fSBarry Smith   PetscInt       i;
2695ac90fabeSBarry Smith   Mat_SeqAIJ     *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
26960805154bSBarry Smith   PetscBLASInt   one=1,bnz = PetscBLASIntCast(x->nz);
2697ac90fabeSBarry Smith 
2698ac90fabeSBarry Smith   PetscFunctionBegin;
2699ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2700f4df32b1SMatthew Knepley     PetscScalar alpha = a;
2701f4df32b1SMatthew Knepley     BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one);
270286c113feSBarry Smith     y->idiagvalid  = PETSC_FALSE;
270386c113feSBarry Smith     y->ibdiagvalid = PETSC_FALSE;
2704c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2705a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2706a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27076bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2708a30b2313SHong Zhang     }
2709a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
2710d0f46423SBarry Smith       ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
2711a30b2313SHong Zhang       y->XtoY = X;
2712407f6b05SHong Zhang       ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2713c537a176SHong Zhang     }
2714f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2715ba0e910bSBarry Smith     ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(double)(PetscReal)(x->nz)/(y->nz+1));CHKERRQ(ierr);
2716ac90fabeSBarry Smith   } else {
27178229c054SShri Abhyankar     Mat      B;
27188229c054SShri Abhyankar     PetscInt *nnz;
271916b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2720ec7775f6SShri Abhyankar     ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr);
2721bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27224aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2723a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2724176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27258229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2726ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2727ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2728ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27298229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2730ac90fabeSBarry Smith   }
2731ac90fabeSBarry Smith   PetscFunctionReturn(0);
2732ac90fabeSBarry Smith }
2733ac90fabeSBarry Smith 
2734521d7252SBarry Smith #undef __FUNCT__
2735354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27367087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2737354c94deSBarry Smith {
2738354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2739354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ *)mat->data;
2740354c94deSBarry Smith   PetscInt    i,nz;
2741354c94deSBarry Smith   PetscScalar *a;
2742354c94deSBarry Smith 
2743354c94deSBarry Smith   PetscFunctionBegin;
2744354c94deSBarry Smith   nz = aij->nz;
2745354c94deSBarry Smith   a  = aij->a;
2746354c94deSBarry Smith   for (i=0; i<nz; i++) {
2747354c94deSBarry Smith     a[i] = PetscConj(a[i]);
2748354c94deSBarry Smith   }
2749354c94deSBarry Smith #else
2750354c94deSBarry Smith   PetscFunctionBegin;
2751354c94deSBarry Smith #endif
2752354c94deSBarry Smith   PetscFunctionReturn(0);
2753354c94deSBarry Smith }
2754354c94deSBarry Smith 
2755e34fafa9SBarry Smith #undef __FUNCT__
2756985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2757985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2758e34fafa9SBarry Smith {
2759e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2760e34fafa9SBarry Smith   PetscErrorCode ierr;
2761d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2762e34fafa9SBarry Smith   PetscReal      atmp;
2763985db425SBarry Smith   PetscScalar    *x;
2764e34fafa9SBarry Smith   MatScalar      *aa;
2765e34fafa9SBarry Smith 
2766e34fafa9SBarry Smith   PetscFunctionBegin;
2767e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2768e34fafa9SBarry Smith   aa   = a->a;
2769e34fafa9SBarry Smith   ai   = a->i;
2770e34fafa9SBarry Smith   aj   = a->j;
2771e34fafa9SBarry Smith 
2772985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2773e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2774e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2775e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2776e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2777e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27789189402eSHong Zhang     x[i] = 0.0;
2779e34fafa9SBarry Smith     for (j=0; j<ncols; j++){
2780985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2781985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2782985db425SBarry Smith       aa++; aj++;
2783985db425SBarry Smith     }
2784985db425SBarry Smith   }
2785985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2786985db425SBarry Smith   PetscFunctionReturn(0);
2787985db425SBarry Smith }
2788985db425SBarry Smith 
2789985db425SBarry Smith #undef __FUNCT__
2790985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2791985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2792985db425SBarry Smith {
2793985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2794985db425SBarry Smith   PetscErrorCode ierr;
2795d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2796985db425SBarry Smith   PetscScalar    *x;
2797985db425SBarry Smith   MatScalar      *aa;
2798985db425SBarry Smith 
2799985db425SBarry Smith   PetscFunctionBegin;
2800e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2801985db425SBarry Smith   aa   = a->a;
2802985db425SBarry Smith   ai   = a->i;
2803985db425SBarry Smith   aj   = a->j;
2804985db425SBarry Smith 
2805985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2806985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2807985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2808e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2809985db425SBarry Smith   for (i=0; i<m; i++) {
2810985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2811d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2812985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2813985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2814985db425SBarry Smith       x[i] = 0.0;
2815985db425SBarry Smith       if (idx) {
2816985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2817985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2818985db425SBarry Smith           if (aj[j] > j) {
2819985db425SBarry Smith             idx[i] = j;
2820985db425SBarry Smith             break;
2821985db425SBarry Smith           }
2822985db425SBarry Smith         }
2823985db425SBarry Smith       }
2824985db425SBarry Smith     }
2825985db425SBarry Smith     for (j=0; j<ncols; j++){
2826985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2827985db425SBarry Smith       aa++; aj++;
2828985db425SBarry Smith     }
2829985db425SBarry Smith   }
2830985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2831985db425SBarry Smith   PetscFunctionReturn(0);
2832985db425SBarry Smith }
2833985db425SBarry Smith 
2834985db425SBarry Smith #undef __FUNCT__
2835c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2836c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2837c87e5d42SMatthew Knepley {
2838c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2839c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2840c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2841c87e5d42SMatthew Knepley   PetscReal      atmp;
2842c87e5d42SMatthew Knepley   PetscScalar    *x;
2843c87e5d42SMatthew Knepley   MatScalar      *aa;
2844c87e5d42SMatthew Knepley 
2845c87e5d42SMatthew Knepley   PetscFunctionBegin;
2846e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2847c87e5d42SMatthew Knepley   aa   = a->a;
2848c87e5d42SMatthew Knepley   ai   = a->i;
2849c87e5d42SMatthew Knepley   aj   = a->j;
2850c87e5d42SMatthew Knepley 
2851c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2852c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2853c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
28543bb78c5cSMatthew 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);
2855c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2856c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2857289a08f5SMatthew Knepley     if (ncols) {
2858289a08f5SMatthew Knepley       /* Get first nonzero */
2859289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2860289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
2861289a08f5SMatthew Knepley         if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;}
2862289a08f5SMatthew Knepley       }
286312431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2864289a08f5SMatthew Knepley     } else {
2865289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2866289a08f5SMatthew Knepley     }
2867c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2868c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2869289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2870c87e5d42SMatthew Knepley       aa++; aj++;
2871c87e5d42SMatthew Knepley     }
2872c87e5d42SMatthew Knepley   }
2873c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2874c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2875c87e5d42SMatthew Knepley }
2876c87e5d42SMatthew Knepley 
2877c87e5d42SMatthew Knepley #undef __FUNCT__
2878985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2879985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2880985db425SBarry Smith {
2881985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2882985db425SBarry Smith   PetscErrorCode ierr;
2883d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2884985db425SBarry Smith   PetscScalar    *x;
2885985db425SBarry Smith   MatScalar      *aa;
2886985db425SBarry Smith 
2887985db425SBarry Smith   PetscFunctionBegin;
2888e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2889985db425SBarry Smith   aa   = a->a;
2890985db425SBarry Smith   ai   = a->i;
2891985db425SBarry Smith   aj   = a->j;
2892985db425SBarry Smith 
2893985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2894985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2895985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2896e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2897985db425SBarry Smith   for (i=0; i<m; i++) {
2898985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2899d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2900985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2901985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2902985db425SBarry Smith       x[i] = 0.0;
2903985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2904985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2905985db425SBarry Smith         for (j=0;j<ncols;j++) {
2906985db425SBarry Smith           if (aj[j] > j) {
2907985db425SBarry Smith             idx[i] = j;
2908985db425SBarry Smith             break;
2909985db425SBarry Smith           }
2910985db425SBarry Smith         }
2911985db425SBarry Smith       }
2912985db425SBarry Smith     }
2913985db425SBarry Smith     for (j=0; j<ncols; j++){
2914985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2915985db425SBarry Smith       aa++; aj++;
2916e34fafa9SBarry Smith     }
2917e34fafa9SBarry Smith   }
2918e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2919e34fafa9SBarry Smith   PetscFunctionReturn(0);
2920e34fafa9SBarry Smith }
2921bbead8a2SBarry Smith 
2922bbead8a2SBarry Smith #include <petscblaslapack.h>
2923bbead8a2SBarry Smith #include <../src/mat/blockinvert.h>
2924bbead8a2SBarry Smith 
2925bbead8a2SBarry Smith #undef __FUNCT__
2926bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2927713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2928bbead8a2SBarry Smith {
2929bbead8a2SBarry Smith   Mat_SeqAIJ    *a = (Mat_SeqAIJ*) A->data;
2930bbead8a2SBarry Smith   PetscErrorCode ierr;
293134fc4b71SJed 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;
2932bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2933bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2934bbead8a2SBarry Smith 
2935bbead8a2SBarry Smith   PetscFunctionBegin;
29364a0d0026SBarry Smith   if (a->ibdiagvalid) {
29374a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29384a0d0026SBarry Smith     PetscFunctionReturn(0);
29394a0d0026SBarry Smith   }
2940bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2941bbead8a2SBarry Smith   if (!a->ibdiag) {
2942bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr);
2943bbead8a2SBarry Smith     ierr = PetscLogObjectMemory(A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2944bbead8a2SBarry Smith   }
2945bbead8a2SBarry Smith   diag    = a->ibdiag;
2946bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2947bbead8a2SBarry Smith   /* factor and invert each block */
2948bbead8a2SBarry Smith   switch (bs){
2949bbead8a2SBarry Smith     case 1:
2950bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2951bbead8a2SBarry Smith         ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2952bbead8a2SBarry Smith         diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2953bbead8a2SBarry Smith       }
2954bbead8a2SBarry Smith       break;
2955bbead8a2SBarry Smith     case 2:
2956bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2957bbead8a2SBarry Smith         ij[0] = 2*i; ij[1] = 2*i + 1;
2958bbead8a2SBarry Smith         ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
295996b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
296096b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2961bbead8a2SBarry Smith 	diag  += 4;
2962bbead8a2SBarry Smith       }
2963bbead8a2SBarry Smith       break;
2964bbead8a2SBarry Smith     case 3:
2965bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2966bbead8a2SBarry Smith         ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2967bbead8a2SBarry Smith         ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
296896b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
296996b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2970bbead8a2SBarry Smith 	diag    += 9;
2971bbead8a2SBarry Smith       }
2972bbead8a2SBarry Smith       break;
2973bbead8a2SBarry Smith     case 4:
2974bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2975bbead8a2SBarry Smith         ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2976bbead8a2SBarry Smith         ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
297796b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
297896b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2979bbead8a2SBarry Smith 	diag  += 16;
2980bbead8a2SBarry Smith       }
2981bbead8a2SBarry Smith       break;
2982bbead8a2SBarry Smith     case 5:
2983bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2984bbead8a2SBarry 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;
2985bbead8a2SBarry Smith         ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
298696b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
298796b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2988bbead8a2SBarry Smith 	diag  += 25;
2989bbead8a2SBarry Smith       }
2990bbead8a2SBarry Smith       break;
2991bbead8a2SBarry Smith     case 6:
2992bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
2993bbead8a2SBarry 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;
2994bbead8a2SBarry Smith         ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
299596b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
299696b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2997bbead8a2SBarry Smith 	diag  += 36;
2998bbead8a2SBarry Smith       }
2999bbead8a2SBarry Smith       break;
3000bbead8a2SBarry Smith     case 7:
3001bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
3002bbead8a2SBarry 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;
3003bbead8a2SBarry Smith         ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
300496b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
300596b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3006bbead8a2SBarry Smith 	diag  += 49;
3007bbead8a2SBarry Smith       }
3008bbead8a2SBarry Smith       break;
3009bbead8a2SBarry Smith     default:
3010bbead8a2SBarry Smith       ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr);
3011bbead8a2SBarry Smith       for (i=0; i<mbs; i++) {
3012bbead8a2SBarry Smith         for (j=0; j<bs; j++) {
3013bbead8a2SBarry Smith           IJ[j] = bs*i + j;
3014bbead8a2SBarry Smith         }
3015bbead8a2SBarry Smith         ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
301696b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
301796b95a6bSBarry Smith         ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3018bbead8a2SBarry Smith 	diag  += bs2;
3019bbead8a2SBarry Smith       }
3020bbead8a2SBarry Smith       ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3021bbead8a2SBarry Smith   }
3022bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3023bbead8a2SBarry Smith   PetscFunctionReturn(0);
3024bbead8a2SBarry Smith }
3025bbead8a2SBarry Smith 
302673a71a0fSBarry Smith #undef __FUNCT__
302773a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
302873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
302973a71a0fSBarry Smith {
303073a71a0fSBarry Smith   PetscErrorCode ierr;
303173a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
303273a71a0fSBarry Smith   PetscScalar    a;
303373a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
303473a71a0fSBarry Smith 
303573a71a0fSBarry Smith   PetscFunctionBegin;
303673a71a0fSBarry Smith   if (!x->assembled) {
303773a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
303873a71a0fSBarry Smith     for (i=0; i<m; i++) {
303973a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
304073a71a0fSBarry Smith         ierr  = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
304173a71a0fSBarry Smith         col   = (PetscInt)(n*PetscRealPart(a));
304273a71a0fSBarry Smith         ierr  = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
304373a71a0fSBarry Smith       }
304473a71a0fSBarry Smith     }
304573a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
304673a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304773a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304873a71a0fSBarry Smith   PetscFunctionReturn(0);
304973a71a0fSBarry Smith }
305073a71a0fSBarry Smith 
30517087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
3052682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30530a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
3054cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
3055cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
3056cb5b572fSBarry Smith        MatMult_SeqAIJ,
305797304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ,
30587c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
30597c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
3060db4efbfdSBarry Smith        0,
3061db4efbfdSBarry Smith        0,
3062db4efbfdSBarry Smith        0,
3063db4efbfdSBarry Smith /*10*/ 0,
3064cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
3065cb5b572fSBarry Smith        0,
306641f059aeSBarry Smith        MatSOR_SeqAIJ,
306717ab2063SBarry Smith        MatTranspose_SeqAIJ,
306897304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ,
3069cb5b572fSBarry Smith        MatEqual_SeqAIJ,
3070cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
3071cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
3072cb5b572fSBarry Smith        MatNorm_SeqAIJ,
307397304618SKris Buschelman /*20*/ 0,
3074cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
3075cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
3076cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
3077d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ,
3078db4efbfdSBarry Smith        0,
3079db4efbfdSBarry Smith        0,
3080db4efbfdSBarry Smith        0,
3081db4efbfdSBarry Smith        0,
30824994cf47SJed Brown /*29*/ MatSetUp_SeqAIJ,
3083db4efbfdSBarry Smith        0,
3084db4efbfdSBarry Smith        0,
30858c778c55SBarry Smith        0,
30868c778c55SBarry Smith        0,
3087d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ,
3088cb5b572fSBarry Smith        0,
3089cb5b572fSBarry Smith        0,
3090cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
3091cb5b572fSBarry Smith        0,
3092d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ,
3093cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
3094cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
3095cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
3096cb5b572fSBarry Smith        MatCopy_SeqAIJ,
3097d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ,
3098cb5b572fSBarry Smith        MatScale_SeqAIJ,
3099cb5b572fSBarry Smith        0,
310079299369SBarry Smith        MatDiagonalSet_SeqAIJ,
31016e169961SBarry Smith        MatZeroRowsColumns_SeqAIJ,
310273a71a0fSBarry Smith /*49*/ MatSetRandom_SeqAIJ,
31033b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
31043b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
31053b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
3106a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
3107d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ,
3108b9617806SBarry Smith        0,
31090513a670SBarry Smith        0,
3110cda55fadSBarry Smith        MatPermute_SeqAIJ,
3111cda55fadSBarry Smith        0,
3112d519adbfSMatthew Knepley /*59*/ 0,
3113b9b97703SBarry Smith        MatDestroy_SeqAIJ,
3114b9b97703SBarry Smith        MatView_SeqAIJ,
3115357abbc8SBarry Smith        0,
3116ee4f033dSBarry Smith        0,
3117d519adbfSMatthew Knepley /*64*/ 0,
3118ee4f033dSBarry Smith        0,
3119ee4f033dSBarry Smith        0,
3120ee4f033dSBarry Smith        0,
3121ee4f033dSBarry Smith        0,
3122d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ,
3123c87e5d42SMatthew Knepley        MatGetRowMinAbs_SeqAIJ,
3124ee4f033dSBarry Smith        0,
3125ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
3126dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
3127ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
3128dcf5cc72SBarry Smith #else
3129dcf5cc72SBarry Smith        0,
3130dcf5cc72SBarry Smith #endif
3131d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ,
31323acb8795SBarry Smith        MatFDColoringApply_AIJ,
313397304618SKris Buschelman        0,
313497304618SKris Buschelman        0,
313597304618SKris Buschelman        0,
31366ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ,
313797304618SKris Buschelman        0,
313897304618SKris Buschelman        0,
313997304618SKris Buschelman        0,
3140bc011b1eSHong Zhang        MatLoad_SeqAIJ,
3141d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ,
31421cbb95d3SBarry Smith        MatIsHermitian_SeqAIJ,
31436284ec50SHong Zhang        0,
31446284ec50SHong Zhang        0,
3145bc011b1eSHong Zhang        0,
3146d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ,
314726be0446SHong Zhang        MatMatMultSymbolic_SeqAIJ_SeqAIJ,
314826be0446SHong Zhang        MatMatMultNumeric_SeqAIJ_SeqAIJ,
3149d439da42SKris Buschelman        MatPtAP_Basic,
31507ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ,
3151d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ,
31526fc122caSHong Zhang        MatMatTransposeMult_SeqAIJ_SeqAIJ,
31536fc122caSHong Zhang        MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31546fc122caSHong Zhang        MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31557ba1a0bfSKris Buschelman        MatPtAPSymbolic_SeqAIJ_SeqAIJ,
3156d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
3157609c6c4dSKris Buschelman        0,
3158609c6c4dSKris Buschelman        0,
315987d4246cSBarry Smith        MatConjugate_SeqAIJ,
316087d4246cSBarry Smith        0,
3161d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ,
316299cafbc1SBarry Smith        MatRealPart_SeqAIJ,
3163f5edf698SHong Zhang        MatImaginaryPart_SeqAIJ,
3164f5edf698SHong Zhang        0,
31652bebee5dSHong Zhang        0,
3166cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ,
3167985db425SBarry Smith        0,
31682af78befSBarry Smith        MatGetRowMin_SeqAIJ,
31692af78befSBarry Smith        0,
3170599ef60dSHong Zhang        MatMissingDiagonal_SeqAIJ,
3171d519adbfSMatthew Knepley /*114*/0,
3172599ef60dSHong Zhang        0,
31733c2a7987SHong Zhang        0,
3174fe97e370SBarry Smith        0,
3175fbdbba38SShri Abhyankar        0,
3176fbdbba38SShri Abhyankar /*119*/0,
3177fbdbba38SShri Abhyankar        0,
3178fbdbba38SShri Abhyankar        0,
317982d44351SHong Zhang        0,
3180b3a44c85SBarry Smith        MatGetMultiProcBlock_SeqAIJ,
31810716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ,
3182bbead8a2SBarry Smith        MatGetColumnNorms_SeqAIJ,
318337868618SMatthew G Knepley        MatInvertBlockDiagonal_SeqAIJ,
318437868618SMatthew G Knepley        0,
318537868618SMatthew G Knepley        0,
31865df89d91SHong Zhang /*129*/0,
318775648e8dSHong Zhang        MatTransposeMatMult_SeqAIJ_SeqAIJ,
318875648e8dSHong Zhang        MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
318975648e8dSHong Zhang        MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3190b9af6bddSHong Zhang        MatTransposeColoringCreate_SeqAIJ,
3191b9af6bddSHong Zhang /*134*/MatTransColoringApplySpToDen_SeqAIJ,
31922b8ad9a3SHong Zhang        MatTransColoringApplyDenToSp_SeqAIJ,
31932b8ad9a3SHong Zhang        MatRARt_SeqAIJ_SeqAIJ,
31942b8ad9a3SHong Zhang        MatRARtSymbolic_SeqAIJ_SeqAIJ,
31952b8ad9a3SHong Zhang        MatRARtNumeric_SeqAIJ_SeqAIJ
31969e29f15eSvictorle };
319717ab2063SBarry Smith 
3198fb2e594dSBarry Smith EXTERN_C_BEGIN
31994a2ae208SSatish Balay #undef __FUNCT__
32004a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32017087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3202bef8e0ddSBarry Smith {
3203bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
320497f1f81fSBarry Smith   PetscInt   i,nz,n;
3205bef8e0ddSBarry Smith 
3206bef8e0ddSBarry Smith   PetscFunctionBegin;
3207bef8e0ddSBarry Smith 
3208bef8e0ddSBarry Smith   nz = aij->maxnz;
3209d0f46423SBarry Smith   n  = mat->rmap->n;
3210bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3211bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3212bef8e0ddSBarry Smith   }
3213bef8e0ddSBarry Smith   aij->nz = nz;
3214bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3215bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3216bef8e0ddSBarry Smith   }
3217bef8e0ddSBarry Smith 
3218bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3219bef8e0ddSBarry Smith }
3220fb2e594dSBarry Smith EXTERN_C_END
3221bef8e0ddSBarry Smith 
32224a2ae208SSatish Balay #undef __FUNCT__
32234a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3224bef8e0ddSBarry Smith /*@
3225bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3226bef8e0ddSBarry Smith        in the matrix.
3227bef8e0ddSBarry Smith 
3228bef8e0ddSBarry Smith   Input Parameters:
3229bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3230bef8e0ddSBarry Smith -  indices - the column indices
3231bef8e0ddSBarry Smith 
323215091d37SBarry Smith   Level: advanced
323315091d37SBarry Smith 
3234bef8e0ddSBarry Smith   Notes:
3235bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3236bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3237bef8e0ddSBarry Smith   of the MatSetValues() operation.
3238bef8e0ddSBarry Smith 
3239bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3240d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3241bef8e0ddSBarry Smith 
3242bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3243bef8e0ddSBarry Smith 
3244b9617806SBarry Smith     The indices should start with zero, not one.
3245b9617806SBarry Smith 
3246bef8e0ddSBarry Smith @*/
32477087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3248bef8e0ddSBarry Smith {
32494ac538c5SBarry Smith   PetscErrorCode ierr;
3250bef8e0ddSBarry Smith 
3251bef8e0ddSBarry Smith   PetscFunctionBegin;
32520700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32534482741eSBarry Smith   PetscValidPointer(indices,2);
32544ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr);
3255bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3256bef8e0ddSBarry Smith }
3257bef8e0ddSBarry Smith 
3258be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3259be6bf707SBarry Smith 
3260fb2e594dSBarry Smith EXTERN_C_BEGIN
32614a2ae208SSatish Balay #undef __FUNCT__
32624a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
32637087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3264be6bf707SBarry Smith {
3265be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
32666849ba73SBarry Smith   PetscErrorCode ierr;
3267d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3268be6bf707SBarry Smith 
3269be6bf707SBarry Smith   PetscFunctionBegin;
3270be6bf707SBarry Smith   if (aij->nonew != 1) {
3271e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3272be6bf707SBarry Smith   }
3273be6bf707SBarry Smith 
3274be6bf707SBarry Smith   /* allocate space for values if not already there */
3275be6bf707SBarry Smith   if (!aij->saved_values) {
327687828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
32779518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3278be6bf707SBarry Smith   }
3279be6bf707SBarry Smith 
3280be6bf707SBarry Smith   /* copy values over */
328187828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3282be6bf707SBarry Smith   PetscFunctionReturn(0);
3283be6bf707SBarry Smith }
3284fb2e594dSBarry Smith EXTERN_C_END
3285be6bf707SBarry Smith 
32864a2ae208SSatish Balay #undef __FUNCT__
3287b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3288be6bf707SBarry Smith /*@
3289be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3290be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3291be6bf707SBarry Smith        nonlinear portion.
3292be6bf707SBarry Smith 
3293be6bf707SBarry Smith    Collect on Mat
3294be6bf707SBarry Smith 
3295be6bf707SBarry Smith   Input Parameters:
32960e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3297be6bf707SBarry Smith 
329815091d37SBarry Smith   Level: advanced
329915091d37SBarry Smith 
3300be6bf707SBarry Smith   Common Usage, with SNESSolve():
3301be6bf707SBarry Smith $    Create Jacobian matrix
3302be6bf707SBarry Smith $    Set linear terms into matrix
3303be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3304be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3305be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3306512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3307be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3308be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3309be6bf707SBarry Smith $    In your Jacobian routine
3310be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3311be6bf707SBarry Smith $      Set nonlinear terms in matrix
3312be6bf707SBarry Smith 
3313be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3314be6bf707SBarry Smith $    // build linear portion of Jacobian
3315512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3316be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3317be6bf707SBarry Smith $    loop over nonlinear iterations
3318be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3319be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3320be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3321be6bf707SBarry Smith $       Solve linear system with Jacobian
3322be6bf707SBarry Smith $    endloop
3323be6bf707SBarry Smith 
3324be6bf707SBarry Smith   Notes:
3325be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3326512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3327be6bf707SBarry Smith     calling this routine.
3328be6bf707SBarry Smith 
33290c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33300c468ba9SBarry Smith     and does not allocated additional space.
33310c468ba9SBarry Smith 
3332be6bf707SBarry Smith .seealso: MatRetrieveValues()
3333be6bf707SBarry Smith 
3334be6bf707SBarry Smith @*/
33357087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3336be6bf707SBarry Smith {
33374ac538c5SBarry Smith   PetscErrorCode ierr;
3338be6bf707SBarry Smith 
3339be6bf707SBarry Smith   PetscFunctionBegin;
33400700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3341e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3342e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33434ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3344be6bf707SBarry Smith   PetscFunctionReturn(0);
3345be6bf707SBarry Smith }
3346be6bf707SBarry Smith 
3347fb2e594dSBarry Smith EXTERN_C_BEGIN
33484a2ae208SSatish Balay #undef __FUNCT__
33494a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33507087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3351be6bf707SBarry Smith {
3352be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ *)mat->data;
33536849ba73SBarry Smith   PetscErrorCode ierr;
3354d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3355be6bf707SBarry Smith 
3356be6bf707SBarry Smith   PetscFunctionBegin;
3357be6bf707SBarry Smith   if (aij->nonew != 1) {
3358e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3359be6bf707SBarry Smith   }
3360be6bf707SBarry Smith   if (!aij->saved_values) {
3361e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3362be6bf707SBarry Smith   }
3363be6bf707SBarry Smith   /* copy values over */
336487828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3365be6bf707SBarry Smith   PetscFunctionReturn(0);
3366be6bf707SBarry Smith }
3367fb2e594dSBarry Smith EXTERN_C_END
3368be6bf707SBarry Smith 
33694a2ae208SSatish Balay #undef __FUNCT__
33704a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3371be6bf707SBarry Smith /*@
3372be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3373be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3374be6bf707SBarry Smith        nonlinear portion.
3375be6bf707SBarry Smith 
3376be6bf707SBarry Smith    Collect on Mat
3377be6bf707SBarry Smith 
3378be6bf707SBarry Smith   Input Parameters:
3379be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3380be6bf707SBarry Smith 
338115091d37SBarry Smith   Level: advanced
338215091d37SBarry Smith 
3383be6bf707SBarry Smith .seealso: MatStoreValues()
3384be6bf707SBarry Smith 
3385be6bf707SBarry Smith @*/
33867087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3387be6bf707SBarry Smith {
33884ac538c5SBarry Smith   PetscErrorCode ierr;
3389be6bf707SBarry Smith 
3390be6bf707SBarry Smith   PetscFunctionBegin;
33910700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3392e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3393e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33944ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3395be6bf707SBarry Smith   PetscFunctionReturn(0);
3396be6bf707SBarry Smith }
3397be6bf707SBarry Smith 
3398f83d6046SBarry Smith 
3399be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34004a2ae208SSatish Balay #undef __FUNCT__
34014a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
340217ab2063SBarry Smith /*@C
3403682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34040d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34056e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
340651c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34072bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
340817ab2063SBarry Smith 
3409db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3410db81eaa0SLois Curfman McInnes 
341117ab2063SBarry Smith    Input Parameters:
3412db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
341317ab2063SBarry Smith .  m - number of rows
341417ab2063SBarry Smith .  n - number of columns
341517ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
341651c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34172bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
341817ab2063SBarry Smith 
341917ab2063SBarry Smith    Output Parameter:
3420416022c9SBarry Smith .  A - the matrix
342117ab2063SBarry Smith 
3422175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3423ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3424175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3425175b88e8SBarry Smith 
3426b259b22eSLois Curfman McInnes    Notes:
342749a6f317SBarry Smith    If nnz is given then nz is ignored
342849a6f317SBarry Smith 
342917ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
343017ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34310002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
343244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
343317ab2063SBarry Smith 
343417ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3435a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
34363d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34376da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
343817ab2063SBarry Smith 
3439682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34404fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3441682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34426c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34436c7ebb05SLois Curfman McInnes 
34446c7ebb05SLois Curfman McInnes    Options Database Keys:
3445698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34469db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
344717ab2063SBarry Smith 
3448027ccd11SLois Curfman McInnes    Level: intermediate
3449027ccd11SLois Curfman McInnes 
345069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
345136db0b34SBarry Smith 
345217ab2063SBarry Smith @*/
34537087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
345417ab2063SBarry Smith {
3455dfbe8321SBarry Smith   PetscErrorCode ierr;
34566945ee14SBarry Smith 
34573a40ed3dSBarry Smith   PetscFunctionBegin;
3458f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3459117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3460c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3461d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3462273d9f13SBarry Smith   PetscFunctionReturn(0);
3463273d9f13SBarry Smith }
3464273d9f13SBarry Smith 
34654a2ae208SSatish Balay #undef __FUNCT__
34664a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3467273d9f13SBarry Smith /*@C
3468273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3469273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3470273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3471273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3472273d9f13SBarry Smith 
3473273d9f13SBarry Smith    Collective on MPI_Comm
3474273d9f13SBarry Smith 
3475273d9f13SBarry Smith    Input Parameters:
3476117016b1SBarry Smith +  B - The matrix-free
3477273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3478273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
3479273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
3480273d9f13SBarry Smith 
3481273d9f13SBarry Smith    Notes:
348249a6f317SBarry Smith      If nnz is given then nz is ignored
348349a6f317SBarry Smith 
3484273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3485273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3486273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3487273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3488273d9f13SBarry Smith 
3489273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
3490273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
3491273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3492273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3493273d9f13SBarry Smith 
3494aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3495aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3496aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3497aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3498aa95bbe8SBarry Smith 
3499a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3500a96a251dSBarry Smith    entries or columns indices
3501a96a251dSBarry Smith 
3502273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3503273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3504273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3505273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3506273d9f13SBarry Smith 
3507273d9f13SBarry Smith    Options Database Keys:
3508698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3509698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3510273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3511273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3512273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith    Level: intermediate
3515273d9f13SBarry Smith 
351669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3517273d9f13SBarry Smith 
3518273d9f13SBarry Smith @*/
35197087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3520273d9f13SBarry Smith {
35214ac538c5SBarry Smith   PetscErrorCode ierr;
3522a23d5eceSKris Buschelman 
3523a23d5eceSKris Buschelman   PetscFunctionBegin;
35246ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35256ba663aaSJed Brown   PetscValidType(B,1);
35264ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3527a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3528a23d5eceSKris Buschelman }
3529a23d5eceSKris Buschelman 
3530a23d5eceSKris Buschelman EXTERN_C_BEGIN
3531a23d5eceSKris Buschelman #undef __FUNCT__
3532a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35337087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3534a23d5eceSKris Buschelman {
3535273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35362576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35376849ba73SBarry Smith   PetscErrorCode ierr;
353897f1f81fSBarry Smith   PetscInt       i;
3539273d9f13SBarry Smith 
3540273d9f13SBarry Smith   PetscFunctionBegin;
35412576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3542a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3543c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3544c461c341SBarry Smith     nz             = 0;
3545c461c341SBarry Smith   }
3546c461c341SBarry Smith 
354726283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
354826283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3549899cda47SBarry Smith 
3550435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3551e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3552b73539f3SBarry Smith   if (nnz) {
3553d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3554e32f2f54SBarry 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]);
3555e32f2f54SBarry 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);
3556b73539f3SBarry Smith     }
3557b73539f3SBarry Smith   }
3558b73539f3SBarry Smith 
3559273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3560273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3561273d9f13SBarry Smith 
3562ab93d7beSBarry Smith   if (!skipallocation) {
35632ee49352SLisandro Dalcin     if (!b->imax) {
3564d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
3565d0f46423SBarry Smith       ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35662ee49352SLisandro Dalcin     }
3567273d9f13SBarry Smith     if (!nnz) {
3568435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3569c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3570d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3571d0f46423SBarry Smith       nz = nz*B->rmap->n;
3572273d9f13SBarry Smith     } else {
3573273d9f13SBarry Smith       nz = 0;
3574d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3575273d9f13SBarry Smith     }
3576ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
3577d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; }
3578ab93d7beSBarry Smith 
3579273d9f13SBarry Smith     /* allocate the matrix space */
35802ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3581d0f46423SBarry Smith     ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
3582d0f46423SBarry Smith     ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3583bfeeae90SHong Zhang     b->i[0] = 0;
3584d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35855da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35865da197adSKris Buschelman     }
3587273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3588e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3589e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3590b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3591b31eba2aSShri Abhyankar   ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3592b31eba2aSShri Abhyankar #endif
3593c461c341SBarry Smith   } else {
3594e6b907acSBarry Smith     b->free_a       = PETSC_FALSE;
3595e6b907acSBarry Smith     b->free_ij      = PETSC_FALSE;
3596c461c341SBarry Smith   }
3597273d9f13SBarry Smith 
3598273d9f13SBarry Smith   b->nz                = 0;
3599273d9f13SBarry Smith   b->maxnz             = nz;
3600273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
36012576faa2SJed Brown   if (realalloc) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);}
3602273d9f13SBarry Smith   PetscFunctionReturn(0);
3603273d9f13SBarry Smith }
3604a23d5eceSKris Buschelman EXTERN_C_END
3605273d9f13SBarry Smith 
3606a1661176SMatthew Knepley #undef  __FUNCT__
3607a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
360858d36128SBarry Smith /*@
3609a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3610a1661176SMatthew Knepley 
3611a1661176SMatthew Knepley    Input Parameters:
3612a1661176SMatthew Knepley +  B - the matrix
3613a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3614a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3615a1661176SMatthew Knepley -  v - optional values in the matrix
3616a1661176SMatthew Knepley 
3617a1661176SMatthew Knepley    Level: developer
3618a1661176SMatthew Knepley 
361958d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
362058d36128SBarry Smith 
3621a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3622a1661176SMatthew Knepley 
3623a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3624a1661176SMatthew Knepley @*/
3625a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3626a1661176SMatthew Knepley {
3627a1661176SMatthew Knepley   PetscErrorCode ierr;
3628a1661176SMatthew Knepley 
3629a1661176SMatthew Knepley   PetscFunctionBegin;
36300700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36316ba663aaSJed Brown   PetscValidType(B,1);
36324ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3633a1661176SMatthew Knepley   PetscFunctionReturn(0);
3634a1661176SMatthew Knepley }
3635a1661176SMatthew Knepley 
3636a1661176SMatthew Knepley EXTERN_C_BEGIN
3637a1661176SMatthew Knepley #undef  __FUNCT__
3638a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36397087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3640a1661176SMatthew Knepley {
3641a1661176SMatthew Knepley   PetscInt       i;
3642a1661176SMatthew Knepley   PetscInt       m,n;
3643a1661176SMatthew Knepley   PetscInt       nz;
3644a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3645a1661176SMatthew Knepley   PetscScalar    *values;
3646a1661176SMatthew Knepley   PetscErrorCode ierr;
3647a1661176SMatthew Knepley 
3648a1661176SMatthew Knepley   PetscFunctionBegin;
364965e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3650779a8d59SSatish Balay 
3651779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3652779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3653779a8d59SSatish Balay 
3654779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3655a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3656a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3657b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3658a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
365965e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3660a1661176SMatthew Knepley     nnz[i] = nz;
3661a1661176SMatthew Knepley   }
3662a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3663a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3664a1661176SMatthew Knepley 
3665a1661176SMatthew Knepley   if (v) {
3666a1661176SMatthew Knepley     values = (PetscScalar*) v;
3667a1661176SMatthew Knepley   } else {
36680e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3669a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3670a1661176SMatthew Knepley   }
3671a1661176SMatthew Knepley 
3672a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3673b7940d39SSatish Balay     nz  = Ii[i+1] - Ii[i];
3674b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3675a1661176SMatthew Knepley   }
3676a1661176SMatthew Knepley 
3677a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3678a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3679a1661176SMatthew Knepley 
3680a1661176SMatthew Knepley   if (!v) {
3681a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3682a1661176SMatthew Knepley   }
36837827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3684a1661176SMatthew Knepley   PetscFunctionReturn(0);
3685a1661176SMatthew Knepley }
3686a1661176SMatthew Knepley EXTERN_C_END
3687a1661176SMatthew Knepley 
3688c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3689b45d2f2cSJed Brown #include <petsc-private/petscaxpy.h>
3690170fe5c8SBarry Smith 
3691170fe5c8SBarry Smith #undef __FUNCT__
3692170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3693170fe5c8SBarry Smith /*
3694170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3695170fe5c8SBarry Smith 
3696170fe5c8SBarry Smith                n                       p                          p
3697170fe5c8SBarry Smith         (              )       (              )         (                  )
3698170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3699170fe5c8SBarry Smith         (              )       (              )         (                  )
3700170fe5c8SBarry Smith 
3701170fe5c8SBarry Smith */
3702170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3703170fe5c8SBarry Smith {
3704170fe5c8SBarry Smith   PetscErrorCode     ierr;
3705170fe5c8SBarry Smith   Mat_SeqDense       *sub_a = (Mat_SeqDense*)A->data;
3706170fe5c8SBarry Smith   Mat_SeqAIJ         *sub_b = (Mat_SeqAIJ*)B->data;
3707170fe5c8SBarry Smith   Mat_SeqDense       *sub_c = (Mat_SeqDense*)C->data;
37081de00fd4SBarry Smith   PetscInt           i,n,m,q,p;
3709170fe5c8SBarry Smith   const PetscInt     *ii,*idx;
3710170fe5c8SBarry Smith   const PetscScalar  *b,*a,*a_q;
3711170fe5c8SBarry Smith   PetscScalar        *c,*c_q;
3712170fe5c8SBarry Smith 
3713170fe5c8SBarry Smith   PetscFunctionBegin;
3714d0f46423SBarry Smith   m = A->rmap->n;
3715d0f46423SBarry Smith   n = A->cmap->n;
3716d0f46423SBarry Smith   p = B->cmap->n;
3717170fe5c8SBarry Smith   a = sub_a->v;
3718170fe5c8SBarry Smith   b = sub_b->a;
3719170fe5c8SBarry Smith   c = sub_c->v;
3720170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3721170fe5c8SBarry Smith 
3722170fe5c8SBarry Smith   ii  = sub_b->i;
3723170fe5c8SBarry Smith   idx = sub_b->j;
3724170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3725170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3726170fe5c8SBarry Smith     while (q-->0) {
3727170fe5c8SBarry Smith       c_q = c + m*(*idx);
3728170fe5c8SBarry Smith       a_q = a + m*i;
3729be7314b0SBarry Smith       PetscAXPY(c_q,*b,a_q,m);
3730170fe5c8SBarry Smith       idx++;
3731170fe5c8SBarry Smith       b++;
3732170fe5c8SBarry Smith     }
3733170fe5c8SBarry Smith   }
3734170fe5c8SBarry Smith   PetscFunctionReturn(0);
3735170fe5c8SBarry Smith }
3736170fe5c8SBarry Smith 
3737170fe5c8SBarry Smith #undef __FUNCT__
3738170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3739170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3740170fe5c8SBarry Smith {
3741170fe5c8SBarry Smith   PetscErrorCode ierr;
3742d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3743170fe5c8SBarry Smith   Mat            Cmat;
3744170fe5c8SBarry Smith 
3745170fe5c8SBarry Smith   PetscFunctionBegin;
3746e32f2f54SBarry 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);
374739804f7cSBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr);
3748170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3749a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3750170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
3751170fe5c8SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);
3752170fe5c8SBarry Smith   Cmat->assembled    = PETSC_TRUE;
37538cdbd757SHong Zhang   Cmat->ops->matmult = MatMatMult_SeqDense_SeqAIJ;
3754170fe5c8SBarry Smith   *C = Cmat;
3755170fe5c8SBarry Smith   PetscFunctionReturn(0);
3756170fe5c8SBarry Smith }
3757170fe5c8SBarry Smith 
3758170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3759170fe5c8SBarry Smith #undef __FUNCT__
3760170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3761170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3762170fe5c8SBarry Smith {
3763170fe5c8SBarry Smith   PetscErrorCode ierr;
3764170fe5c8SBarry Smith 
3765170fe5c8SBarry Smith   PetscFunctionBegin;
3766170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX){
3767170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
3768170fe5c8SBarry Smith   }
3769170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
3770170fe5c8SBarry Smith   PetscFunctionReturn(0);
3771170fe5c8SBarry Smith }
3772170fe5c8SBarry Smith 
3773170fe5c8SBarry Smith 
37740bad9183SKris Buschelman /*MC
3775fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37760bad9183SKris Buschelman    based on compressed sparse row format.
37770bad9183SKris Buschelman 
37780bad9183SKris Buschelman    Options Database Keys:
37790bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37800bad9183SKris Buschelman 
37810bad9183SKris Buschelman   Level: beginner
37820bad9183SKris Buschelman 
3783f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37840bad9183SKris Buschelman M*/
37850bad9183SKris Buschelman 
3786ccd284c7SBarry Smith /*MC
3787ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3788ccd284c7SBarry Smith 
3789ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3790ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3791ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3792ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3793ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3794ccd284c7SBarry Smith 
3795ccd284c7SBarry Smith    Options Database Keys:
3796ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3797ccd284c7SBarry Smith 
3798ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3799ccd284c7SBarry Smith    enough exist.
3800ccd284c7SBarry Smith 
3801ccd284c7SBarry Smith   Level: beginner
3802ccd284c7SBarry Smith 
3803ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3804ccd284c7SBarry Smith M*/
3805ccd284c7SBarry Smith 
3806ccd284c7SBarry Smith /*MC
3807ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3808ccd284c7SBarry Smith 
3809ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3810ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3811ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3812ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3813ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3814ccd284c7SBarry Smith 
3815ccd284c7SBarry Smith    Options Database Keys:
3816ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3817ccd284c7SBarry Smith 
3818ccd284c7SBarry Smith   Level: beginner
3819ccd284c7SBarry Smith 
3820ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3821ccd284c7SBarry Smith M*/
3822ccd284c7SBarry Smith 
3823a6175056SHong Zhang EXTERN_C_BEGIN
3824b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3825b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3826b5e56a35SBarry Smith #endif
3827ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3828af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *);
3829af1023dbSSatish Balay #endif
38307087cfbeSBarry Smith extern PetscErrorCode  MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38317087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38327087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38337087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool  *);
3834611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38357087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3836611f576cSBarry Smith #endif
3837611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38387087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3839611f576cSBarry Smith #endif
3840f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3841f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3842f3c0ef26SHong Zhang #endif
3843eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38447087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3845eb3b5408SSatish Balay #endif
3846586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38477087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3848586621ddSJed Brown #endif
3849719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38507087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3851719d5645SBarry Smith #endif
3852b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38537087cfbeSBarry Smith extern PetscErrorCode  MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38547087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38557087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3856b3866ffcSBarry Smith #endif
385717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
385817f1a0eaSHong Zhang extern PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
385917f1a0eaSHong Zhang #endif
386017667f90SBarry Smith EXTERN_C_END
386117667f90SBarry Smith 
3862c0c8ee5eSDmitry Karpeev 
38638c778c55SBarry Smith #undef __FUNCT__
38648c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
38658c778c55SBarry Smith /*@C
38668c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
38678c778c55SBarry Smith 
38688c778c55SBarry Smith    Not Collective
38698c778c55SBarry Smith 
38708c778c55SBarry Smith    Input Parameter:
38718c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
38728c778c55SBarry Smith 
38738c778c55SBarry Smith    Output Parameter:
38748c778c55SBarry Smith .   array - pointer to the data
38758c778c55SBarry Smith 
38768c778c55SBarry Smith    Level: intermediate
38778c778c55SBarry Smith 
38788c778c55SBarry Smith .seealso: MatSeqAIJRestoreArray()
38798c778c55SBarry Smith @*/
38808c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38818c778c55SBarry Smith {
38828c778c55SBarry Smith   PetscErrorCode ierr;
38838c778c55SBarry Smith 
38848c778c55SBarry Smith   PetscFunctionBegin;
38858c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38868c778c55SBarry Smith   PetscFunctionReturn(0);
38878c778c55SBarry Smith }
38888c778c55SBarry Smith 
38898c778c55SBarry Smith #undef __FUNCT__
38908c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
38918c778c55SBarry Smith /*@C
38928c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
38938c778c55SBarry Smith 
38948c778c55SBarry Smith    Not Collective
38958c778c55SBarry Smith 
38968c778c55SBarry Smith    Input Parameters:
38978c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
38988c778c55SBarry Smith .  array - pointer to the data
38998c778c55SBarry Smith 
39008c778c55SBarry Smith    Level: intermediate
39018c778c55SBarry Smith 
39028c778c55SBarry Smith .seealso: MatSeqAIJGetArray()
39038c778c55SBarry Smith @*/
39048c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39058c778c55SBarry Smith {
39068c778c55SBarry Smith   PetscErrorCode ierr;
39078c778c55SBarry Smith 
39088c778c55SBarry Smith   PetscFunctionBegin;
39098c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39108c778c55SBarry Smith   PetscFunctionReturn(0);
39118c778c55SBarry Smith }
39128c778c55SBarry Smith 
391317667f90SBarry Smith EXTERN_C_BEGIN
39144a2ae208SSatish Balay #undef __FUNCT__
39154a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39167087cfbeSBarry Smith PetscErrorCode  MatCreate_SeqAIJ(Mat B)
3917273d9f13SBarry Smith {
3918273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3919dfbe8321SBarry Smith   PetscErrorCode ierr;
392038baddfdSBarry Smith   PetscMPIInt    size;
3921273d9f13SBarry Smith 
3922273d9f13SBarry Smith   PetscFunctionBegin;
39237adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr);
3924e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3925273d9f13SBarry Smith 
392638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
3927b0a32e0cSBarry Smith   B->data             = (void*)b;
3928549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
3929416022c9SBarry Smith   b->row              = 0;
3930416022c9SBarry Smith   b->col              = 0;
393182bf6240SBarry Smith   b->icol             = 0;
3932b810aeb4SBarry Smith   b->reallocs         = 0;
393336db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
3934f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
3935416022c9SBarry Smith   b->nonew             = 0;
3936416022c9SBarry Smith   b->diag              = 0;
3937416022c9SBarry Smith   b->solve_work        = 0;
39382a1b7f2aSHong Zhang   B->spptr             = 0;
3939be6bf707SBarry Smith   b->saved_values      = 0;
3940d7f994e1SBarry Smith   b->idiag             = 0;
394171f1c65dSBarry Smith   b->mdiag             = 0;
394271f1c65dSBarry Smith   b->ssor_work         = 0;
394371f1c65dSBarry Smith   b->omega             = 1.0;
394471f1c65dSBarry Smith   b->fshift            = 0.0;
394571f1c65dSBarry Smith   b->idiagvalid        = PETSC_FALSE;
3946bbead8a2SBarry Smith   b->ibdiagvalid       = PETSC_FALSE;
3947a9817697SBarry Smith   b->keepnonzeropattern    = PETSC_FALSE;
3948a30b2313SHong Zhang   b->xtoy              = 0;
3949a30b2313SHong Zhang   b->XtoY              = 0;
395088e51ccdSHong Zhang   B->same_nonzero          = PETSC_FALSE;
395117ab2063SBarry Smith 
395235d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39538c778c55SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetArray_C","MatSeqAIJGetArray_SeqAIJ",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
39548c778c55SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJRestoreArray_C","MatSeqAIJRestoreArray_SeqAIJ",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39558c778c55SBarry Smith 
3956b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3957700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3958b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3959b3866ffcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3960b3866ffcSBarry Smith #endif
3961b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3962700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3963b5e56a35SBarry Smith #endif
3964ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3965700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3966719d5645SBarry Smith #endif
3967611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3968700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3969611f576cSBarry Smith #endif
3970f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3971700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
3972f3c0ef26SHong Zhang #endif
3973611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
3974700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr);
3975611f576cSBarry Smith #endif
3976eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
3977700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
3978eb3b5408SSatish Balay #endif
3979586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
3980700c5bfcSBarry Smith     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
3981586621ddSJed Brown #endif
3982719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
398317f1a0eaSHong Zhang     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_aij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
3984719d5645SBarry Smith #endif
398517f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
398617f1a0eaSHong Zhang     ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_clique_C","MatGetFactor_aij_clique",MatGetFactor_aij_clique);CHKERRQ(ierr);
398717f1a0eaSHong Zhang #endif
398817f1a0eaSHong Zhang 
3989700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
3990700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
3991700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
3992700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3993700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3994700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3995700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3996700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3997700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3998700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3999700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4000700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4001700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4002700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4003700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4004700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4005700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4006700c5bfcSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40074108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
400817667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40093a40ed3dSBarry Smith   PetscFunctionReturn(0);
401017ab2063SBarry Smith }
4011273d9f13SBarry Smith EXTERN_C_END
401217ab2063SBarry Smith 
40134a2ae208SSatish Balay #undef __FUNCT__
4014b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4015b24902e0SBarry Smith /*
4016b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4017b24902e0SBarry Smith */
4018ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool  mallocmatspace)
401917ab2063SBarry Smith {
4020416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40216849ba73SBarry Smith   PetscErrorCode ierr;
4022d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
402317ab2063SBarry Smith 
40243a40ed3dSBarry Smith   PetscFunctionBegin;
4025273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4026273d9f13SBarry Smith 
4027d5f3da31SBarry Smith   C->factortype     = A->factortype;
4028416022c9SBarry Smith   c->row            = 0;
4029416022c9SBarry Smith   c->col            = 0;
403082bf6240SBarry Smith   c->icol           = 0;
40316ad4291fSHong Zhang   c->reallocs       = 0;
403217ab2063SBarry Smith 
40336ad4291fSHong Zhang   C->assembled      = PETSC_TRUE;
403417ab2063SBarry Smith 
4035aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4036aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4037eec197d1SBarry Smith 
403833b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40399518dbb4SMatthew Knepley   ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
404017ab2063SBarry Smith   for (i=0; i<m; i++) {
4041416022c9SBarry Smith     c->imax[i] = a->imax[i];
4042416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
404317ab2063SBarry Smith   }
404417ab2063SBarry Smith 
404517ab2063SBarry Smith   /* allocate the matrix space */
4046f77e22a1SHong Zhang   if (mallocmatspace){
4047a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40489518dbb4SMatthew Knepley     ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
4049f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
405097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
405117ab2063SBarry Smith     if (m > 0) {
405297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4053be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4054bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4055be6bf707SBarry Smith       } else {
4056bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
405717ab2063SBarry Smith       }
405808480c60SBarry Smith     }
4059f77e22a1SHong Zhang   }
406017ab2063SBarry Smith 
40616ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4062416022c9SBarry Smith   c->roworiented       = a->roworiented;
4063416022c9SBarry Smith   c->nonew             = a->nonew;
4064416022c9SBarry Smith   if (a->diag) {
406597f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
406652e6d16bSBarry Smith     ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
406717ab2063SBarry Smith     for (i=0; i<m; i++) {
4068416022c9SBarry Smith       c->diag[i] = a->diag[i];
406917ab2063SBarry Smith     }
40703a40ed3dSBarry Smith   } else c->diag           = 0;
40716ad4291fSHong Zhang   c->solve_work            = 0;
40726ad4291fSHong Zhang   c->saved_values          = 0;
40736ad4291fSHong Zhang   c->idiag                 = 0;
407471f1c65dSBarry Smith   c->ssor_work             = 0;
4075a9817697SBarry Smith   c->keepnonzeropattern    = a->keepnonzeropattern;
4076e6b907acSBarry Smith   c->free_a                = PETSC_TRUE;
4077e6b907acSBarry Smith   c->free_ij               = PETSC_TRUE;
40786ad4291fSHong Zhang   c->xtoy                  = 0;
40796ad4291fSHong Zhang   c->XtoY                  = 0;
40806ad4291fSHong Zhang 
4081893ad86cSHong Zhang   c->rmax               = a->rmax;
4082416022c9SBarry Smith   c->nz                 = a->nz;
40838ed568f8SMatthew G Knepley   c->maxnz              = a->nz; /* Since we allocate exactly the right amount */
4084273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
4085754ec7b1SSatish Balay 
40866ad4291fSHong Zhang   c->compressedrow.use     = a->compressedrow.use;
40876ad4291fSHong Zhang   c->compressedrow.nrows   = a->compressedrow.nrows;
4088cd6b891eSBarry Smith   c->compressedrow.check   = a->compressedrow.check;
4089cd6b891eSBarry Smith   if (a->compressedrow.use){
40906ad4291fSHong Zhang     i = a->compressedrow.nrows;
40910e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
40926ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40936ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
409427ea64f8SHong Zhang   } else {
409527ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
409627ea64f8SHong Zhang     c->compressedrow.i      = PETSC_NULL;
409727ea64f8SHong Zhang     c->compressedrow.rindex = PETSC_NULL;
40986ad4291fSHong Zhang   }
409988e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41004108e4d5SBarry Smith   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
41014846f1f5SKris Buschelman 
41027adad957SLisandro Dalcin   ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41033a40ed3dSBarry Smith   PetscFunctionReturn(0);
410417ab2063SBarry Smith }
410517ab2063SBarry Smith 
41064a2ae208SSatish Balay #undef __FUNCT__
4107b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4108b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4109b24902e0SBarry Smith {
4110b24902e0SBarry Smith   PetscErrorCode ierr;
4111b24902e0SBarry Smith 
4112b24902e0SBarry Smith   PetscFunctionBegin;
4113b24902e0SBarry Smith   ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr);
41144b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4115a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4116a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4117f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4118b24902e0SBarry Smith   PetscFunctionReturn(0);
4119b24902e0SBarry Smith }
4120b24902e0SBarry Smith 
4121b24902e0SBarry Smith #undef __FUNCT__
41224a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4123112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4124fbdbba38SShri Abhyankar {
4125fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4126fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4127fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4128fbdbba38SShri Abhyankar   int            fd;
4129fbdbba38SShri Abhyankar   PetscMPIInt    size;
4130fbdbba38SShri Abhyankar   MPI_Comm       comm;
4131bbead8a2SBarry Smith   PetscInt       bs = 1;
4132fbdbba38SShri Abhyankar 
4133fbdbba38SShri Abhyankar   PetscFunctionBegin;
4134fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4135fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4136fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4137bbead8a2SBarry Smith 
4138bbead8a2SBarry Smith   ierr = PetscOptionsBegin(comm,PETSC_NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
4139bbead8a2SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,PETSC_NULL);CHKERRQ(ierr);
4140bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4141bbead8a2SBarry Smith 
4142fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4143fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4144fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4145fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4146fbdbba38SShri Abhyankar 
4147bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4148fbdbba38SShri Abhyankar 
4149fbdbba38SShri Abhyankar   /* read in row lengths */
4150fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4151fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4152fbdbba38SShri Abhyankar 
4153fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4154fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4155fbdbba38SShri 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);
4156fbdbba38SShri Abhyankar 
4157fbdbba38SShri Abhyankar   /* set global size if not set already*/
4158f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4159fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4160aabbc4fbSShri Abhyankar   } else {
4161fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4162fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41634c5b953cSHong Zhang     if (rows < 0 && cols < 0){ /* user might provide local size instead of global size */
41644c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41654c5b953cSHong Zhang     }
4166f501eaabSShri 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);
4167aabbc4fbSShri Abhyankar   }
4168fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4169fbdbba38SShri Abhyankar   a = (Mat_SeqAIJ*)newMat->data;
4170fbdbba38SShri Abhyankar 
4171fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4172fbdbba38SShri Abhyankar 
4173fbdbba38SShri Abhyankar   /* read in nonzero values */
4174fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4175fbdbba38SShri Abhyankar 
4176fbdbba38SShri Abhyankar   /* set matrix "i" values */
4177fbdbba38SShri Abhyankar   a->i[0] = 0;
4178fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4179fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4180fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4181fbdbba38SShri Abhyankar   }
4182fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4183fbdbba38SShri Abhyankar 
4184fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4185fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4186bbead8a2SBarry Smith   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4187fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4188fbdbba38SShri Abhyankar }
4189fbdbba38SShri Abhyankar 
4190fbdbba38SShri Abhyankar #undef __FUNCT__
4191b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4192ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41937264ac53SSatish Balay {
41947264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
4195dfbe8321SBarry Smith   PetscErrorCode ierr;
4196eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4197eeffb40dSHong Zhang   PetscInt k;
4198eeffb40dSHong Zhang #endif
41997264ac53SSatish Balay 
42003a40ed3dSBarry Smith   PetscFunctionBegin;
4201bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4202d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4203ca44d042SBarry Smith     *flg = PETSC_FALSE;
4204ca44d042SBarry Smith     PetscFunctionReturn(0);
4205bcd2baecSBarry Smith   }
42067264ac53SSatish Balay 
42077264ac53SSatish Balay   /* if the a->i are the same */
4208d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4209abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42107264ac53SSatish Balay 
42117264ac53SSatish Balay   /* if a->j are the same */
421297f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4213abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4214bcd2baecSBarry Smith 
4215bcd2baecSBarry Smith   /* if a->a are the same */
4216eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4217eeffb40dSHong Zhang   for (k=0; k<a->nz; k++){
4218eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){
4219eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42203a40ed3dSBarry Smith       PetscFunctionReturn(0);
4221eeffb40dSHong Zhang     }
4222eeffb40dSHong Zhang   }
4223eeffb40dSHong Zhang #else
4224eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4225eeffb40dSHong Zhang #endif
4226eeffb40dSHong Zhang   PetscFunctionReturn(0);
42277264ac53SSatish Balay }
422836db0b34SBarry Smith 
42294a2ae208SSatish Balay #undef __FUNCT__
42304a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
423105869f15SSatish Balay /*@
423236db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
423336db0b34SBarry Smith               provided by the user.
423436db0b34SBarry Smith 
4235c75a6043SHong Zhang       Collective on MPI_Comm
423636db0b34SBarry Smith 
423736db0b34SBarry Smith    Input Parameters:
423836db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
423936db0b34SBarry Smith .   m - number of rows
424036db0b34SBarry Smith .   n - number of columns
424136db0b34SBarry Smith .   i - row indices
424236db0b34SBarry Smith .   j - column indices
424336db0b34SBarry Smith -   a - matrix values
424436db0b34SBarry Smith 
424536db0b34SBarry Smith    Output Parameter:
424636db0b34SBarry Smith .   mat - the matrix
424736db0b34SBarry Smith 
424836db0b34SBarry Smith    Level: intermediate
424936db0b34SBarry Smith 
425036db0b34SBarry Smith    Notes:
42510551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4252292fb18eSBarry Smith     once the matrix is destroyed and not before
425336db0b34SBarry Smith 
425436db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
425536db0b34SBarry Smith 
4256bfeeae90SHong Zhang        The i and j indices are 0 based
425736db0b34SBarry Smith 
4258a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4259a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4260a4552177SSatish Balay     as shown:
4261a4552177SSatish Balay 
4262a4552177SSatish Balay         1 0 0
4263a4552177SSatish Balay         2 0 3
4264a4552177SSatish Balay         4 5 6
4265a4552177SSatish Balay 
4266a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42679985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4268a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4269a4552177SSatish Balay 
42709985e31cSBarry Smith 
427169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
427236db0b34SBarry Smith 
427336db0b34SBarry Smith @*/
42747087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat)
427536db0b34SBarry Smith {
4276dfbe8321SBarry Smith   PetscErrorCode ierr;
4277cbcfb4deSHong Zhang   PetscInt       ii;
427836db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4279cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4280cbcfb4deSHong Zhang   PetscInt       jj;
4281cbcfb4deSHong Zhang #endif
428236db0b34SBarry Smith 
428336db0b34SBarry Smith   PetscFunctionBegin;
4284a96a251dSBarry Smith   if (i[0]) {
4285e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
428636db0b34SBarry Smith   }
4287f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4288f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4289a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4290ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4291ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4292ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4293ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4294ab93d7beSBarry Smith 
429536db0b34SBarry Smith   aij->i = i;
429636db0b34SBarry Smith   aij->j = j;
429736db0b34SBarry Smith   aij->a = a;
429836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
429936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4300e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4301e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
430236db0b34SBarry Smith 
430336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
430436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43052515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4306e32f2f54SBarry 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]);
43079985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4308e32f2f54SBarry 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);
4309e32f2f54SBarry 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);
43109985e31cSBarry Smith     }
431136db0b34SBarry Smith #endif
431236db0b34SBarry Smith   }
43132515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
431436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4315e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4316e32f2f54SBarry 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]);
431736db0b34SBarry Smith   }
431836db0b34SBarry Smith #endif
431936db0b34SBarry Smith 
4320b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4321b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
432236db0b34SBarry Smith   PetscFunctionReturn(0);
432336db0b34SBarry Smith }
43248a0b0e6bSVictor Minden #undef __FUNCT__
43258a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
432680ef6e79SMatthew G Knepley /*@C
4327d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43288a0b0e6bSVictor Minden               provided by the user.
43298a0b0e6bSVictor Minden 
43308a0b0e6bSVictor Minden       Collective on MPI_Comm
43318a0b0e6bSVictor Minden 
43328a0b0e6bSVictor Minden    Input Parameters:
43338a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43348a0b0e6bSVictor Minden .   m   - number of rows
43358a0b0e6bSVictor Minden .   n   - number of columns
43368a0b0e6bSVictor Minden .   i   - row indices
43378a0b0e6bSVictor Minden .   j   - column indices
43381230e6d1SVictor Minden .   a   - matrix values
43391230e6d1SVictor Minden .   nz  - number of nonzeros
43401230e6d1SVictor Minden -   idx - 0 or 1 based
43418a0b0e6bSVictor Minden 
43428a0b0e6bSVictor Minden    Output Parameter:
43438a0b0e6bSVictor Minden .   mat - the matrix
43448a0b0e6bSVictor Minden 
43458a0b0e6bSVictor Minden    Level: intermediate
43468a0b0e6bSVictor Minden 
43478a0b0e6bSVictor Minden    Notes:
43488a0b0e6bSVictor Minden        The i and j indices are 0 based
43498a0b0e6bSVictor Minden 
43508a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43518a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43528a0b0e6bSVictor Minden     as shown:
43538a0b0e6bSVictor Minden 
43548a0b0e6bSVictor Minden         1 0 0
43558a0b0e6bSVictor Minden         2 0 3
43568a0b0e6bSVictor Minden         4 5 6
43578a0b0e6bSVictor Minden 
43588a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43598a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43608a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43618a0b0e6bSVictor Minden 
43628a0b0e6bSVictor Minden 
436369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43648a0b0e6bSVictor Minden 
43658a0b0e6bSVictor Minden @*/
43661230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
43678a0b0e6bSVictor Minden {
43688a0b0e6bSVictor Minden   PetscErrorCode ierr;
4369d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43708a0b0e6bSVictor Minden 
43718a0b0e6bSVictor Minden 
43728a0b0e6bSVictor Minden   PetscFunctionBegin;
4373d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
43741230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
43751230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++){
43761230e6d1SVictor Minden     nnz[i[ii]] += 1;
43771230e6d1SVictor Minden   }
43788a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43798a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4380a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
43818a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43821230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43831230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++){
43841230e6d1SVictor Minden     if (idx){
43851230e6d1SVictor Minden       row = i[ii] - 1;
43861230e6d1SVictor Minden       col = j[ii] - 1;
43871230e6d1SVictor Minden     } else {
43881230e6d1SVictor Minden       row = i[ii];
43891230e6d1SVictor Minden       col = j[ii];
43908a0b0e6bSVictor Minden     }
43911230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43928a0b0e6bSVictor Minden   }
43938a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43948a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4395d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43968a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43978a0b0e6bSVictor Minden }
439836db0b34SBarry Smith 
4399cc8ba8e1SBarry Smith #undef __FUNCT__
4400ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4401dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4402cc8ba8e1SBarry Smith {
4403dfbe8321SBarry Smith   PetscErrorCode ierr;
4404cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
440536db0b34SBarry Smith 
4406cc8ba8e1SBarry Smith   PetscFunctionBegin;
44078ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4408cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4409cc8ba8e1SBarry Smith     a->coloring = coloring;
441012c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
441197f1f81fSBarry Smith     PetscInt             i,*larray;
441212c595b3SBarry Smith     ISColoring      ocoloring;
441308b6dcc0SBarry Smith     ISColoringValue *colors;
441412c595b3SBarry Smith 
441512c595b3SBarry Smith     /* set coloring for diagonal portion */
44160e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
4417d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
441812c595b3SBarry Smith       larray[i] = i;
441912c595b3SBarry Smith     }
4420992144d0SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
44210e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
4422d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {
442312c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
442412c595b3SBarry Smith     }
442512c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
4426d0f46423SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
442712c595b3SBarry Smith     a->coloring = ocoloring;
442812c595b3SBarry Smith   }
4429cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4430cc8ba8e1SBarry Smith }
4431cc8ba8e1SBarry Smith 
4432dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC)
4433ee4f033dSBarry Smith EXTERN_C_BEGIN
4434c6db04a5SJed Brown #include <adic/ad_utils.h>
4435ee4f033dSBarry Smith EXTERN_C_END
4436cc8ba8e1SBarry Smith 
4437cc8ba8e1SBarry Smith #undef __FUNCT__
4438ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
4439dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
4440cc8ba8e1SBarry Smith {
4441cc8ba8e1SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4442d0f46423SBarry Smith   PetscInt        m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen;
44434440f671SBarry Smith   PetscScalar     *v = a->a,*values = ((PetscScalar*)advalues)+1;
444408b6dcc0SBarry Smith   ISColoringValue *color;
4445cc8ba8e1SBarry Smith 
4446cc8ba8e1SBarry Smith   PetscFunctionBegin;
4447e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
44484440f671SBarry Smith   nlen  = PetscADGetDerivTypeSize()/sizeof(PetscScalar);
4449cc8ba8e1SBarry Smith   color = a->coloring->colors;
4450cc8ba8e1SBarry Smith   /* loop over rows */
4451cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
4452cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
4453cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
4454cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
4455cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
4456cc8ba8e1SBarry Smith     }
44574440f671SBarry Smith     values += nlen; /* jump to next row of derivatives */
4458ee4f033dSBarry Smith   }
4459ee4f033dSBarry Smith   PetscFunctionReturn(0);
4460ee4f033dSBarry Smith }
4461ee4f033dSBarry Smith #endif
4462ee4f033dSBarry Smith 
4463ee4f033dSBarry Smith #undef __FUNCT__
4464ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446597f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4466ee4f033dSBarry Smith {
4467ee4f033dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
4468d0f46423SBarry Smith   PetscInt         m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
446954f21887SBarry Smith   MatScalar       *v = a->a;
447054f21887SBarry Smith   PetscScalar     *values = (PetscScalar *)advalues;
447108b6dcc0SBarry Smith   ISColoringValue *color;
4472ee4f033dSBarry Smith 
4473ee4f033dSBarry Smith   PetscFunctionBegin;
4474e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4475ee4f033dSBarry Smith   color = a->coloring->colors;
4476ee4f033dSBarry Smith   /* loop over rows */
4477ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4478ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4479ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
4480ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
4481ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
4482ee4f033dSBarry Smith     }
4483ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4484cc8ba8e1SBarry Smith   }
4485cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4486cc8ba8e1SBarry Smith }
448736db0b34SBarry Smith 
448881824310SBarry Smith /*
448981824310SBarry Smith     Special version for direct calls from Fortran
449081824310SBarry Smith */
4491b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
449281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
449381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
449481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
449581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
449681824310SBarry Smith #endif
449781824310SBarry Smith 
449881824310SBarry Smith /* Change these macros so can be used in void function */
449981824310SBarry Smith #undef CHKERRQ
45007adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr)
450181824310SBarry Smith #undef SETERRQ2
4502e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45034994cf47SJed Brown #undef SETERRQ3
45044994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
450581824310SBarry Smith 
450681824310SBarry Smith EXTERN_C_BEGIN
450781824310SBarry Smith #undef __FUNCT__
450881824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45091f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
451081824310SBarry Smith {
451181824310SBarry Smith   Mat            A = *AA;
451281824310SBarry Smith   PetscInt       m = *mm, n = *nn;
451381824310SBarry Smith   InsertMode     is = *isis;
451481824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
451581824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
451681824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
451781824310SBarry Smith   PetscErrorCode ierr;
451881824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
451954f21887SBarry Smith   MatScalar      *ap,value,*aa;
4520ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4521ace3abfcSBarry Smith   PetscBool      roworiented = a->roworiented;
452281824310SBarry Smith 
452381824310SBarry Smith   PetscFunctionBegin;
45244994cf47SJed Brown   MatCheckPreallocated(A,1);
452581824310SBarry Smith   imax = a->imax;
452681824310SBarry Smith   ai = a->i;
452781824310SBarry Smith   ailen = a->ilen;
452881824310SBarry Smith   aj = a->j;
452981824310SBarry Smith   aa = a->a;
453081824310SBarry Smith 
453181824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
453281824310SBarry Smith     row  = im[k];
453381824310SBarry Smith     if (row < 0) continue;
453481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4535d0f46423SBarry Smith     if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
453681824310SBarry Smith #endif
453781824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
453881824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
453981824310SBarry Smith     low  = 0;
454081824310SBarry Smith     high = nrow;
454181824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
454281824310SBarry Smith       if (in[l] < 0) continue;
454381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4544d0f46423SBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
454581824310SBarry Smith #endif
454681824310SBarry Smith       col = in[l];
454781824310SBarry Smith       if (roworiented) {
454881824310SBarry Smith         value = v[l + k*n];
454981824310SBarry Smith       } else {
455081824310SBarry Smith         value = v[k + l*m];
455181824310SBarry Smith       }
455281824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
455381824310SBarry Smith 
455481824310SBarry Smith       if (col <= lastcol) low = 0; else high = nrow;
455581824310SBarry Smith       lastcol = col;
455681824310SBarry Smith       while (high-low > 5) {
455781824310SBarry Smith         t = (low+high)/2;
455881824310SBarry Smith         if (rp[t] > col) high = t;
455981824310SBarry Smith         else             low  = t;
456081824310SBarry Smith       }
456181824310SBarry Smith       for (i=low; i<high; i++) {
456281824310SBarry Smith         if (rp[i] > col) break;
456381824310SBarry Smith         if (rp[i] == col) {
456481824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
456581824310SBarry Smith           else                  ap[i] = value;
456681824310SBarry Smith           goto noinsert;
456781824310SBarry Smith         }
456881824310SBarry Smith       }
456981824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
457081824310SBarry Smith       if (nonew == 1) goto noinsert;
45717adad957SLisandro Dalcin       if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4572fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
457381824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
457481824310SBarry Smith       /* shift up all the later entries in this row */
457581824310SBarry Smith       for (ii=N; ii>=i; ii--) {
457681824310SBarry Smith         rp[ii+1] = rp[ii];
457781824310SBarry Smith         ap[ii+1] = ap[ii];
457881824310SBarry Smith       }
457981824310SBarry Smith       rp[i] = col;
458081824310SBarry Smith       ap[i] = value;
458181824310SBarry Smith       noinsert:;
458281824310SBarry Smith       low = i + 1;
458381824310SBarry Smith     }
458481824310SBarry Smith     ailen[row] = nrow;
458581824310SBarry Smith   }
458681824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
458781824310SBarry Smith   PetscFunctionReturnVoid();
458881824310SBarry Smith }
458981824310SBarry Smith EXTERN_C_END
459062298a1eSBarry Smith 
4591