xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 390e1bf27627d887df99a9f4d0d0ad68037f55ec)
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>
11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h>
120716a85fSBarry Smith 
130716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
140716a85fSBarry Smith {
150716a85fSBarry Smith   PetscErrorCode ierr;
160716a85fSBarry Smith   PetscInt       i,m,n;
170716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
180716a85fSBarry Smith 
190716a85fSBarry Smith   PetscFunctionBegin;
200716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
210716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
220716a85fSBarry Smith   if (type == NORM_2) {
230716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
240716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
250716a85fSBarry Smith     }
260716a85fSBarry Smith   } else if (type == NORM_1) {
270716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
280716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
290716a85fSBarry Smith     }
300716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
310716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
320716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
330716a85fSBarry Smith     }
340716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
350716a85fSBarry Smith 
360716a85fSBarry Smith   if (type == NORM_2) {
378f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
380716a85fSBarry Smith   }
390716a85fSBarry Smith   PetscFunctionReturn(0);
400716a85fSBarry Smith }
410716a85fSBarry Smith 
423a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
433a062f41SBarry Smith {
443a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
453a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
463a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
473a062f41SBarry Smith   PetscInt        *rows;
483a062f41SBarry Smith   PetscErrorCode  ierr;
493a062f41SBarry Smith 
503a062f41SBarry Smith   PetscFunctionBegin;
513a062f41SBarry Smith   for (i=0; i<m; i++) {
523a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
533a062f41SBarry Smith       cnt++;
543a062f41SBarry Smith     }
553a062f41SBarry Smith   }
563a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
573a062f41SBarry Smith   cnt  = 0;
583a062f41SBarry Smith   for (i=0; i<m; i++) {
593a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
603a062f41SBarry Smith       rows[cnt] = i;
613a062f41SBarry Smith       cnt++;
623a062f41SBarry Smith     }
633a062f41SBarry Smith   }
643a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
653a062f41SBarry Smith   PetscFunctionReturn(0);
663a062f41SBarry Smith }
673a062f41SBarry Smith 
68f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
696ce1633cSBarry Smith {
706ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
716ce1633cSBarry Smith   const MatScalar *aa = a->a;
726ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
73b2db7409Sstefano_zampini   const PetscInt  *ii = a->i,*jj = a->j,*diag;
746ce1633cSBarry Smith   PetscInt        *rows;
756ce1633cSBarry Smith   PetscErrorCode  ierr;
766ce1633cSBarry Smith 
776ce1633cSBarry Smith   PetscFunctionBegin;
786ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
796ce1633cSBarry Smith   diag = a->diag;
806ce1633cSBarry Smith   for (i=0; i<m; i++) {
81b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
826ce1633cSBarry Smith       cnt++;
836ce1633cSBarry Smith     }
846ce1633cSBarry Smith   }
85785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
866ce1633cSBarry Smith   cnt  = 0;
876ce1633cSBarry Smith   for (i=0; i<m; i++) {
88b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
896ce1633cSBarry Smith       rows[cnt++] = i;
906ce1633cSBarry Smith     }
916ce1633cSBarry Smith   }
92f1f41ecbSJed Brown   *nrows = cnt;
93f1f41ecbSJed Brown   *zrows = rows;
94f1f41ecbSJed Brown   PetscFunctionReturn(0);
95f1f41ecbSJed Brown }
96f1f41ecbSJed Brown 
97f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
98f1f41ecbSJed Brown {
99f1f41ecbSJed Brown   PetscInt       nrows,*rows;
100f1f41ecbSJed Brown   PetscErrorCode ierr;
101f1f41ecbSJed Brown 
102f1f41ecbSJed Brown   PetscFunctionBegin;
1030298fd71SBarry Smith   *zrows = NULL;
104f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
105ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1066ce1633cSBarry Smith   PetscFunctionReturn(0);
1076ce1633cSBarry Smith }
1086ce1633cSBarry Smith 
109b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
110b3a44c85SBarry Smith {
111b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
112b3a44c85SBarry Smith   const MatScalar *aa;
113b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
114b3a44c85SBarry Smith   const PetscInt  *ii;
115b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
116b3a44c85SBarry Smith   PetscErrorCode  ierr;
117b3a44c85SBarry Smith 
118b3a44c85SBarry Smith   PetscFunctionBegin;
119b3a44c85SBarry Smith   *keptrows = 0;
120b3a44c85SBarry Smith   ii        = a->i;
121b3a44c85SBarry Smith   for (i=0; i<m; i++) {
122b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
123b3a44c85SBarry Smith     if (!n) {
124b3a44c85SBarry Smith       cnt++;
125b3a44c85SBarry Smith       goto ok1;
126b3a44c85SBarry Smith     }
127b3a44c85SBarry Smith     aa = a->a + ii[i];
128b3a44c85SBarry Smith     for (j=0; j<n; j++) {
129b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
130b3a44c85SBarry Smith     }
131b3a44c85SBarry Smith     cnt++;
132b3a44c85SBarry Smith ok1:;
133b3a44c85SBarry Smith   }
134b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
135854ce69bSBarry Smith   ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr);
136b3a44c85SBarry Smith   cnt  = 0;
137b3a44c85SBarry Smith   for (i=0; i<m; i++) {
138b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
139b3a44c85SBarry Smith     if (!n) continue;
140b3a44c85SBarry Smith     aa = a->a + ii[i];
141b3a44c85SBarry Smith     for (j=0; j<n; j++) {
142b3a44c85SBarry Smith       if (aa[j] != 0.0) {
143b3a44c85SBarry Smith         rows[cnt++] = i;
144b3a44c85SBarry Smith         break;
145b3a44c85SBarry Smith       }
146b3a44c85SBarry Smith     }
147b3a44c85SBarry Smith   }
148b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
149b3a44c85SBarry Smith   PetscFunctionReturn(0);
150b3a44c85SBarry Smith }
151b3a44c85SBarry Smith 
1527087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
15379299369SBarry Smith {
15479299369SBarry Smith   PetscErrorCode    ierr;
15579299369SBarry Smith   Mat_SeqAIJ        *aij = (Mat_SeqAIJ*) Y->data;
15699e65526SBarry Smith   PetscInt          i,m = Y->rmap->n;
15799e65526SBarry Smith   const PetscInt    *diag;
15854f21887SBarry Smith   MatScalar         *aa = aij->a;
15999e65526SBarry Smith   const PetscScalar *v;
160ace3abfcSBarry Smith   PetscBool         missing;
16179299369SBarry Smith 
16279299369SBarry Smith   PetscFunctionBegin;
16309f38230SBarry Smith   if (Y->assembled) {
1640298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
16509f38230SBarry Smith     if (!missing) {
16679299369SBarry Smith       diag = aij->diag;
16799e65526SBarry Smith       ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr);
16879299369SBarry Smith       if (is == INSERT_VALUES) {
16979299369SBarry Smith         for (i=0; i<m; i++) {
17079299369SBarry Smith           aa[diag[i]] = v[i];
17179299369SBarry Smith         }
17279299369SBarry Smith       } else {
17379299369SBarry Smith         for (i=0; i<m; i++) {
17479299369SBarry Smith           aa[diag[i]] += v[i];
17579299369SBarry Smith         }
17679299369SBarry Smith       }
17799e65526SBarry Smith       ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr);
17879299369SBarry Smith       PetscFunctionReturn(0);
17979299369SBarry Smith     }
180acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
18109f38230SBarry Smith   }
18209f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
18309f38230SBarry Smith   PetscFunctionReturn(0);
18409f38230SBarry Smith }
18579299369SBarry Smith 
1861a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
18717ab2063SBarry Smith {
188416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
189dfbe8321SBarry Smith   PetscErrorCode ierr;
19097f1f81fSBarry Smith   PetscInt       i,ishift;
19117ab2063SBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionBegin;
193d0f46423SBarry Smith   *m = A->rmap->n;
1943a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
195bfeeae90SHong Zhang   ishift = 0;
19653e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
1972462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
198bfeeae90SHong Zhang   } else if (oshift == 1) {
1991a83f524SJed Brown     PetscInt *tia;
200d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2013b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
202854ce69bSBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr);
2031a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2041a83f524SJed Brown     *ia = tia;
205ecc77c7aSBarry Smith     if (ja) {
2061a83f524SJed Brown       PetscInt *tja;
207854ce69bSBarry Smith       ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr);
2081a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2091a83f524SJed Brown       *ja = tja;
210ecc77c7aSBarry Smith     }
2116945ee14SBarry Smith   } else {
212ecc77c7aSBarry Smith     *ia = a->i;
213ecc77c7aSBarry Smith     if (ja) *ja = a->j;
214a2ce50c7SBarry Smith   }
2153a40ed3dSBarry Smith   PetscFunctionReturn(0);
216a2744918SBarry Smith }
217a2744918SBarry Smith 
2181a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2196945ee14SBarry Smith {
220dfbe8321SBarry Smith   PetscErrorCode ierr;
2216945ee14SBarry Smith 
2223a40ed3dSBarry Smith   PetscFunctionBegin;
2233a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
224bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
225606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
226ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
227bcd2baecSBarry Smith   }
2283a40ed3dSBarry Smith   PetscFunctionReturn(0);
22917ab2063SBarry Smith }
23017ab2063SBarry Smith 
2311a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2323b2fbd54SBarry Smith {
2333b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
234dfbe8321SBarry Smith   PetscErrorCode ierr;
235d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
23697f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2373b2fbd54SBarry Smith 
2383a40ed3dSBarry Smith   PetscFunctionBegin;
239899cda47SBarry Smith   *nn = n;
2403a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2413b2fbd54SBarry Smith   if (symmetric) {
2422462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2433b2fbd54SBarry Smith   } else {
2441795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
245854ce69bSBarry Smith     ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
246854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
2473b2fbd54SBarry Smith     jj   = a->j;
2483b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
249bfeeae90SHong Zhang       collengths[jj[i]]++;
2503b2fbd54SBarry Smith     }
2513b2fbd54SBarry Smith     cia[0] = oshift;
2523b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2533b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2543b2fbd54SBarry Smith     }
25597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2563b2fbd54SBarry Smith     jj   = a->j;
257a93ec695SBarry Smith     for (row=0; row<m; row++) {
258a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
259a93ec695SBarry Smith       for (i=0; i<mr; i++) {
260bfeeae90SHong Zhang         col = *jj++;
2612205254eSKarl Rupp 
2623b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2633b2fbd54SBarry Smith       }
2643b2fbd54SBarry Smith     }
265606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2663b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2673b2fbd54SBarry Smith   }
2683a40ed3dSBarry Smith   PetscFunctionReturn(0);
2693b2fbd54SBarry Smith }
2703b2fbd54SBarry Smith 
2711a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2723b2fbd54SBarry Smith {
273dfbe8321SBarry Smith   PetscErrorCode ierr;
274606d414cSSatish Balay 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2763a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2773b2fbd54SBarry Smith 
278606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
279606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2813b2fbd54SBarry Smith }
2823b2fbd54SBarry Smith 
2837cee066cSHong Zhang /*
2847cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2857cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
286040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2877cee066cSHong Zhang */
2887cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
2897cee066cSHong Zhang {
2907cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2917cee066cSHong Zhang   PetscErrorCode ierr;
2927cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2937cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2947cee066cSHong Zhang   PetscInt       *cspidx;
2957cee066cSHong Zhang 
2967cee066cSHong Zhang   PetscFunctionBegin;
2977cee066cSHong Zhang   *nn = n;
2987cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
299625f6d37SHong Zhang 
3001795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
301854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
302854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
303854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cspidx);CHKERRQ(ierr);
3047cee066cSHong Zhang   jj   = a->j;
3057cee066cSHong Zhang   for (i=0; i<nz; i++) {
3067cee066cSHong Zhang     collengths[jj[i]]++;
3077cee066cSHong Zhang   }
3087cee066cSHong Zhang   cia[0] = oshift;
3097cee066cSHong Zhang   for (i=0; i<n; i++) {
3107cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3117cee066cSHong Zhang   }
3127cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3137cee066cSHong Zhang   jj   = a->j;
3147cee066cSHong Zhang   for (row=0; row<m; row++) {
3157cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3167cee066cSHong Zhang     for (i=0; i<mr; i++) {
3177cee066cSHong Zhang       col = *jj++;
3187cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3197cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3207cee066cSHong Zhang     }
3217cee066cSHong Zhang   }
3227cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3237cee066cSHong Zhang   *ia    = cia; *ja = cja;
3247cee066cSHong Zhang   *spidx = cspidx;
3257cee066cSHong Zhang   PetscFunctionReturn(0);
3267cee066cSHong Zhang }
3277cee066cSHong Zhang 
3287cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3297cee066cSHong Zhang {
3307cee066cSHong Zhang   PetscErrorCode ierr;
3317cee066cSHong Zhang 
3327cee066cSHong Zhang   PetscFunctionBegin;
3335243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3347cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3357cee066cSHong Zhang   PetscFunctionReturn(0);
3367cee066cSHong Zhang }
3377cee066cSHong Zhang 
33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
33987d4246cSBarry Smith {
34087d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34187d4246cSBarry Smith   PetscInt       *ai = a->i;
34287d4246cSBarry Smith   PetscErrorCode ierr;
34387d4246cSBarry Smith 
34487d4246cSBarry Smith   PetscFunctionBegin;
34587d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
34687d4246cSBarry Smith   PetscFunctionReturn(0);
34787d4246cSBarry Smith }
34887d4246cSBarry Smith 
349bd04181cSBarry Smith /*
350bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
351bd04181cSBarry Smith 
352bd04181cSBarry Smith       -   a single row of values is set with each call
353bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
354bd04181cSBarry Smith       -   the values are always added to the matrix, not set
355bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
356bd04181cSBarry Smith 
3571f763a69SBarry Smith      This does NOT assume the global column indices are sorted
358bd04181cSBarry Smith 
3591f763a69SBarry Smith */
360bd04181cSBarry Smith 
361af0996ceSBarry Smith #include <petsc/private/isimpl.h>
362189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
363189e4007SBarry Smith {
364189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3651f763a69SBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
3661f763a69SBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j;
3671f763a69SBarry Smith   PetscInt       lastcol = -1;
368189e4007SBarry Smith   MatScalar      *ap,value,*aa = a->a;
369189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
370189e4007SBarry Smith 
371f38dd0b8SBarry Smith   row = ridx[im[0]];
3721f763a69SBarry Smith   rp   = aj + ai[row];
3731f763a69SBarry Smith   ap = aa + ai[row];
3741f763a69SBarry Smith   nrow = ailen[row];
375189e4007SBarry Smith   low  = 0;
376189e4007SBarry Smith   high = nrow;
377189e4007SBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
378189e4007SBarry Smith     col = cidx[in[l]];
379f38dd0b8SBarry Smith     value = v[l];
380189e4007SBarry Smith 
381189e4007SBarry Smith     if (col <= lastcol) low = 0;
382189e4007SBarry Smith     else high = nrow;
383189e4007SBarry Smith     lastcol = col;
384189e4007SBarry Smith     while (high-low > 5) {
385189e4007SBarry Smith       t = (low+high)/2;
386189e4007SBarry Smith       if (rp[t] > col) high = t;
387189e4007SBarry Smith       else low = t;
388189e4007SBarry Smith     }
389189e4007SBarry Smith     for (i=low; i<high; i++) {
390189e4007SBarry Smith       if (rp[i] == col) {
3911f763a69SBarry Smith         ap[i] += value;
392189e4007SBarry Smith         low = i + 1;
3931f763a69SBarry Smith         break;
394189e4007SBarry Smith       }
395189e4007SBarry Smith     }
396189e4007SBarry Smith   }
397f38dd0b8SBarry Smith   return 0;
398189e4007SBarry Smith }
399189e4007SBarry Smith 
40097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
40117ab2063SBarry Smith {
402416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
403e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
40497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
4056849ba73SBarry Smith   PetscErrorCode ierr;
406e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
40754f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
408ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
409ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
41017ab2063SBarry Smith 
4113a40ed3dSBarry Smith   PetscFunctionBegin;
41217ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
413416022c9SBarry Smith     row = im[k];
4145ef9f2a5SBarry Smith     if (row < 0) continue;
4152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
416e32f2f54SBarry 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);
4173b2fbd54SBarry Smith #endif
418bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
41917ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
420416022c9SBarry Smith     low  = 0;
421c71e6ed7SBarry Smith     high = nrow;
42217ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4235ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4242515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
425e32f2f54SBarry 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);
4263b2fbd54SBarry Smith #endif
427bfeeae90SHong Zhang       col = in[l];
4284b0e389bSBarry Smith       if (roworiented) {
4295ef9f2a5SBarry Smith         value = v[l + k*n];
430bef8e0ddSBarry Smith       } else {
4314b0e389bSBarry Smith         value = v[k + l*m];
4324b0e389bSBarry Smith       }
43333b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
43436db0b34SBarry Smith 
4352205254eSKarl Rupp       if (col <= lastcol) low = 0;
4362205254eSKarl Rupp       else high = nrow;
437e2ee6c50SBarry Smith       lastcol = col;
438416022c9SBarry Smith       while (high-low > 5) {
439416022c9SBarry Smith         t = (low+high)/2;
440416022c9SBarry Smith         if (rp[t] > col) high = t;
441416022c9SBarry Smith         else low = t;
44217ab2063SBarry Smith       }
443416022c9SBarry Smith       for (i=low; i<high; i++) {
44417ab2063SBarry Smith         if (rp[i] > col) break;
44517ab2063SBarry Smith         if (rp[i] == col) {
446416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
44717ab2063SBarry Smith           else ap[i] = value;
448e44c0bd4SBarry Smith           low = i + 1;
44917ab2063SBarry Smith           goto noinsert;
45017ab2063SBarry Smith         }
45117ab2063SBarry Smith       }
452abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
453c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
454e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
455fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
456c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
457416022c9SBarry Smith       /* shift up all the later entries in this row */
458416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
45917ab2063SBarry Smith         rp[ii+1] = rp[ii];
46017ab2063SBarry Smith         ap[ii+1] = ap[ii];
46117ab2063SBarry Smith       }
46217ab2063SBarry Smith       rp[i] = col;
46317ab2063SBarry Smith       ap[i] = value;
464416022c9SBarry Smith       low   = i + 1;
465e56f5c9eSBarry Smith       A->nonzerostate++;
466e44c0bd4SBarry Smith noinsert:;
46717ab2063SBarry Smith     }
46817ab2063SBarry Smith     ailen[row] = nrow;
46917ab2063SBarry Smith   }
4703a40ed3dSBarry Smith   PetscFunctionReturn(0);
47117ab2063SBarry Smith }
47217ab2063SBarry Smith 
47381824310SBarry Smith 
474a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4757eb43aa7SLois Curfman McInnes {
4767eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
47797f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
47897f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
47954f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4807eb43aa7SLois Curfman McInnes 
4813a40ed3dSBarry Smith   PetscFunctionBegin;
4827eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4837eb43aa7SLois Curfman McInnes     row = im[k];
484e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
485e32f2f54SBarry 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);
486bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4877eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4887eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
489e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
490e32f2f54SBarry 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);
491bfeeae90SHong Zhang       col  = in[l];
4927eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4937eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4947eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4957eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4967eb43aa7SLois Curfman McInnes         else low = t;
4977eb43aa7SLois Curfman McInnes       }
4987eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4997eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5007eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
501b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5027eb43aa7SLois Curfman McInnes           goto finished;
5037eb43aa7SLois Curfman McInnes         }
5047eb43aa7SLois Curfman McInnes       }
50597e567efSBarry Smith       *v++ = 0.0;
5067eb43aa7SLois Curfman McInnes finished:;
5077eb43aa7SLois Curfman McInnes     }
5087eb43aa7SLois Curfman McInnes   }
5093a40ed3dSBarry Smith   PetscFunctionReturn(0);
5107eb43aa7SLois Curfman McInnes }
5117eb43aa7SLois Curfman McInnes 
51217ab2063SBarry Smith 
513dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
51417ab2063SBarry Smith {
515416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5166849ba73SBarry Smith   PetscErrorCode ierr;
5176f69ff64SBarry Smith   PetscInt       i,*col_lens;
5186f69ff64SBarry Smith   int            fd;
519b37d52dbSMark F. Adams   FILE           *file;
52017ab2063SBarry Smith 
5213a40ed3dSBarry Smith   PetscFunctionBegin;
522b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
523854ce69bSBarry Smith   ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr);
5242205254eSKarl Rupp 
5250700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
526d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
527d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
528416022c9SBarry Smith   col_lens[3] = a->nz;
529416022c9SBarry Smith 
530416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
531d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
532416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
53317ab2063SBarry Smith   }
534d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
535606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
536416022c9SBarry Smith 
537416022c9SBarry Smith   /* store column indices (zero start index) */
5386f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
539416022c9SBarry Smith 
540416022c9SBarry Smith   /* store nonzero values */
5416f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
542b37d52dbSMark F. Adams 
543b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
544b37d52dbSMark F. Adams   if (file) {
54533d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
546b37d52dbSMark F. Adams   }
5473a40ed3dSBarry Smith   PetscFunctionReturn(0);
54817ab2063SBarry Smith }
549416022c9SBarry Smith 
55009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
551cd155464SBarry Smith 
552dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
553416022c9SBarry Smith {
554416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
555dfbe8321SBarry Smith   PetscErrorCode    ierr;
55660e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
557e060cb09SBarry Smith   const char        *name;
558f3ef73ceSBarry Smith   PetscViewerFormat format;
55917ab2063SBarry Smith 
5603a40ed3dSBarry Smith   PetscFunctionBegin;
561b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
56271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
56397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
56460e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
565c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
566d00d2cf4SBarry Smith       nofinalvalue = 1;
567d00d2cf4SBarry Smith     }
568d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
569d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
57077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
571fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
572fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
573fbfe6fa7SJed Brown #else
57477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
575fbfe6fa7SJed Brown #endif
576b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
57717ab2063SBarry Smith 
57817ab2063SBarry Smith     for (i=0; i<m; i++) {
57960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
580aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
581a9bf72d8SJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
58217ab2063SBarry Smith #else
58360e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
58417ab2063SBarry Smith #endif
58517ab2063SBarry Smith       }
58617ab2063SBarry Smith     }
587d00d2cf4SBarry Smith     if (nofinalvalue) {
588c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
589c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
590c337ccceSJed Brown #else
591d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
592c337ccceSJed Brown #endif
593d00d2cf4SBarry Smith     }
594317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
595fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
596d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
59768369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
598cd155464SBarry Smith     PetscFunctionReturn(0);
599fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
600d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
60144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
60277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
60360e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
604aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
60536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
60660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
60736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
60860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
60936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
61060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6116831982aSBarry Smith         }
61244cd7ae7SLois Curfman McInnes #else
61360e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
61444cd7ae7SLois Curfman McInnes #endif
61544cd7ae7SLois Curfman McInnes       }
616b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
61744cd7ae7SLois Curfman McInnes     }
618d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
619fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
62097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
621d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
622854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
623496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
624496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
62560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
626496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
627aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
629496be53dSLois Curfman McInnes #else
630496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
631496be53dSLois Curfman McInnes #endif
632496be53dSLois Curfman McInnes         }
633496be53dSLois Curfman McInnes       }
634496be53dSLois Curfman McInnes     }
6352e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
63677431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6372e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6382205254eSKarl Rupp       if (i+4<m) {
6392205254eSKarl Rupp         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);
6402205254eSKarl Rupp       } else if (i+3<m) {
6412205254eSKarl Rupp         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);
6422205254eSKarl Rupp       } else if (i+2<m) {
6432205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6442205254eSKarl Rupp       } else if (i+1<m) {
6452205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6462205254eSKarl Rupp       } else if (i<m) {
6472205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6482205254eSKarl Rupp       } else {
6492205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6502205254eSKarl Rupp       }
651496be53dSLois Curfman McInnes     }
652b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
653606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
654496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
65560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
65677431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
657496be53dSLois Curfman McInnes       }
658b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
659496be53dSLois Curfman McInnes     }
660b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
661496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
66260e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
663496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
664aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
66660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6676831982aSBarry Smith           }
668496be53dSLois Curfman McInnes #else
66960e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
670496be53dSLois Curfman McInnes #endif
671496be53dSLois Curfman McInnes         }
672496be53dSLois Curfman McInnes       }
673b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
674496be53dSLois Curfman McInnes     }
675d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
676fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
67797f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
67887828ca2SBarry Smith     PetscScalar value;
67968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
68068f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
68168f1ed48SBarry Smith 
68268f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
68368f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
68468f1ed48SBarry Smith         realonly = PETSC_FALSE;
68568f1ed48SBarry Smith         break;
68668f1ed48SBarry Smith       }
68768f1ed48SBarry Smith     }
68868f1ed48SBarry Smith #endif
68902594712SBarry Smith 
690d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
69102594712SBarry Smith     for (i=0; i<m; i++) {
69202594712SBarry Smith       jcnt = 0;
693d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
694e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
69502594712SBarry Smith           value = a->a[cnt++];
696e24b481bSBarry Smith           jcnt++;
69702594712SBarry Smith         } else {
69802594712SBarry Smith           value = 0.0;
69902594712SBarry Smith         }
700aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70168f1ed48SBarry Smith         if (realonly) {
70260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
70368f1ed48SBarry Smith         } else {
70460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
70568f1ed48SBarry Smith         }
70602594712SBarry Smith #else
70760e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
70802594712SBarry Smith #endif
70902594712SBarry Smith       }
710b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
71102594712SBarry Smith     }
712d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7133c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
714150b93efSMatthew G. Knepley     PetscInt fshift=1;
715d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7163c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
71719303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7183c215bfdSMatthew Knepley #else
71919303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7203c215bfdSMatthew Knepley #endif
721d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7223c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
72360e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7243c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
725a9a0e077SKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7263c215bfdSMatthew Knepley #else
727150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7283c215bfdSMatthew Knepley #endif
7293c215bfdSMatthew Knepley       }
7303c215bfdSMatthew Knepley     }
731d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7323a40ed3dSBarry Smith   } else {
733d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
734d5f3da31SBarry Smith     if (A->factortype) {
73516cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
73616cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
73716cd7e1dSShri Abhyankar         /* L part */
73860e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
73916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
74016cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
74160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
74216cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7436712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
74416cd7e1dSShri Abhyankar           } else {
74560e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
74616cd7e1dSShri Abhyankar           }
74716cd7e1dSShri Abhyankar #else
74860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
74916cd7e1dSShri Abhyankar #endif
75016cd7e1dSShri Abhyankar         }
75116cd7e1dSShri Abhyankar         /* diagonal */
75216cd7e1dSShri Abhyankar         j = a->diag[i];
75316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
75416cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
75560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
75616cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7576712e2f1SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr);
75816cd7e1dSShri Abhyankar         } else {
75960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
76016cd7e1dSShri Abhyankar         }
76116cd7e1dSShri Abhyankar #else
76260e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
76316cd7e1dSShri Abhyankar #endif
76416cd7e1dSShri Abhyankar 
76516cd7e1dSShri Abhyankar         /* U part */
76660e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
76716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
76816cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
76960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
77016cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
77122ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
77216cd7e1dSShri Abhyankar           } else {
77360e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
77416cd7e1dSShri Abhyankar           }
77516cd7e1dSShri Abhyankar #else
77660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
77716cd7e1dSShri Abhyankar #endif
77816cd7e1dSShri Abhyankar         }
77916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
78016cd7e1dSShri Abhyankar       }
78116cd7e1dSShri Abhyankar     } else {
78217ab2063SBarry Smith       for (i=0; i<m; i++) {
78377431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
78460e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
785aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
78636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
78760e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
78836db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
78960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7903a40ed3dSBarry Smith           } else {
79160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
79217ab2063SBarry Smith           }
79317ab2063SBarry Smith #else
79460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
79517ab2063SBarry Smith #endif
79617ab2063SBarry Smith         }
797b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
79817ab2063SBarry Smith       }
79916cd7e1dSShri Abhyankar     }
800d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
80117ab2063SBarry Smith   }
802b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8033a40ed3dSBarry Smith   PetscFunctionReturn(0);
804416022c9SBarry Smith }
805416022c9SBarry Smith 
8069804daf3SBarry Smith #include <petscdraw.h>
807dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
808416022c9SBarry Smith {
809480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
810416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
811dfbe8321SBarry Smith   PetscErrorCode    ierr;
812383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
813383922c3SLisandro Dalcin   int               color;
814b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
815b0a32e0cSBarry Smith   PetscViewer       viewer;
816f3ef73ceSBarry Smith   PetscViewerFormat format;
817cddf8d76SBarry Smith 
8183a40ed3dSBarry Smith   PetscFunctionBegin;
819480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
820b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
821b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
822383922c3SLisandro Dalcin 
823416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8240513a670SBarry Smith 
825fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
826383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8270513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
828b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
829416022c9SBarry Smith     for (i=0; i<m; i++) {
830cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
831bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
832bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
83336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
834b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
835cddf8d76SBarry Smith       }
836cddf8d76SBarry Smith     }
837b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
838cddf8d76SBarry Smith     for (i=0; i<m; i++) {
839cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
840bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
841bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
842cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
843b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
844cddf8d76SBarry Smith       }
845cddf8d76SBarry Smith     }
846b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
847cddf8d76SBarry Smith     for (i=0; i<m; i++) {
848cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
849bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
850bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
85136db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
852b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
853416022c9SBarry Smith       }
854416022c9SBarry Smith     }
855383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8560513a670SBarry Smith   } else {
8570513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8580513a670SBarry Smith     /* first determine max of all nonzero values */
859b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
860383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
861b0a32e0cSBarry Smith     PetscDraw popup;
8620513a670SBarry Smith 
8630513a670SBarry Smith     for (i=0; i<nz; i++) {
8640513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8650513a670SBarry Smith     }
866383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
867b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
86845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
869383922c3SLisandro Dalcin 
870383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8710513a670SBarry Smith     for (i=0; i<m; i++) {
872383922c3SLisandro Dalcin       y_l = m - i - 1.0;
873383922c3SLisandro Dalcin       y_r = y_l + 1.0;
874bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
875383922c3SLisandro Dalcin         x_l = a->j[j];
876383922c3SLisandro Dalcin         x_r = x_l + 1.0;
877b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
878b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8790513a670SBarry Smith         count++;
8800513a670SBarry Smith       }
8810513a670SBarry Smith     }
882383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8830513a670SBarry Smith   }
884480ef9eaSBarry Smith   PetscFunctionReturn(0);
885480ef9eaSBarry Smith }
886cddf8d76SBarry Smith 
8879804daf3SBarry Smith #include <petscdraw.h>
888dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
889480ef9eaSBarry Smith {
890dfbe8321SBarry Smith   PetscErrorCode ierr;
891b0a32e0cSBarry Smith   PetscDraw      draw;
89236db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
893ace3abfcSBarry Smith   PetscBool      isnull;
894480ef9eaSBarry Smith 
895480ef9eaSBarry Smith   PetscFunctionBegin;
896b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
897b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
898480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
899480ef9eaSBarry Smith 
900d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
901480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
902b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
903832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
904b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9050298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
906832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9073a40ed3dSBarry Smith   PetscFunctionReturn(0);
908416022c9SBarry Smith }
909416022c9SBarry Smith 
910dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
911416022c9SBarry Smith {
912dfbe8321SBarry Smith   PetscErrorCode ierr;
913ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
914416022c9SBarry Smith 
9153a40ed3dSBarry Smith   PetscFunctionBegin;
916251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
917251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
918251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
919c45a1595SBarry Smith   if (iascii) {
9203a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9210f5bd95cSBarry Smith   } else if (isbinary) {
9223a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9230f5bd95cSBarry Smith   } else if (isdraw) {
9243a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
92511aeaf0aSBarry Smith   }
9264108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9273a40ed3dSBarry Smith   PetscFunctionReturn(0);
92817ab2063SBarry Smith }
92919bcc07fSBarry Smith 
930dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
93117ab2063SBarry Smith {
932416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9336849ba73SBarry Smith   PetscErrorCode ierr;
93497f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
935d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
93654f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9373447b6efSHong Zhang   PetscReal      ratio  = 0.6;
93817ab2063SBarry Smith 
9393a40ed3dSBarry Smith   PetscFunctionBegin;
9403a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
94117ab2063SBarry Smith 
94243ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
94317ab2063SBarry Smith   for (i=1; i<m; i++) {
944416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
94517ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
94694a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
94717ab2063SBarry Smith     if (fshift) {
948bfeeae90SHong Zhang       ip = aj + ai[i];
949bfeeae90SHong Zhang       ap = aa + ai[i];
95017ab2063SBarry Smith       N  = ailen[i];
95117ab2063SBarry Smith       for (j=0; j<N; j++) {
95217ab2063SBarry Smith         ip[j-fshift] = ip[j];
95317ab2063SBarry Smith         ap[j-fshift] = ap[j];
95417ab2063SBarry Smith       }
95517ab2063SBarry Smith     }
95617ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
95717ab2063SBarry Smith   }
95817ab2063SBarry Smith   if (m) {
95917ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
96017ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
96117ab2063SBarry Smith   }
9627b083b7cSBarry Smith 
96317ab2063SBarry Smith   /* reset ilen and imax for each row */
9647b083b7cSBarry Smith   a->nonzerorowcnt = 0;
96517ab2063SBarry Smith   for (i=0; i<m; i++) {
96617ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9677b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
96817ab2063SBarry Smith   }
969bfeeae90SHong Zhang   a->nz = ai[m];
97065e19b50SBarry 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);
97117ab2063SBarry Smith 
97209f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
973d0f46423SBarry 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);
974ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
975ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9762205254eSKarl Rupp 
9778e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
978dd5f02e7SSatish Balay   a->reallocs         = 0;
9796712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
98036db0b34SBarry Smith   a->rmax             = rmax;
9814e220ebcSLois Curfman McInnes 
98211e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9834108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
984acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9853a40ed3dSBarry Smith   PetscFunctionReturn(0);
98617ab2063SBarry Smith }
98717ab2063SBarry Smith 
98899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
98999cafbc1SBarry Smith {
99099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
99199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
99254f21887SBarry Smith   MatScalar      *aa = a->a;
993acf2f550SJed Brown   PetscErrorCode ierr;
99499cafbc1SBarry Smith 
99599cafbc1SBarry Smith   PetscFunctionBegin;
99699cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
997acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99899cafbc1SBarry Smith   PetscFunctionReturn(0);
99999cafbc1SBarry Smith }
100099cafbc1SBarry Smith 
100199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
100299cafbc1SBarry Smith {
100399cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
100499cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
100554f21887SBarry Smith   MatScalar      *aa = a->a;
1006acf2f550SJed Brown   PetscErrorCode ierr;
100799cafbc1SBarry Smith 
100899cafbc1SBarry Smith   PetscFunctionBegin;
100999cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1010acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101199cafbc1SBarry Smith   PetscFunctionReturn(0);
101299cafbc1SBarry Smith }
101399cafbc1SBarry Smith 
1014dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
101517ab2063SBarry Smith {
1016416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1017dfbe8321SBarry Smith   PetscErrorCode ierr;
10183a40ed3dSBarry Smith 
10193a40ed3dSBarry Smith   PetscFunctionBegin;
1020d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1021acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10223a40ed3dSBarry Smith   PetscFunctionReturn(0);
102317ab2063SBarry Smith }
1024416022c9SBarry Smith 
1025dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
102617ab2063SBarry Smith {
1027416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1028dfbe8321SBarry Smith   PetscErrorCode ierr;
1029d5d45c9bSBarry Smith 
10303a40ed3dSBarry Smith   PetscFunctionBegin;
1031aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1032d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
103317ab2063SBarry Smith #endif
1034e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10356bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10366bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
103705b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1038d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
103905b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
104071f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
104105b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10426bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
104305b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10446bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1045cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10460b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1047a30b2313SHong Zhang 
10484108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1049bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1050901853e0SKris Buschelman 
1051dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1058af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1059af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1060af8000cdSHong Zhang #endif
106163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
106263c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
10633dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
106463c07aadSStefano Zampini #endif
1065b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1066bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1067bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1069bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10703a40ed3dSBarry Smith   PetscFunctionReturn(0);
107117ab2063SBarry Smith }
107217ab2063SBarry Smith 
1073ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
107417ab2063SBarry Smith {
1075416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10764846f1f5SKris Buschelman   PetscErrorCode ierr;
10773a40ed3dSBarry Smith 
10783a40ed3dSBarry Smith   PetscFunctionBegin;
1079a65d3064SKris Buschelman   switch (op) {
1080a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10814e0d8c25SBarry Smith     a->roworiented = flg;
1082a65d3064SKris Buschelman     break;
1083a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1084a9817697SBarry Smith     a->keepnonzeropattern = flg;
1085a65d3064SKris Buschelman     break;
1086512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1087512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1088a65d3064SKris Buschelman     break;
1089a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10904e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1091a65d3064SKris Buschelman     break;
1092a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10934e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1094a65d3064SKris Buschelman     break;
109528b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
109628b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
109728b2fa4aSMatthew Knepley     break;
1098a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10994e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11000df259c2SBarry Smith     break;
11013d472b54SHong Zhang   case MAT_SPD:
1102b1646e73SJed Brown   case MAT_SYMMETRIC:
1103b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1104b1646e73SJed Brown   case MAT_HERMITIAN:
1105b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11065021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11075021d80fSJed Brown     break;
11084e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1109a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1110a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1111290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1112a65d3064SKris Buschelman     break;
1113b87ac2d8SJed Brown   case MAT_USE_INODES:
1114b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1115b87ac2d8SJed Brown     break;
1116c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1117c10200c1SHong Zhang     A->submat_singleis = flg;
1118c10200c1SHong Zhang     break;
1119a65d3064SKris Buschelman   default:
1120e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1121a65d3064SKris Buschelman   }
11224108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11233a40ed3dSBarry Smith   PetscFunctionReturn(0);
112417ab2063SBarry Smith }
112517ab2063SBarry Smith 
1126dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
112717ab2063SBarry Smith {
1128416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11296849ba73SBarry Smith   PetscErrorCode ierr;
1130d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
113135e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
113217ab2063SBarry Smith 
11333a40ed3dSBarry Smith   PetscFunctionBegin;
1134d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1135e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
113635e7444dSHong Zhang 
1137d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1138d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
113935e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11402c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
114135e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
114235e7444dSHong Zhang     PetscFunctionReturn(0);
114335e7444dSHong Zhang   }
114435e7444dSHong Zhang 
11452dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11461ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
114735e7444dSHong Zhang   for (i=0; i<n; i++) {
114835e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11492f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
115035e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
115135e7444dSHong Zhang       if (aj[j] == i) {
115235e7444dSHong Zhang         x[i] = aa[j];
115317ab2063SBarry Smith         break;
115417ab2063SBarry Smith       }
115517ab2063SBarry Smith     }
115617ab2063SBarry Smith   }
11571ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11583a40ed3dSBarry Smith   PetscFunctionReturn(0);
115917ab2063SBarry Smith }
116017ab2063SBarry Smith 
1161c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1162dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
116317ab2063SBarry Smith {
1164416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1165d9ca1df4SBarry Smith   PetscScalar       *y;
1166d9ca1df4SBarry Smith   const PetscScalar *x;
1167dfbe8321SBarry Smith   PetscErrorCode    ierr;
1168d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
11695c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1170d9ca1df4SBarry Smith   const MatScalar   *v;
1171a77337e4SBarry Smith   PetscScalar       alpha;
1172d9ca1df4SBarry Smith   PetscInt          n,i,j;
1173d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
11743447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1175ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11765c897100SBarry Smith #endif
117717ab2063SBarry Smith 
11783a40ed3dSBarry Smith   PetscFunctionBegin;
11792e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1180d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11811ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11825c897100SBarry Smith 
11835c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1184bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11855c897100SBarry Smith #else
11863447b6efSHong Zhang   if (usecprow) {
11873447b6efSHong Zhang     m    = cprow.nrows;
11883447b6efSHong Zhang     ii   = cprow.i;
11897b2bb3b9SHong Zhang     ridx = cprow.rindex;
11903447b6efSHong Zhang   } else {
11913447b6efSHong Zhang     ii = a->i;
11923447b6efSHong Zhang   }
119317ab2063SBarry Smith   for (i=0; i<m; i++) {
11943447b6efSHong Zhang     idx = a->j + ii[i];
11953447b6efSHong Zhang     v   = a->a + ii[i];
11963447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11973447b6efSHong Zhang     if (usecprow) {
11987b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11993447b6efSHong Zhang     } else {
120017ab2063SBarry Smith       alpha = x[i];
12013447b6efSHong Zhang     }
120204fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
120317ab2063SBarry Smith   }
12045c897100SBarry Smith #endif
1205dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1206d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12071ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12083a40ed3dSBarry Smith   PetscFunctionReturn(0);
120917ab2063SBarry Smith }
121017ab2063SBarry Smith 
1211dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12125c897100SBarry Smith {
1213dfbe8321SBarry Smith   PetscErrorCode ierr;
12145c897100SBarry Smith 
12155c897100SBarry Smith   PetscFunctionBegin;
1216170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12175c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12185c897100SBarry Smith   PetscFunctionReturn(0);
12195c897100SBarry Smith }
12205c897100SBarry Smith 
1221c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
122278b84d54SShri Abhyankar 
1223dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
122417ab2063SBarry Smith {
1225416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1226d9fead3dSBarry Smith   PetscScalar       *y;
122754f21887SBarry Smith   const PetscScalar *x;
122854f21887SBarry Smith   const MatScalar   *aa;
1229dfbe8321SBarry Smith   PetscErrorCode    ierr;
1230003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12310298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12327b083b7cSBarry Smith   PetscInt          n,i;
1233362ced78SSatish Balay   PetscScalar       sum;
1234ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
123517ab2063SBarry Smith 
1236b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
123797952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1238fee21e36SBarry Smith #endif
1239fee21e36SBarry Smith 
12403a40ed3dSBarry Smith   PetscFunctionBegin;
12413649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12421ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1243416022c9SBarry Smith   ii   = a->i;
12444eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12454f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
124697952fefSHong Zhang     m    = a->compressedrow.nrows;
124797952fefSHong Zhang     ii   = a->compressedrow.i;
124897952fefSHong Zhang     ridx = a->compressedrow.rindex;
124997952fefSHong Zhang     for (i=0; i<m; i++) {
125097952fefSHong Zhang       n           = ii[i+1] - ii[i];
125197952fefSHong Zhang       aj          = a->j + ii[i];
125297952fefSHong Zhang       aa          = a->a + ii[i];
125397952fefSHong Zhang       sum         = 0.0;
1254003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1255003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
125697952fefSHong Zhang       y[*ridx++] = sum;
125797952fefSHong Zhang     }
125897952fefSHong Zhang   } else { /* do not use compressed row format */
1259b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
12603d3eaba7SBarry Smith     aj   = a->j;
12613d3eaba7SBarry Smith     aa   = a->a;
1262b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1263b05257ddSBarry Smith #else
126417ab2063SBarry Smith     for (i=0; i<m; i++) {
1265003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1266003131ecSBarry Smith       aj          = a->j + ii[i];
1267003131ecSBarry Smith       aa          = a->a + ii[i];
126817ab2063SBarry Smith       sum         = 0.0;
1269003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
127017ab2063SBarry Smith       y[i] = sum;
127117ab2063SBarry Smith     }
12728d195f9aSBarry Smith #endif
1273b05257ddSBarry Smith   }
12747b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
12753649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12761ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12773a40ed3dSBarry Smith   PetscFunctionReturn(0);
127817ab2063SBarry Smith }
127917ab2063SBarry Smith 
1280b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1281b434eb95SMatthew G. Knepley {
1282b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1283b434eb95SMatthew G. Knepley   PetscScalar       *y;
1284b434eb95SMatthew G. Knepley   const PetscScalar *x;
1285b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1286b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1287b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1288b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1289b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1290b434eb95SMatthew G. Knepley   PetscScalar       sum;
1291b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1292b434eb95SMatthew G. Knepley 
1293b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1294b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1295b434eb95SMatthew G. Knepley #endif
1296b434eb95SMatthew G. Knepley 
1297b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1298b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1299b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1300b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1301b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1302b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1303b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1304b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1305b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1306b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1307b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1308b434eb95SMatthew G. Knepley       sum         = 0.0;
1309b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1310b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1311b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1312b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1313b434eb95SMatthew G. Knepley     }
1314b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13153d3eaba7SBarry Smith     ii = a->i;
1316b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1317b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1318b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1319b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1320b434eb95SMatthew G. Knepley       sum         = 0.0;
1321b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1322b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1323b434eb95SMatthew G. Knepley       y[i] = sum;
1324b434eb95SMatthew G. Knepley     }
1325b434eb95SMatthew G. Knepley   }
1326b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1327b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1328b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1329b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1330b434eb95SMatthew G. Knepley }
1331b434eb95SMatthew G. Knepley 
1332b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1333b434eb95SMatthew G. Knepley {
1334b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1335b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1336b434eb95SMatthew G. Knepley   const PetscScalar *x;
1337b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1338b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1339b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1340b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1341b434eb95SMatthew G. Knepley   PetscScalar       sum;
1342b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1343b434eb95SMatthew G. Knepley 
1344b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1345b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1346d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1347b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1348b434eb95SMatthew G. Knepley     if (zz != yy) {
1349b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1350b434eb95SMatthew G. Knepley     }
1351b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1352b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1353b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1354b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1355b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1356b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1357b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1358b434eb95SMatthew G. Knepley       sum = y[*ridx];
1359b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1360b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1361b434eb95SMatthew G. Knepley     }
1362b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13633d3eaba7SBarry Smith     ii = a->i;
1364b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1365b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1366b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1367b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1368b434eb95SMatthew G. Knepley       sum = y[i];
1369b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1370b434eb95SMatthew G. Knepley       z[i] = sum;
1371b434eb95SMatthew G. Knepley     }
1372b434eb95SMatthew G. Knepley   }
1373b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1374b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1375d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1376b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1377b434eb95SMatthew G. Knepley }
1378b434eb95SMatthew G. Knepley 
1379c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1380dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
138117ab2063SBarry Smith {
1382416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1383f15663dcSBarry Smith   PetscScalar       *y,*z;
1384f15663dcSBarry Smith   const PetscScalar *x;
138554f21887SBarry Smith   const MatScalar   *aa;
1386dfbe8321SBarry Smith   PetscErrorCode    ierr;
1387d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1388d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1389362ced78SSatish Balay   PetscScalar       sum;
1390ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
13919ea0dfa2SSatish Balay 
13923a40ed3dSBarry Smith   PetscFunctionBegin;
1393f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1394d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
13954eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
13964eb6d288SHong Zhang     if (zz != yy) {
13974eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
13984eb6d288SHong Zhang     }
139997952fefSHong Zhang     m    = a->compressedrow.nrows;
140097952fefSHong Zhang     ii   = a->compressedrow.i;
140197952fefSHong Zhang     ridx = a->compressedrow.rindex;
140297952fefSHong Zhang     for (i=0; i<m; i++) {
140397952fefSHong Zhang       n   = ii[i+1] - ii[i];
140497952fefSHong Zhang       aj  = a->j + ii[i];
140597952fefSHong Zhang       aa  = a->a + ii[i];
140697952fefSHong Zhang       sum = y[*ridx];
1407f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
140897952fefSHong Zhang       z[*ridx++] = sum;
140997952fefSHong Zhang     }
141097952fefSHong Zhang   } else { /* do not use compressed row format */
14113d3eaba7SBarry Smith     ii = a->i;
1412f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14133d3eaba7SBarry Smith     aj = a->j;
14143d3eaba7SBarry Smith     aa = a->a;
1415f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1416f15663dcSBarry Smith #else
141717ab2063SBarry Smith     for (i=0; i<m; i++) {
1418f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1419f15663dcSBarry Smith       aj  = a->j + ii[i];
1420f15663dcSBarry Smith       aa  = a->a + ii[i];
142117ab2063SBarry Smith       sum = y[i];
1422f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142317ab2063SBarry Smith       z[i] = sum;
142417ab2063SBarry Smith     }
142502ab625aSSatish Balay #endif
1426f15663dcSBarry Smith   }
1427dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1428f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1429d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14308154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14316b375ea7SVictor Minden   /*
1432918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1433918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1434918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14356b375ea7SVictor Minden   */
1436918e98c3SVictor Minden #endif
14373a40ed3dSBarry Smith   PetscFunctionReturn(0);
143817ab2063SBarry Smith }
143917ab2063SBarry Smith 
144017ab2063SBarry Smith /*
144117ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
144217ab2063SBarry Smith */
1443dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
144417ab2063SBarry Smith {
1445416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14466849ba73SBarry Smith   PetscErrorCode ierr;
1447d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
144817ab2063SBarry Smith 
14493a40ed3dSBarry Smith   PetscFunctionBegin;
145009f38230SBarry Smith   if (!a->diag) {
1451785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14523bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
145309f38230SBarry Smith   }
1454d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
145509f38230SBarry Smith     a->diag[i] = a->i[i+1];
1456bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1457bfeeae90SHong Zhang       if (a->j[j] == i) {
145809f38230SBarry Smith         a->diag[i] = j;
145917ab2063SBarry Smith         break;
146017ab2063SBarry Smith       }
146117ab2063SBarry Smith     }
146217ab2063SBarry Smith   }
14633a40ed3dSBarry Smith   PetscFunctionReturn(0);
146417ab2063SBarry Smith }
146517ab2063SBarry Smith 
1466be5855fcSBarry Smith /*
1467be5855fcSBarry Smith      Checks for missing diagonals
1468be5855fcSBarry Smith */
1469ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1470be5855fcSBarry Smith {
1471be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14727734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1473be5855fcSBarry Smith 
1474be5855fcSBarry Smith   PetscFunctionBegin;
147509f38230SBarry Smith   *missing = PETSC_FALSE;
14767734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
147709f38230SBarry Smith     *missing = PETSC_TRUE;
147809f38230SBarry Smith     if (d) *d = 0;
1479955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
148009f38230SBarry Smith   } else {
1481f1e2ffcdSBarry Smith     diag = a->diag;
1482d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
14837734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
148409f38230SBarry Smith         *missing = PETSC_TRUE;
148509f38230SBarry Smith         if (d) *d = i;
1486955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1487358d2f5dSShri Abhyankar         break;
148809f38230SBarry Smith       }
1489be5855fcSBarry Smith     }
1490be5855fcSBarry Smith   }
1491be5855fcSBarry Smith   PetscFunctionReturn(0);
1492be5855fcSBarry Smith }
1493be5855fcSBarry Smith 
1494422a814eSBarry Smith /*
1495422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1496422a814eSBarry Smith */
14977087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
149871f1c65dSBarry Smith {
149971f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
150071f1c65dSBarry Smith   PetscErrorCode ierr;
1501d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
150254f21887SBarry Smith   MatScalar      *v = a->a;
150354f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
150471f1c65dSBarry Smith 
150571f1c65dSBarry Smith   PetscFunctionBegin;
150671f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
150771f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
150871f1c65dSBarry Smith   diag = a->diag;
150971f1c65dSBarry Smith   if (!a->idiag) {
1510dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15113bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
151271f1c65dSBarry Smith     v    = a->a;
151371f1c65dSBarry Smith   }
151471f1c65dSBarry Smith   mdiag = a->mdiag;
151571f1c65dSBarry Smith   idiag = a->idiag;
151671f1c65dSBarry Smith 
1517422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
151871f1c65dSBarry Smith     for (i=0; i<m; i++) {
151971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1520899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1521899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1522899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15237b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15247b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15257b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15267b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1527899639b0SHong Zhang       }
152871f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
152971f1c65dSBarry Smith     }
153071f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
153171f1c65dSBarry Smith   } else {
153271f1c65dSBarry Smith     for (i=0; i<m; i++) {
153371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
153471f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
153571f1c65dSBarry Smith     }
1536dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
153771f1c65dSBarry Smith   }
153871f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
153971f1c65dSBarry Smith   PetscFunctionReturn(0);
154071f1c65dSBarry Smith }
154171f1c65dSBarry Smith 
1542c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
154341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
154417ab2063SBarry Smith {
1545416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1546e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15473d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
154854f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1549dfbe8321SBarry Smith   PetscErrorCode    ierr;
15503d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
155197f1f81fSBarry Smith   const PetscInt    *idx,*diag;
155217ab2063SBarry Smith 
15533a40ed3dSBarry Smith   PetscFunctionBegin;
1554b965ef7fSBarry Smith   its = its*lits;
155591723122SBarry Smith 
155671f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
155771f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
155871f1c65dSBarry Smith   a->fshift = fshift;
155971f1c65dSBarry Smith   a->omega  = omega;
1560ed480e8bSBarry Smith 
156171f1c65dSBarry Smith   diag  = a->diag;
156271f1c65dSBarry Smith   t     = a->ssor_work;
1563ed480e8bSBarry Smith   idiag = a->idiag;
156471f1c65dSBarry Smith   mdiag = a->mdiag;
1565ed480e8bSBarry Smith 
15661ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15673649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1568ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
156917ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
157017ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1571ed480e8bSBarry Smith     bs = b;
157217ab2063SBarry Smith     for (i=0; i<m; i++) {
157371f1c65dSBarry Smith       d   = fshift + mdiag[i];
1574416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1575ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1576ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
157717ab2063SBarry Smith       sum = b[i]*d/omega;
1578003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
157917ab2063SBarry Smith       x[i] = sum;
158017ab2063SBarry Smith     }
15811ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
15823649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1583efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
15843a40ed3dSBarry Smith     PetscFunctionReturn(0);
158517ab2063SBarry Smith   }
1586c783ea89SBarry Smith 
15872205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
15882205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
158917ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1590887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
159117ab2063SBarry Smith 
159217ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
159317ab2063SBarry Smith 
1594887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
159517ab2063SBarry Smith     */
159617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
159717ab2063SBarry Smith 
159817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
159917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1600416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1601ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1602ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
160317ab2063SBarry Smith       sum = b[i];
1604e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1605ed480e8bSBarry Smith       x[i] = sum*idiag[i];
160617ab2063SBarry Smith     }
160717ab2063SBarry Smith 
160817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1609416022c9SBarry Smith     v = a->a;
16102205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
161117ab2063SBarry Smith 
161217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1613ed480e8bSBarry Smith     ts   = t;
1614416022c9SBarry Smith     diag = a->diag;
161517ab2063SBarry Smith     for (i=0; i<m; i++) {
1616416022c9SBarry Smith       n   = diag[i] - a->i[i];
1617ed480e8bSBarry Smith       idx = a->j + a->i[i];
1618ed480e8bSBarry Smith       v   = a->a + a->i[i];
161917ab2063SBarry Smith       sum = t[i];
1620003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1621ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1622733d66baSBarry Smith       /*  x = x + t */
1623733d66baSBarry Smith       x[i] += t[i];
162417ab2063SBarry Smith     }
162517ab2063SBarry Smith 
1626dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16271ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16283649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16293a40ed3dSBarry Smith     PetscFunctionReturn(0);
163017ab2063SBarry Smith   }
163117ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
163217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
163317ab2063SBarry Smith       for (i=0; i<m; i++) {
1634416022c9SBarry Smith         n   = diag[i] - a->i[i];
1635ed480e8bSBarry Smith         idx = a->j + a->i[i];
1636ed480e8bSBarry Smith         v   = a->a + a->i[i];
163717ab2063SBarry Smith         sum = b[i];
1638e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16395c99c7daSBarry Smith         t[i] = sum;
1640ed480e8bSBarry Smith         x[i] = sum*idiag[i];
164117ab2063SBarry Smith       }
16425c99c7daSBarry Smith       xb   = t;
1643efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16443a40ed3dSBarry Smith     } else xb = b;
164517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
164617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1647416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1648ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1649ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
165017ab2063SBarry Smith         sum = xb[i];
1651e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16525c99c7daSBarry Smith         if (xb == b) {
1653ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16545c99c7daSBarry Smith         } else {
1655b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
165617ab2063SBarry Smith         }
16575c99c7daSBarry Smith       }
1658b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
165917ab2063SBarry Smith     }
166017ab2063SBarry Smith     its--;
166117ab2063SBarry Smith   }
166217ab2063SBarry Smith   while (its--) {
166317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
166417ab2063SBarry Smith       for (i=0; i<m; i++) {
1665b19a5dc2SMark Adams         /* lower */
1666b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1667ed480e8bSBarry Smith         idx = a->j + a->i[i];
1668ed480e8bSBarry Smith         v   = a->a + a->i[i];
166917ab2063SBarry Smith         sum = b[i];
1670e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1671b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1672b19a5dc2SMark Adams         /* upper */
1673b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1674b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1675b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1676b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1677b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
167817ab2063SBarry Smith       }
1679b19a5dc2SMark Adams       xb   = t;
16809f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1681b19a5dc2SMark Adams     } else xb = b;
168217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
168317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1684b19a5dc2SMark Adams         sum = xb[i];
1685b19a5dc2SMark Adams         if (xb == b) {
1686b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1687416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1688ed480e8bSBarry Smith           idx = a->j + a->i[i];
1689ed480e8bSBarry Smith           v   = a->a + a->i[i];
1690e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1691ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1692b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1693b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1694b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1695b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1696b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1697b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
169817ab2063SBarry Smith         }
1699b19a5dc2SMark Adams       }
1700b19a5dc2SMark Adams       if (xb == b) {
17019f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1702b19a5dc2SMark Adams       } else {
1703b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1704b19a5dc2SMark Adams       }
170517ab2063SBarry Smith     }
170617ab2063SBarry Smith   }
17071ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17083649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1709365a8a9eSBarry Smith   PetscFunctionReturn(0);
171017ab2063SBarry Smith }
171117ab2063SBarry Smith 
17122af78befSBarry Smith 
1713dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
171417ab2063SBarry Smith {
1715416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17164e220ebcSLois Curfman McInnes 
17173a40ed3dSBarry Smith   PetscFunctionBegin;
17184e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17194e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17204e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17214e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17224e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17238e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17247adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1725d5f3da31SBarry Smith   if (A->factortype) {
17264e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17274e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17284e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17294e220ebcSLois Curfman McInnes   } else {
17304e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17314e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17324e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17334e220ebcSLois Curfman McInnes   }
17343a40ed3dSBarry Smith   PetscFunctionReturn(0);
173517ab2063SBarry Smith }
173617ab2063SBarry Smith 
17372b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
173817ab2063SBarry Smith {
1739416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
17403b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
17416849ba73SBarry Smith   PetscErrorCode    ierr;
174297b48c8fSBarry Smith   const PetscScalar *xx;
174397b48c8fSBarry Smith   PetscScalar       *bb;
1744ace3abfcSBarry Smith   PetscBool         missing;
174517ab2063SBarry Smith 
17463a40ed3dSBarry Smith   PetscFunctionBegin;
174797b48c8fSBarry Smith   if (x && b) {
174897b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
174997b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
175097b48c8fSBarry Smith     for (i=0; i<N; i++) {
175197b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
175297b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
175397b48c8fSBarry Smith     }
175497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
175597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
175697b48c8fSBarry Smith   }
175797b48c8fSBarry Smith 
17581d5a398dSstefano_zampini   ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1759a9817697SBarry Smith   if (a->keepnonzeropattern) {
1760f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1761e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1762bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1763f1e2ffcdSBarry Smith     }
1764f4df32b1SMatthew Knepley     if (diag != 0.0) {
1765e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1766f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1767f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1768f1e2ffcdSBarry Smith       }
1769f1e2ffcdSBarry Smith     }
1770f1e2ffcdSBarry Smith   } else {
1771f4df32b1SMatthew Knepley     if (diag != 0.0) {
177217ab2063SBarry Smith       for (i=0; i<N; i++) {
1773e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17747ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1775416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1776f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1777bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
17787ae801bdSBarry Smith         } else { /* in case row was completely empty */
1779f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
178017ab2063SBarry Smith         }
178117ab2063SBarry Smith       }
17823a40ed3dSBarry Smith     } else {
178317ab2063SBarry Smith       for (i=0; i<N; i++) {
1784e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1785416022c9SBarry Smith         a->ilen[rows[i]] = 0;
178617ab2063SBarry Smith       }
178717ab2063SBarry Smith     }
1788e56f5c9eSBarry Smith     A->nonzerostate++;
1789f1e2ffcdSBarry Smith   }
179043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17913a40ed3dSBarry Smith   PetscFunctionReturn(0);
179217ab2063SBarry Smith }
179317ab2063SBarry Smith 
17946e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17956e169961SBarry Smith {
17966e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
17976e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
17986e169961SBarry Smith   PetscErrorCode    ierr;
17992b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18006e169961SBarry Smith   const PetscScalar *xx;
18016e169961SBarry Smith   PetscScalar       *bb;
18026e169961SBarry Smith 
18036e169961SBarry Smith   PetscFunctionBegin;
18046e169961SBarry Smith   if (x && b) {
18056e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18066e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18072b40b63fSBarry Smith     vecs = PETSC_TRUE;
18086e169961SBarry Smith   }
18091795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18106e169961SBarry Smith   for (i=0; i<N; i++) {
18116e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18126e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18132205254eSKarl Rupp 
18146e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18156e169961SBarry Smith   }
18166e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18176e169961SBarry Smith     if (!zeroed[i]) {
18186e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18196e169961SBarry Smith         if (zeroed[a->j[j]]) {
18202b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18216e169961SBarry Smith           a->a[j] = 0.0;
18226e169961SBarry Smith         }
18236e169961SBarry Smith       }
18242b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18256e169961SBarry Smith   }
18266e169961SBarry Smith   if (x && b) {
18276e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18286e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18296e169961SBarry Smith   }
18306e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18316e169961SBarry Smith   if (diag != 0.0) {
18326e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18331d5a398dSstefano_zampini     if (missing) {
18341d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18351d5a398dSstefano_zampini       else {
18361d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18371d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18381d5a398dSstefano_zampini         }
18391d5a398dSstefano_zampini       }
18401d5a398dSstefano_zampini     } else {
18416e169961SBarry Smith       for (i=0; i<N; i++) {
18426e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18436e169961SBarry Smith       }
18446e169961SBarry Smith     }
18451d5a398dSstefano_zampini   }
18466e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18476e169961SBarry Smith   PetscFunctionReturn(0);
18486e169961SBarry Smith }
18496e169961SBarry Smith 
1850a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
185117ab2063SBarry Smith {
1852416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
185397f1f81fSBarry Smith   PetscInt   *itmp;
185417ab2063SBarry Smith 
18553a40ed3dSBarry Smith   PetscFunctionBegin;
1856e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
185717ab2063SBarry Smith 
1858416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1859bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
186017ab2063SBarry Smith   if (idx) {
1861bfeeae90SHong Zhang     itmp = a->j + a->i[row];
186226fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
186317ab2063SBarry Smith     else *idx = 0;
186417ab2063SBarry Smith   }
18653a40ed3dSBarry Smith   PetscFunctionReturn(0);
186617ab2063SBarry Smith }
186717ab2063SBarry Smith 
1868bfeeae90SHong Zhang /* remove this function? */
1869a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187017ab2063SBarry Smith {
18713a40ed3dSBarry Smith   PetscFunctionBegin;
18723a40ed3dSBarry Smith   PetscFunctionReturn(0);
187317ab2063SBarry Smith }
187417ab2063SBarry Smith 
1875dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
187617ab2063SBarry Smith {
1877416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
187854f21887SBarry Smith   MatScalar      *v  = a->a;
187936db0b34SBarry Smith   PetscReal      sum = 0.0;
18806849ba73SBarry Smith   PetscErrorCode ierr;
188197f1f81fSBarry Smith   PetscInt       i,j;
188217ab2063SBarry Smith 
18833a40ed3dSBarry Smith   PetscFunctionBegin;
188417ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1885570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1886570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1887570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1888570b7f6dSBarry Smith #else
1889416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
189036db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
189117ab2063SBarry Smith     }
18928f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1893570b7f6dSBarry Smith #endif
189451f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
18953a40ed3dSBarry Smith   } else if (type == NORM_1) {
189636db0b34SBarry Smith     PetscReal *tmp;
189797f1f81fSBarry Smith     PetscInt  *jj = a->j;
18981795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1899064f8208SBarry Smith     *nrm = 0.0;
1900416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1901bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
190217ab2063SBarry Smith     }
1903d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1904064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
190517ab2063SBarry Smith     }
1906606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
190751f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19083a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1909064f8208SBarry Smith     *nrm = 0.0;
1910d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1911bfeeae90SHong Zhang       v   = a->a + a->i[j];
191217ab2063SBarry Smith       sum = 0.0;
1913416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1914cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
191517ab2063SBarry Smith       }
1916064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
191717ab2063SBarry Smith     }
191851f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1919f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19203a40ed3dSBarry Smith   PetscFunctionReturn(0);
192117ab2063SBarry Smith }
192217ab2063SBarry Smith 
19234e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19244e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19254e938277SHong Zhang {
19264e938277SHong Zhang   PetscErrorCode ierr;
19274e938277SHong Zhang   PetscInt       i,j,anzj;
19284e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19294e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19304e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19314e938277SHong Zhang 
19324e938277SHong Zhang   PetscFunctionBegin;
19334e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1934854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1935785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1936785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19374e938277SHong Zhang 
19384e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19394e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
194026fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19414e938277SHong Zhang   /* Form ati for csr format of A^T. */
194226fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19434e938277SHong Zhang 
19444e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19454e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19464e938277SHong Zhang 
19474e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19484e938277SHong Zhang   for (i=0;i<am;i++) {
19494e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19504e938277SHong Zhang     for (j=0;j<anzj;j++) {
19514e938277SHong Zhang       atj[atfill[*aj]] = i;
19524e938277SHong Zhang       atfill[*aj++]   += 1;
19534e938277SHong Zhang     }
19544e938277SHong Zhang   }
19554e938277SHong Zhang 
19564e938277SHong Zhang   /* Clean up temporary space and complete requests. */
19574e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
1958ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
195933d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
1960a2f3521dSMark F. Adams 
19614e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
19624e938277SHong Zhang   b->free_a  = PETSC_FALSE;
19634e938277SHong Zhang   b->free_ij = PETSC_TRUE;
19644e938277SHong Zhang   b->nonew   = 0;
19654e938277SHong Zhang   PetscFunctionReturn(0);
19664e938277SHong Zhang }
19674e938277SHong Zhang 
1968fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
196917ab2063SBarry Smith {
1970416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1971416022c9SBarry Smith   Mat            C;
19726849ba73SBarry Smith   PetscErrorCode ierr;
1973d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
197454f21887SBarry Smith   MatScalar      *array = a->a;
197517ab2063SBarry Smith 
19763a40ed3dSBarry Smith   PetscFunctionBegin;
1977cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1978fc4dec0aSBarry Smith 
1979cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
1980854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
1981bfeeae90SHong Zhang 
1982bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1983ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
1984d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
198533d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
19867adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1987ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1988606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1989a541d17aSBarry Smith   } else {
1990a541d17aSBarry Smith     C = *B;
1991a541d17aSBarry Smith   }
1992a541d17aSBarry Smith 
199317ab2063SBarry Smith   for (i=0; i<m; i++) {
199417ab2063SBarry Smith     len    = ai[i+1]-ai[i];
199587d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1996b9b97703SBarry Smith     array += len;
1997b9b97703SBarry Smith     aj    += len;
199817ab2063SBarry Smith   }
19996d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20006d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
200117ab2063SBarry Smith 
2002cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2003416022c9SBarry Smith     *B = C;
200417ab2063SBarry Smith   } else {
200528be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
200617ab2063SBarry Smith   }
20073a40ed3dSBarry Smith   PetscFunctionReturn(0);
200817ab2063SBarry Smith }
200917ab2063SBarry Smith 
20107087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2011cd0d46ebSvictorle {
20123d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
201354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
201454f21887SBarry Smith   MatScalar      *va,*vb;
20156849ba73SBarry Smith   PetscErrorCode ierr;
201697f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2017cd0d46ebSvictorle 
2018cd0d46ebSvictorle   PetscFunctionBegin;
2019cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2020cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20215485867bSBarry Smith   if (ma!=nb || na!=mb) {
20225485867bSBarry Smith     *f = PETSC_FALSE;
20235485867bSBarry Smith     PetscFunctionReturn(0);
20245485867bSBarry Smith   }
2025cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2026cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2027cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2028785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2029785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2030cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2031cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2032cd0d46ebSvictorle 
2033cd0d46ebSvictorle   *f = PETSC_TRUE;
2034cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2035cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
203697f1f81fSBarry Smith       PetscInt    idc,idr;
20375485867bSBarry Smith       PetscScalar vc,vr;
2038cd0d46ebSvictorle       /* column/row index/value */
20395485867bSBarry Smith       idc = adx[aptr[i]];
20405485867bSBarry Smith       idr = bdx[bptr[idc]];
20415485867bSBarry Smith       vc  = va[aptr[i]];
20425485867bSBarry Smith       vr  = vb[bptr[idc]];
20435485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20445485867bSBarry Smith         *f = PETSC_FALSE;
20455485867bSBarry Smith         goto done;
2046cd0d46ebSvictorle       } else {
20475485867bSBarry Smith         aptr[i]++;
20485485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2049cd0d46ebSvictorle       }
2050cd0d46ebSvictorle     }
2051cd0d46ebSvictorle   }
2052cd0d46ebSvictorle done:
2053cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20543aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2055cd0d46ebSvictorle   PetscFunctionReturn(0);
2056cd0d46ebSvictorle }
2057cd0d46ebSvictorle 
20587087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20591cbb95d3SBarry Smith {
20603d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
206154f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
206254f21887SBarry Smith   MatScalar      *va,*vb;
20631cbb95d3SBarry Smith   PetscErrorCode ierr;
20641cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20651cbb95d3SBarry Smith 
20661cbb95d3SBarry Smith   PetscFunctionBegin;
20671cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20681cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20691cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
20701cbb95d3SBarry Smith     *f = PETSC_FALSE;
20711cbb95d3SBarry Smith     PetscFunctionReturn(0);
20721cbb95d3SBarry Smith   }
20731cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
20741cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
20751cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2076785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2077785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
20781cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20791cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20801cbb95d3SBarry Smith 
20811cbb95d3SBarry Smith   *f = PETSC_TRUE;
20821cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20831cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
20841cbb95d3SBarry Smith       PetscInt    idc,idr;
20851cbb95d3SBarry Smith       PetscScalar vc,vr;
20861cbb95d3SBarry Smith       /* column/row index/value */
20871cbb95d3SBarry Smith       idc = adx[aptr[i]];
20881cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
20891cbb95d3SBarry Smith       vc  = va[aptr[i]];
20901cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
20911cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
20921cbb95d3SBarry Smith         *f = PETSC_FALSE;
20931cbb95d3SBarry Smith         goto done;
20941cbb95d3SBarry Smith       } else {
20951cbb95d3SBarry Smith         aptr[i]++;
20961cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
20971cbb95d3SBarry Smith       }
20981cbb95d3SBarry Smith     }
20991cbb95d3SBarry Smith   }
21001cbb95d3SBarry Smith done:
21011cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21021cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21031cbb95d3SBarry Smith   PetscFunctionReturn(0);
21041cbb95d3SBarry Smith }
21051cbb95d3SBarry Smith 
2106ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21079e29f15eSvictorle {
2108dfbe8321SBarry Smith   PetscErrorCode ierr;
21096e111a19SKarl Rupp 
21109e29f15eSvictorle   PetscFunctionBegin;
21115485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21129e29f15eSvictorle   PetscFunctionReturn(0);
21139e29f15eSvictorle }
21149e29f15eSvictorle 
2115ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21161cbb95d3SBarry Smith {
21171cbb95d3SBarry Smith   PetscErrorCode ierr;
21186e111a19SKarl Rupp 
21191cbb95d3SBarry Smith   PetscFunctionBegin;
21201cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21211cbb95d3SBarry Smith   PetscFunctionReturn(0);
21221cbb95d3SBarry Smith }
21231cbb95d3SBarry Smith 
2124dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
212517ab2063SBarry Smith {
2126416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
212754f21887SBarry Smith   PetscScalar    *l,*r,x;
212854f21887SBarry Smith   MatScalar      *v;
2129dfbe8321SBarry Smith   PetscErrorCode ierr;
2130d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
213117ab2063SBarry Smith 
21323a40ed3dSBarry Smith   PetscFunctionBegin;
213317ab2063SBarry Smith   if (ll) {
21343ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21353ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2136e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2137e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21381ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2139416022c9SBarry Smith     v    = a->a;
214017ab2063SBarry Smith     for (i=0; i<m; i++) {
214117ab2063SBarry Smith       x = l[i];
2142416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21432205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
214417ab2063SBarry Smith     }
21451ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2146efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
214717ab2063SBarry Smith   }
214817ab2063SBarry Smith   if (rr) {
2149e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2150e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21511ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2152416022c9SBarry Smith     v    = a->a; jj = a->j;
21532205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21541ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2155efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
215617ab2063SBarry Smith   }
2157acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
21583a40ed3dSBarry Smith   PetscFunctionReturn(0);
215917ab2063SBarry Smith }
216017ab2063SBarry Smith 
216197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
216217ab2063SBarry Smith {
2163db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21646849ba73SBarry Smith   PetscErrorCode ierr;
2165d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
216697f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21675d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21685d0c19d7SBarry Smith   PetscInt       nrows,ncols;
216997f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
217054f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2171416022c9SBarry Smith   Mat            C;
2172cdc6f3adSToby Isaac   PetscBool      stride;
217317ab2063SBarry Smith 
21743a40ed3dSBarry Smith   PetscFunctionBegin;
217599141d43SSatish Balay 
217617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2177b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2178b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
217917ab2063SBarry Smith 
2180251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2181ff718158SBarry Smith   if (stride) {
2182ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2183ff718158SBarry Smith   } else {
2184ff718158SBarry Smith     first = 0;
2185ff718158SBarry Smith     step  = 0;
2186ff718158SBarry Smith   }
2187fee21e36SBarry Smith   if (stride && step == 1) {
218802834360SBarry Smith     /* special case of contiguous rows */
2189dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
219002834360SBarry Smith     /* loop over new rows determining lens and starting points */
219102834360SBarry Smith     for (i=0; i<nrows; i++) {
2192bfeeae90SHong Zhang       kstart = ai[irow[i]];
2193a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2194a91a9bebSLisandro Dalcin       starts[i] = kstart;
219502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2196bfeeae90SHong Zhang         if (aj[k] >= first) {
219702834360SBarry Smith           starts[i] = k;
219802834360SBarry Smith           break;
219902834360SBarry Smith         }
220002834360SBarry Smith       }
2201a2744918SBarry Smith       sum = 0;
220202834360SBarry Smith       while (k < kend) {
2203bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2204a2744918SBarry Smith         sum++;
220502834360SBarry Smith       }
2206a2744918SBarry Smith       lens[i] = sum;
220702834360SBarry Smith     }
220802834360SBarry Smith     /* create submatrix */
2209cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
221097f1f81fSBarry Smith       PetscInt n_cols,n_rows;
221108480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2212e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2213d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
221408480c60SBarry Smith       C    = *B;
22153a40ed3dSBarry Smith     } else {
22163bef6203SJed Brown       PetscInt rbs,cbs;
2217ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2218f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22193bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22203bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22213bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22227adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2223ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
222408480c60SBarry Smith     }
2225db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2226db02288aSLois Curfman McInnes 
222702834360SBarry Smith     /* loop over rows inserting into submatrix */
2228db02288aSLois Curfman McInnes     a_new = c->a;
2229db02288aSLois Curfman McInnes     j_new = c->j;
2230db02288aSLois Curfman McInnes     i_new = c->i;
2231bfeeae90SHong Zhang 
223202834360SBarry Smith     for (i=0; i<nrows; i++) {
2233a2744918SBarry Smith       ii    = starts[i];
2234a2744918SBarry Smith       lensi = lens[i];
2235a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2236a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
223702834360SBarry Smith       }
223887828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2239a2744918SBarry Smith       a_new     += lensi;
2240a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2241a2744918SBarry Smith       c->ilen[i] = lensi;
224202834360SBarry Smith     }
22430e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22443a40ed3dSBarry Smith   } else {
224502834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22461795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2247854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22484dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22494dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22504dcab191SBarry 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);
22514dcab191SBarry Smith #endif
22524dcab191SBarry Smith       smap[icol[i]] = i+1;
22534dcab191SBarry Smith     }
22544dcab191SBarry Smith 
225502834360SBarry Smith     /* determine lens of each row */
225602834360SBarry Smith     for (i=0; i<nrows; i++) {
2257bfeeae90SHong Zhang       kstart  = ai[irow[i]];
225802834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
225902834360SBarry Smith       lens[i] = 0;
226002834360SBarry Smith       for (k=kstart; k<kend; k++) {
2261bfeeae90SHong Zhang         if (smap[aj[k]]) {
226202834360SBarry Smith           lens[i]++;
226302834360SBarry Smith         }
226402834360SBarry Smith       }
226502834360SBarry Smith     }
226617ab2063SBarry Smith     /* Create and fill new matrix */
2267a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2268ace3abfcSBarry Smith       PetscBool equal;
22690f5bd95cSBarry Smith 
227099141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2271e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2272d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2273f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2274d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
227508480c60SBarry Smith       C    = *B;
22763a40ed3dSBarry Smith     } else {
22773bef6203SJed Brown       PetscInt rbs,cbs;
2278ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2279f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22803bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22813bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22823bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22837adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2284ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
228508480c60SBarry Smith     }
228699141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
228717ab2063SBarry Smith     for (i=0; i<nrows; i++) {
228899141d43SSatish Balay       row      = irow[i];
2289bfeeae90SHong Zhang       kstart   = ai[row];
229099141d43SSatish Balay       kend     = kstart + a->ilen[row];
2291bfeeae90SHong Zhang       mat_i    = c->i[i];
229299141d43SSatish Balay       mat_j    = c->j + mat_i;
229399141d43SSatish Balay       mat_a    = c->a + mat_i;
229499141d43SSatish Balay       mat_ilen = c->ilen + i;
229517ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2296bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2297ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
229899141d43SSatish Balay           *mat_a++ = a->a[k];
229999141d43SSatish Balay           (*mat_ilen)++;
230099141d43SSatish Balay 
230117ab2063SBarry Smith         }
230217ab2063SBarry Smith       }
230317ab2063SBarry Smith     }
230402834360SBarry Smith     /* Free work space */
230502834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2306606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2307606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2308cdc6f3adSToby Isaac     /* sort */
2309cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2310cdc6f3adSToby Isaac       PetscInt ilen;
2311cdc6f3adSToby Isaac 
2312cdc6f3adSToby Isaac       mat_i = c->i[i];
2313cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2314cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2315cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2316*390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2317cdc6f3adSToby Isaac     }
231802834360SBarry Smith   }
23196d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23206d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
232117ab2063SBarry Smith 
232217ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2323416022c9SBarry Smith   *B   = C;
23243a40ed3dSBarry Smith   PetscFunctionReturn(0);
232517ab2063SBarry Smith }
232617ab2063SBarry Smith 
2327fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
232882d44351SHong Zhang {
232982d44351SHong Zhang   PetscErrorCode ierr;
233082d44351SHong Zhang   Mat            B;
233182d44351SHong Zhang 
233282d44351SHong Zhang   PetscFunctionBegin;
2333c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
233482d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
233582d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
233633d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
233782d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
233882d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
233982d44351SHong Zhang     *subMat = B;
2340c2d650bdSHong Zhang   } else {
2341c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2342c2d650bdSHong Zhang   }
234382d44351SHong Zhang   PetscFunctionReturn(0);
234482d44351SHong Zhang }
234582d44351SHong Zhang 
23469a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2347a871dcd8SBarry Smith {
234863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2349dfbe8321SBarry Smith   PetscErrorCode ierr;
235063b91edcSBarry Smith   Mat            outA;
2351ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
235263b91edcSBarry Smith 
23533a40ed3dSBarry Smith   PetscFunctionBegin;
2354e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23551df811f5SHong Zhang 
2356b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2357b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2358a871dcd8SBarry Smith 
235963b91edcSBarry Smith   outA             = inA;
2360d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2361f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2362f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
23632205254eSKarl Rupp 
2364c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23656bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
23662205254eSKarl Rupp 
2367c3122656SLisandro Dalcin   a->row = row;
23682205254eSKarl Rupp 
2369c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23706bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
23712205254eSKarl Rupp 
2372c3122656SLisandro Dalcin   a->col = col;
237363b91edcSBarry Smith 
237436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23756bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23764c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
23773bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2378f0ec6fceSSatish Balay 
237994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2380854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
23813bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
238294a9d846SBarry Smith   }
238363b91edcSBarry Smith 
2384f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2385137fb511SHong Zhang   if (row_identity && col_identity) {
2386ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2387137fb511SHong Zhang   } else {
2388719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2389137fb511SHong Zhang   }
23903a40ed3dSBarry Smith   PetscFunctionReturn(0);
2391a871dcd8SBarry Smith }
2392a871dcd8SBarry Smith 
2393f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2394f0b747eeSBarry Smith {
2395f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2396f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2397efee365bSSatish Balay   PetscErrorCode ierr;
2398c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
23993a40ed3dSBarry Smith 
24003a40ed3dSBarry Smith   PetscFunctionBegin;
2401c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24028b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2403efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2404acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24053a40ed3dSBarry Smith   PetscFunctionReturn(0);
2406f0b747eeSBarry Smith }
2407f0b747eeSBarry Smith 
240897f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2409cddf8d76SBarry Smith {
2410dfbe8321SBarry Smith   PetscErrorCode ierr;
241197f1f81fSBarry Smith   PetscInt       i;
2412cddf8d76SBarry Smith 
24133a40ed3dSBarry Smith   PetscFunctionBegin;
2414cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2415854ce69bSBarry Smith     ierr = PetscMalloc1(n+1,B);CHKERRQ(ierr);
2416cddf8d76SBarry Smith   }
2417cddf8d76SBarry Smith 
2418cddf8d76SBarry Smith   for (i=0; i<n; i++) {
24196a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2420cddf8d76SBarry Smith   }
24213a40ed3dSBarry Smith   PetscFunctionReturn(0);
2422cddf8d76SBarry Smith }
2423cddf8d76SBarry Smith 
242497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
24254dcbc457SBarry Smith {
2426e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24276849ba73SBarry Smith   PetscErrorCode ierr;
24285d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
24295d0c19d7SBarry Smith   const PetscInt *idx;
243097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2431f1af5d2fSBarry Smith   PetscBT        table;
2432bbd702dbSSatish Balay 
24333a40ed3dSBarry Smith   PetscFunctionBegin;
2434d0f46423SBarry Smith   m  = A->rmap->n;
2435e4d965acSSatish Balay   ai = a->i;
2436bfeeae90SHong Zhang   aj = a->j;
24378a047759SSatish Balay 
2438e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
243906763907SSatish Balay 
2440854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
244153b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
244206763907SSatish Balay 
2443e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2444b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2445e4d965acSSatish Balay     isz  = 0;
24466831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2447e4d965acSSatish Balay 
2448e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
24494dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2450b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2451e4d965acSSatish Balay 
2452dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2453e4d965acSSatish Balay     for (j=0; j<n; ++j) {
24542205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
24554dcbc457SBarry Smith     }
245606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
24576bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2458e4d965acSSatish Balay 
245904a348a9SBarry Smith     k = 0;
246004a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
246104a348a9SBarry Smith       n = isz;
246206763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2463e4d965acSSatish Balay         row   = nidx[k];
2464e4d965acSSatish Balay         start = ai[row];
2465e4d965acSSatish Balay         end   = ai[row+1];
246604a348a9SBarry Smith         for (l = start; l<end; l++) {
2467efb16452SHong Zhang           val = aj[l];
24682205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2469e4d965acSSatish Balay         }
2470e4d965acSSatish Balay       }
2471e4d965acSSatish Balay     }
247270b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2473e4d965acSSatish Balay   }
247494bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2475606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
24763a40ed3dSBarry Smith   PetscFunctionReturn(0);
24774dcbc457SBarry Smith }
247817ab2063SBarry Smith 
24790513a670SBarry Smith /* -------------------------------------------------------------- */
2480dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
24810513a670SBarry Smith {
24820513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24836849ba73SBarry Smith   PetscErrorCode ierr;
24843b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
24855d0c19d7SBarry Smith   const PetscInt *row,*col;
24865d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
248756cd22aeSBarry Smith   IS             icolp,irowp;
24880298fd71SBarry Smith   PetscInt       *cwork = NULL;
24890298fd71SBarry Smith   PetscScalar    *vwork = NULL;
24900513a670SBarry Smith 
24913a40ed3dSBarry Smith   PetscFunctionBegin;
24924c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
249356cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
24944c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
249556cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
24960513a670SBarry Smith 
24970513a670SBarry Smith   /* determine lengths of permuted rows */
2498854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
24992205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2500ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2501f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
250233d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
25037adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2504ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2505606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
25060513a670SBarry Smith 
2507785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
25080513a670SBarry Smith   for (i=0; i<m; i++) {
250932ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25102205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2511cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
251232ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25130513a670SBarry Smith   }
2514606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
25152205254eSKarl Rupp 
25163c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
25172205254eSKarl Rupp 
25180513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25190513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
252056cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
252156cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
25226bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
25236bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
25243a40ed3dSBarry Smith   PetscFunctionReturn(0);
25250513a670SBarry Smith }
25260513a670SBarry Smith 
2527dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2528cb5b572fSBarry Smith {
2529dfbe8321SBarry Smith   PetscErrorCode ierr;
2530cb5b572fSBarry Smith 
2531cb5b572fSBarry Smith   PetscFunctionBegin;
253233f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
253333f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2534be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2535be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2536be6bf707SBarry Smith 
2537700c5bfcSBarry 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");
2538d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2539cb5b572fSBarry Smith   } else {
2540cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2541cb5b572fSBarry Smith   }
2542cb5b572fSBarry Smith   PetscFunctionReturn(0);
2543cb5b572fSBarry Smith }
2544cb5b572fSBarry Smith 
25454994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2546273d9f13SBarry Smith {
2547dfbe8321SBarry Smith   PetscErrorCode ierr;
2548273d9f13SBarry Smith 
2549273d9f13SBarry Smith   PetscFunctionBegin;
2550ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2551273d9f13SBarry Smith   PetscFunctionReturn(0);
2552273d9f13SBarry Smith }
2553273d9f13SBarry Smith 
25548c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
25556c0721eeSBarry Smith {
25566c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
25576e111a19SKarl Rupp 
25586c0721eeSBarry Smith   PetscFunctionBegin;
25596c0721eeSBarry Smith   *array = a->a;
25606c0721eeSBarry Smith   PetscFunctionReturn(0);
25616c0721eeSBarry Smith }
25626c0721eeSBarry Smith 
25638c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
25646c0721eeSBarry Smith {
25656c0721eeSBarry Smith   PetscFunctionBegin;
25666c0721eeSBarry Smith   PetscFunctionReturn(0);
25676c0721eeSBarry Smith }
2568273d9f13SBarry Smith 
25698229c054SShri Abhyankar /*
25708229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
25718229c054SShri Abhyankar    have different nonzero structure.
25728229c054SShri Abhyankar */
2573b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2574ec7775f6SShri Abhyankar {
2575b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2576ec7775f6SShri Abhyankar 
2577ec7775f6SShri Abhyankar   PetscFunctionBegin;
2578ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2579ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2580b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2581b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2582b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
25838af7cee1SJed Brown     nnz[i] = 0;
25848af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2585b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2586b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
25878af7cee1SJed Brown       nnz[i]++;
25888af7cee1SJed Brown     }
25898af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2590ec7775f6SShri Abhyankar   }
2591ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2592ec7775f6SShri Abhyankar }
2593ec7775f6SShri Abhyankar 
2594b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2595b264fe52SHong Zhang {
2596b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2597b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2598b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2599b264fe52SHong Zhang   PetscErrorCode ierr;
2600b264fe52SHong Zhang 
2601b264fe52SHong Zhang   PetscFunctionBegin;
2602b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2603b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2604b264fe52SHong Zhang   PetscFunctionReturn(0);
2605b264fe52SHong Zhang }
2606b264fe52SHong Zhang 
2607f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2608ac90fabeSBarry Smith {
2609dfbe8321SBarry Smith   PetscErrorCode ierr;
2610ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2611c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2612ac90fabeSBarry Smith 
2613ac90fabeSBarry Smith   PetscFunctionBegin;
2614c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2615ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2616f4df32b1SMatthew Knepley     PetscScalar alpha = a;
26178b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2618acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2619a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2620ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2621ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2622ac90fabeSBarry Smith   } else {
26238229c054SShri Abhyankar     Mat      B;
26248229c054SShri Abhyankar     PetscInt *nnz;
2625785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2626ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2627bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
26284aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
262933d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2630176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
26318229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2632ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2633ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
263428be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
26358229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2636ac90fabeSBarry Smith   }
2637ac90fabeSBarry Smith   PetscFunctionReturn(0);
2638ac90fabeSBarry Smith }
2639ac90fabeSBarry Smith 
26407087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2641354c94deSBarry Smith {
2642354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2643354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2644354c94deSBarry Smith   PetscInt    i,nz;
2645354c94deSBarry Smith   PetscScalar *a;
2646354c94deSBarry Smith 
2647354c94deSBarry Smith   PetscFunctionBegin;
2648354c94deSBarry Smith   nz = aij->nz;
2649354c94deSBarry Smith   a  = aij->a;
26502205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2651354c94deSBarry Smith #else
2652354c94deSBarry Smith   PetscFunctionBegin;
2653354c94deSBarry Smith #endif
2654354c94deSBarry Smith   PetscFunctionReturn(0);
2655354c94deSBarry Smith }
2656354c94deSBarry Smith 
2657985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2658e34fafa9SBarry Smith {
2659e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2660e34fafa9SBarry Smith   PetscErrorCode ierr;
2661d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2662e34fafa9SBarry Smith   PetscReal      atmp;
2663985db425SBarry Smith   PetscScalar    *x;
2664e34fafa9SBarry Smith   MatScalar      *aa;
2665e34fafa9SBarry Smith 
2666e34fafa9SBarry Smith   PetscFunctionBegin;
2667e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2668e34fafa9SBarry Smith   aa = a->a;
2669e34fafa9SBarry Smith   ai = a->i;
2670e34fafa9SBarry Smith   aj = a->j;
2671e34fafa9SBarry Smith 
2672985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2673e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2674e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2675e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2676e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2677e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
26789189402eSHong Zhang     x[i]  = 0.0;
2679e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2680985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2681985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2682985db425SBarry Smith       aa++; aj++;
2683985db425SBarry Smith     }
2684985db425SBarry Smith   }
2685985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2686985db425SBarry Smith   PetscFunctionReturn(0);
2687985db425SBarry Smith }
2688985db425SBarry Smith 
2689985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2690985db425SBarry Smith {
2691985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2692985db425SBarry Smith   PetscErrorCode ierr;
2693d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2694985db425SBarry Smith   PetscScalar    *x;
2695985db425SBarry Smith   MatScalar      *aa;
2696985db425SBarry Smith 
2697985db425SBarry Smith   PetscFunctionBegin;
2698e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2699985db425SBarry Smith   aa = a->a;
2700985db425SBarry Smith   ai = a->i;
2701985db425SBarry Smith   aj = a->j;
2702985db425SBarry Smith 
2703985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2704985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2705985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2706e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2707985db425SBarry Smith   for (i=0; i<m; i++) {
2708985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2709d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2710985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2711985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2712985db425SBarry Smith       x[i] = 0.0;
2713985db425SBarry Smith       if (idx) {
2714985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2715985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2716985db425SBarry Smith           if (aj[j] > j) {
2717985db425SBarry Smith             idx[i] = j;
2718985db425SBarry Smith             break;
2719985db425SBarry Smith           }
2720985db425SBarry Smith         }
2721985db425SBarry Smith       }
2722985db425SBarry Smith     }
2723985db425SBarry Smith     for (j=0; j<ncols; j++) {
2724985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2725985db425SBarry Smith       aa++; aj++;
2726985db425SBarry Smith     }
2727985db425SBarry Smith   }
2728985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2729985db425SBarry Smith   PetscFunctionReturn(0);
2730985db425SBarry Smith }
2731985db425SBarry Smith 
2732c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2733c87e5d42SMatthew Knepley {
2734c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2735c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2736c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2737c87e5d42SMatthew Knepley   PetscReal      atmp;
2738c87e5d42SMatthew Knepley   PetscScalar    *x;
2739c87e5d42SMatthew Knepley   MatScalar      *aa;
2740c87e5d42SMatthew Knepley 
2741c87e5d42SMatthew Knepley   PetscFunctionBegin;
2742e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2743c87e5d42SMatthew Knepley   aa = a->a;
2744c87e5d42SMatthew Knepley   ai = a->i;
2745c87e5d42SMatthew Knepley   aj = a->j;
2746c87e5d42SMatthew Knepley 
2747c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2748c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2749c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
275060e0710aSBarry Smith   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);
2751c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2752c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2753289a08f5SMatthew Knepley     if (ncols) {
2754289a08f5SMatthew Knepley       /* Get first nonzero */
2755289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2756289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
27572205254eSKarl Rupp         if (atmp > 1.0e-12) {
27582205254eSKarl Rupp           x[i] = atmp;
27592205254eSKarl Rupp           if (idx) idx[i] = aj[j];
27602205254eSKarl Rupp           break;
27612205254eSKarl Rupp         }
2762289a08f5SMatthew Knepley       }
276312431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2764289a08f5SMatthew Knepley     } else {
2765289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2766289a08f5SMatthew Knepley     }
2767c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2768c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2769289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2770c87e5d42SMatthew Knepley       aa++; aj++;
2771c87e5d42SMatthew Knepley     }
2772c87e5d42SMatthew Knepley   }
2773c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2774c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2775c87e5d42SMatthew Knepley }
2776c87e5d42SMatthew Knepley 
2777985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2778985db425SBarry Smith {
2779985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2780985db425SBarry Smith   PetscErrorCode  ierr;
2781d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2782d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2783985db425SBarry Smith   PetscScalar     *x;
2784d9ca1df4SBarry Smith   const MatScalar *aa;
2785985db425SBarry Smith 
2786985db425SBarry Smith   PetscFunctionBegin;
2787e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2788985db425SBarry Smith   aa = a->a;
2789985db425SBarry Smith   ai = a->i;
2790985db425SBarry Smith   aj = a->j;
2791985db425SBarry Smith 
2792985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2793985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2794985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2795e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2796985db425SBarry Smith   for (i=0; i<m; i++) {
2797985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2798d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2799985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2800985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2801985db425SBarry Smith       x[i] = 0.0;
2802985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2803985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2804985db425SBarry Smith         for (j=0; j<ncols; j++) {
2805985db425SBarry Smith           if (aj[j] > j) {
2806985db425SBarry Smith             idx[i] = j;
2807985db425SBarry Smith             break;
2808985db425SBarry Smith           }
2809985db425SBarry Smith         }
2810985db425SBarry Smith       }
2811985db425SBarry Smith     }
2812985db425SBarry Smith     for (j=0; j<ncols; j++) {
2813985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2814985db425SBarry Smith       aa++; aj++;
2815e34fafa9SBarry Smith     }
2816e34fafa9SBarry Smith   }
2817e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2818e34fafa9SBarry Smith   PetscFunctionReturn(0);
2819e34fafa9SBarry Smith }
2820bbead8a2SBarry Smith 
2821bbead8a2SBarry Smith #include <petscblaslapack.h>
2822af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2823bbead8a2SBarry Smith 
2824713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2825bbead8a2SBarry Smith {
2826bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2827bbead8a2SBarry Smith   PetscErrorCode ierr;
282833d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2829bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2830bbead8a2SBarry Smith   PetscReal      shift = 0.0;
28311a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2832bbead8a2SBarry Smith 
2833bbead8a2SBarry Smith   PetscFunctionBegin;
2834a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
28354a0d0026SBarry Smith   if (a->ibdiagvalid) {
28364a0d0026SBarry Smith     if (values) *values = a->ibdiag;
28374a0d0026SBarry Smith     PetscFunctionReturn(0);
28384a0d0026SBarry Smith   }
2839bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2840bbead8a2SBarry Smith   if (!a->ibdiag) {
2841785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
28423bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2843bbead8a2SBarry Smith   }
2844bbead8a2SBarry Smith   diag = a->ibdiag;
2845bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2846bbead8a2SBarry Smith   /* factor and invert each block */
2847bbead8a2SBarry Smith   switch (bs) {
2848bbead8a2SBarry Smith   case 1:
2849bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2850bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2851ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2852ec1892c8SHong Zhang         if (allowzeropivot) {
28537b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
28547b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
28557b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
28567b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
28577b6c816cSBarry Smith         } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %D pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);
2858ec1892c8SHong Zhang       }
2859bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2860bbead8a2SBarry Smith     }
2861bbead8a2SBarry Smith     break;
2862bbead8a2SBarry Smith   case 2:
2863bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2864bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2865bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2866a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
28677b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
286896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2869bbead8a2SBarry Smith       diag += 4;
2870bbead8a2SBarry Smith     }
2871bbead8a2SBarry Smith     break;
2872bbead8a2SBarry Smith   case 3:
2873bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2874bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2875bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2876a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
28777b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
287896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2879bbead8a2SBarry Smith       diag += 9;
2880bbead8a2SBarry Smith     }
2881bbead8a2SBarry Smith     break;
2882bbead8a2SBarry Smith   case 4:
2883bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2884bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2885bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2886a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
28877b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
288896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2889bbead8a2SBarry Smith       diag += 16;
2890bbead8a2SBarry Smith     }
2891bbead8a2SBarry Smith     break;
2892bbead8a2SBarry Smith   case 5:
2893bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2894bbead8a2SBarry 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;
2895bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2896a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
28977b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
289896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2899bbead8a2SBarry Smith       diag += 25;
2900bbead8a2SBarry Smith     }
2901bbead8a2SBarry Smith     break;
2902bbead8a2SBarry Smith   case 6:
2903bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2904bbead8a2SBarry 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;
2905bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
2906a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29077b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
290896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2909bbead8a2SBarry Smith       diag += 36;
2910bbead8a2SBarry Smith     }
2911bbead8a2SBarry Smith     break;
2912bbead8a2SBarry Smith   case 7:
2913bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2914bbead8a2SBarry 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;
2915bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
2916a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29177b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
291896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
2919bbead8a2SBarry Smith       diag += 49;
2920bbead8a2SBarry Smith     }
2921bbead8a2SBarry Smith     break;
2922bbead8a2SBarry Smith   default:
2923dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
2924bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2925bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
2926bbead8a2SBarry Smith         IJ[j] = bs*i + j;
2927bbead8a2SBarry Smith       }
2928bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
29295f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29307b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
293196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
2932bbead8a2SBarry Smith       diag += bs2;
2933bbead8a2SBarry Smith     }
2934bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
2935bbead8a2SBarry Smith   }
2936bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
2937bbead8a2SBarry Smith   PetscFunctionReturn(0);
2938bbead8a2SBarry Smith }
2939bbead8a2SBarry Smith 
294073a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
294173a71a0fSBarry Smith {
294273a71a0fSBarry Smith   PetscErrorCode ierr;
294373a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
294473a71a0fSBarry Smith   PetscScalar    a;
294573a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
294673a71a0fSBarry Smith 
294773a71a0fSBarry Smith   PetscFunctionBegin;
294873a71a0fSBarry Smith   if (!x->assembled) {
294973a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
295073a71a0fSBarry Smith     for (i=0; i<m; i++) {
295173a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
295273a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
295373a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
295473a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
295573a71a0fSBarry Smith       }
295673a71a0fSBarry Smith     }
295773a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
295873a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
295973a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
296073a71a0fSBarry Smith   PetscFunctionReturn(0);
296173a71a0fSBarry Smith }
296273a71a0fSBarry Smith 
29637d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
29647d68702bSBarry Smith {
29657d68702bSBarry Smith   PetscErrorCode ierr;
29667d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
29677d68702bSBarry Smith 
29687d68702bSBarry Smith   PetscFunctionBegin;
29696f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
29707d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
29717d68702bSBarry Smith   }
29727d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
29737d68702bSBarry Smith   PetscFunctionReturn(0);
29747d68702bSBarry Smith }
29757d68702bSBarry Smith 
2976682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
29770a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
2978cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
2979cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
2980cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
298197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
29827c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
29837c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
2984db4efbfdSBarry Smith                                         0,
2985db4efbfdSBarry Smith                                         0,
2986db4efbfdSBarry Smith                                         0,
2987db4efbfdSBarry Smith                                 /* 10*/ 0,
2988cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
2989cb5b572fSBarry Smith                                         0,
299041f059aeSBarry Smith                                         MatSOR_SeqAIJ,
299117ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
299297304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
2993cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
2994cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
2995cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
2996cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
299797304618SKris Buschelman                                 /* 20*/ 0,
2998cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
2999cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3000cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3001d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3002db4efbfdSBarry Smith                                         0,
3003db4efbfdSBarry Smith                                         0,
3004db4efbfdSBarry Smith                                         0,
3005db4efbfdSBarry Smith                                         0,
30064994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3007db4efbfdSBarry Smith                                         0,
3008db4efbfdSBarry Smith                                         0,
30098c778c55SBarry Smith                                         0,
30108c778c55SBarry Smith                                         0,
3011d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3012cb5b572fSBarry Smith                                         0,
3013cb5b572fSBarry Smith                                         0,
3014cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3015cb5b572fSBarry Smith                                         0,
3016d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3017cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3018cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3019cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3020cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3021d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3022cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
30237d68702bSBarry Smith                                         MatShift_SeqAIJ,
302479299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
30256e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
302673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
30273b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
30283b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
30293b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3030a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
303193dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3032b9617806SBarry Smith                                         0,
30330513a670SBarry Smith                                         0,
3034cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3035cda55fadSBarry Smith                                         0,
3036d519adbfSMatthew Knepley                                 /* 59*/ 0,
3037b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3038b9b97703SBarry Smith                                         MatView_SeqAIJ,
3039357abbc8SBarry Smith                                         0,
3040321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3041321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3042321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3043ee4f033dSBarry Smith                                         0,
3044ee4f033dSBarry Smith                                         0,
3045ee4f033dSBarry Smith                                         0,
3046d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3047c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3048ee4f033dSBarry Smith                                         0,
3049dcf5cc72SBarry Smith                                         0,
30502c93a97aSBarry Smith                                         0,
30512c93a97aSBarry Smith                                 /* 74*/ 0,
30523acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
305397304618SKris Buschelman                                         0,
305497304618SKris Buschelman                                         0,
305597304618SKris Buschelman                                         0,
30566ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
305797304618SKris Buschelman                                         0,
305897304618SKris Buschelman                                         0,
305997304618SKris Buschelman                                         0,
3060bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3061d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
30621cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
30636284ec50SHong Zhang                                         0,
30646284ec50SHong Zhang                                         0,
3065bc011b1eSHong Zhang                                         0,
3066d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
306726be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
306826be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
306965e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
30704a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
307165e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
30726fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
30736fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
30746fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
30752121bac1SHong Zhang                                         0,
30762121bac1SHong Zhang                                 /* 99*/ 0,
3077609c6c4dSKris Buschelman                                         0,
3078609c6c4dSKris Buschelman                                         0,
307987d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
308087d4246cSBarry Smith                                         0,
3081d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
308299cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3083f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3084f5edf698SHong Zhang                                         0,
30852bebee5dSHong Zhang                                         0,
3086cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3087985db425SBarry Smith                                         0,
30882af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
30892af78befSBarry Smith                                         0,
3090599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3091d519adbfSMatthew Knepley                                 /*114*/ 0,
3092599ef60dSHong Zhang                                         0,
30933c2a7987SHong Zhang                                         0,
3094fe97e370SBarry Smith                                         0,
3095fbdbba38SShri Abhyankar                                         0,
3096fbdbba38SShri Abhyankar                                 /*119*/ 0,
3097fbdbba38SShri Abhyankar                                         0,
3098fbdbba38SShri Abhyankar                                         0,
309982d44351SHong Zhang                                         0,
3100b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
31010716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3102bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
310337868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
310437868618SMatthew G Knepley                                         0,
310537868618SMatthew G Knepley                                         0,
31065df89d91SHong Zhang                                 /*129*/ 0,
310775648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
310875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
310975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3110b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3111b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
31122b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
31132b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
31142b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
31153964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
31163964eb88SJed Brown                                  /*139*/0,
3117f9426fe0SMark Adams                                         0,
31181919a2e2SJed Brown                                         0,
31193a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
31209c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
31219c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
31229e29f15eSvictorle };
312317ab2063SBarry Smith 
31247087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3125bef8e0ddSBarry Smith {
3126bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
312797f1f81fSBarry Smith   PetscInt   i,nz,n;
3128bef8e0ddSBarry Smith 
3129bef8e0ddSBarry Smith   PetscFunctionBegin;
3130bef8e0ddSBarry Smith   nz = aij->maxnz;
3131d0f46423SBarry Smith   n  = mat->rmap->n;
3132bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3133bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3134bef8e0ddSBarry Smith   }
3135bef8e0ddSBarry Smith   aij->nz = nz;
3136bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3137bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3138bef8e0ddSBarry Smith   }
3139bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3140bef8e0ddSBarry Smith }
3141bef8e0ddSBarry Smith 
3142bef8e0ddSBarry Smith /*@
3143bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3144bef8e0ddSBarry Smith        in the matrix.
3145bef8e0ddSBarry Smith 
3146bef8e0ddSBarry Smith   Input Parameters:
3147bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3148bef8e0ddSBarry Smith -  indices - the column indices
3149bef8e0ddSBarry Smith 
315015091d37SBarry Smith   Level: advanced
315115091d37SBarry Smith 
3152bef8e0ddSBarry Smith   Notes:
3153bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3154bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3155bef8e0ddSBarry Smith   of the MatSetValues() operation.
3156bef8e0ddSBarry Smith 
3157bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3158d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3159bef8e0ddSBarry Smith 
3160bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3161bef8e0ddSBarry Smith 
3162b9617806SBarry Smith     The indices should start with zero, not one.
3163b9617806SBarry Smith 
3164bef8e0ddSBarry Smith @*/
31657087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3166bef8e0ddSBarry Smith {
31674ac538c5SBarry Smith   PetscErrorCode ierr;
3168bef8e0ddSBarry Smith 
3169bef8e0ddSBarry Smith   PetscFunctionBegin;
31700700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
31714482741eSBarry Smith   PetscValidPointer(indices,2);
31724ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3173bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3174bef8e0ddSBarry Smith }
3175bef8e0ddSBarry Smith 
3176be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3177be6bf707SBarry Smith 
31787087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3179be6bf707SBarry Smith {
3180be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
31816849ba73SBarry Smith   PetscErrorCode ierr;
3182d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3183be6bf707SBarry Smith 
3184be6bf707SBarry Smith   PetscFunctionBegin;
3185169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3186be6bf707SBarry Smith 
3187be6bf707SBarry Smith   /* allocate space for values if not already there */
3188be6bf707SBarry Smith   if (!aij->saved_values) {
3189854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
31903bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3191be6bf707SBarry Smith   }
3192be6bf707SBarry Smith 
3193be6bf707SBarry Smith   /* copy values over */
319487828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3195be6bf707SBarry Smith   PetscFunctionReturn(0);
3196be6bf707SBarry Smith }
3197be6bf707SBarry Smith 
3198be6bf707SBarry Smith /*@
3199be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3200be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3201be6bf707SBarry Smith        nonlinear portion.
3202be6bf707SBarry Smith 
3203be6bf707SBarry Smith    Collect on Mat
3204be6bf707SBarry Smith 
3205be6bf707SBarry Smith   Input Parameters:
32060e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3207be6bf707SBarry Smith 
320815091d37SBarry Smith   Level: advanced
320915091d37SBarry Smith 
3210be6bf707SBarry Smith   Common Usage, with SNESSolve():
3211be6bf707SBarry Smith $    Create Jacobian matrix
3212be6bf707SBarry Smith $    Set linear terms into matrix
3213be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3214be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3215be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3216512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3217be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3218be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3219be6bf707SBarry Smith $    In your Jacobian routine
3220be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3221be6bf707SBarry Smith $      Set nonlinear terms in matrix
3222be6bf707SBarry Smith 
3223be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3224be6bf707SBarry Smith $    // build linear portion of Jacobian
3225512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3226be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3227be6bf707SBarry Smith $    loop over nonlinear iterations
3228be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3229be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3230be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3231be6bf707SBarry Smith $       Solve linear system with Jacobian
3232be6bf707SBarry Smith $    endloop
3233be6bf707SBarry Smith 
3234be6bf707SBarry Smith   Notes:
3235be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3236512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3237be6bf707SBarry Smith     calling this routine.
3238be6bf707SBarry Smith 
32390c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
32400c468ba9SBarry Smith     and does not allocated additional space.
32410c468ba9SBarry Smith 
3242be6bf707SBarry Smith .seealso: MatRetrieveValues()
3243be6bf707SBarry Smith 
3244be6bf707SBarry Smith @*/
32457087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3246be6bf707SBarry Smith {
32474ac538c5SBarry Smith   PetscErrorCode ierr;
3248be6bf707SBarry Smith 
3249be6bf707SBarry Smith   PetscFunctionBegin;
32500700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3251e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3252e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32534ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3254be6bf707SBarry Smith   PetscFunctionReturn(0);
3255be6bf707SBarry Smith }
3256be6bf707SBarry Smith 
32577087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3258be6bf707SBarry Smith {
3259be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32606849ba73SBarry Smith   PetscErrorCode ierr;
3261d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3262be6bf707SBarry Smith 
3263be6bf707SBarry Smith   PetscFunctionBegin;
3264169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3265f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3266be6bf707SBarry Smith   /* copy values over */
326787828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3268be6bf707SBarry Smith   PetscFunctionReturn(0);
3269be6bf707SBarry Smith }
3270be6bf707SBarry Smith 
3271be6bf707SBarry Smith /*@
3272be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3273be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3274be6bf707SBarry Smith        nonlinear portion.
3275be6bf707SBarry Smith 
3276be6bf707SBarry Smith    Collect on Mat
3277be6bf707SBarry Smith 
3278be6bf707SBarry Smith   Input Parameters:
3279386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3280be6bf707SBarry Smith 
328115091d37SBarry Smith   Level: advanced
328215091d37SBarry Smith 
3283be6bf707SBarry Smith .seealso: MatStoreValues()
3284be6bf707SBarry Smith 
3285be6bf707SBarry Smith @*/
32867087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3287be6bf707SBarry Smith {
32884ac538c5SBarry Smith   PetscErrorCode ierr;
3289be6bf707SBarry Smith 
3290be6bf707SBarry Smith   PetscFunctionBegin;
32910700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3292e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3293e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
32944ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3295be6bf707SBarry Smith   PetscFunctionReturn(0);
3296be6bf707SBarry Smith }
3297be6bf707SBarry Smith 
3298f83d6046SBarry Smith 
3299be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
330017ab2063SBarry Smith /*@C
3301682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33020d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33036e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
330451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33052bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
330617ab2063SBarry Smith 
3307db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3308db81eaa0SLois Curfman McInnes 
330917ab2063SBarry Smith    Input Parameters:
3310db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
331117ab2063SBarry Smith .  m - number of rows
331217ab2063SBarry Smith .  n - number of columns
331317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
331451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33150298fd71SBarry Smith          (possibly different for each row) or NULL
331617ab2063SBarry Smith 
331717ab2063SBarry Smith    Output Parameter:
3318416022c9SBarry Smith .  A - the matrix
331917ab2063SBarry Smith 
3320175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3321ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3322175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3323175b88e8SBarry Smith 
3324b259b22eSLois Curfman McInnes    Notes:
332549a6f317SBarry Smith    If nnz is given then nz is ignored
332649a6f317SBarry Smith 
332717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
332817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
33290002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
333044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
333117ab2063SBarry Smith 
333217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
33330298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
33343d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
33356da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
333617ab2063SBarry Smith 
3337682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
33384fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3339682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
33406c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
33416c7ebb05SLois Curfman McInnes 
33426c7ebb05SLois Curfman McInnes    Options Database Keys:
3343698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
33449db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
334517ab2063SBarry Smith 
3346027ccd11SLois Curfman McInnes    Level: intermediate
3347027ccd11SLois Curfman McInnes 
334869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
334936db0b34SBarry Smith 
335017ab2063SBarry Smith @*/
33517087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
335217ab2063SBarry Smith {
3353dfbe8321SBarry Smith   PetscErrorCode ierr;
33546945ee14SBarry Smith 
33553a40ed3dSBarry Smith   PetscFunctionBegin;
3356f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3357117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3358c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3359d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3360273d9f13SBarry Smith   PetscFunctionReturn(0);
3361273d9f13SBarry Smith }
3362273d9f13SBarry Smith 
3363273d9f13SBarry Smith /*@C
3364273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3365273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3366273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3367273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3368273d9f13SBarry Smith 
3369273d9f13SBarry Smith    Collective on MPI_Comm
3370273d9f13SBarry Smith 
3371273d9f13SBarry Smith    Input Parameters:
33721c4f3114SJed Brown +  B - The matrix
3373273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3374273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33750298fd71SBarry Smith          (possibly different for each row) or NULL
3376273d9f13SBarry Smith 
3377273d9f13SBarry Smith    Notes:
337849a6f317SBarry Smith      If nnz is given then nz is ignored
337949a6f317SBarry Smith 
3380273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3381273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3382273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3383273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3384273d9f13SBarry Smith 
3385273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
33860298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3387273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3388273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3389273d9f13SBarry Smith 
3390aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3391aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3392aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3393aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3394aa95bbe8SBarry Smith 
3395a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3396a96a251dSBarry Smith    entries or columns indices
3397a96a251dSBarry Smith 
3398273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3399273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3400273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3401273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3402273d9f13SBarry Smith 
3403273d9f13SBarry Smith    Options Database Keys:
3404698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3405698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3406273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3407273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3408273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3409273d9f13SBarry Smith 
3410273d9f13SBarry Smith    Level: intermediate
3411273d9f13SBarry Smith 
341269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3413273d9f13SBarry Smith 
3414273d9f13SBarry Smith @*/
34157087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3416273d9f13SBarry Smith {
34174ac538c5SBarry Smith   PetscErrorCode ierr;
3418a23d5eceSKris Buschelman 
3419a23d5eceSKris Buschelman   PetscFunctionBegin;
34206ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
34216ba663aaSJed Brown   PetscValidType(B,1);
34224ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3423a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3424a23d5eceSKris Buschelman }
3425a23d5eceSKris Buschelman 
34267087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3427a23d5eceSKris Buschelman {
3428273d9f13SBarry Smith   Mat_SeqAIJ     *b;
34292576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
34306849ba73SBarry Smith   PetscErrorCode ierr;
343197f1f81fSBarry Smith   PetscInt       i;
3432273d9f13SBarry Smith 
3433273d9f13SBarry Smith   PetscFunctionBegin;
34342576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3435a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3436c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3437c461c341SBarry Smith     nz             = 0;
3438c461c341SBarry Smith   }
3439c461c341SBarry Smith 
344026283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
344126283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3442899cda47SBarry Smith 
3443435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
344460e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3445b73539f3SBarry Smith   if (nnz) {
3446d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
344760e0710aSBarry 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]);
344860e0710aSBarry 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);
3449b73539f3SBarry Smith     }
3450b73539f3SBarry Smith   }
3451b73539f3SBarry Smith 
3452273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
34532205254eSKarl Rupp 
3454273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3455273d9f13SBarry Smith 
3456ab93d7beSBarry Smith   if (!skipallocation) {
34572ee49352SLisandro Dalcin     if (!b->imax) {
3458dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
34593bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
34602ee49352SLisandro Dalcin     }
3461273d9f13SBarry Smith     if (!nnz) {
3462435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3463c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3464d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3465d0f46423SBarry Smith       nz = nz*B->rmap->n;
3466273d9f13SBarry Smith     } else {
3467273d9f13SBarry Smith       nz = 0;
3468d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3469273d9f13SBarry Smith     }
3470ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
34712205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3472ab93d7beSBarry Smith 
3473273d9f13SBarry Smith     /* allocate the matrix space */
347453dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
34752ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3476dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
34773bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3478bfeeae90SHong Zhang     b->i[0] = 0;
3479d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
34805da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
34815da197adSKris Buschelman     }
3482273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3483e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3484e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3485c461c341SBarry Smith   } else {
3486e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3487e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3488c461c341SBarry Smith   }
3489273d9f13SBarry Smith 
3490273d9f13SBarry Smith   b->nz               = 0;
3491273d9f13SBarry Smith   b->maxnz            = nz;
3492273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
34932205254eSKarl Rupp   if (realalloc) {
34942205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
34952205254eSKarl Rupp   }
3496cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3497cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3498273d9f13SBarry Smith   PetscFunctionReturn(0);
3499273d9f13SBarry Smith }
3500273d9f13SBarry Smith 
350158d36128SBarry Smith /*@
3502a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3503a1661176SMatthew Knepley 
3504a1661176SMatthew Knepley    Input Parameters:
3505a1661176SMatthew Knepley +  B - the matrix
3506a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3507a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3508a1661176SMatthew Knepley -  v - optional values in the matrix
3509a1661176SMatthew Knepley 
3510a1661176SMatthew Knepley    Level: developer
3511a1661176SMatthew Knepley 
351258d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
351358d36128SBarry Smith 
3514a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3515a1661176SMatthew Knepley 
3516a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3517a1661176SMatthew Knepley @*/
3518a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3519a1661176SMatthew Knepley {
3520a1661176SMatthew Knepley   PetscErrorCode ierr;
3521a1661176SMatthew Knepley 
3522a1661176SMatthew Knepley   PetscFunctionBegin;
35230700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35246ba663aaSJed Brown   PetscValidType(B,1);
35254ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3526a1661176SMatthew Knepley   PetscFunctionReturn(0);
3527a1661176SMatthew Knepley }
3528a1661176SMatthew Knepley 
35297087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3530a1661176SMatthew Knepley {
3531a1661176SMatthew Knepley   PetscInt       i;
3532a1661176SMatthew Knepley   PetscInt       m,n;
3533a1661176SMatthew Knepley   PetscInt       nz;
3534a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3535a1661176SMatthew Knepley   PetscScalar    *values;
3536a1661176SMatthew Knepley   PetscErrorCode ierr;
3537a1661176SMatthew Knepley 
3538a1661176SMatthew Knepley   PetscFunctionBegin;
353965e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3540779a8d59SSatish Balay 
3541779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3542779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3543779a8d59SSatish Balay 
3544779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3545854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3546a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3547b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3548a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
354965e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3550a1661176SMatthew Knepley     nnz[i] = nz;
3551a1661176SMatthew Knepley   }
3552a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3553a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3554a1661176SMatthew Knepley 
3555a1661176SMatthew Knepley   if (v) {
3556a1661176SMatthew Knepley     values = (PetscScalar*) v;
3557a1661176SMatthew Knepley   } else {
35581795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3559a1661176SMatthew Knepley   }
3560a1661176SMatthew Knepley 
3561a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3562b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3563b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3564a1661176SMatthew Knepley   }
3565a1661176SMatthew Knepley 
3566a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3567a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3568a1661176SMatthew Knepley 
3569a1661176SMatthew Knepley   if (!v) {
3570a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3571a1661176SMatthew Knepley   }
35727827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3573a1661176SMatthew Knepley   PetscFunctionReturn(0);
3574a1661176SMatthew Knepley }
3575a1661176SMatthew Knepley 
3576c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3577af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3578170fe5c8SBarry Smith 
3579170fe5c8SBarry Smith /*
3580170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3581170fe5c8SBarry Smith 
3582170fe5c8SBarry Smith                n                       p                          p
3583170fe5c8SBarry Smith         (              )       (              )         (                  )
3584170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3585170fe5c8SBarry Smith         (              )       (              )         (                  )
3586170fe5c8SBarry Smith 
3587170fe5c8SBarry Smith */
3588170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3589170fe5c8SBarry Smith {
3590170fe5c8SBarry Smith   PetscErrorCode    ierr;
3591170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3592170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3593170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
35941de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3595170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3596170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3597170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3598170fe5c8SBarry Smith 
3599170fe5c8SBarry Smith   PetscFunctionBegin;
3600d0f46423SBarry Smith   m    = A->rmap->n;
3601d0f46423SBarry Smith   n    = A->cmap->n;
3602d0f46423SBarry Smith   p    = B->cmap->n;
3603170fe5c8SBarry Smith   a    = sub_a->v;
3604170fe5c8SBarry Smith   b    = sub_b->a;
3605170fe5c8SBarry Smith   c    = sub_c->v;
3606170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3607170fe5c8SBarry Smith 
3608170fe5c8SBarry Smith   ii  = sub_b->i;
3609170fe5c8SBarry Smith   idx = sub_b->j;
3610170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3611170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3612170fe5c8SBarry Smith     while (q-->0) {
3613170fe5c8SBarry Smith       c_q = c + m*(*idx);
3614170fe5c8SBarry Smith       a_q = a + m*i;
3615854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3616170fe5c8SBarry Smith       idx++;
3617170fe5c8SBarry Smith       b++;
3618170fe5c8SBarry Smith     }
3619170fe5c8SBarry Smith   }
3620170fe5c8SBarry Smith   PetscFunctionReturn(0);
3621170fe5c8SBarry Smith }
3622170fe5c8SBarry Smith 
3623170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3624170fe5c8SBarry Smith {
3625170fe5c8SBarry Smith   PetscErrorCode ierr;
3626d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3627170fe5c8SBarry Smith   Mat            Cmat;
3628170fe5c8SBarry Smith 
3629170fe5c8SBarry Smith   PetscFunctionBegin;
363060e0710aSBarry 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);
3631ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3632170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
363333d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3634170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
36350298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3636d73949e8SHong Zhang 
3637d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
36382205254eSKarl Rupp 
3639170fe5c8SBarry Smith   *C = Cmat;
3640170fe5c8SBarry Smith   PetscFunctionReturn(0);
3641170fe5c8SBarry Smith }
3642170fe5c8SBarry Smith 
3643170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3644150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3645170fe5c8SBarry Smith {
3646170fe5c8SBarry Smith   PetscErrorCode ierr;
3647170fe5c8SBarry Smith 
3648170fe5c8SBarry Smith   PetscFunctionBegin;
3649170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
36503ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3651170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
36523ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3653170fe5c8SBarry Smith   }
36543ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3655170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
36563ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3657170fe5c8SBarry Smith   PetscFunctionReturn(0);
3658170fe5c8SBarry Smith }
3659170fe5c8SBarry Smith 
3660170fe5c8SBarry Smith 
36610bad9183SKris Buschelman /*MC
3662fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
36630bad9183SKris Buschelman    based on compressed sparse row format.
36640bad9183SKris Buschelman 
36650bad9183SKris Buschelman    Options Database Keys:
36660bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
36670bad9183SKris Buschelman 
36680bad9183SKris Buschelman   Level: beginner
36690bad9183SKris Buschelman 
3670f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
36710bad9183SKris Buschelman M*/
36720bad9183SKris Buschelman 
3673ccd284c7SBarry Smith /*MC
3674ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3675ccd284c7SBarry Smith 
3676ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3677ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3678ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3679ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3680ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3681ccd284c7SBarry Smith 
3682ccd284c7SBarry Smith    Options Database Keys:
3683ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3684ccd284c7SBarry Smith 
3685ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3686ccd284c7SBarry Smith    enough exist.
3687ccd284c7SBarry Smith 
3688ccd284c7SBarry Smith   Level: beginner
3689ccd284c7SBarry Smith 
3690ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3691ccd284c7SBarry Smith M*/
3692ccd284c7SBarry Smith 
3693ccd284c7SBarry Smith /*MC
3694ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3695ccd284c7SBarry Smith 
3696ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3697ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3698ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3699ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3700ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3701ccd284c7SBarry Smith 
3702ccd284c7SBarry Smith    Options Database Keys:
3703ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3704ccd284c7SBarry Smith 
3705ccd284c7SBarry Smith   Level: beginner
3706ccd284c7SBarry Smith 
3707ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3708ccd284c7SBarry Smith M*/
3709ccd284c7SBarry Smith 
3710cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3711af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3712cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3713af8000cdSHong Zhang #endif
371463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
371563c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
37163dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
371763c07aadSStefano Zampini #endif
3718cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
371942c9c57cSBarry Smith 
3720b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
372129b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
372229b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3723b3866ffcSBarry Smith #endif
372417667f90SBarry Smith 
3725c0c8ee5eSDmitry Karpeev 
37268c778c55SBarry Smith /*@C
37278c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
37288c778c55SBarry Smith 
37298c778c55SBarry Smith    Not Collective
37308c778c55SBarry Smith 
37318c778c55SBarry Smith    Input Parameter:
3732579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
37338c778c55SBarry Smith 
37348c778c55SBarry Smith    Output Parameter:
37358c778c55SBarry Smith .   array - pointer to the data
37368c778c55SBarry Smith 
37378c778c55SBarry Smith    Level: intermediate
37388c778c55SBarry Smith 
3739774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
37408c778c55SBarry Smith @*/
37418c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
37428c778c55SBarry Smith {
37438c778c55SBarry Smith   PetscErrorCode ierr;
37448c778c55SBarry Smith 
37458c778c55SBarry Smith   PetscFunctionBegin;
37468c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
37478c778c55SBarry Smith   PetscFunctionReturn(0);
37488c778c55SBarry Smith }
37498c778c55SBarry Smith 
375021e72a00SBarry Smith /*@C
375121e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
375221e72a00SBarry Smith 
375321e72a00SBarry Smith    Not Collective
375421e72a00SBarry Smith 
375521e72a00SBarry Smith    Input Parameter:
3756579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
375721e72a00SBarry Smith 
375821e72a00SBarry Smith    Output Parameter:
375921e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
376021e72a00SBarry Smith 
376121e72a00SBarry Smith    Level: intermediate
376221e72a00SBarry Smith 
376321e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
376421e72a00SBarry Smith @*/
376521e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
376621e72a00SBarry Smith {
376721e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
376821e72a00SBarry Smith 
376921e72a00SBarry Smith   PetscFunctionBegin;
377021e72a00SBarry Smith   *nz = aij->rmax;
377121e72a00SBarry Smith   PetscFunctionReturn(0);
377221e72a00SBarry Smith }
377321e72a00SBarry Smith 
37748c778c55SBarry Smith /*@C
3775579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
37768c778c55SBarry Smith 
37778c778c55SBarry Smith    Not Collective
37788c778c55SBarry Smith 
37798c778c55SBarry Smith    Input Parameters:
3780579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
37818c778c55SBarry Smith .  array - pointer to the data
37828c778c55SBarry Smith 
37838c778c55SBarry Smith    Level: intermediate
37848c778c55SBarry Smith 
3785774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
37868c778c55SBarry Smith @*/
37878c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
37888c778c55SBarry Smith {
37898c778c55SBarry Smith   PetscErrorCode ierr;
37908c778c55SBarry Smith 
37918c778c55SBarry Smith   PetscFunctionBegin;
37928c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
37938c778c55SBarry Smith   PetscFunctionReturn(0);
37948c778c55SBarry Smith }
37958c778c55SBarry Smith 
37968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3797273d9f13SBarry Smith {
3798273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3799dfbe8321SBarry Smith   PetscErrorCode ierr;
380038baddfdSBarry Smith   PetscMPIInt    size;
3801273d9f13SBarry Smith 
3802273d9f13SBarry Smith   PetscFunctionBegin;
3803ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3804e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3805273d9f13SBarry Smith 
3806b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
38072205254eSKarl Rupp 
3808b0a32e0cSBarry Smith   B->data = (void*)b;
38092205254eSKarl Rupp 
3810549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
38112205254eSKarl Rupp 
3812416022c9SBarry Smith   b->row                = 0;
3813416022c9SBarry Smith   b->col                = 0;
381482bf6240SBarry Smith   b->icol               = 0;
3815b810aeb4SBarry Smith   b->reallocs           = 0;
381636db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3817f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3818416022c9SBarry Smith   b->nonew              = 0;
3819416022c9SBarry Smith   b->diag               = 0;
3820416022c9SBarry Smith   b->solve_work         = 0;
38212a1b7f2aSHong Zhang   B->spptr              = 0;
3822be6bf707SBarry Smith   b->saved_values       = 0;
3823d7f994e1SBarry Smith   b->idiag              = 0;
382471f1c65dSBarry Smith   b->mdiag              = 0;
382571f1c65dSBarry Smith   b->ssor_work          = 0;
382671f1c65dSBarry Smith   b->omega              = 1.0;
382771f1c65dSBarry Smith   b->fshift             = 0.0;
382871f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3829bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3830a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
383117ab2063SBarry Smith 
383235d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3833bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3834bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
38358c778c55SBarry Smith 
3836b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3837bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3838bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3839b3866ffcSBarry Smith #endif
384017f1a0eaSHong Zhang 
3841bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3842bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3843bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3844bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3845bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3846bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3847bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3848af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3849af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3850af8000cdSHong Zhang #endif
385163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
385263c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
38533dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
385463c07aadSStefano Zampini #endif
3855b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3856bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3857bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3858bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3859bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3860bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3861bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3862bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3863bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
38644108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
386517667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
38663a40ed3dSBarry Smith   PetscFunctionReturn(0);
386717ab2063SBarry Smith }
386817ab2063SBarry Smith 
3869b24902e0SBarry Smith /*
3870b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3871b24902e0SBarry Smith */
3872ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
387317ab2063SBarry Smith {
3874416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
38756849ba73SBarry Smith   PetscErrorCode ierr;
3876d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
387717ab2063SBarry Smith 
38783a40ed3dSBarry Smith   PetscFunctionBegin;
3879273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3880273d9f13SBarry Smith 
3881d5f3da31SBarry Smith   C->factortype = A->factortype;
3882416022c9SBarry Smith   c->row        = 0;
3883416022c9SBarry Smith   c->col        = 0;
388482bf6240SBarry Smith   c->icol       = 0;
38856ad4291fSHong Zhang   c->reallocs   = 0;
388617ab2063SBarry Smith 
38876ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
388817ab2063SBarry Smith 
3889aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3890aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3891eec197d1SBarry Smith 
3892dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
38933bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
389417ab2063SBarry Smith   for (i=0; i<m; i++) {
3895416022c9SBarry Smith     c->imax[i] = a->imax[i];
3896416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
389717ab2063SBarry Smith   }
389817ab2063SBarry Smith 
389917ab2063SBarry Smith   /* allocate the matrix space */
3900f77e22a1SHong Zhang   if (mallocmatspace) {
3901dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
39023bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
39032205254eSKarl Rupp 
3904f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
39052205254eSKarl Rupp 
390697f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
390717ab2063SBarry Smith     if (m > 0) {
390897f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3909be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3910bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3911be6bf707SBarry Smith       } else {
3912bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
391317ab2063SBarry Smith       }
391408480c60SBarry Smith     }
3915f77e22a1SHong Zhang   }
391617ab2063SBarry Smith 
39176ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3918416022c9SBarry Smith   c->roworiented       = a->roworiented;
3919416022c9SBarry Smith   c->nonew             = a->nonew;
3920416022c9SBarry Smith   if (a->diag) {
3921854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
39223bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
392317ab2063SBarry Smith     for (i=0; i<m; i++) {
3924416022c9SBarry Smith       c->diag[i] = a->diag[i];
392517ab2063SBarry Smith     }
39263a40ed3dSBarry Smith   } else c->diag = 0;
39272205254eSKarl Rupp 
39286ad4291fSHong Zhang   c->solve_work         = 0;
39296ad4291fSHong Zhang   c->saved_values       = 0;
39306ad4291fSHong Zhang   c->idiag              = 0;
393171f1c65dSBarry Smith   c->ssor_work          = 0;
3932a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
3933e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
3934e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
39356ad4291fSHong Zhang 
3936893ad86cSHong Zhang   c->rmax         = a->rmax;
3937416022c9SBarry Smith   c->nz           = a->nz;
39388ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
3939273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
3940754ec7b1SSatish Balay 
39416ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
39426ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
3943cd6b891eSBarry Smith   if (a->compressedrow.use) {
39446ad4291fSHong Zhang     i    = a->compressedrow.nrows;
3945dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
39466ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
39476ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
394827ea64f8SHong Zhang   } else {
394927ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
39500298fd71SBarry Smith     c->compressedrow.i      = NULL;
39510298fd71SBarry Smith     c->compressedrow.rindex = NULL;
39526ad4291fSHong Zhang   }
3953ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
3954e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
39554846f1f5SKris Buschelman 
39562205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
3957140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
39583a40ed3dSBarry Smith   PetscFunctionReturn(0);
395917ab2063SBarry Smith }
396017ab2063SBarry Smith 
3961b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
3962b24902e0SBarry Smith {
3963b24902e0SBarry Smith   PetscErrorCode ierr;
3964b24902e0SBarry Smith 
3965b24902e0SBarry Smith   PetscFunctionBegin;
3966ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
39674b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3968cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
396933d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
3970cfd3f464SBarry Smith   }
3971a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
3972f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
3973b24902e0SBarry Smith   PetscFunctionReturn(0);
3974b24902e0SBarry Smith }
3975b24902e0SBarry Smith 
3976112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
3977fbdbba38SShri Abhyankar {
3978fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
3979fbdbba38SShri Abhyankar   PetscErrorCode ierr;
3980fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
3981fbdbba38SShri Abhyankar   int            fd;
3982fbdbba38SShri Abhyankar   PetscMPIInt    size;
3983fbdbba38SShri Abhyankar   MPI_Comm       comm;
39843059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
3985fbdbba38SShri Abhyankar 
3986fbdbba38SShri Abhyankar   PetscFunctionBegin;
3987c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
3988c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
3989fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
3990fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3991fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
3992bbead8a2SBarry Smith 
39930298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
39940298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
3995bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
39963059b6faSBarry Smith   if (bs < 0) bs = 1;
39973059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
3998bbead8a2SBarry Smith 
3999fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4000fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4001fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4002fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4003fbdbba38SShri Abhyankar 
4004bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4005fbdbba38SShri Abhyankar 
4006fbdbba38SShri Abhyankar   /* read in row lengths */
4007785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4008fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4009fbdbba38SShri Abhyankar 
4010fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4011fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
401260e0710aSBarry Smith   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %dD, sum-row-lengths = %D\n",nz,sum);
4013fbdbba38SShri Abhyankar 
4014fbdbba38SShri Abhyankar   /* set global size if not set already*/
4015f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4016fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4017aabbc4fbSShri Abhyankar   } else {
40189d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4019fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
40204c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
40214c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
40224c5b953cSHong Zhang     }
402360e0710aSBarry Smith     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);
4024aabbc4fbSShri Abhyankar   }
4025fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4026fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4027fbdbba38SShri Abhyankar 
4028fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4029fbdbba38SShri Abhyankar 
4030fbdbba38SShri Abhyankar   /* read in nonzero values */
4031fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4032fbdbba38SShri Abhyankar 
4033fbdbba38SShri Abhyankar   /* set matrix "i" values */
4034fbdbba38SShri Abhyankar   a->i[0] = 0;
4035fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4036fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4037fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4038fbdbba38SShri Abhyankar   }
4039fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4040fbdbba38SShri Abhyankar 
4041fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4042fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4043fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4044fbdbba38SShri Abhyankar }
4045fbdbba38SShri Abhyankar 
4046ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
40477264ac53SSatish Balay {
40487264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4049dfbe8321SBarry Smith   PetscErrorCode ierr;
4050eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4051eeffb40dSHong Zhang   PetscInt k;
4052eeffb40dSHong Zhang #endif
40537264ac53SSatish Balay 
40543a40ed3dSBarry Smith   PetscFunctionBegin;
4055bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4056d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4057ca44d042SBarry Smith     *flg = PETSC_FALSE;
4058ca44d042SBarry Smith     PetscFunctionReturn(0);
4059bcd2baecSBarry Smith   }
40607264ac53SSatish Balay 
40617264ac53SSatish Balay   /* if the a->i are the same */
4062d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4063abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
40647264ac53SSatish Balay 
40657264ac53SSatish Balay   /* if a->j are the same */
406697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4067abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4068bcd2baecSBarry Smith 
4069bcd2baecSBarry Smith   /* if a->a are the same */
4070eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4071eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4072eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4073eeffb40dSHong Zhang       *flg = PETSC_FALSE;
40743a40ed3dSBarry Smith       PetscFunctionReturn(0);
4075eeffb40dSHong Zhang     }
4076eeffb40dSHong Zhang   }
4077eeffb40dSHong Zhang #else
4078eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4079eeffb40dSHong Zhang #endif
4080eeffb40dSHong Zhang   PetscFunctionReturn(0);
40817264ac53SSatish Balay }
408236db0b34SBarry Smith 
408305869f15SSatish Balay /*@
408436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
408536db0b34SBarry Smith               provided by the user.
408636db0b34SBarry Smith 
4087c75a6043SHong Zhang       Collective on MPI_Comm
408836db0b34SBarry Smith 
408936db0b34SBarry Smith    Input Parameters:
409036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
409136db0b34SBarry Smith .   m - number of rows
409236db0b34SBarry Smith .   n - number of columns
409336db0b34SBarry Smith .   i - row indices
409436db0b34SBarry Smith .   j - column indices
409536db0b34SBarry Smith -   a - matrix values
409636db0b34SBarry Smith 
409736db0b34SBarry Smith    Output Parameter:
409836db0b34SBarry Smith .   mat - the matrix
409936db0b34SBarry Smith 
410036db0b34SBarry Smith    Level: intermediate
410136db0b34SBarry Smith 
410236db0b34SBarry Smith    Notes:
41030551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4104292fb18eSBarry Smith     once the matrix is destroyed and not before
410536db0b34SBarry Smith 
410636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
410736db0b34SBarry Smith 
4108bfeeae90SHong Zhang        The i and j indices are 0 based
410936db0b34SBarry Smith 
4110a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4111a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
41128eef79e4SBarry Smith     as shown
4113a4552177SSatish Balay 
41148eef79e4SBarry Smith $        1 0 0
41158eef79e4SBarry Smith $        2 0 3
41168eef79e4SBarry Smith $        4 5 6
41178eef79e4SBarry Smith $
41188eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
41198eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
41208eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4121a4552177SSatish Balay 
41229985e31cSBarry Smith 
412369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
412436db0b34SBarry Smith 
412536db0b34SBarry Smith @*/
41267087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
412736db0b34SBarry Smith {
4128dfbe8321SBarry Smith   PetscErrorCode ierr;
4129cbcfb4deSHong Zhang   PetscInt       ii;
413036db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4131cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4132cbcfb4deSHong Zhang   PetscInt jj;
4133cbcfb4deSHong Zhang #endif
413436db0b34SBarry Smith 
413536db0b34SBarry Smith   PetscFunctionBegin;
413641096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4137f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4138f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4139a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4140ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4141ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4142ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4143dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4144ab93d7beSBarry Smith 
414536db0b34SBarry Smith   aij->i            = i;
414636db0b34SBarry Smith   aij->j            = j;
414736db0b34SBarry Smith   aij->a            = a;
414836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
414936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4150e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4151e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
415236db0b34SBarry Smith 
415336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
415436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
41552515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
415660e0710aSBarry 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]);
41579985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4158e32f2f54SBarry 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);
4159e32f2f54SBarry 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);
41609985e31cSBarry Smith     }
416136db0b34SBarry Smith #endif
416236db0b34SBarry Smith   }
41632515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
416436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
416560e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
416660e0710aSBarry 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]);
416736db0b34SBarry Smith   }
416836db0b34SBarry Smith #endif
416936db0b34SBarry Smith 
4170b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4171b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
417236db0b34SBarry Smith   PetscFunctionReturn(0);
417336db0b34SBarry Smith }
417480ef6e79SMatthew G Knepley /*@C
4175d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
41768a0b0e6bSVictor Minden               provided by the user.
41778a0b0e6bSVictor Minden 
41788a0b0e6bSVictor Minden       Collective on MPI_Comm
41798a0b0e6bSVictor Minden 
41808a0b0e6bSVictor Minden    Input Parameters:
41818a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
41828a0b0e6bSVictor Minden .   m   - number of rows
41838a0b0e6bSVictor Minden .   n   - number of columns
41848a0b0e6bSVictor Minden .   i   - row indices
41858a0b0e6bSVictor Minden .   j   - column indices
41861230e6d1SVictor Minden .   a   - matrix values
41871230e6d1SVictor Minden .   nz  - number of nonzeros
41881230e6d1SVictor Minden -   idx - 0 or 1 based
41898a0b0e6bSVictor Minden 
41908a0b0e6bSVictor Minden    Output Parameter:
41918a0b0e6bSVictor Minden .   mat - the matrix
41928a0b0e6bSVictor Minden 
41938a0b0e6bSVictor Minden    Level: intermediate
41948a0b0e6bSVictor Minden 
41958a0b0e6bSVictor Minden    Notes:
41968a0b0e6bSVictor Minden        The i and j indices are 0 based
41978a0b0e6bSVictor Minden 
41988a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
41998a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
42008a0b0e6bSVictor Minden     as shown:
42018a0b0e6bSVictor Minden 
42028a0b0e6bSVictor Minden         1 0 0
42038a0b0e6bSVictor Minden         2 0 3
42048a0b0e6bSVictor Minden         4 5 6
42058a0b0e6bSVictor Minden 
42068a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
42078a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
42088a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
42098a0b0e6bSVictor Minden 
42108a0b0e6bSVictor Minden 
421169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
42128a0b0e6bSVictor Minden 
42138a0b0e6bSVictor Minden @*/
42141230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
42158a0b0e6bSVictor Minden {
42168a0b0e6bSVictor Minden   PetscErrorCode ierr;
4217d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
42188a0b0e6bSVictor Minden 
42198a0b0e6bSVictor Minden 
42208a0b0e6bSVictor Minden   PetscFunctionBegin;
42211795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
42221230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4223c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
42241230e6d1SVictor Minden   }
42258a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
42268a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
42278a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
42281230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
42291230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
42301230e6d1SVictor Minden     if (idx) {
42311230e6d1SVictor Minden       row = i[ii] - 1;
42321230e6d1SVictor Minden       col = j[ii] - 1;
42331230e6d1SVictor Minden     } else {
42341230e6d1SVictor Minden       row = i[ii];
42351230e6d1SVictor Minden       col = j[ii];
42368a0b0e6bSVictor Minden     }
42371230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
42388a0b0e6bSVictor Minden   }
42398a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
42408a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4241d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
42428a0b0e6bSVictor Minden   PetscFunctionReturn(0);
42438a0b0e6bSVictor Minden }
424436db0b34SBarry Smith 
4245acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4246acf2f550SJed Brown {
4247acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4248acf2f550SJed Brown   PetscErrorCode ierr;
4249acf2f550SJed Brown 
4250acf2f550SJed Brown   PetscFunctionBegin;
4251acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4252acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
42532205254eSKarl Rupp 
4254acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4255acf2f550SJed Brown   PetscFunctionReturn(0);
4256acf2f550SJed Brown }
4257acf2f550SJed Brown 
42589c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
42599c8f2541SHong Zhang {
42609c8f2541SHong Zhang   PetscErrorCode ierr;
42619c8f2541SHong Zhang 
42629c8f2541SHong Zhang   PetscFunctionBegin;
42639c8f2541SHong Zhang   ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
42649c8f2541SHong Zhang   PetscFunctionReturn(0);
42659c8f2541SHong Zhang }
42669c8f2541SHong Zhang 
426781824310SBarry Smith /*
426853dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
426953dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
427053dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
427153dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
427253dd7562SDmitry Karpeev  */
427353dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
427453dd7562SDmitry Karpeev {
427553dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
427653dd7562SDmitry Karpeev   PetscErrorCode ierr;
427753dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
427853dd7562SDmitry Karpeev   PetscBool      seqaij;
427953dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
428053dd7562SDmitry Karpeev   PetscScalar    v;
428153dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
428253dd7562SDmitry Karpeev 
428353dd7562SDmitry Karpeev   PetscFunctionBegin;
428453dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
428553dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
428653dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
428753dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
428853dd7562SDmitry Karpeev   if (rowemb) {
428953dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
429053dd7562SDmitry Karpeev     if (m != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %D is incompatible with matrix row size %D",m,B->rmap->n);
429153dd7562SDmitry Karpeev   } else {
42926c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
429353dd7562SDmitry Karpeev   }
429453dd7562SDmitry Karpeev   if (colemb) {
429553dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
429653dd7562SDmitry Karpeev     if (n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %D is incompatible with input matrix col size %D",n,B->cmap->n);
429753dd7562SDmitry Karpeev   } else {
429853dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
429953dd7562SDmitry Karpeev   }
430053dd7562SDmitry Karpeev 
430153dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
430253dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
430353dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
430453dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
430553dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
430653dd7562SDmitry Karpeev     }
430753dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
430853dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
430953dd7562SDmitry Karpeev   }
431053dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
431153dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
431253dd7562SDmitry Karpeev   }
431353dd7562SDmitry Karpeev   count = 0;
431453dd7562SDmitry Karpeev   rowindices = NULL;
431553dd7562SDmitry Karpeev   colindices = NULL;
431653dd7562SDmitry Karpeev   if (rowemb) {
431753dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
431853dd7562SDmitry Karpeev   }
431953dd7562SDmitry Karpeev   if (colemb) {
432053dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
432153dd7562SDmitry Karpeev   }
432253dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
432353dd7562SDmitry Karpeev     PetscInt row;
432453dd7562SDmitry Karpeev     row = i;
432553dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
432653dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
432753dd7562SDmitry Karpeev       PetscInt col;
432853dd7562SDmitry Karpeev       col  = Baij->j[count];
432953dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
433053dd7562SDmitry Karpeev       v    = Baij->a[count];
433153dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
433253dd7562SDmitry Karpeev       ++count;
433353dd7562SDmitry Karpeev     }
433453dd7562SDmitry Karpeev   }
433553dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
433653dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
433753dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
433853dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
433953dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
434053dd7562SDmitry Karpeev   PetscFunctionReturn(0);
434153dd7562SDmitry Karpeev }
434253dd7562SDmitry Karpeev 
434353dd7562SDmitry Karpeev 
434453dd7562SDmitry Karpeev /*
434581824310SBarry Smith     Special version for direct calls from Fortran
434681824310SBarry Smith */
4347af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
434881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
434981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
435081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
435181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
435281824310SBarry Smith #endif
435381824310SBarry Smith 
435481824310SBarry Smith /* Change these macros so can be used in void function */
435581824310SBarry Smith #undef CHKERRQ
4356ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
435781824310SBarry Smith #undef SETERRQ2
4358e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
43594994cf47SJed Brown #undef SETERRQ3
43604994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
436181824310SBarry Smith 
43628cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
436381824310SBarry Smith {
436481824310SBarry Smith   Mat            A  = *AA;
436581824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
436681824310SBarry Smith   InsertMode     is = *isis;
436781824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
436881824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
436981824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
437081824310SBarry Smith   PetscErrorCode ierr;
437181824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
437254f21887SBarry Smith   MatScalar      *ap,value,*aa;
4373ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4374ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
437581824310SBarry Smith 
437681824310SBarry Smith   PetscFunctionBegin;
43774994cf47SJed Brown   MatCheckPreallocated(A,1);
437881824310SBarry Smith   imax  = a->imax;
437981824310SBarry Smith   ai    = a->i;
438081824310SBarry Smith   ailen = a->ilen;
438181824310SBarry Smith   aj    = a->j;
438281824310SBarry Smith   aa    = a->a;
438381824310SBarry Smith 
438481824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
438581824310SBarry Smith     row = im[k];
438681824310SBarry Smith     if (row < 0) continue;
438781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4388ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
438981824310SBarry Smith #endif
439081824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
439181824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
439281824310SBarry Smith     low  = 0;
439381824310SBarry Smith     high = nrow;
439481824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
439581824310SBarry Smith       if (in[l] < 0) continue;
439681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4397ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
439881824310SBarry Smith #endif
439981824310SBarry Smith       col = in[l];
44002205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
44012205254eSKarl Rupp       else value = v[k + l*m];
44022205254eSKarl Rupp 
440381824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
440481824310SBarry Smith 
44052205254eSKarl Rupp       if (col <= lastcol) low = 0;
44062205254eSKarl Rupp       else high = nrow;
440781824310SBarry Smith       lastcol = col;
440881824310SBarry Smith       while (high-low > 5) {
440981824310SBarry Smith         t = (low+high)/2;
441081824310SBarry Smith         if (rp[t] > col) high = t;
441181824310SBarry Smith         else             low  = t;
441281824310SBarry Smith       }
441381824310SBarry Smith       for (i=low; i<high; i++) {
441481824310SBarry Smith         if (rp[i] > col) break;
441581824310SBarry Smith         if (rp[i] == col) {
441681824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
441781824310SBarry Smith           else                  ap[i] = value;
441881824310SBarry Smith           goto noinsert;
441981824310SBarry Smith         }
442081824310SBarry Smith       }
442181824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
442281824310SBarry Smith       if (nonew == 1) goto noinsert;
4423ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4424fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
442581824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
442681824310SBarry Smith       /* shift up all the later entries in this row */
442781824310SBarry Smith       for (ii=N; ii>=i; ii--) {
442881824310SBarry Smith         rp[ii+1] = rp[ii];
442981824310SBarry Smith         ap[ii+1] = ap[ii];
443081824310SBarry Smith       }
443181824310SBarry Smith       rp[i] = col;
443281824310SBarry Smith       ap[i] = value;
4433e56f5c9eSBarry Smith       A->nonzerostate++;
443481824310SBarry Smith noinsert:;
443581824310SBarry Smith       low = i + 1;
443681824310SBarry Smith     }
443781824310SBarry Smith     ailen[row] = nrow;
443881824310SBarry Smith   }
443981824310SBarry Smith   PetscFunctionReturnVoid();
444081824310SBarry Smith }
44419f7953f8SBarry Smith 
4442