xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 957cac9f980ff6dd21f1a82ba84abdda2c18b08c)
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       }
433dcd36c23SBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) 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       }
452dcd36c23SBarry Smith       if (value == 0.0 && ignorezeroentries && row != col) 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;
56143e49210SHong Zhang   if (!a->a) PetscFunctionReturn(0);
56243e49210SHong Zhang 
563b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
56471c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
56597f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
56660e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
567c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
568d00d2cf4SBarry Smith       nofinalvalue = 1;
569d00d2cf4SBarry Smith     }
570d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
571d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
57277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
573fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
574fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
575fbfe6fa7SJed Brown #else
57677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
577fbfe6fa7SJed Brown #endif
578b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
57917ab2063SBarry Smith 
58017ab2063SBarry Smith     for (i=0; i<m; i++) {
58160e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
582aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
583a9bf72d8SJed 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);
58417ab2063SBarry Smith #else
58560e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
58617ab2063SBarry Smith #endif
58717ab2063SBarry Smith       }
58817ab2063SBarry Smith     }
589d00d2cf4SBarry Smith     if (nofinalvalue) {
590c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
591c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
592c337ccceSJed Brown #else
593d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
594c337ccceSJed Brown #endif
595d00d2cf4SBarry Smith     }
596317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
597fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
598d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
59968369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
600cd155464SBarry Smith     PetscFunctionReturn(0);
601fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
602d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
60344cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
60477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
60560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
606aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
60736db0b34SBarry Smith         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 (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
61060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
61136db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
61260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6136831982aSBarry Smith         }
61444cd7ae7SLois Curfman McInnes #else
61560e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
61644cd7ae7SLois Curfman McInnes #endif
61744cd7ae7SLois Curfman McInnes       }
618b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
61944cd7ae7SLois Curfman McInnes     }
620d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
621fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
62297f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
623d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
624854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
625496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
626496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
62760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
628496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
629aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
63036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
631496be53dSLois Curfman McInnes #else
632496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
633496be53dSLois Curfman McInnes #endif
634496be53dSLois Curfman McInnes         }
635496be53dSLois Curfman McInnes       }
636496be53dSLois Curfman McInnes     }
6372e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
63877431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6392e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6402205254eSKarl Rupp       if (i+4<m) {
6412205254eSKarl 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);
6422205254eSKarl Rupp       } else if (i+3<m) {
6432205254eSKarl 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);
6442205254eSKarl Rupp       } else if (i+2<m) {
6452205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6462205254eSKarl Rupp       } else if (i+1<m) {
6472205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6482205254eSKarl Rupp       } else if (i<m) {
6492205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6502205254eSKarl Rupp       } else {
6512205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6522205254eSKarl Rupp       }
653496be53dSLois Curfman McInnes     }
654b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
655606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
656496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
65760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
65877431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
659496be53dSLois Curfman McInnes       }
660b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
661496be53dSLois Curfman McInnes     }
662b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
663496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
66460e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
665496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
666aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66736db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
66860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6696831982aSBarry Smith           }
670496be53dSLois Curfman McInnes #else
67160e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
672496be53dSLois Curfman McInnes #endif
673496be53dSLois Curfman McInnes         }
674496be53dSLois Curfman McInnes       }
675b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
676496be53dSLois Curfman McInnes     }
677d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
678fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
67997f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
68087828ca2SBarry Smith     PetscScalar value;
68168f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
68268f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
68368f1ed48SBarry Smith 
68468f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
68568f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
68668f1ed48SBarry Smith         realonly = PETSC_FALSE;
68768f1ed48SBarry Smith         break;
68868f1ed48SBarry Smith       }
68968f1ed48SBarry Smith     }
69068f1ed48SBarry Smith #endif
69102594712SBarry Smith 
692d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
69302594712SBarry Smith     for (i=0; i<m; i++) {
69402594712SBarry Smith       jcnt = 0;
695d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
696e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
69702594712SBarry Smith           value = a->a[cnt++];
698e24b481bSBarry Smith           jcnt++;
69902594712SBarry Smith         } else {
70002594712SBarry Smith           value = 0.0;
70102594712SBarry Smith         }
702aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70368f1ed48SBarry Smith         if (realonly) {
70460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
70568f1ed48SBarry Smith         } else {
70660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
70768f1ed48SBarry Smith         }
70802594712SBarry Smith #else
70960e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
71002594712SBarry Smith #endif
71102594712SBarry Smith       }
712b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
71302594712SBarry Smith     }
714d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7153c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
716150b93efSMatthew G. Knepley     PetscInt fshift=1;
717d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7183c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
71919303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7203c215bfdSMatthew Knepley #else
72119303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7223c215bfdSMatthew Knepley #endif
723d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7243c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
72560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7263c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
727a9a0e077SKarl 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);
7283c215bfdSMatthew Knepley #else
729150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7303c215bfdSMatthew Knepley #endif
7313c215bfdSMatthew Knepley       }
7323c215bfdSMatthew Knepley     }
733d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7343a40ed3dSBarry Smith   } else {
735d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
736d5f3da31SBarry Smith     if (A->factortype) {
73716cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
73816cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
73916cd7e1dSShri Abhyankar         /* L part */
74060e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
74116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
74216cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
74360e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) {
7456712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
74616cd7e1dSShri Abhyankar           } else {
74760e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
74816cd7e1dSShri Abhyankar           }
74916cd7e1dSShri Abhyankar #else
75060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
75116cd7e1dSShri Abhyankar #endif
75216cd7e1dSShri Abhyankar         }
75316cd7e1dSShri Abhyankar         /* diagonal */
75416cd7e1dSShri Abhyankar         j = a->diag[i];
75516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
75616cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
75760e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) {
7596712e2f1SBarry 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);
76016cd7e1dSShri Abhyankar         } else {
76160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
76216cd7e1dSShri Abhyankar         }
76316cd7e1dSShri Abhyankar #else
76460e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
76516cd7e1dSShri Abhyankar #endif
76616cd7e1dSShri Abhyankar 
76716cd7e1dSShri Abhyankar         /* U part */
76860e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
76916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
77016cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
77160e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) {
77322ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
77416cd7e1dSShri Abhyankar           } else {
77560e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
77616cd7e1dSShri Abhyankar           }
77716cd7e1dSShri Abhyankar #else
77860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
77916cd7e1dSShri Abhyankar #endif
78016cd7e1dSShri Abhyankar         }
78116cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
78216cd7e1dSShri Abhyankar       }
78316cd7e1dSShri Abhyankar     } else {
78417ab2063SBarry Smith       for (i=0; i<m; i++) {
78577431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
78660e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
787aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
78836db0b34SBarry Smith           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);
79036db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
79160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7923a40ed3dSBarry Smith           } else {
79360e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
79417ab2063SBarry Smith           }
79517ab2063SBarry Smith #else
79660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
79717ab2063SBarry Smith #endif
79817ab2063SBarry Smith         }
799b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
80017ab2063SBarry Smith       }
80116cd7e1dSShri Abhyankar     }
802d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
80317ab2063SBarry Smith   }
804b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8053a40ed3dSBarry Smith   PetscFunctionReturn(0);
806416022c9SBarry Smith }
807416022c9SBarry Smith 
8089804daf3SBarry Smith #include <petscdraw.h>
809dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
810416022c9SBarry Smith {
811480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
812416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
813dfbe8321SBarry Smith   PetscErrorCode    ierr;
814383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
815383922c3SLisandro Dalcin   int               color;
816b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
817b0a32e0cSBarry Smith   PetscViewer       viewer;
818f3ef73ceSBarry Smith   PetscViewerFormat format;
819cddf8d76SBarry Smith 
8203a40ed3dSBarry Smith   PetscFunctionBegin;
821480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
822b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
823b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
824383922c3SLisandro Dalcin 
825416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8260513a670SBarry Smith 
827fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
828383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8290513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
830b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
831416022c9SBarry Smith     for (i=0; i<m; i++) {
832cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
833bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
834bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
83536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
836b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
837cddf8d76SBarry Smith       }
838cddf8d76SBarry Smith     }
839b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
840cddf8d76SBarry Smith     for (i=0; i<m; i++) {
841cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
842bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
843bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
844cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
845b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
846cddf8d76SBarry Smith       }
847cddf8d76SBarry Smith     }
848b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
849cddf8d76SBarry Smith     for (i=0; i<m; i++) {
850cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
851bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
852bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
85336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
854b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
855416022c9SBarry Smith       }
856416022c9SBarry Smith     }
857383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8580513a670SBarry Smith   } else {
8590513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8600513a670SBarry Smith     /* first determine max of all nonzero values */
861b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
862383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
863b0a32e0cSBarry Smith     PetscDraw popup;
8640513a670SBarry Smith 
8650513a670SBarry Smith     for (i=0; i<nz; i++) {
8660513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8670513a670SBarry Smith     }
868383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
869b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
87045f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
871383922c3SLisandro Dalcin 
872383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8730513a670SBarry Smith     for (i=0; i<m; i++) {
874383922c3SLisandro Dalcin       y_l = m - i - 1.0;
875383922c3SLisandro Dalcin       y_r = y_l + 1.0;
876bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
877383922c3SLisandro Dalcin         x_l = a->j[j];
878383922c3SLisandro Dalcin         x_r = x_l + 1.0;
879b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
880b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8810513a670SBarry Smith         count++;
8820513a670SBarry Smith       }
8830513a670SBarry Smith     }
884383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8850513a670SBarry Smith   }
886480ef9eaSBarry Smith   PetscFunctionReturn(0);
887480ef9eaSBarry Smith }
888cddf8d76SBarry Smith 
8899804daf3SBarry Smith #include <petscdraw.h>
890dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
891480ef9eaSBarry Smith {
892dfbe8321SBarry Smith   PetscErrorCode ierr;
893b0a32e0cSBarry Smith   PetscDraw      draw;
89436db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
895ace3abfcSBarry Smith   PetscBool      isnull;
896480ef9eaSBarry Smith 
897480ef9eaSBarry Smith   PetscFunctionBegin;
898b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
899b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
900480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
901480ef9eaSBarry Smith 
902d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
903480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
904b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
905832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
906b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9070298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
908832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9093a40ed3dSBarry Smith   PetscFunctionReturn(0);
910416022c9SBarry Smith }
911416022c9SBarry Smith 
912dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
913416022c9SBarry Smith {
914dfbe8321SBarry Smith   PetscErrorCode ierr;
915ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
916416022c9SBarry Smith 
9173a40ed3dSBarry Smith   PetscFunctionBegin;
918251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
919251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
920251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
921c45a1595SBarry Smith   if (iascii) {
9223a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9230f5bd95cSBarry Smith   } else if (isbinary) {
9243a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9250f5bd95cSBarry Smith   } else if (isdraw) {
9263a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
92711aeaf0aSBarry Smith   }
9284108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9293a40ed3dSBarry Smith   PetscFunctionReturn(0);
93017ab2063SBarry Smith }
93119bcc07fSBarry Smith 
932dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
93317ab2063SBarry Smith {
934416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9356849ba73SBarry Smith   PetscErrorCode ierr;
93697f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
937d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
93854f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9393447b6efSHong Zhang   PetscReal      ratio  = 0.6;
94017ab2063SBarry Smith 
9413a40ed3dSBarry Smith   PetscFunctionBegin;
9423a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
94317ab2063SBarry Smith 
94443ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
94517ab2063SBarry Smith   for (i=1; i<m; i++) {
946416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
94717ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
94894a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
94917ab2063SBarry Smith     if (fshift) {
950bfeeae90SHong Zhang       ip = aj + ai[i];
951bfeeae90SHong Zhang       ap = aa + ai[i];
95217ab2063SBarry Smith       N  = ailen[i];
95317ab2063SBarry Smith       for (j=0; j<N; j++) {
95417ab2063SBarry Smith         ip[j-fshift] = ip[j];
95517ab2063SBarry Smith         ap[j-fshift] = ap[j];
95617ab2063SBarry Smith       }
95717ab2063SBarry Smith     }
95817ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
95917ab2063SBarry Smith   }
96017ab2063SBarry Smith   if (m) {
96117ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
96217ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
96317ab2063SBarry Smith   }
9647b083b7cSBarry Smith 
96517ab2063SBarry Smith   /* reset ilen and imax for each row */
9667b083b7cSBarry Smith   a->nonzerorowcnt = 0;
96717ab2063SBarry Smith   for (i=0; i<m; i++) {
96817ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9697b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
97017ab2063SBarry Smith   }
971bfeeae90SHong Zhang   a->nz = ai[m];
97265e19b50SBarry 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);
97317ab2063SBarry Smith 
97409f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
975d0f46423SBarry 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);
976ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
977ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9782205254eSKarl Rupp 
9798e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
980dd5f02e7SSatish Balay   a->reallocs         = 0;
9816712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
98236db0b34SBarry Smith   a->rmax             = rmax;
9834e220ebcSLois Curfman McInnes 
98411e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9854108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
986acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9873a40ed3dSBarry Smith   PetscFunctionReturn(0);
98817ab2063SBarry Smith }
98917ab2063SBarry Smith 
99099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
99199cafbc1SBarry Smith {
99299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
99399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
99454f21887SBarry Smith   MatScalar      *aa = a->a;
995acf2f550SJed Brown   PetscErrorCode ierr;
99699cafbc1SBarry Smith 
99799cafbc1SBarry Smith   PetscFunctionBegin;
99899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
999acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
100099cafbc1SBarry Smith   PetscFunctionReturn(0);
100199cafbc1SBarry Smith }
100299cafbc1SBarry Smith 
100399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
100499cafbc1SBarry Smith {
100599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
100699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
100754f21887SBarry Smith   MatScalar      *aa = a->a;
1008acf2f550SJed Brown   PetscErrorCode ierr;
100999cafbc1SBarry Smith 
101099cafbc1SBarry Smith   PetscFunctionBegin;
101199cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1012acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101399cafbc1SBarry Smith   PetscFunctionReturn(0);
101499cafbc1SBarry Smith }
101599cafbc1SBarry Smith 
1016dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
101717ab2063SBarry Smith {
1018416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1019dfbe8321SBarry Smith   PetscErrorCode ierr;
10203a40ed3dSBarry Smith 
10213a40ed3dSBarry Smith   PetscFunctionBegin;
1022d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1023acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10243a40ed3dSBarry Smith   PetscFunctionReturn(0);
102517ab2063SBarry Smith }
1026416022c9SBarry Smith 
1027dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
102817ab2063SBarry Smith {
1029416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1030dfbe8321SBarry Smith   PetscErrorCode ierr;
1031d5d45c9bSBarry Smith 
10323a40ed3dSBarry Smith   PetscFunctionBegin;
1033aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1034d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
103517ab2063SBarry Smith #endif
1036e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10376bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10386bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
103905b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1040d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
104105b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
104271f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
104305b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10446bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
104505b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10466bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1047cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10480b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1049a30b2313SHong Zhang 
10504108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1051bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1052901853e0SKris Buschelman 
1053dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1058bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1059bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1060af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1061af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1062af8000cdSHong Zhang #endif
106363c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
106463c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
10653dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
106663c07aadSStefano Zampini #endif
1067b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1069bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1070bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1071bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10723a40ed3dSBarry Smith   PetscFunctionReturn(0);
107317ab2063SBarry Smith }
107417ab2063SBarry Smith 
1075ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
107617ab2063SBarry Smith {
1077416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10784846f1f5SKris Buschelman   PetscErrorCode ierr;
10793a40ed3dSBarry Smith 
10803a40ed3dSBarry Smith   PetscFunctionBegin;
1081a65d3064SKris Buschelman   switch (op) {
1082a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10834e0d8c25SBarry Smith     a->roworiented = flg;
1084a65d3064SKris Buschelman     break;
1085a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1086a9817697SBarry Smith     a->keepnonzeropattern = flg;
1087a65d3064SKris Buschelman     break;
1088512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1089512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1090a65d3064SKris Buschelman     break;
1091a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10924e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1093a65d3064SKris Buschelman     break;
1094a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10954e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1096a65d3064SKris Buschelman     break;
109728b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
109828b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
109928b2fa4aSMatthew Knepley     break;
1100a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11014e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11020df259c2SBarry Smith     break;
11033d472b54SHong Zhang   case MAT_SPD:
1104b1646e73SJed Brown   case MAT_SYMMETRIC:
1105b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1106b1646e73SJed Brown   case MAT_HERMITIAN:
1107b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1108*957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11095021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11105021d80fSJed Brown     break;
11114e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1112a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1113a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1114290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1115a65d3064SKris Buschelman     break;
1116b87ac2d8SJed Brown   case MAT_USE_INODES:
1117b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1118b87ac2d8SJed Brown     break;
1119c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1120c10200c1SHong Zhang     A->submat_singleis = flg;
1121c10200c1SHong Zhang     break;
1122a65d3064SKris Buschelman   default:
1123e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1124a65d3064SKris Buschelman   }
11254108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11263a40ed3dSBarry Smith   PetscFunctionReturn(0);
112717ab2063SBarry Smith }
112817ab2063SBarry Smith 
1129dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
113017ab2063SBarry Smith {
1131416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11326849ba73SBarry Smith   PetscErrorCode ierr;
1133d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
113435e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
113517ab2063SBarry Smith 
11363a40ed3dSBarry Smith   PetscFunctionBegin;
1137d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1138e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
113935e7444dSHong Zhang 
1140d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1141d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
114235e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11432c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
114435e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
114535e7444dSHong Zhang     PetscFunctionReturn(0);
114635e7444dSHong Zhang   }
114735e7444dSHong Zhang 
11482dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11491ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
115035e7444dSHong Zhang   for (i=0; i<n; i++) {
115135e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11522f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
115335e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
115435e7444dSHong Zhang       if (aj[j] == i) {
115535e7444dSHong Zhang         x[i] = aa[j];
115617ab2063SBarry Smith         break;
115717ab2063SBarry Smith       }
115817ab2063SBarry Smith     }
115917ab2063SBarry Smith   }
11601ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11613a40ed3dSBarry Smith   PetscFunctionReturn(0);
116217ab2063SBarry Smith }
116317ab2063SBarry Smith 
1164c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1165dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
116617ab2063SBarry Smith {
1167416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1168d9ca1df4SBarry Smith   PetscScalar       *y;
1169d9ca1df4SBarry Smith   const PetscScalar *x;
1170dfbe8321SBarry Smith   PetscErrorCode    ierr;
1171d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
11725c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1173d9ca1df4SBarry Smith   const MatScalar   *v;
1174a77337e4SBarry Smith   PetscScalar       alpha;
1175d9ca1df4SBarry Smith   PetscInt          n,i,j;
1176d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
11773447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1178ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11795c897100SBarry Smith #endif
118017ab2063SBarry Smith 
11813a40ed3dSBarry Smith   PetscFunctionBegin;
11822e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1183d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11855c897100SBarry Smith 
11865c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1187bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11885c897100SBarry Smith #else
11893447b6efSHong Zhang   if (usecprow) {
11903447b6efSHong Zhang     m    = cprow.nrows;
11913447b6efSHong Zhang     ii   = cprow.i;
11927b2bb3b9SHong Zhang     ridx = cprow.rindex;
11933447b6efSHong Zhang   } else {
11943447b6efSHong Zhang     ii = a->i;
11953447b6efSHong Zhang   }
119617ab2063SBarry Smith   for (i=0; i<m; i++) {
11973447b6efSHong Zhang     idx = a->j + ii[i];
11983447b6efSHong Zhang     v   = a->a + ii[i];
11993447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12003447b6efSHong Zhang     if (usecprow) {
12017b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12023447b6efSHong Zhang     } else {
120317ab2063SBarry Smith       alpha = x[i];
12043447b6efSHong Zhang     }
120504fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
120617ab2063SBarry Smith   }
12075c897100SBarry Smith #endif
1208dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1209d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12101ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12113a40ed3dSBarry Smith   PetscFunctionReturn(0);
121217ab2063SBarry Smith }
121317ab2063SBarry Smith 
1214dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12155c897100SBarry Smith {
1216dfbe8321SBarry Smith   PetscErrorCode ierr;
12175c897100SBarry Smith 
12185c897100SBarry Smith   PetscFunctionBegin;
1219170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12205c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12215c897100SBarry Smith   PetscFunctionReturn(0);
12225c897100SBarry Smith }
12235c897100SBarry Smith 
1224c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
122578b84d54SShri Abhyankar 
1226dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
122717ab2063SBarry Smith {
1228416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1229d9fead3dSBarry Smith   PetscScalar       *y;
123054f21887SBarry Smith   const PetscScalar *x;
123154f21887SBarry Smith   const MatScalar   *aa;
1232dfbe8321SBarry Smith   PetscErrorCode    ierr;
1233003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12340298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12357b083b7cSBarry Smith   PetscInt          n,i;
1236362ced78SSatish Balay   PetscScalar       sum;
1237ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
123817ab2063SBarry Smith 
1239b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
124097952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1241fee21e36SBarry Smith #endif
1242fee21e36SBarry Smith 
12433a40ed3dSBarry Smith   PetscFunctionBegin;
12443649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12451ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1246416022c9SBarry Smith   ii   = a->i;
12474eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12484f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
124997952fefSHong Zhang     m    = a->compressedrow.nrows;
125097952fefSHong Zhang     ii   = a->compressedrow.i;
125197952fefSHong Zhang     ridx = a->compressedrow.rindex;
125297952fefSHong Zhang     for (i=0; i<m; i++) {
125397952fefSHong Zhang       n           = ii[i+1] - ii[i];
125497952fefSHong Zhang       aj          = a->j + ii[i];
125597952fefSHong Zhang       aa          = a->a + ii[i];
125697952fefSHong Zhang       sum         = 0.0;
1257003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1258003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
125997952fefSHong Zhang       y[*ridx++] = sum;
126097952fefSHong Zhang     }
126197952fefSHong Zhang   } else { /* do not use compressed row format */
1262b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
12633d3eaba7SBarry Smith     aj   = a->j;
12643d3eaba7SBarry Smith     aa   = a->a;
1265b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1266b05257ddSBarry Smith #else
126717ab2063SBarry Smith     for (i=0; i<m; i++) {
1268003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1269003131ecSBarry Smith       aj          = a->j + ii[i];
1270003131ecSBarry Smith       aa          = a->a + ii[i];
127117ab2063SBarry Smith       sum         = 0.0;
1272003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
127317ab2063SBarry Smith       y[i] = sum;
127417ab2063SBarry Smith     }
12758d195f9aSBarry Smith #endif
1276b05257ddSBarry Smith   }
12777b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
12783649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12791ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12803a40ed3dSBarry Smith   PetscFunctionReturn(0);
128117ab2063SBarry Smith }
128217ab2063SBarry Smith 
1283b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1284b434eb95SMatthew G. Knepley {
1285b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1286b434eb95SMatthew G. Knepley   PetscScalar       *y;
1287b434eb95SMatthew G. Knepley   const PetscScalar *x;
1288b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1289b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1290b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1291b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1292b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1293b434eb95SMatthew G. Knepley   PetscScalar       sum;
1294b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1295b434eb95SMatthew G. Knepley 
1296b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1297b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1298b434eb95SMatthew G. Knepley #endif
1299b434eb95SMatthew G. Knepley 
1300b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1301b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1302b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1303b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1304b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1305b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1306b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1307b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1308b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1309b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1310b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1311b434eb95SMatthew G. Knepley       sum         = 0.0;
1312b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1313b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1314b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1315b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1316b434eb95SMatthew G. Knepley     }
1317b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13183d3eaba7SBarry Smith     ii = a->i;
1319b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1320b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1321b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1322b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1323b434eb95SMatthew G. Knepley       sum         = 0.0;
1324b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1325b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1326b434eb95SMatthew G. Knepley       y[i] = sum;
1327b434eb95SMatthew G. Knepley     }
1328b434eb95SMatthew G. Knepley   }
1329b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1330b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1331b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1332b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1333b434eb95SMatthew G. Knepley }
1334b434eb95SMatthew G. Knepley 
1335b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1336b434eb95SMatthew G. Knepley {
1337b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1338b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1339b434eb95SMatthew G. Knepley   const PetscScalar *x;
1340b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1341b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1342b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1343b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1344b434eb95SMatthew G. Knepley   PetscScalar       sum;
1345b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1346b434eb95SMatthew G. Knepley 
1347b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1348b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1349d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1350b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1351b434eb95SMatthew G. Knepley     if (zz != yy) {
1352b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1353b434eb95SMatthew G. Knepley     }
1354b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1355b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1356b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1357b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1358b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1359b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1360b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1361b434eb95SMatthew G. Knepley       sum = y[*ridx];
1362b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1363b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1364b434eb95SMatthew G. Knepley     }
1365b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13663d3eaba7SBarry Smith     ii = a->i;
1367b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1368b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1369b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1370b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1371b434eb95SMatthew G. Knepley       sum = y[i];
1372b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1373b434eb95SMatthew G. Knepley       z[i] = sum;
1374b434eb95SMatthew G. Knepley     }
1375b434eb95SMatthew G. Knepley   }
1376b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1377b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1378d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1379b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1380b434eb95SMatthew G. Knepley }
1381b434eb95SMatthew G. Knepley 
1382c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1383dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
138417ab2063SBarry Smith {
1385416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1386f15663dcSBarry Smith   PetscScalar       *y,*z;
1387f15663dcSBarry Smith   const PetscScalar *x;
138854f21887SBarry Smith   const MatScalar   *aa;
1389dfbe8321SBarry Smith   PetscErrorCode    ierr;
1390d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1391d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1392362ced78SSatish Balay   PetscScalar       sum;
1393ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
13949ea0dfa2SSatish Balay 
13953a40ed3dSBarry Smith   PetscFunctionBegin;
1396f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1397d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
13984eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
13994eb6d288SHong Zhang     if (zz != yy) {
14004eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14014eb6d288SHong Zhang     }
140297952fefSHong Zhang     m    = a->compressedrow.nrows;
140397952fefSHong Zhang     ii   = a->compressedrow.i;
140497952fefSHong Zhang     ridx = a->compressedrow.rindex;
140597952fefSHong Zhang     for (i=0; i<m; i++) {
140697952fefSHong Zhang       n   = ii[i+1] - ii[i];
140797952fefSHong Zhang       aj  = a->j + ii[i];
140897952fefSHong Zhang       aa  = a->a + ii[i];
140997952fefSHong Zhang       sum = y[*ridx];
1410f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
141197952fefSHong Zhang       z[*ridx++] = sum;
141297952fefSHong Zhang     }
141397952fefSHong Zhang   } else { /* do not use compressed row format */
14143d3eaba7SBarry Smith     ii = a->i;
1415f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14163d3eaba7SBarry Smith     aj = a->j;
14173d3eaba7SBarry Smith     aa = a->a;
1418f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1419f15663dcSBarry Smith #else
142017ab2063SBarry Smith     for (i=0; i<m; i++) {
1421f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1422f15663dcSBarry Smith       aj  = a->j + ii[i];
1423f15663dcSBarry Smith       aa  = a->a + ii[i];
142417ab2063SBarry Smith       sum = y[i];
1425f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142617ab2063SBarry Smith       z[i] = sum;
142717ab2063SBarry Smith     }
142802ab625aSSatish Balay #endif
1429f15663dcSBarry Smith   }
1430dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1431f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1432d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14338154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14346b375ea7SVictor Minden   /*
1435918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1436918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1437918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14386b375ea7SVictor Minden   */
1439918e98c3SVictor Minden #endif
14403a40ed3dSBarry Smith   PetscFunctionReturn(0);
144117ab2063SBarry Smith }
144217ab2063SBarry Smith 
144317ab2063SBarry Smith /*
144417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
144517ab2063SBarry Smith */
1446dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
144717ab2063SBarry Smith {
1448416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14496849ba73SBarry Smith   PetscErrorCode ierr;
1450d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
145117ab2063SBarry Smith 
14523a40ed3dSBarry Smith   PetscFunctionBegin;
145309f38230SBarry Smith   if (!a->diag) {
1454785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14553bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
145609f38230SBarry Smith   }
1457d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
145809f38230SBarry Smith     a->diag[i] = a->i[i+1];
1459bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1460bfeeae90SHong Zhang       if (a->j[j] == i) {
146109f38230SBarry Smith         a->diag[i] = j;
146217ab2063SBarry Smith         break;
146317ab2063SBarry Smith       }
146417ab2063SBarry Smith     }
146517ab2063SBarry Smith   }
14663a40ed3dSBarry Smith   PetscFunctionReturn(0);
146717ab2063SBarry Smith }
146817ab2063SBarry Smith 
1469be5855fcSBarry Smith /*
1470be5855fcSBarry Smith      Checks for missing diagonals
1471be5855fcSBarry Smith */
1472ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1473be5855fcSBarry Smith {
1474be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14757734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1476be5855fcSBarry Smith 
1477be5855fcSBarry Smith   PetscFunctionBegin;
147809f38230SBarry Smith   *missing = PETSC_FALSE;
14797734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
148009f38230SBarry Smith     *missing = PETSC_TRUE;
148109f38230SBarry Smith     if (d) *d = 0;
1482955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
148309f38230SBarry Smith   } else {
1484f1e2ffcdSBarry Smith     diag = a->diag;
1485d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
14867734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
148709f38230SBarry Smith         *missing = PETSC_TRUE;
148809f38230SBarry Smith         if (d) *d = i;
1489955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1490358d2f5dSShri Abhyankar         break;
149109f38230SBarry Smith       }
1492be5855fcSBarry Smith     }
1493be5855fcSBarry Smith   }
1494be5855fcSBarry Smith   PetscFunctionReturn(0);
1495be5855fcSBarry Smith }
1496be5855fcSBarry Smith 
1497422a814eSBarry Smith /*
1498422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1499422a814eSBarry Smith */
15007087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
150171f1c65dSBarry Smith {
150271f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
150371f1c65dSBarry Smith   PetscErrorCode ierr;
1504d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
150554f21887SBarry Smith   MatScalar      *v = a->a;
150654f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
150771f1c65dSBarry Smith 
150871f1c65dSBarry Smith   PetscFunctionBegin;
150971f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
151071f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
151171f1c65dSBarry Smith   diag = a->diag;
151271f1c65dSBarry Smith   if (!a->idiag) {
1513dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15143bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
151571f1c65dSBarry Smith     v    = a->a;
151671f1c65dSBarry Smith   }
151771f1c65dSBarry Smith   mdiag = a->mdiag;
151871f1c65dSBarry Smith   idiag = a->idiag;
151971f1c65dSBarry Smith 
1520422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
152171f1c65dSBarry Smith     for (i=0; i<m; i++) {
152271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1523899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1524899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1525899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15267b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15277b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15287b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15297b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1530899639b0SHong Zhang       }
153171f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
153271f1c65dSBarry Smith     }
153371f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
153471f1c65dSBarry Smith   } else {
153571f1c65dSBarry Smith     for (i=0; i<m; i++) {
153671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
153771f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
153871f1c65dSBarry Smith     }
1539dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
154071f1c65dSBarry Smith   }
154171f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
154271f1c65dSBarry Smith   PetscFunctionReturn(0);
154371f1c65dSBarry Smith }
154471f1c65dSBarry Smith 
1545c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
154641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
154717ab2063SBarry Smith {
1548416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1549e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15503d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
155154f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1552dfbe8321SBarry Smith   PetscErrorCode    ierr;
15533d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
155497f1f81fSBarry Smith   const PetscInt    *idx,*diag;
155517ab2063SBarry Smith 
15563a40ed3dSBarry Smith   PetscFunctionBegin;
1557b965ef7fSBarry Smith   its = its*lits;
155891723122SBarry Smith 
155971f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
156071f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
156171f1c65dSBarry Smith   a->fshift = fshift;
156271f1c65dSBarry Smith   a->omega  = omega;
1563ed480e8bSBarry Smith 
156471f1c65dSBarry Smith   diag  = a->diag;
156571f1c65dSBarry Smith   t     = a->ssor_work;
1566ed480e8bSBarry Smith   idiag = a->idiag;
156771f1c65dSBarry Smith   mdiag = a->mdiag;
1568ed480e8bSBarry Smith 
15691ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15703649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1571ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
157217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
157317ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1574ed480e8bSBarry Smith     bs = b;
157517ab2063SBarry Smith     for (i=0; i<m; i++) {
157671f1c65dSBarry Smith       d   = fshift + mdiag[i];
1577416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1578ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1579ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
158017ab2063SBarry Smith       sum = b[i]*d/omega;
1581003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
158217ab2063SBarry Smith       x[i] = sum;
158317ab2063SBarry Smith     }
15841ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
15853649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1586efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
15873a40ed3dSBarry Smith     PetscFunctionReturn(0);
158817ab2063SBarry Smith   }
1589c783ea89SBarry Smith 
15902205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
15912205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
159217ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1593887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
159417ab2063SBarry Smith 
159517ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
159617ab2063SBarry Smith 
1597887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
159817ab2063SBarry Smith     */
159917ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
160017ab2063SBarry Smith 
160117ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
160217ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1603416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1604ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1605ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
160617ab2063SBarry Smith       sum = b[i];
1607e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1608ed480e8bSBarry Smith       x[i] = sum*idiag[i];
160917ab2063SBarry Smith     }
161017ab2063SBarry Smith 
161117ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1612416022c9SBarry Smith     v = a->a;
16132205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
161417ab2063SBarry Smith 
161517ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1616ed480e8bSBarry Smith     ts   = t;
1617416022c9SBarry Smith     diag = a->diag;
161817ab2063SBarry Smith     for (i=0; i<m; i++) {
1619416022c9SBarry Smith       n   = diag[i] - a->i[i];
1620ed480e8bSBarry Smith       idx = a->j + a->i[i];
1621ed480e8bSBarry Smith       v   = a->a + a->i[i];
162217ab2063SBarry Smith       sum = t[i];
1623003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1624ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1625733d66baSBarry Smith       /*  x = x + t */
1626733d66baSBarry Smith       x[i] += t[i];
162717ab2063SBarry Smith     }
162817ab2063SBarry Smith 
1629dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16301ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16313649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16323a40ed3dSBarry Smith     PetscFunctionReturn(0);
163317ab2063SBarry Smith   }
163417ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
163517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
163617ab2063SBarry Smith       for (i=0; i<m; i++) {
1637416022c9SBarry Smith         n   = diag[i] - a->i[i];
1638ed480e8bSBarry Smith         idx = a->j + a->i[i];
1639ed480e8bSBarry Smith         v   = a->a + a->i[i];
164017ab2063SBarry Smith         sum = b[i];
1641e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16425c99c7daSBarry Smith         t[i] = sum;
1643ed480e8bSBarry Smith         x[i] = sum*idiag[i];
164417ab2063SBarry Smith       }
16455c99c7daSBarry Smith       xb   = t;
1646efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16473a40ed3dSBarry Smith     } else xb = b;
164817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
164917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1650416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1651ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1652ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
165317ab2063SBarry Smith         sum = xb[i];
1654e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16555c99c7daSBarry Smith         if (xb == b) {
1656ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16575c99c7daSBarry Smith         } else {
1658b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
165917ab2063SBarry Smith         }
16605c99c7daSBarry Smith       }
1661b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
166217ab2063SBarry Smith     }
166317ab2063SBarry Smith     its--;
166417ab2063SBarry Smith   }
166517ab2063SBarry Smith   while (its--) {
166617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
166717ab2063SBarry Smith       for (i=0; i<m; i++) {
1668b19a5dc2SMark Adams         /* lower */
1669b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1670ed480e8bSBarry Smith         idx = a->j + a->i[i];
1671ed480e8bSBarry Smith         v   = a->a + a->i[i];
167217ab2063SBarry Smith         sum = b[i];
1673e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1674b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1675b19a5dc2SMark Adams         /* upper */
1676b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1677b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1678b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1679b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1680b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
168117ab2063SBarry Smith       }
1682b19a5dc2SMark Adams       xb   = t;
16839f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1684b19a5dc2SMark Adams     } else xb = b;
168517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
168617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1687b19a5dc2SMark Adams         sum = xb[i];
1688b19a5dc2SMark Adams         if (xb == b) {
1689b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1690416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1691ed480e8bSBarry Smith           idx = a->j + a->i[i];
1692ed480e8bSBarry Smith           v   = a->a + a->i[i];
1693e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1694ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1695b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1696b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1697b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1698b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1699b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1700b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
170117ab2063SBarry Smith         }
1702b19a5dc2SMark Adams       }
1703b19a5dc2SMark Adams       if (xb == b) {
17049f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1705b19a5dc2SMark Adams       } else {
1706b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1707b19a5dc2SMark Adams       }
170817ab2063SBarry Smith     }
170917ab2063SBarry Smith   }
17101ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17113649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1712365a8a9eSBarry Smith   PetscFunctionReturn(0);
171317ab2063SBarry Smith }
171417ab2063SBarry Smith 
17152af78befSBarry Smith 
1716dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
171717ab2063SBarry Smith {
1718416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17194e220ebcSLois Curfman McInnes 
17203a40ed3dSBarry Smith   PetscFunctionBegin;
17214e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17224e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17234e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17244e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17254e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17268e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17277adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1728d5f3da31SBarry Smith   if (A->factortype) {
17294e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17304e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17314e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17324e220ebcSLois Curfman McInnes   } else {
17334e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17344e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17354e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17364e220ebcSLois Curfman McInnes   }
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
173817ab2063SBarry Smith }
173917ab2063SBarry Smith 
17402b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
174117ab2063SBarry Smith {
1742416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1743c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17446849ba73SBarry Smith   PetscErrorCode    ierr;
174597b48c8fSBarry Smith   const PetscScalar *xx;
174697b48c8fSBarry Smith   PetscScalar       *bb;
1747c7da8527SEric Chamberland   PetscInt          d = 0;
174817ab2063SBarry Smith 
17493a40ed3dSBarry Smith   PetscFunctionBegin;
175097b48c8fSBarry Smith   if (x && b) {
175197b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
175297b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
175397b48c8fSBarry Smith     for (i=0; i<N; i++) {
175497b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
175597b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
175697b48c8fSBarry Smith     }
175797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
175897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
175997b48c8fSBarry Smith   }
176097b48c8fSBarry Smith 
1761a9817697SBarry Smith   if (a->keepnonzeropattern) {
1762f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1763e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1764bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1765f1e2ffcdSBarry Smith     }
1766f4df32b1SMatthew Knepley     if (diag != 0.0) {
1767c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1768c7da8527SEric Chamberland         d = rows[i];
1769c7da8527SEric Chamberland         if (a->diag[d] >= a->i[d+1]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %D",d);
1770c7da8527SEric Chamberland       }
1771f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1772f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1773f1e2ffcdSBarry Smith       }
1774f1e2ffcdSBarry Smith     }
1775f1e2ffcdSBarry Smith   } else {
1776f4df32b1SMatthew Knepley     if (diag != 0.0) {
177717ab2063SBarry Smith       for (i=0; i<N; i++) {
1778e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17797ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1780416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1781f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1782bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
17837ae801bdSBarry Smith         } else { /* in case row was completely empty */
1784f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
178517ab2063SBarry Smith         }
178617ab2063SBarry Smith       }
17873a40ed3dSBarry Smith     } else {
178817ab2063SBarry Smith       for (i=0; i<N; i++) {
1789e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1790416022c9SBarry Smith         a->ilen[rows[i]] = 0;
179117ab2063SBarry Smith       }
179217ab2063SBarry Smith     }
1793e56f5c9eSBarry Smith     A->nonzerostate++;
1794f1e2ffcdSBarry Smith   }
179543a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17963a40ed3dSBarry Smith   PetscFunctionReturn(0);
179717ab2063SBarry Smith }
179817ab2063SBarry Smith 
17996e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18006e169961SBarry Smith {
18016e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18026e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18036e169961SBarry Smith   PetscErrorCode    ierr;
18042b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18056e169961SBarry Smith   const PetscScalar *xx;
18066e169961SBarry Smith   PetscScalar       *bb;
18076e169961SBarry Smith 
18086e169961SBarry Smith   PetscFunctionBegin;
18096e169961SBarry Smith   if (x && b) {
18106e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18116e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18122b40b63fSBarry Smith     vecs = PETSC_TRUE;
18136e169961SBarry Smith   }
18141795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18156e169961SBarry Smith   for (i=0; i<N; i++) {
18166e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18176e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18182205254eSKarl Rupp 
18196e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18206e169961SBarry Smith   }
18216e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18226e169961SBarry Smith     if (!zeroed[i]) {
18236e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18246e169961SBarry Smith         if (zeroed[a->j[j]]) {
18252b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18266e169961SBarry Smith           a->a[j] = 0.0;
18276e169961SBarry Smith         }
18286e169961SBarry Smith       }
18292b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18306e169961SBarry Smith   }
18316e169961SBarry Smith   if (x && b) {
18326e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18336e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18346e169961SBarry Smith   }
18356e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18366e169961SBarry Smith   if (diag != 0.0) {
18376e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18381d5a398dSstefano_zampini     if (missing) {
18391d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18401d5a398dSstefano_zampini       else {
18411d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18421d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18431d5a398dSstefano_zampini         }
18441d5a398dSstefano_zampini       }
18451d5a398dSstefano_zampini     } else {
18466e169961SBarry Smith       for (i=0; i<N; i++) {
18476e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18486e169961SBarry Smith       }
18496e169961SBarry Smith     }
18501d5a398dSstefano_zampini   }
18516e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18526e169961SBarry Smith   PetscFunctionReturn(0);
18536e169961SBarry Smith }
18546e169961SBarry Smith 
1855a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
185617ab2063SBarry Smith {
1857416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
185897f1f81fSBarry Smith   PetscInt   *itmp;
185917ab2063SBarry Smith 
18603a40ed3dSBarry Smith   PetscFunctionBegin;
1861e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
186217ab2063SBarry Smith 
1863416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1864bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
186517ab2063SBarry Smith   if (idx) {
1866bfeeae90SHong Zhang     itmp = a->j + a->i[row];
186726fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
186817ab2063SBarry Smith     else *idx = 0;
186917ab2063SBarry Smith   }
18703a40ed3dSBarry Smith   PetscFunctionReturn(0);
187117ab2063SBarry Smith }
187217ab2063SBarry Smith 
1873bfeeae90SHong Zhang /* remove this function? */
1874a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187517ab2063SBarry Smith {
18763a40ed3dSBarry Smith   PetscFunctionBegin;
18773a40ed3dSBarry Smith   PetscFunctionReturn(0);
187817ab2063SBarry Smith }
187917ab2063SBarry Smith 
1880dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
188117ab2063SBarry Smith {
1882416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
188354f21887SBarry Smith   MatScalar      *v  = a->a;
188436db0b34SBarry Smith   PetscReal      sum = 0.0;
18856849ba73SBarry Smith   PetscErrorCode ierr;
188697f1f81fSBarry Smith   PetscInt       i,j;
188717ab2063SBarry Smith 
18883a40ed3dSBarry Smith   PetscFunctionBegin;
188917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1890570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1891570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1892570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1893570b7f6dSBarry Smith #else
1894416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
189536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
189617ab2063SBarry Smith     }
18978f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1898570b7f6dSBarry Smith #endif
189951f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19003a40ed3dSBarry Smith   } else if (type == NORM_1) {
190136db0b34SBarry Smith     PetscReal *tmp;
190297f1f81fSBarry Smith     PetscInt  *jj = a->j;
19031795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1904064f8208SBarry Smith     *nrm = 0.0;
1905416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1906bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
190717ab2063SBarry Smith     }
1908d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1909064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
191017ab2063SBarry Smith     }
1911606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
191251f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19133a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1914064f8208SBarry Smith     *nrm = 0.0;
1915d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1916bfeeae90SHong Zhang       v   = a->a + a->i[j];
191717ab2063SBarry Smith       sum = 0.0;
1918416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1919cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
192017ab2063SBarry Smith       }
1921064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
192217ab2063SBarry Smith     }
192351f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1924f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19253a40ed3dSBarry Smith   PetscFunctionReturn(0);
192617ab2063SBarry Smith }
192717ab2063SBarry Smith 
19284e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19294e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19304e938277SHong Zhang {
19314e938277SHong Zhang   PetscErrorCode ierr;
19324e938277SHong Zhang   PetscInt       i,j,anzj;
19334e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19344e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19354e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19364e938277SHong Zhang 
19374e938277SHong Zhang   PetscFunctionBegin;
19384e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1939854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1940785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1941785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19424e938277SHong Zhang 
19434e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19444e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
194526fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19464e938277SHong Zhang   /* Form ati for csr format of A^T. */
194726fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19484e938277SHong Zhang 
19494e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19504e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19514e938277SHong Zhang 
19524e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19534e938277SHong Zhang   for (i=0;i<am;i++) {
19544e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19554e938277SHong Zhang     for (j=0;j<anzj;j++) {
19564e938277SHong Zhang       atj[atfill[*aj]] = i;
19574e938277SHong Zhang       atfill[*aj++]   += 1;
19584e938277SHong Zhang     }
19594e938277SHong Zhang   }
19604e938277SHong Zhang 
19614e938277SHong Zhang   /* Clean up temporary space and complete requests. */
19624e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
1963ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
196433d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
1965a2f3521dSMark F. Adams 
19664e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
19674e938277SHong Zhang   b->free_a  = PETSC_FALSE;
19684e938277SHong Zhang   b->free_ij = PETSC_TRUE;
19694e938277SHong Zhang   b->nonew   = 0;
19704e938277SHong Zhang   PetscFunctionReturn(0);
19714e938277SHong Zhang }
19724e938277SHong Zhang 
1973fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
197417ab2063SBarry Smith {
1975416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1976416022c9SBarry Smith   Mat            C;
19776849ba73SBarry Smith   PetscErrorCode ierr;
1978d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
197954f21887SBarry Smith   MatScalar      *array = a->a;
198017ab2063SBarry Smith 
19813a40ed3dSBarry Smith   PetscFunctionBegin;
1982cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1983fc4dec0aSBarry Smith 
1984cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
1985854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
1986bfeeae90SHong Zhang 
1987bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1988ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
1989d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
199033d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
19917adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
1992ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
1993606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
1994a541d17aSBarry Smith   } else {
1995a541d17aSBarry Smith     C = *B;
1996a541d17aSBarry Smith   }
1997a541d17aSBarry Smith 
199817ab2063SBarry Smith   for (i=0; i<m; i++) {
199917ab2063SBarry Smith     len    = ai[i+1]-ai[i];
200087d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2001b9b97703SBarry Smith     array += len;
2002b9b97703SBarry Smith     aj    += len;
200317ab2063SBarry Smith   }
20046d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20056d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
200617ab2063SBarry Smith 
2007cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2008416022c9SBarry Smith     *B = C;
200917ab2063SBarry Smith   } else {
201028be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
201117ab2063SBarry Smith   }
20123a40ed3dSBarry Smith   PetscFunctionReturn(0);
201317ab2063SBarry Smith }
201417ab2063SBarry Smith 
20157087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2016cd0d46ebSvictorle {
20173d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
201854f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
201954f21887SBarry Smith   MatScalar      *va,*vb;
20206849ba73SBarry Smith   PetscErrorCode ierr;
202197f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2022cd0d46ebSvictorle 
2023cd0d46ebSvictorle   PetscFunctionBegin;
2024cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2025cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20265485867bSBarry Smith   if (ma!=nb || na!=mb) {
20275485867bSBarry Smith     *f = PETSC_FALSE;
20285485867bSBarry Smith     PetscFunctionReturn(0);
20295485867bSBarry Smith   }
2030cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2031cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2032cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2033785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2034785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2035cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2036cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2037cd0d46ebSvictorle 
2038cd0d46ebSvictorle   *f = PETSC_TRUE;
2039cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2040cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
204197f1f81fSBarry Smith       PetscInt    idc,idr;
20425485867bSBarry Smith       PetscScalar vc,vr;
2043cd0d46ebSvictorle       /* column/row index/value */
20445485867bSBarry Smith       idc = adx[aptr[i]];
20455485867bSBarry Smith       idr = bdx[bptr[idc]];
20465485867bSBarry Smith       vc  = va[aptr[i]];
20475485867bSBarry Smith       vr  = vb[bptr[idc]];
20485485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20495485867bSBarry Smith         *f = PETSC_FALSE;
20505485867bSBarry Smith         goto done;
2051cd0d46ebSvictorle       } else {
20525485867bSBarry Smith         aptr[i]++;
20535485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2054cd0d46ebSvictorle       }
2055cd0d46ebSvictorle     }
2056cd0d46ebSvictorle   }
2057cd0d46ebSvictorle done:
2058cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20593aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2060cd0d46ebSvictorle   PetscFunctionReturn(0);
2061cd0d46ebSvictorle }
2062cd0d46ebSvictorle 
20637087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20641cbb95d3SBarry Smith {
20653d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
206654f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
206754f21887SBarry Smith   MatScalar      *va,*vb;
20681cbb95d3SBarry Smith   PetscErrorCode ierr;
20691cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20701cbb95d3SBarry Smith 
20711cbb95d3SBarry Smith   PetscFunctionBegin;
20721cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20731cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20741cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
20751cbb95d3SBarry Smith     *f = PETSC_FALSE;
20761cbb95d3SBarry Smith     PetscFunctionReturn(0);
20771cbb95d3SBarry Smith   }
20781cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
20791cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
20801cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2081785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2082785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
20831cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20841cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20851cbb95d3SBarry Smith 
20861cbb95d3SBarry Smith   *f = PETSC_TRUE;
20871cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20881cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
20891cbb95d3SBarry Smith       PetscInt    idc,idr;
20901cbb95d3SBarry Smith       PetscScalar vc,vr;
20911cbb95d3SBarry Smith       /* column/row index/value */
20921cbb95d3SBarry Smith       idc = adx[aptr[i]];
20931cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
20941cbb95d3SBarry Smith       vc  = va[aptr[i]];
20951cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
20961cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
20971cbb95d3SBarry Smith         *f = PETSC_FALSE;
20981cbb95d3SBarry Smith         goto done;
20991cbb95d3SBarry Smith       } else {
21001cbb95d3SBarry Smith         aptr[i]++;
21011cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21021cbb95d3SBarry Smith       }
21031cbb95d3SBarry Smith     }
21041cbb95d3SBarry Smith   }
21051cbb95d3SBarry Smith done:
21061cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21071cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21081cbb95d3SBarry Smith   PetscFunctionReturn(0);
21091cbb95d3SBarry Smith }
21101cbb95d3SBarry Smith 
2111ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21129e29f15eSvictorle {
2113dfbe8321SBarry Smith   PetscErrorCode ierr;
21146e111a19SKarl Rupp 
21159e29f15eSvictorle   PetscFunctionBegin;
21165485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21179e29f15eSvictorle   PetscFunctionReturn(0);
21189e29f15eSvictorle }
21199e29f15eSvictorle 
2120ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21211cbb95d3SBarry Smith {
21221cbb95d3SBarry Smith   PetscErrorCode ierr;
21236e111a19SKarl Rupp 
21241cbb95d3SBarry Smith   PetscFunctionBegin;
21251cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21261cbb95d3SBarry Smith   PetscFunctionReturn(0);
21271cbb95d3SBarry Smith }
21281cbb95d3SBarry Smith 
2129dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
213017ab2063SBarry Smith {
2131416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
213254f21887SBarry Smith   PetscScalar    *l,*r,x;
213354f21887SBarry Smith   MatScalar      *v;
2134dfbe8321SBarry Smith   PetscErrorCode ierr;
2135d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
213617ab2063SBarry Smith 
21373a40ed3dSBarry Smith   PetscFunctionBegin;
213817ab2063SBarry Smith   if (ll) {
21393ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21403ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2141e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2142e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21431ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2144416022c9SBarry Smith     v    = a->a;
214517ab2063SBarry Smith     for (i=0; i<m; i++) {
214617ab2063SBarry Smith       x = l[i];
2147416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21482205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
214917ab2063SBarry Smith     }
21501ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2151efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
215217ab2063SBarry Smith   }
215317ab2063SBarry Smith   if (rr) {
2154e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2155e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21561ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2157416022c9SBarry Smith     v    = a->a; jj = a->j;
21582205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21591ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2160efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
216117ab2063SBarry Smith   }
2162acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
21633a40ed3dSBarry Smith   PetscFunctionReturn(0);
216417ab2063SBarry Smith }
216517ab2063SBarry Smith 
21667dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
216717ab2063SBarry Smith {
2168db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21696849ba73SBarry Smith   PetscErrorCode ierr;
2170d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
217197f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21725d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21735d0c19d7SBarry Smith   PetscInt       nrows,ncols;
217497f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
217554f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2176416022c9SBarry Smith   Mat            C;
2177cdc6f3adSToby Isaac   PetscBool      stride;
217817ab2063SBarry Smith 
21793a40ed3dSBarry Smith   PetscFunctionBegin;
218099141d43SSatish Balay 
218117ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2182b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2183b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
218417ab2063SBarry Smith 
2185251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2186ff718158SBarry Smith   if (stride) {
2187ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2188ff718158SBarry Smith   } else {
2189ff718158SBarry Smith     first = 0;
2190ff718158SBarry Smith     step  = 0;
2191ff718158SBarry Smith   }
2192fee21e36SBarry Smith   if (stride && step == 1) {
219302834360SBarry Smith     /* special case of contiguous rows */
2194dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
219502834360SBarry Smith     /* loop over new rows determining lens and starting points */
219602834360SBarry Smith     for (i=0; i<nrows; i++) {
2197bfeeae90SHong Zhang       kstart = ai[irow[i]];
2198a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2199a91a9bebSLisandro Dalcin       starts[i] = kstart;
220002834360SBarry Smith       for (k=kstart; k<kend; k++) {
2201bfeeae90SHong Zhang         if (aj[k] >= first) {
220202834360SBarry Smith           starts[i] = k;
220302834360SBarry Smith           break;
220402834360SBarry Smith         }
220502834360SBarry Smith       }
2206a2744918SBarry Smith       sum = 0;
220702834360SBarry Smith       while (k < kend) {
2208bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2209a2744918SBarry Smith         sum++;
221002834360SBarry Smith       }
2211a2744918SBarry Smith       lens[i] = sum;
221202834360SBarry Smith     }
221302834360SBarry Smith     /* create submatrix */
2214cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
221597f1f81fSBarry Smith       PetscInt n_cols,n_rows;
221608480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2217e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2218d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
221908480c60SBarry Smith       C    = *B;
22203a40ed3dSBarry Smith     } else {
22213bef6203SJed Brown       PetscInt rbs,cbs;
2222ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2223f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22243bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22253bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22263bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22277adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2228ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
222908480c60SBarry Smith     }
2230db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2231db02288aSLois Curfman McInnes 
223202834360SBarry Smith     /* loop over rows inserting into submatrix */
2233db02288aSLois Curfman McInnes     a_new = c->a;
2234db02288aSLois Curfman McInnes     j_new = c->j;
2235db02288aSLois Curfman McInnes     i_new = c->i;
2236bfeeae90SHong Zhang 
223702834360SBarry Smith     for (i=0; i<nrows; i++) {
2238a2744918SBarry Smith       ii    = starts[i];
2239a2744918SBarry Smith       lensi = lens[i];
2240a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2241a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
224202834360SBarry Smith       }
224387828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2244a2744918SBarry Smith       a_new     += lensi;
2245a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2246a2744918SBarry Smith       c->ilen[i] = lensi;
224702834360SBarry Smith     }
22480e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22493a40ed3dSBarry Smith   } else {
225002834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22511795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2252854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22534dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22544dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22554dcab191SBarry 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);
22564dcab191SBarry Smith #endif
22574dcab191SBarry Smith       smap[icol[i]] = i+1;
22584dcab191SBarry Smith     }
22594dcab191SBarry Smith 
226002834360SBarry Smith     /* determine lens of each row */
226102834360SBarry Smith     for (i=0; i<nrows; i++) {
2262bfeeae90SHong Zhang       kstart  = ai[irow[i]];
226302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
226402834360SBarry Smith       lens[i] = 0;
226502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2266bfeeae90SHong Zhang         if (smap[aj[k]]) {
226702834360SBarry Smith           lens[i]++;
226802834360SBarry Smith         }
226902834360SBarry Smith       }
227002834360SBarry Smith     }
227117ab2063SBarry Smith     /* Create and fill new matrix */
2272a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2273ace3abfcSBarry Smith       PetscBool equal;
22740f5bd95cSBarry Smith 
227599141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2276e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2277d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2278f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2279d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
228008480c60SBarry Smith       C    = *B;
22813a40ed3dSBarry Smith     } else {
22823bef6203SJed Brown       PetscInt rbs,cbs;
2283ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2284f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22853bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22863bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22873bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22887adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2289ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
229008480c60SBarry Smith     }
229199141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
229217ab2063SBarry Smith     for (i=0; i<nrows; i++) {
229399141d43SSatish Balay       row      = irow[i];
2294bfeeae90SHong Zhang       kstart   = ai[row];
229599141d43SSatish Balay       kend     = kstart + a->ilen[row];
2296bfeeae90SHong Zhang       mat_i    = c->i[i];
229799141d43SSatish Balay       mat_j    = c->j + mat_i;
229899141d43SSatish Balay       mat_a    = c->a + mat_i;
229999141d43SSatish Balay       mat_ilen = c->ilen + i;
230017ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2301bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2302ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
230399141d43SSatish Balay           *mat_a++ = a->a[k];
230499141d43SSatish Balay           (*mat_ilen)++;
230599141d43SSatish Balay 
230617ab2063SBarry Smith         }
230717ab2063SBarry Smith       }
230817ab2063SBarry Smith     }
230902834360SBarry Smith     /* Free work space */
231002834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2311606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2312606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2313cdc6f3adSToby Isaac     /* sort */
2314cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2315cdc6f3adSToby Isaac       PetscInt ilen;
2316cdc6f3adSToby Isaac 
2317cdc6f3adSToby Isaac       mat_i = c->i[i];
2318cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2319cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2320cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2321390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2322cdc6f3adSToby Isaac     }
232302834360SBarry Smith   }
23246d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23256d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
232617ab2063SBarry Smith 
232717ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2328416022c9SBarry Smith   *B   = C;
23293a40ed3dSBarry Smith   PetscFunctionReturn(0);
233017ab2063SBarry Smith }
233117ab2063SBarry Smith 
2332fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
233382d44351SHong Zhang {
233482d44351SHong Zhang   PetscErrorCode ierr;
233582d44351SHong Zhang   Mat            B;
233682d44351SHong Zhang 
233782d44351SHong Zhang   PetscFunctionBegin;
2338c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
233982d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
234082d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
234133d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
234282d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
234382d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
234482d44351SHong Zhang     *subMat = B;
2345c2d650bdSHong Zhang   } else {
2346c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2347c2d650bdSHong Zhang   }
234882d44351SHong Zhang   PetscFunctionReturn(0);
234982d44351SHong Zhang }
235082d44351SHong Zhang 
23519a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2352a871dcd8SBarry Smith {
235363b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2354dfbe8321SBarry Smith   PetscErrorCode ierr;
235563b91edcSBarry Smith   Mat            outA;
2356ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
235763b91edcSBarry Smith 
23583a40ed3dSBarry Smith   PetscFunctionBegin;
2359e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23601df811f5SHong Zhang 
2361b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2362b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2363a871dcd8SBarry Smith 
236463b91edcSBarry Smith   outA             = inA;
2365d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2366f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2367f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
23682205254eSKarl Rupp 
2369c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23706bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
23712205254eSKarl Rupp 
2372c3122656SLisandro Dalcin   a->row = row;
23732205254eSKarl Rupp 
2374c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23756bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
23762205254eSKarl Rupp 
2377c3122656SLisandro Dalcin   a->col = col;
237863b91edcSBarry Smith 
237936db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23806bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23814c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
23823bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2383f0ec6fceSSatish Balay 
238494a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2385854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
23863bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
238794a9d846SBarry Smith   }
238863b91edcSBarry Smith 
2389f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2390137fb511SHong Zhang   if (row_identity && col_identity) {
2391ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2392137fb511SHong Zhang   } else {
2393719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2394137fb511SHong Zhang   }
23953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2396a871dcd8SBarry Smith }
2397a871dcd8SBarry Smith 
2398f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2399f0b747eeSBarry Smith {
2400f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2401f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2402efee365bSSatish Balay   PetscErrorCode ierr;
2403c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24043a40ed3dSBarry Smith 
24053a40ed3dSBarry Smith   PetscFunctionBegin;
2406c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24078b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2408efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2409acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24103a40ed3dSBarry Smith   PetscFunctionReturn(0);
2411f0b747eeSBarry Smith }
2412f0b747eeSBarry Smith 
24135c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
241416b64355SHong Zhang {
241516b64355SHong Zhang   PetscErrorCode ierr;
241616b64355SHong Zhang   PetscInt       i;
241716b64355SHong Zhang 
241816b64355SHong Zhang   PetscFunctionBegin;
241916b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
242016b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
242116b64355SHong Zhang 
242216b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
242316b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
242416b64355SHong Zhang     }
242516b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
242616b64355SHong Zhang 
242716b64355SHong Zhang     if (submatj->rbuf1) {
242816b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
242916b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
243016b64355SHong Zhang     }
243116b64355SHong Zhang 
243216b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
243316b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
243416b64355SHong Zhang     }
243516b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
243616b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
243716b64355SHong Zhang   }
243816b64355SHong Zhang 
243916b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
244016b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
244116b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
244216b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
244316b64355SHong Zhang #else
244416b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
244516b64355SHong Zhang #endif
244616b64355SHong Zhang 
244716b64355SHong Zhang   if (!submatj->allcolumns) {
244816b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
244916b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
245016b64355SHong Zhang #else
245116b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
245216b64355SHong Zhang #endif
245316b64355SHong Zhang   }
245416b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
245516b64355SHong Zhang 
245616b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
245716b64355SHong Zhang   PetscFunctionReturn(0);
245816b64355SHong Zhang }
245916b64355SHong Zhang 
246016b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
246116b64355SHong Zhang {
246216b64355SHong Zhang   PetscErrorCode ierr;
246316b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
24645c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
246516b64355SHong Zhang 
246616b64355SHong Zhang   PetscFunctionBegin;
246716b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2468e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
246916b64355SHong Zhang   PetscFunctionReturn(0);
247016b64355SHong Zhang }
247116b64355SHong Zhang 
24727dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2473cddf8d76SBarry Smith {
2474dfbe8321SBarry Smith   PetscErrorCode ierr;
247597f1f81fSBarry Smith   PetscInt       i;
2476cddf8d76SBarry Smith 
24773a40ed3dSBarry Smith   PetscFunctionBegin;
2478cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2479df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2480cddf8d76SBarry Smith   }
2481cddf8d76SBarry Smith 
2482cddf8d76SBarry Smith   for (i=0; i<n; i++) {
24837dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2484cddf8d76SBarry Smith   }
24853a40ed3dSBarry Smith   PetscFunctionReturn(0);
2486cddf8d76SBarry Smith }
2487cddf8d76SBarry Smith 
248897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
24894dcbc457SBarry Smith {
2490e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
24916849ba73SBarry Smith   PetscErrorCode ierr;
24925d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
24935d0c19d7SBarry Smith   const PetscInt *idx;
249497f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2495f1af5d2fSBarry Smith   PetscBT        table;
2496bbd702dbSSatish Balay 
24973a40ed3dSBarry Smith   PetscFunctionBegin;
2498d0f46423SBarry Smith   m  = A->rmap->n;
2499e4d965acSSatish Balay   ai = a->i;
2500bfeeae90SHong Zhang   aj = a->j;
25018a047759SSatish Balay 
2502e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
250306763907SSatish Balay 
2504854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
250553b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
250606763907SSatish Balay 
2507e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2508b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2509e4d965acSSatish Balay     isz  = 0;
25106831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2511e4d965acSSatish Balay 
2512e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25134dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2514b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2515e4d965acSSatish Balay 
2516dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2517e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25182205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25194dcbc457SBarry Smith     }
252006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25216bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2522e4d965acSSatish Balay 
252304a348a9SBarry Smith     k = 0;
252404a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
252504a348a9SBarry Smith       n = isz;
252606763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2527e4d965acSSatish Balay         row   = nidx[k];
2528e4d965acSSatish Balay         start = ai[row];
2529e4d965acSSatish Balay         end   = ai[row+1];
253004a348a9SBarry Smith         for (l = start; l<end; l++) {
2531efb16452SHong Zhang           val = aj[l];
25322205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2533e4d965acSSatish Balay         }
2534e4d965acSSatish Balay       }
2535e4d965acSSatish Balay     }
253670b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2537e4d965acSSatish Balay   }
253894bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2539606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25403a40ed3dSBarry Smith   PetscFunctionReturn(0);
25414dcbc457SBarry Smith }
254217ab2063SBarry Smith 
25430513a670SBarry Smith /* -------------------------------------------------------------- */
2544dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25450513a670SBarry Smith {
25460513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25476849ba73SBarry Smith   PetscErrorCode ierr;
25483b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25495d0c19d7SBarry Smith   const PetscInt *row,*col;
25505d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
255156cd22aeSBarry Smith   IS             icolp,irowp;
25520298fd71SBarry Smith   PetscInt       *cwork = NULL;
25530298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25540513a670SBarry Smith 
25553a40ed3dSBarry Smith   PetscFunctionBegin;
25564c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
255756cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25584c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
255956cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
25600513a670SBarry Smith 
25610513a670SBarry Smith   /* determine lengths of permuted rows */
2562854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
25632205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2564ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2565f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
256633d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
25677adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2568ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2569606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
25700513a670SBarry Smith 
2571785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
25720513a670SBarry Smith   for (i=0; i<m; i++) {
257332ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25742205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2575cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
257632ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25770513a670SBarry Smith   }
2578606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
25792205254eSKarl Rupp 
25803c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
25812205254eSKarl Rupp 
25820513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25830513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
258456cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
258556cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
25866bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
25876bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
25883a40ed3dSBarry Smith   PetscFunctionReturn(0);
25890513a670SBarry Smith }
25900513a670SBarry Smith 
2591dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2592cb5b572fSBarry Smith {
2593dfbe8321SBarry Smith   PetscErrorCode ierr;
2594cb5b572fSBarry Smith 
2595cb5b572fSBarry Smith   PetscFunctionBegin;
259633f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
259733f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2598be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2599be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2600be6bf707SBarry Smith 
2601700c5bfcSBarry 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");
2602d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2603cb5b572fSBarry Smith   } else {
2604cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2605cb5b572fSBarry Smith   }
2606cb5b572fSBarry Smith   PetscFunctionReturn(0);
2607cb5b572fSBarry Smith }
2608cb5b572fSBarry Smith 
26094994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2610273d9f13SBarry Smith {
2611dfbe8321SBarry Smith   PetscErrorCode ierr;
2612273d9f13SBarry Smith 
2613273d9f13SBarry Smith   PetscFunctionBegin;
2614ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2615273d9f13SBarry Smith   PetscFunctionReturn(0);
2616273d9f13SBarry Smith }
2617273d9f13SBarry Smith 
26188c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26196c0721eeSBarry Smith {
26206c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26216e111a19SKarl Rupp 
26226c0721eeSBarry Smith   PetscFunctionBegin;
26236c0721eeSBarry Smith   *array = a->a;
26246c0721eeSBarry Smith   PetscFunctionReturn(0);
26256c0721eeSBarry Smith }
26266c0721eeSBarry Smith 
26278c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26286c0721eeSBarry Smith {
26296c0721eeSBarry Smith   PetscFunctionBegin;
26306c0721eeSBarry Smith   PetscFunctionReturn(0);
26316c0721eeSBarry Smith }
2632273d9f13SBarry Smith 
26338229c054SShri Abhyankar /*
26348229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26358229c054SShri Abhyankar    have different nonzero structure.
26368229c054SShri Abhyankar */
2637b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2638ec7775f6SShri Abhyankar {
2639b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2640ec7775f6SShri Abhyankar 
2641ec7775f6SShri Abhyankar   PetscFunctionBegin;
2642ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2643ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2644b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2645b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2646b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26478af7cee1SJed Brown     nnz[i] = 0;
26488af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2649b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2650b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26518af7cee1SJed Brown       nnz[i]++;
26528af7cee1SJed Brown     }
26538af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2654ec7775f6SShri Abhyankar   }
2655ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2656ec7775f6SShri Abhyankar }
2657ec7775f6SShri Abhyankar 
2658b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2659b264fe52SHong Zhang {
2660b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2661b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2662b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2663b264fe52SHong Zhang   PetscErrorCode ierr;
2664b264fe52SHong Zhang 
2665b264fe52SHong Zhang   PetscFunctionBegin;
2666b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2667b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2668b264fe52SHong Zhang   PetscFunctionReturn(0);
2669b264fe52SHong Zhang }
2670b264fe52SHong Zhang 
2671f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2672ac90fabeSBarry Smith {
2673dfbe8321SBarry Smith   PetscErrorCode ierr;
2674ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2675c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2676ac90fabeSBarry Smith 
2677ac90fabeSBarry Smith   PetscFunctionBegin;
2678c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2679ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2680f4df32b1SMatthew Knepley     PetscScalar alpha = a;
26818b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2682acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2683a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2684ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2685ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2686ac90fabeSBarry Smith   } else {
26878229c054SShri Abhyankar     Mat      B;
26888229c054SShri Abhyankar     PetscInt *nnz;
2689785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2690ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2691bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
26924aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
269333d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2694176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
26958229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2696ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2697ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
269828be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
26998229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2700ac90fabeSBarry Smith   }
2701ac90fabeSBarry Smith   PetscFunctionReturn(0);
2702ac90fabeSBarry Smith }
2703ac90fabeSBarry Smith 
27047087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2705354c94deSBarry Smith {
2706354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2707354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2708354c94deSBarry Smith   PetscInt    i,nz;
2709354c94deSBarry Smith   PetscScalar *a;
2710354c94deSBarry Smith 
2711354c94deSBarry Smith   PetscFunctionBegin;
2712354c94deSBarry Smith   nz = aij->nz;
2713354c94deSBarry Smith   a  = aij->a;
27142205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2715354c94deSBarry Smith #else
2716354c94deSBarry Smith   PetscFunctionBegin;
2717354c94deSBarry Smith #endif
2718354c94deSBarry Smith   PetscFunctionReturn(0);
2719354c94deSBarry Smith }
2720354c94deSBarry Smith 
2721985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2722e34fafa9SBarry Smith {
2723e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2724e34fafa9SBarry Smith   PetscErrorCode ierr;
2725d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2726e34fafa9SBarry Smith   PetscReal      atmp;
2727985db425SBarry Smith   PetscScalar    *x;
2728e34fafa9SBarry Smith   MatScalar      *aa;
2729e34fafa9SBarry Smith 
2730e34fafa9SBarry Smith   PetscFunctionBegin;
2731e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2732e34fafa9SBarry Smith   aa = a->a;
2733e34fafa9SBarry Smith   ai = a->i;
2734e34fafa9SBarry Smith   aj = a->j;
2735e34fafa9SBarry Smith 
2736985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2737e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2738e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2739e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2740e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2741e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27429189402eSHong Zhang     x[i]  = 0.0;
2743e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2744985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2745985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2746985db425SBarry Smith       aa++; aj++;
2747985db425SBarry Smith     }
2748985db425SBarry Smith   }
2749985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2750985db425SBarry Smith   PetscFunctionReturn(0);
2751985db425SBarry Smith }
2752985db425SBarry Smith 
2753985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2754985db425SBarry Smith {
2755985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2756985db425SBarry Smith   PetscErrorCode ierr;
2757d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2758985db425SBarry Smith   PetscScalar    *x;
2759985db425SBarry Smith   MatScalar      *aa;
2760985db425SBarry Smith 
2761985db425SBarry Smith   PetscFunctionBegin;
2762e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2763985db425SBarry Smith   aa = a->a;
2764985db425SBarry Smith   ai = a->i;
2765985db425SBarry Smith   aj = a->j;
2766985db425SBarry Smith 
2767985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2768985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2769985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2770e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2771985db425SBarry Smith   for (i=0; i<m; i++) {
2772985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2773d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2774985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2775985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2776985db425SBarry Smith       x[i] = 0.0;
2777985db425SBarry Smith       if (idx) {
2778985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2779985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2780985db425SBarry Smith           if (aj[j] > j) {
2781985db425SBarry Smith             idx[i] = j;
2782985db425SBarry Smith             break;
2783985db425SBarry Smith           }
2784985db425SBarry Smith         }
2785985db425SBarry Smith       }
2786985db425SBarry Smith     }
2787985db425SBarry Smith     for (j=0; j<ncols; j++) {
2788985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2789985db425SBarry Smith       aa++; aj++;
2790985db425SBarry Smith     }
2791985db425SBarry Smith   }
2792985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2793985db425SBarry Smith   PetscFunctionReturn(0);
2794985db425SBarry Smith }
2795985db425SBarry Smith 
2796c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2797c87e5d42SMatthew Knepley {
2798c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2799c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2800c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2801c87e5d42SMatthew Knepley   PetscReal      atmp;
2802c87e5d42SMatthew Knepley   PetscScalar    *x;
2803c87e5d42SMatthew Knepley   MatScalar      *aa;
2804c87e5d42SMatthew Knepley 
2805c87e5d42SMatthew Knepley   PetscFunctionBegin;
2806e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2807c87e5d42SMatthew Knepley   aa = a->a;
2808c87e5d42SMatthew Knepley   ai = a->i;
2809c87e5d42SMatthew Knepley   aj = a->j;
2810c87e5d42SMatthew Knepley 
2811c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2812c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2813c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
281460e0710aSBarry 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);
2815c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2816c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2817289a08f5SMatthew Knepley     if (ncols) {
2818289a08f5SMatthew Knepley       /* Get first nonzero */
2819289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2820289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28212205254eSKarl Rupp         if (atmp > 1.0e-12) {
28222205254eSKarl Rupp           x[i] = atmp;
28232205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28242205254eSKarl Rupp           break;
28252205254eSKarl Rupp         }
2826289a08f5SMatthew Knepley       }
282712431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2828289a08f5SMatthew Knepley     } else {
2829289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2830289a08f5SMatthew Knepley     }
2831c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2832c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2833289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2834c87e5d42SMatthew Knepley       aa++; aj++;
2835c87e5d42SMatthew Knepley     }
2836c87e5d42SMatthew Knepley   }
2837c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2838c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2839c87e5d42SMatthew Knepley }
2840c87e5d42SMatthew Knepley 
2841985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2842985db425SBarry Smith {
2843985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2844985db425SBarry Smith   PetscErrorCode  ierr;
2845d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2846d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2847985db425SBarry Smith   PetscScalar     *x;
2848d9ca1df4SBarry Smith   const MatScalar *aa;
2849985db425SBarry Smith 
2850985db425SBarry Smith   PetscFunctionBegin;
2851e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2852985db425SBarry Smith   aa = a->a;
2853985db425SBarry Smith   ai = a->i;
2854985db425SBarry Smith   aj = a->j;
2855985db425SBarry Smith 
2856985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2857985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2858985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2859e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2860985db425SBarry Smith   for (i=0; i<m; i++) {
2861985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2862d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2863985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2864985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2865985db425SBarry Smith       x[i] = 0.0;
2866985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2867985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2868985db425SBarry Smith         for (j=0; j<ncols; j++) {
2869985db425SBarry Smith           if (aj[j] > j) {
2870985db425SBarry Smith             idx[i] = j;
2871985db425SBarry Smith             break;
2872985db425SBarry Smith           }
2873985db425SBarry Smith         }
2874985db425SBarry Smith       }
2875985db425SBarry Smith     }
2876985db425SBarry Smith     for (j=0; j<ncols; j++) {
2877985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2878985db425SBarry Smith       aa++; aj++;
2879e34fafa9SBarry Smith     }
2880e34fafa9SBarry Smith   }
2881e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2882e34fafa9SBarry Smith   PetscFunctionReturn(0);
2883e34fafa9SBarry Smith }
2884bbead8a2SBarry Smith 
2885bbead8a2SBarry Smith #include <petscblaslapack.h>
2886af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2887bbead8a2SBarry Smith 
2888713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2889bbead8a2SBarry Smith {
2890bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2891bbead8a2SBarry Smith   PetscErrorCode ierr;
289233d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2893bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2894bbead8a2SBarry Smith   PetscReal      shift = 0.0;
28951a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2896bbead8a2SBarry Smith 
2897bbead8a2SBarry Smith   PetscFunctionBegin;
2898a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
28994a0d0026SBarry Smith   if (a->ibdiagvalid) {
29004a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29014a0d0026SBarry Smith     PetscFunctionReturn(0);
29024a0d0026SBarry Smith   }
2903bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2904bbead8a2SBarry Smith   if (!a->ibdiag) {
2905785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29063bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2907bbead8a2SBarry Smith   }
2908bbead8a2SBarry Smith   diag = a->ibdiag;
2909bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2910bbead8a2SBarry Smith   /* factor and invert each block */
2911bbead8a2SBarry Smith   switch (bs) {
2912bbead8a2SBarry Smith   case 1:
2913bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2914bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2915ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2916ec1892c8SHong Zhang         if (allowzeropivot) {
29177b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29187b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29197b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29207b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29217b6c816cSBarry 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);
2922ec1892c8SHong Zhang       }
2923bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2924bbead8a2SBarry Smith     }
2925bbead8a2SBarry Smith     break;
2926bbead8a2SBarry Smith   case 2:
2927bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2928bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2929bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2930a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29317b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
293296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2933bbead8a2SBarry Smith       diag += 4;
2934bbead8a2SBarry Smith     }
2935bbead8a2SBarry Smith     break;
2936bbead8a2SBarry Smith   case 3:
2937bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2938bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2939bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2940a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29417b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
294296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2943bbead8a2SBarry Smith       diag += 9;
2944bbead8a2SBarry Smith     }
2945bbead8a2SBarry Smith     break;
2946bbead8a2SBarry Smith   case 4:
2947bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2948bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2949bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2950a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29517b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
295296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2953bbead8a2SBarry Smith       diag += 16;
2954bbead8a2SBarry Smith     }
2955bbead8a2SBarry Smith     break;
2956bbead8a2SBarry Smith   case 5:
2957bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2958bbead8a2SBarry 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;
2959bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2960a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29617b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
296296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2963bbead8a2SBarry Smith       diag += 25;
2964bbead8a2SBarry Smith     }
2965bbead8a2SBarry Smith     break;
2966bbead8a2SBarry Smith   case 6:
2967bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2968bbead8a2SBarry 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;
2969bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
2970a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29717b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2973bbead8a2SBarry Smith       diag += 36;
2974bbead8a2SBarry Smith     }
2975bbead8a2SBarry Smith     break;
2976bbead8a2SBarry Smith   case 7:
2977bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2978bbead8a2SBarry 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;
2979bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
2980a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29817b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
2983bbead8a2SBarry Smith       diag += 49;
2984bbead8a2SBarry Smith     }
2985bbead8a2SBarry Smith     break;
2986bbead8a2SBarry Smith   default:
2987dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
2988bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2989bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
2990bbead8a2SBarry Smith         IJ[j] = bs*i + j;
2991bbead8a2SBarry Smith       }
2992bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
29935f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29947b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
2996bbead8a2SBarry Smith       diag += bs2;
2997bbead8a2SBarry Smith     }
2998bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
2999bbead8a2SBarry Smith   }
3000bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3001bbead8a2SBarry Smith   PetscFunctionReturn(0);
3002bbead8a2SBarry Smith }
3003bbead8a2SBarry Smith 
300473a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
300573a71a0fSBarry Smith {
300673a71a0fSBarry Smith   PetscErrorCode ierr;
300773a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
300873a71a0fSBarry Smith   PetscScalar    a;
300973a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
301073a71a0fSBarry Smith 
301173a71a0fSBarry Smith   PetscFunctionBegin;
301273a71a0fSBarry Smith   if (!x->assembled) {
301373a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
301473a71a0fSBarry Smith     for (i=0; i<m; i++) {
301573a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
301673a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
301773a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
301873a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
301973a71a0fSBarry Smith       }
302073a71a0fSBarry Smith     }
302173a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
302273a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
302373a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
302473a71a0fSBarry Smith   PetscFunctionReturn(0);
302573a71a0fSBarry Smith }
302673a71a0fSBarry Smith 
30277d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30287d68702bSBarry Smith {
30297d68702bSBarry Smith   PetscErrorCode ierr;
30307d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30317d68702bSBarry Smith 
30327d68702bSBarry Smith   PetscFunctionBegin;
30336f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30347d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30357d68702bSBarry Smith   }
30367d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30377d68702bSBarry Smith   PetscFunctionReturn(0);
30387d68702bSBarry Smith }
30397d68702bSBarry Smith 
3040682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30410a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3042cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3043cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3044cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
304597304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30467c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30477c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3048db4efbfdSBarry Smith                                         0,
3049db4efbfdSBarry Smith                                         0,
3050db4efbfdSBarry Smith                                         0,
3051db4efbfdSBarry Smith                                 /* 10*/ 0,
3052cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3053cb5b572fSBarry Smith                                         0,
305441f059aeSBarry Smith                                         MatSOR_SeqAIJ,
305517ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
305697304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3057cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3058cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3059cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3060cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
306197304618SKris Buschelman                                 /* 20*/ 0,
3062cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3063cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3064cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3065d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3066db4efbfdSBarry Smith                                         0,
3067db4efbfdSBarry Smith                                         0,
3068db4efbfdSBarry Smith                                         0,
3069db4efbfdSBarry Smith                                         0,
30704994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3071db4efbfdSBarry Smith                                         0,
3072db4efbfdSBarry Smith                                         0,
30738c778c55SBarry Smith                                         0,
30748c778c55SBarry Smith                                         0,
3075d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3076cb5b572fSBarry Smith                                         0,
3077cb5b572fSBarry Smith                                         0,
3078cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3079cb5b572fSBarry Smith                                         0,
3080d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
30817dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3082cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3083cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3084cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3085d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3086cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
30877d68702bSBarry Smith                                         MatShift_SeqAIJ,
308879299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
30896e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
309073a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
30913b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
30923b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
30933b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3094a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
309593dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3096b9617806SBarry Smith                                         0,
30970513a670SBarry Smith                                         0,
3098cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3099cda55fadSBarry Smith                                         0,
3100d519adbfSMatthew Knepley                                 /* 59*/ 0,
3101b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3102b9b97703SBarry Smith                                         MatView_SeqAIJ,
3103357abbc8SBarry Smith                                         0,
3104321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3105321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3106321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3107ee4f033dSBarry Smith                                         0,
3108ee4f033dSBarry Smith                                         0,
3109ee4f033dSBarry Smith                                         0,
3110d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3111c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3112ee4f033dSBarry Smith                                         0,
3113dcf5cc72SBarry Smith                                         0,
31142c93a97aSBarry Smith                                         0,
31152c93a97aSBarry Smith                                 /* 74*/ 0,
31163acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
311797304618SKris Buschelman                                         0,
311897304618SKris Buschelman                                         0,
311997304618SKris Buschelman                                         0,
31206ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
312197304618SKris Buschelman                                         0,
312297304618SKris Buschelman                                         0,
312397304618SKris Buschelman                                         0,
3124bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3125d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31261cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31276284ec50SHong Zhang                                         0,
31286284ec50SHong Zhang                                         0,
3129bc011b1eSHong Zhang                                         0,
3130d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
313126be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
313226be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
313365e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31344a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
313565e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31366fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31376fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31386fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31392121bac1SHong Zhang                                         0,
31402121bac1SHong Zhang                                 /* 99*/ 0,
3141609c6c4dSKris Buschelman                                         0,
3142609c6c4dSKris Buschelman                                         0,
314387d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
314487d4246cSBarry Smith                                         0,
3145d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
314699cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3147f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3148f5edf698SHong Zhang                                         0,
31492bebee5dSHong Zhang                                         0,
3150cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3151985db425SBarry Smith                                         0,
31522af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31532af78befSBarry Smith                                         0,
3154599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3155d519adbfSMatthew Knepley                                 /*114*/ 0,
3156599ef60dSHong Zhang                                         0,
31573c2a7987SHong Zhang                                         0,
3158fe97e370SBarry Smith                                         0,
3159fbdbba38SShri Abhyankar                                         0,
3160fbdbba38SShri Abhyankar                                 /*119*/ 0,
3161fbdbba38SShri Abhyankar                                         0,
3162fbdbba38SShri Abhyankar                                         0,
316382d44351SHong Zhang                                         0,
3164b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
31650716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3166bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
316737868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
316837868618SMatthew G Knepley                                         0,
316937868618SMatthew G Knepley                                         0,
31705df89d91SHong Zhang                                 /*129*/ 0,
317175648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
317275648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
317375648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3174b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3175b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
31762b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
31772b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
31782b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
31793964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
31803964eb88SJed Brown                                  /*139*/0,
3181f9426fe0SMark Adams                                         0,
31821919a2e2SJed Brown                                         0,
31833a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
31849c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
31859c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
31869e29f15eSvictorle };
318717ab2063SBarry Smith 
31887087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3189bef8e0ddSBarry Smith {
3190bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
319197f1f81fSBarry Smith   PetscInt   i,nz,n;
3192bef8e0ddSBarry Smith 
3193bef8e0ddSBarry Smith   PetscFunctionBegin;
3194bef8e0ddSBarry Smith   nz = aij->maxnz;
3195d0f46423SBarry Smith   n  = mat->rmap->n;
3196bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3197bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3198bef8e0ddSBarry Smith   }
3199bef8e0ddSBarry Smith   aij->nz = nz;
3200bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3201bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3202bef8e0ddSBarry Smith   }
3203bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3204bef8e0ddSBarry Smith }
3205bef8e0ddSBarry Smith 
3206bef8e0ddSBarry Smith /*@
3207bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3208bef8e0ddSBarry Smith        in the matrix.
3209bef8e0ddSBarry Smith 
3210bef8e0ddSBarry Smith   Input Parameters:
3211bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3212bef8e0ddSBarry Smith -  indices - the column indices
3213bef8e0ddSBarry Smith 
321415091d37SBarry Smith   Level: advanced
321515091d37SBarry Smith 
3216bef8e0ddSBarry Smith   Notes:
3217bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3218bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3219bef8e0ddSBarry Smith   of the MatSetValues() operation.
3220bef8e0ddSBarry Smith 
3221bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3222d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3223bef8e0ddSBarry Smith 
3224bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3225bef8e0ddSBarry Smith 
3226b9617806SBarry Smith     The indices should start with zero, not one.
3227b9617806SBarry Smith 
3228bef8e0ddSBarry Smith @*/
32297087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3230bef8e0ddSBarry Smith {
32314ac538c5SBarry Smith   PetscErrorCode ierr;
3232bef8e0ddSBarry Smith 
3233bef8e0ddSBarry Smith   PetscFunctionBegin;
32340700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32354482741eSBarry Smith   PetscValidPointer(indices,2);
32364ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3237bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3238bef8e0ddSBarry Smith }
3239bef8e0ddSBarry Smith 
3240be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3241be6bf707SBarry Smith 
32427087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3243be6bf707SBarry Smith {
3244be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32456849ba73SBarry Smith   PetscErrorCode ierr;
3246d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3247be6bf707SBarry Smith 
3248be6bf707SBarry Smith   PetscFunctionBegin;
3249169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3250be6bf707SBarry Smith 
3251be6bf707SBarry Smith   /* allocate space for values if not already there */
3252be6bf707SBarry Smith   if (!aij->saved_values) {
3253854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32543bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3255be6bf707SBarry Smith   }
3256be6bf707SBarry Smith 
3257be6bf707SBarry Smith   /* copy values over */
325887828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3259be6bf707SBarry Smith   PetscFunctionReturn(0);
3260be6bf707SBarry Smith }
3261be6bf707SBarry Smith 
3262be6bf707SBarry Smith /*@
3263be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3264be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3265be6bf707SBarry Smith        nonlinear portion.
3266be6bf707SBarry Smith 
3267be6bf707SBarry Smith    Collect on Mat
3268be6bf707SBarry Smith 
3269be6bf707SBarry Smith   Input Parameters:
32700e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3271be6bf707SBarry Smith 
327215091d37SBarry Smith   Level: advanced
327315091d37SBarry Smith 
3274be6bf707SBarry Smith   Common Usage, with SNESSolve():
3275be6bf707SBarry Smith $    Create Jacobian matrix
3276be6bf707SBarry Smith $    Set linear terms into matrix
3277be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3278be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3279be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3280512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3281be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3282be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3283be6bf707SBarry Smith $    In your Jacobian routine
3284be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3285be6bf707SBarry Smith $      Set nonlinear terms in matrix
3286be6bf707SBarry Smith 
3287be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3288be6bf707SBarry Smith $    // build linear portion of Jacobian
3289512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3290be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3291be6bf707SBarry Smith $    loop over nonlinear iterations
3292be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3293be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3294be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3295be6bf707SBarry Smith $       Solve linear system with Jacobian
3296be6bf707SBarry Smith $    endloop
3297be6bf707SBarry Smith 
3298be6bf707SBarry Smith   Notes:
3299be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3300512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3301be6bf707SBarry Smith     calling this routine.
3302be6bf707SBarry Smith 
33030c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33040c468ba9SBarry Smith     and does not allocated additional space.
33050c468ba9SBarry Smith 
3306be6bf707SBarry Smith .seealso: MatRetrieveValues()
3307be6bf707SBarry Smith 
3308be6bf707SBarry Smith @*/
33097087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3310be6bf707SBarry Smith {
33114ac538c5SBarry Smith   PetscErrorCode ierr;
3312be6bf707SBarry Smith 
3313be6bf707SBarry Smith   PetscFunctionBegin;
33140700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3315e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3316e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33174ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3318be6bf707SBarry Smith   PetscFunctionReturn(0);
3319be6bf707SBarry Smith }
3320be6bf707SBarry Smith 
33217087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3322be6bf707SBarry Smith {
3323be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33246849ba73SBarry Smith   PetscErrorCode ierr;
3325d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3326be6bf707SBarry Smith 
3327be6bf707SBarry Smith   PetscFunctionBegin;
3328169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3329f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3330be6bf707SBarry Smith   /* copy values over */
333187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3332be6bf707SBarry Smith   PetscFunctionReturn(0);
3333be6bf707SBarry Smith }
3334be6bf707SBarry Smith 
3335be6bf707SBarry Smith /*@
3336be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3337be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3338be6bf707SBarry Smith        nonlinear portion.
3339be6bf707SBarry Smith 
3340be6bf707SBarry Smith    Collect on Mat
3341be6bf707SBarry Smith 
3342be6bf707SBarry Smith   Input Parameters:
3343386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3344be6bf707SBarry Smith 
334515091d37SBarry Smith   Level: advanced
334615091d37SBarry Smith 
3347be6bf707SBarry Smith .seealso: MatStoreValues()
3348be6bf707SBarry Smith 
3349be6bf707SBarry Smith @*/
33507087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3351be6bf707SBarry Smith {
33524ac538c5SBarry Smith   PetscErrorCode ierr;
3353be6bf707SBarry Smith 
3354be6bf707SBarry Smith   PetscFunctionBegin;
33550700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3356e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3357e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33584ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3359be6bf707SBarry Smith   PetscFunctionReturn(0);
3360be6bf707SBarry Smith }
3361be6bf707SBarry Smith 
3362f83d6046SBarry Smith 
3363be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
336417ab2063SBarry Smith /*@C
3365682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33660d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33676e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
336851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33692bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
337017ab2063SBarry Smith 
3371db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3372db81eaa0SLois Curfman McInnes 
337317ab2063SBarry Smith    Input Parameters:
3374db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
337517ab2063SBarry Smith .  m - number of rows
337617ab2063SBarry Smith .  n - number of columns
337717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
337851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33790298fd71SBarry Smith          (possibly different for each row) or NULL
338017ab2063SBarry Smith 
338117ab2063SBarry Smith    Output Parameter:
3382416022c9SBarry Smith .  A - the matrix
338317ab2063SBarry Smith 
3384175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3385ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3386175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3387175b88e8SBarry Smith 
3388b259b22eSLois Curfman McInnes    Notes:
338949a6f317SBarry Smith    If nnz is given then nz is ignored
339049a6f317SBarry Smith 
339117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
339217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
33930002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
339444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
339517ab2063SBarry Smith 
339617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
33970298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
33983d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
33996da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
340017ab2063SBarry Smith 
3401682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34024fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3403682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34046c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34056c7ebb05SLois Curfman McInnes 
34066c7ebb05SLois Curfman McInnes    Options Database Keys:
3407698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34089db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
340917ab2063SBarry Smith 
3410027ccd11SLois Curfman McInnes    Level: intermediate
3411027ccd11SLois Curfman McInnes 
341269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
341336db0b34SBarry Smith 
341417ab2063SBarry Smith @*/
34157087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
341617ab2063SBarry Smith {
3417dfbe8321SBarry Smith   PetscErrorCode ierr;
34186945ee14SBarry Smith 
34193a40ed3dSBarry Smith   PetscFunctionBegin;
3420f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3421117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3422c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3423d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3424273d9f13SBarry Smith   PetscFunctionReturn(0);
3425273d9f13SBarry Smith }
3426273d9f13SBarry Smith 
3427273d9f13SBarry Smith /*@C
3428273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3429273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3430273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3431273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3432273d9f13SBarry Smith 
3433273d9f13SBarry Smith    Collective on MPI_Comm
3434273d9f13SBarry Smith 
3435273d9f13SBarry Smith    Input Parameters:
34361c4f3114SJed Brown +  B - The matrix
3437273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3438273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34390298fd71SBarry Smith          (possibly different for each row) or NULL
3440273d9f13SBarry Smith 
3441273d9f13SBarry Smith    Notes:
344249a6f317SBarry Smith      If nnz is given then nz is ignored
344349a6f317SBarry Smith 
3444273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3445273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3446273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3447273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3448273d9f13SBarry Smith 
3449273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34500298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3451273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3452273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3453273d9f13SBarry Smith 
3454aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3455aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3456aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3457aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3458aa95bbe8SBarry Smith 
3459a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3460a96a251dSBarry Smith    entries or columns indices
3461a96a251dSBarry Smith 
3462273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3463273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3464273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3465273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3466273d9f13SBarry Smith 
3467273d9f13SBarry Smith    Options Database Keys:
3468698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3469698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3470273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3471273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3472273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3473273d9f13SBarry Smith 
3474273d9f13SBarry Smith    Level: intermediate
3475273d9f13SBarry Smith 
347669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3477273d9f13SBarry Smith 
3478273d9f13SBarry Smith @*/
34797087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3480273d9f13SBarry Smith {
34814ac538c5SBarry Smith   PetscErrorCode ierr;
3482a23d5eceSKris Buschelman 
3483a23d5eceSKris Buschelman   PetscFunctionBegin;
34846ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
34856ba663aaSJed Brown   PetscValidType(B,1);
34864ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3487a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3488a23d5eceSKris Buschelman }
3489a23d5eceSKris Buschelman 
34907087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3491a23d5eceSKris Buschelman {
3492273d9f13SBarry Smith   Mat_SeqAIJ     *b;
34932576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
34946849ba73SBarry Smith   PetscErrorCode ierr;
349597f1f81fSBarry Smith   PetscInt       i;
3496273d9f13SBarry Smith 
3497273d9f13SBarry Smith   PetscFunctionBegin;
34982576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3499a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3500c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3501c461c341SBarry Smith     nz             = 0;
3502c461c341SBarry Smith   }
3503c461c341SBarry Smith 
350426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
350526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3506899cda47SBarry Smith 
3507435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
350860e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3509b73539f3SBarry Smith   if (nnz) {
3510d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
351160e0710aSBarry 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]);
351260e0710aSBarry 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);
3513b73539f3SBarry Smith     }
3514b73539f3SBarry Smith   }
3515b73539f3SBarry Smith 
3516273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35172205254eSKarl Rupp 
3518273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3519273d9f13SBarry Smith 
3520ab93d7beSBarry Smith   if (!skipallocation) {
35212ee49352SLisandro Dalcin     if (!b->imax) {
3522dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35233bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35242ee49352SLisandro Dalcin     }
3525273d9f13SBarry Smith     if (!nnz) {
3526435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3527c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3528d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3529d0f46423SBarry Smith       nz = nz*B->rmap->n;
3530273d9f13SBarry Smith     } else {
3531273d9f13SBarry Smith       nz = 0;
3532d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3533273d9f13SBarry Smith     }
3534ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35352205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3536ab93d7beSBarry Smith 
3537273d9f13SBarry Smith     /* allocate the matrix space */
353853dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35392ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3540dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35413bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3542bfeeae90SHong Zhang     b->i[0] = 0;
3543d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35445da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35455da197adSKris Buschelman     }
3546273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3547e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3548e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3549c461c341SBarry Smith   } else {
3550e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3551e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3552c461c341SBarry Smith   }
3553273d9f13SBarry Smith 
3554273d9f13SBarry Smith   b->nz               = 0;
3555273d9f13SBarry Smith   b->maxnz            = nz;
3556273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
35572205254eSKarl Rupp   if (realalloc) {
35582205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
35592205254eSKarl Rupp   }
3560cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3561cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3562273d9f13SBarry Smith   PetscFunctionReturn(0);
3563273d9f13SBarry Smith }
3564273d9f13SBarry Smith 
356558d36128SBarry Smith /*@
3566a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3567a1661176SMatthew Knepley 
3568a1661176SMatthew Knepley    Input Parameters:
3569a1661176SMatthew Knepley +  B - the matrix
3570a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3571a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3572a1661176SMatthew Knepley -  v - optional values in the matrix
3573a1661176SMatthew Knepley 
3574a1661176SMatthew Knepley    Level: developer
3575a1661176SMatthew Knepley 
357658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
357758d36128SBarry Smith 
3578a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3579a1661176SMatthew Knepley 
3580a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3581a1661176SMatthew Knepley @*/
3582a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3583a1661176SMatthew Knepley {
3584a1661176SMatthew Knepley   PetscErrorCode ierr;
3585a1661176SMatthew Knepley 
3586a1661176SMatthew Knepley   PetscFunctionBegin;
35870700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35886ba663aaSJed Brown   PetscValidType(B,1);
35894ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3590a1661176SMatthew Knepley   PetscFunctionReturn(0);
3591a1661176SMatthew Knepley }
3592a1661176SMatthew Knepley 
35937087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3594a1661176SMatthew Knepley {
3595a1661176SMatthew Knepley   PetscInt       i;
3596a1661176SMatthew Knepley   PetscInt       m,n;
3597a1661176SMatthew Knepley   PetscInt       nz;
3598a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3599a1661176SMatthew Knepley   PetscScalar    *values;
3600a1661176SMatthew Knepley   PetscErrorCode ierr;
3601a1661176SMatthew Knepley 
3602a1661176SMatthew Knepley   PetscFunctionBegin;
360365e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3604779a8d59SSatish Balay 
3605779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3606779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3607779a8d59SSatish Balay 
3608779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3609854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3610a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3611b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3612a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
361365e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3614a1661176SMatthew Knepley     nnz[i] = nz;
3615a1661176SMatthew Knepley   }
3616a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3617a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3618a1661176SMatthew Knepley 
3619a1661176SMatthew Knepley   if (v) {
3620a1661176SMatthew Knepley     values = (PetscScalar*) v;
3621a1661176SMatthew Knepley   } else {
36221795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3623a1661176SMatthew Knepley   }
3624a1661176SMatthew Knepley 
3625a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3626b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3627b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3628a1661176SMatthew Knepley   }
3629a1661176SMatthew Knepley 
3630a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3631a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3632a1661176SMatthew Knepley 
3633a1661176SMatthew Knepley   if (!v) {
3634a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3635a1661176SMatthew Knepley   }
36367827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3637a1661176SMatthew Knepley   PetscFunctionReturn(0);
3638a1661176SMatthew Knepley }
3639a1661176SMatthew Knepley 
3640c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3641af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3642170fe5c8SBarry Smith 
3643170fe5c8SBarry Smith /*
3644170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3645170fe5c8SBarry Smith 
3646170fe5c8SBarry Smith                n                       p                          p
3647170fe5c8SBarry Smith         (              )       (              )         (                  )
3648170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3649170fe5c8SBarry Smith         (              )       (              )         (                  )
3650170fe5c8SBarry Smith 
3651170fe5c8SBarry Smith */
3652170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3653170fe5c8SBarry Smith {
3654170fe5c8SBarry Smith   PetscErrorCode    ierr;
3655170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3656170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3657170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
36581de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3659170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3660170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3661170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3662170fe5c8SBarry Smith 
3663170fe5c8SBarry Smith   PetscFunctionBegin;
3664d0f46423SBarry Smith   m    = A->rmap->n;
3665d0f46423SBarry Smith   n    = A->cmap->n;
3666d0f46423SBarry Smith   p    = B->cmap->n;
3667170fe5c8SBarry Smith   a    = sub_a->v;
3668170fe5c8SBarry Smith   b    = sub_b->a;
3669170fe5c8SBarry Smith   c    = sub_c->v;
3670170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3671170fe5c8SBarry Smith 
3672170fe5c8SBarry Smith   ii  = sub_b->i;
3673170fe5c8SBarry Smith   idx = sub_b->j;
3674170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3675170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3676170fe5c8SBarry Smith     while (q-->0) {
3677170fe5c8SBarry Smith       c_q = c + m*(*idx);
3678170fe5c8SBarry Smith       a_q = a + m*i;
3679854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3680170fe5c8SBarry Smith       idx++;
3681170fe5c8SBarry Smith       b++;
3682170fe5c8SBarry Smith     }
3683170fe5c8SBarry Smith   }
3684170fe5c8SBarry Smith   PetscFunctionReturn(0);
3685170fe5c8SBarry Smith }
3686170fe5c8SBarry Smith 
3687170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3688170fe5c8SBarry Smith {
3689170fe5c8SBarry Smith   PetscErrorCode ierr;
3690d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3691170fe5c8SBarry Smith   Mat            Cmat;
3692170fe5c8SBarry Smith 
3693170fe5c8SBarry Smith   PetscFunctionBegin;
369460e0710aSBarry 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);
3695ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3696170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
369733d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3698170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
36990298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3700d73949e8SHong Zhang 
3701d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37022205254eSKarl Rupp 
3703170fe5c8SBarry Smith   *C = Cmat;
3704170fe5c8SBarry Smith   PetscFunctionReturn(0);
3705170fe5c8SBarry Smith }
3706170fe5c8SBarry Smith 
3707170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3708150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3709170fe5c8SBarry Smith {
3710170fe5c8SBarry Smith   PetscErrorCode ierr;
3711170fe5c8SBarry Smith 
3712170fe5c8SBarry Smith   PetscFunctionBegin;
3713170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37143ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3715170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37163ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3717170fe5c8SBarry Smith   }
37183ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3719170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37203ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3721170fe5c8SBarry Smith   PetscFunctionReturn(0);
3722170fe5c8SBarry Smith }
3723170fe5c8SBarry Smith 
3724170fe5c8SBarry Smith 
37250bad9183SKris Buschelman /*MC
3726fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37270bad9183SKris Buschelman    based on compressed sparse row format.
37280bad9183SKris Buschelman 
37290bad9183SKris Buschelman    Options Database Keys:
37300bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37310bad9183SKris Buschelman 
37320bad9183SKris Buschelman   Level: beginner
37330bad9183SKris Buschelman 
3734f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37350bad9183SKris Buschelman M*/
37360bad9183SKris Buschelman 
3737ccd284c7SBarry Smith /*MC
3738ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3739ccd284c7SBarry Smith 
3740ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3741ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3742ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3743ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3744ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3745ccd284c7SBarry Smith 
3746ccd284c7SBarry Smith    Options Database Keys:
3747ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3748ccd284c7SBarry Smith 
3749ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3750ccd284c7SBarry Smith    enough exist.
3751ccd284c7SBarry Smith 
3752ccd284c7SBarry Smith   Level: beginner
3753ccd284c7SBarry Smith 
3754ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3755ccd284c7SBarry Smith M*/
3756ccd284c7SBarry Smith 
3757ccd284c7SBarry Smith /*MC
3758ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3759ccd284c7SBarry Smith 
3760ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3761ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3762ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3763ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3764ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3765ccd284c7SBarry Smith 
3766ccd284c7SBarry Smith    Options Database Keys:
3767ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3768ccd284c7SBarry Smith 
3769ccd284c7SBarry Smith   Level: beginner
3770ccd284c7SBarry Smith 
3771ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3772ccd284c7SBarry Smith M*/
3773ccd284c7SBarry Smith 
3774cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3775af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3776cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3777af8000cdSHong Zhang #endif
377863c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
377963c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
37803dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
378163c07aadSStefano Zampini #endif
3782cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
378342c9c57cSBarry Smith 
3784b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
378529b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
378629b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3787b3866ffcSBarry Smith #endif
378817667f90SBarry Smith 
3789c0c8ee5eSDmitry Karpeev 
37908c778c55SBarry Smith /*@C
37918397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
37928c778c55SBarry Smith 
37938c778c55SBarry Smith    Not Collective
37948c778c55SBarry Smith 
37958c778c55SBarry Smith    Input Parameter:
3796579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
37978c778c55SBarry Smith 
37988c778c55SBarry Smith    Output Parameter:
37998c778c55SBarry Smith .   array - pointer to the data
38008c778c55SBarry Smith 
38018c778c55SBarry Smith    Level: intermediate
38028c778c55SBarry Smith 
3803774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38048c778c55SBarry Smith @*/
38058c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38068c778c55SBarry Smith {
38078c778c55SBarry Smith   PetscErrorCode ierr;
38088c778c55SBarry Smith 
38098c778c55SBarry Smith   PetscFunctionBegin;
38108c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38118c778c55SBarry Smith   PetscFunctionReturn(0);
38128c778c55SBarry Smith }
38138c778c55SBarry Smith 
381421e72a00SBarry Smith /*@C
381521e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
381621e72a00SBarry Smith 
381721e72a00SBarry Smith    Not Collective
381821e72a00SBarry Smith 
381921e72a00SBarry Smith    Input Parameter:
3820579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
382121e72a00SBarry Smith 
382221e72a00SBarry Smith    Output Parameter:
382321e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
382421e72a00SBarry Smith 
382521e72a00SBarry Smith    Level: intermediate
382621e72a00SBarry Smith 
382721e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
382821e72a00SBarry Smith @*/
382921e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
383021e72a00SBarry Smith {
383121e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
383221e72a00SBarry Smith 
383321e72a00SBarry Smith   PetscFunctionBegin;
383421e72a00SBarry Smith   *nz = aij->rmax;
383521e72a00SBarry Smith   PetscFunctionReturn(0);
383621e72a00SBarry Smith }
383721e72a00SBarry Smith 
38388c778c55SBarry Smith /*@C
3839579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38408c778c55SBarry Smith 
38418c778c55SBarry Smith    Not Collective
38428c778c55SBarry Smith 
38438c778c55SBarry Smith    Input Parameters:
3844579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38458c778c55SBarry Smith .  array - pointer to the data
38468c778c55SBarry Smith 
38478c778c55SBarry Smith    Level: intermediate
38488c778c55SBarry Smith 
3849774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
38508c778c55SBarry Smith @*/
38518c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
38528c778c55SBarry Smith {
38538c778c55SBarry Smith   PetscErrorCode ierr;
38548c778c55SBarry Smith 
38558c778c55SBarry Smith   PetscFunctionBegin;
38568c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38578c778c55SBarry Smith   PetscFunctionReturn(0);
38588c778c55SBarry Smith }
38598c778c55SBarry Smith 
38608cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3861273d9f13SBarry Smith {
3862273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3863dfbe8321SBarry Smith   PetscErrorCode ierr;
386438baddfdSBarry Smith   PetscMPIInt    size;
3865273d9f13SBarry Smith 
3866273d9f13SBarry Smith   PetscFunctionBegin;
3867ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3868e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3869273d9f13SBarry Smith 
3870b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
38712205254eSKarl Rupp 
3872b0a32e0cSBarry Smith   B->data = (void*)b;
38732205254eSKarl Rupp 
3874549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
38752205254eSKarl Rupp 
3876416022c9SBarry Smith   b->row                = 0;
3877416022c9SBarry Smith   b->col                = 0;
387882bf6240SBarry Smith   b->icol               = 0;
3879b810aeb4SBarry Smith   b->reallocs           = 0;
388036db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3881f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3882416022c9SBarry Smith   b->nonew              = 0;
3883416022c9SBarry Smith   b->diag               = 0;
3884416022c9SBarry Smith   b->solve_work         = 0;
38852a1b7f2aSHong Zhang   B->spptr              = 0;
3886be6bf707SBarry Smith   b->saved_values       = 0;
3887d7f994e1SBarry Smith   b->idiag              = 0;
388871f1c65dSBarry Smith   b->mdiag              = 0;
388971f1c65dSBarry Smith   b->ssor_work          = 0;
389071f1c65dSBarry Smith   b->omega              = 1.0;
389171f1c65dSBarry Smith   b->fshift             = 0.0;
389271f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3893bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3894a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
389517ab2063SBarry Smith 
389635d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3897bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3898bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
38998c778c55SBarry Smith 
3900b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3901bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3902bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3903b3866ffcSBarry Smith #endif
390417f1a0eaSHong Zhang 
3905bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3906bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3907bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3908bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3909bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3910bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3911bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3912af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3913af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3914af8000cdSHong Zhang #endif
391563c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
391663c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39173dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
391863c07aadSStefano Zampini #endif
3919b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3920bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3921bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3922bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3923bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3924bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3925bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3926bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3927bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39284108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
392917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39303a40ed3dSBarry Smith   PetscFunctionReturn(0);
393117ab2063SBarry Smith }
393217ab2063SBarry Smith 
3933b24902e0SBarry Smith /*
3934b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3935b24902e0SBarry Smith */
3936ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
393717ab2063SBarry Smith {
3938416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39396849ba73SBarry Smith   PetscErrorCode ierr;
3940d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
394117ab2063SBarry Smith 
39423a40ed3dSBarry Smith   PetscFunctionBegin;
3943273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3944273d9f13SBarry Smith 
3945d5f3da31SBarry Smith   C->factortype = A->factortype;
3946416022c9SBarry Smith   c->row        = 0;
3947416022c9SBarry Smith   c->col        = 0;
394882bf6240SBarry Smith   c->icol       = 0;
39496ad4291fSHong Zhang   c->reallocs   = 0;
395017ab2063SBarry Smith 
39516ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
395217ab2063SBarry Smith 
3953aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3954aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3955eec197d1SBarry Smith 
3956dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
39573bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
395817ab2063SBarry Smith   for (i=0; i<m; i++) {
3959416022c9SBarry Smith     c->imax[i] = a->imax[i];
3960416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
396117ab2063SBarry Smith   }
396217ab2063SBarry Smith 
396317ab2063SBarry Smith   /* allocate the matrix space */
3964f77e22a1SHong Zhang   if (mallocmatspace) {
3965dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
39663bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
39672205254eSKarl Rupp 
3968f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
39692205254eSKarl Rupp 
397097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
397117ab2063SBarry Smith     if (m > 0) {
397297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3973be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3974bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3975be6bf707SBarry Smith       } else {
3976bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
397717ab2063SBarry Smith       }
397808480c60SBarry Smith     }
3979f77e22a1SHong Zhang   }
398017ab2063SBarry Smith 
39816ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3982416022c9SBarry Smith   c->roworiented       = a->roworiented;
3983416022c9SBarry Smith   c->nonew             = a->nonew;
3984416022c9SBarry Smith   if (a->diag) {
3985854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
39863bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
398717ab2063SBarry Smith     for (i=0; i<m; i++) {
3988416022c9SBarry Smith       c->diag[i] = a->diag[i];
398917ab2063SBarry Smith     }
39903a40ed3dSBarry Smith   } else c->diag = 0;
39912205254eSKarl Rupp 
39926ad4291fSHong Zhang   c->solve_work         = 0;
39936ad4291fSHong Zhang   c->saved_values       = 0;
39946ad4291fSHong Zhang   c->idiag              = 0;
399571f1c65dSBarry Smith   c->ssor_work          = 0;
3996a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
3997e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
3998e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
39996ad4291fSHong Zhang 
4000893ad86cSHong Zhang   c->rmax         = a->rmax;
4001416022c9SBarry Smith   c->nz           = a->nz;
40028ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4003273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4004754ec7b1SSatish Balay 
40056ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40066ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4007cd6b891eSBarry Smith   if (a->compressedrow.use) {
40086ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4009dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40106ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40116ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
401227ea64f8SHong Zhang   } else {
401327ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40140298fd71SBarry Smith     c->compressedrow.i      = NULL;
40150298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40166ad4291fSHong Zhang   }
4017ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4018e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40194846f1f5SKris Buschelman 
40202205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4021140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40223a40ed3dSBarry Smith   PetscFunctionReturn(0);
402317ab2063SBarry Smith }
402417ab2063SBarry Smith 
4025b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4026b24902e0SBarry Smith {
4027b24902e0SBarry Smith   PetscErrorCode ierr;
4028b24902e0SBarry Smith 
4029b24902e0SBarry Smith   PetscFunctionBegin;
4030ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40314b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4032cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
403333d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4034cfd3f464SBarry Smith   }
4035a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4036f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4037b24902e0SBarry Smith   PetscFunctionReturn(0);
4038b24902e0SBarry Smith }
4039b24902e0SBarry Smith 
4040112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4041fbdbba38SShri Abhyankar {
4042fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4043fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4044fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4045fbdbba38SShri Abhyankar   int            fd;
4046fbdbba38SShri Abhyankar   PetscMPIInt    size;
4047fbdbba38SShri Abhyankar   MPI_Comm       comm;
40483059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4049fbdbba38SShri Abhyankar 
4050fbdbba38SShri Abhyankar   PetscFunctionBegin;
4051c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4052c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4053fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4054fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4055fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4056bbead8a2SBarry Smith 
40570298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
40580298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4059bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40603059b6faSBarry Smith   if (bs < 0) bs = 1;
40613059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4062bbead8a2SBarry Smith 
4063fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4064fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4065fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4066fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4067fbdbba38SShri Abhyankar 
4068bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4069fbdbba38SShri Abhyankar 
4070fbdbba38SShri Abhyankar   /* read in row lengths */
4071785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4072fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4073fbdbba38SShri Abhyankar 
4074fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4075fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
407660e0710aSBarry 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);
4077fbdbba38SShri Abhyankar 
4078fbdbba38SShri Abhyankar   /* set global size if not set already*/
4079f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4080fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4081aabbc4fbSShri Abhyankar   } else {
40829d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4083fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
40844c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
40854c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
40864c5b953cSHong Zhang     }
408760e0710aSBarry 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);
4088aabbc4fbSShri Abhyankar   }
4089fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4090fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4091fbdbba38SShri Abhyankar 
4092fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4093fbdbba38SShri Abhyankar 
4094fbdbba38SShri Abhyankar   /* read in nonzero values */
4095fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4096fbdbba38SShri Abhyankar 
4097fbdbba38SShri Abhyankar   /* set matrix "i" values */
4098fbdbba38SShri Abhyankar   a->i[0] = 0;
4099fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4100fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4101fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4102fbdbba38SShri Abhyankar   }
4103fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4104fbdbba38SShri Abhyankar 
4105fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4106fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4107fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4108fbdbba38SShri Abhyankar }
4109fbdbba38SShri Abhyankar 
4110ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41117264ac53SSatish Balay {
41127264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4113dfbe8321SBarry Smith   PetscErrorCode ierr;
4114eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4115eeffb40dSHong Zhang   PetscInt k;
4116eeffb40dSHong Zhang #endif
41177264ac53SSatish Balay 
41183a40ed3dSBarry Smith   PetscFunctionBegin;
4119bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4120d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4121ca44d042SBarry Smith     *flg = PETSC_FALSE;
4122ca44d042SBarry Smith     PetscFunctionReturn(0);
4123bcd2baecSBarry Smith   }
41247264ac53SSatish Balay 
41257264ac53SSatish Balay   /* if the a->i are the same */
4126d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4127abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41287264ac53SSatish Balay 
41297264ac53SSatish Balay   /* if a->j are the same */
413097f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4131abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4132bcd2baecSBarry Smith 
4133bcd2baecSBarry Smith   /* if a->a are the same */
4134eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4135eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4136eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4137eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41383a40ed3dSBarry Smith       PetscFunctionReturn(0);
4139eeffb40dSHong Zhang     }
4140eeffb40dSHong Zhang   }
4141eeffb40dSHong Zhang #else
4142eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4143eeffb40dSHong Zhang #endif
4144eeffb40dSHong Zhang   PetscFunctionReturn(0);
41457264ac53SSatish Balay }
414636db0b34SBarry Smith 
414705869f15SSatish Balay /*@
414836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
414936db0b34SBarry Smith               provided by the user.
415036db0b34SBarry Smith 
4151c75a6043SHong Zhang       Collective on MPI_Comm
415236db0b34SBarry Smith 
415336db0b34SBarry Smith    Input Parameters:
415436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
415536db0b34SBarry Smith .   m - number of rows
415636db0b34SBarry Smith .   n - number of columns
415736db0b34SBarry Smith .   i - row indices
415836db0b34SBarry Smith .   j - column indices
415936db0b34SBarry Smith -   a - matrix values
416036db0b34SBarry Smith 
416136db0b34SBarry Smith    Output Parameter:
416236db0b34SBarry Smith .   mat - the matrix
416336db0b34SBarry Smith 
416436db0b34SBarry Smith    Level: intermediate
416536db0b34SBarry Smith 
416636db0b34SBarry Smith    Notes:
41670551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4168292fb18eSBarry Smith     once the matrix is destroyed and not before
416936db0b34SBarry Smith 
417036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
417136db0b34SBarry Smith 
4172bfeeae90SHong Zhang        The i and j indices are 0 based
417336db0b34SBarry Smith 
4174a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4175a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
41768eef79e4SBarry Smith     as shown
4177a4552177SSatish Balay 
41788eef79e4SBarry Smith $        1 0 0
41798eef79e4SBarry Smith $        2 0 3
41808eef79e4SBarry Smith $        4 5 6
41818eef79e4SBarry Smith $
41828eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
41838eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
41848eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4185a4552177SSatish Balay 
41869985e31cSBarry Smith 
418769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
418836db0b34SBarry Smith 
418936db0b34SBarry Smith @*/
4190c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
419136db0b34SBarry Smith {
4192dfbe8321SBarry Smith   PetscErrorCode ierr;
4193cbcfb4deSHong Zhang   PetscInt       ii;
419436db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4195cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4196cbcfb4deSHong Zhang   PetscInt jj;
4197cbcfb4deSHong Zhang #endif
419836db0b34SBarry Smith 
419936db0b34SBarry Smith   PetscFunctionBegin;
420041096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4201f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4202f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4203a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4204ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4205ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4206ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4207dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4208ab93d7beSBarry Smith 
420936db0b34SBarry Smith   aij->i            = i;
421036db0b34SBarry Smith   aij->j            = j;
421136db0b34SBarry Smith   aij->a            = a;
421236db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
421336db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4214e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4215e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
421636db0b34SBarry Smith 
421736db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
421836db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42192515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
422060e0710aSBarry 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]);
42219985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4222e32f2f54SBarry 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);
4223e32f2f54SBarry 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);
42249985e31cSBarry Smith     }
422536db0b34SBarry Smith #endif
422636db0b34SBarry Smith   }
42272515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
422836db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
422960e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
423060e0710aSBarry 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]);
423136db0b34SBarry Smith   }
423236db0b34SBarry Smith #endif
423336db0b34SBarry Smith 
4234b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4235b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
423636db0b34SBarry Smith   PetscFunctionReturn(0);
423736db0b34SBarry Smith }
423880ef6e79SMatthew G Knepley /*@C
4239d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42408a0b0e6bSVictor Minden               provided by the user.
42418a0b0e6bSVictor Minden 
42428a0b0e6bSVictor Minden       Collective on MPI_Comm
42438a0b0e6bSVictor Minden 
42448a0b0e6bSVictor Minden    Input Parameters:
42458a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42468a0b0e6bSVictor Minden .   m   - number of rows
42478a0b0e6bSVictor Minden .   n   - number of columns
42488a0b0e6bSVictor Minden .   i   - row indices
42498a0b0e6bSVictor Minden .   j   - column indices
42501230e6d1SVictor Minden .   a   - matrix values
42511230e6d1SVictor Minden .   nz  - number of nonzeros
42521230e6d1SVictor Minden -   idx - 0 or 1 based
42538a0b0e6bSVictor Minden 
42548a0b0e6bSVictor Minden    Output Parameter:
42558a0b0e6bSVictor Minden .   mat - the matrix
42568a0b0e6bSVictor Minden 
42578a0b0e6bSVictor Minden    Level: intermediate
42588a0b0e6bSVictor Minden 
42598a0b0e6bSVictor Minden    Notes:
42608a0b0e6bSVictor Minden        The i and j indices are 0 based
42618a0b0e6bSVictor Minden 
42628a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
42638a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
42648a0b0e6bSVictor Minden     as shown:
42658a0b0e6bSVictor Minden 
42668a0b0e6bSVictor Minden         1 0 0
42678a0b0e6bSVictor Minden         2 0 3
42688a0b0e6bSVictor Minden         4 5 6
42698a0b0e6bSVictor Minden 
42708a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
42718a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
42728a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
42738a0b0e6bSVictor Minden 
42748a0b0e6bSVictor Minden 
427569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
42768a0b0e6bSVictor Minden 
42778a0b0e6bSVictor Minden @*/
4278c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
42798a0b0e6bSVictor Minden {
42808a0b0e6bSVictor Minden   PetscErrorCode ierr;
4281d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
42828a0b0e6bSVictor Minden 
42838a0b0e6bSVictor Minden 
42848a0b0e6bSVictor Minden   PetscFunctionBegin;
42851795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
42861230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4287c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
42881230e6d1SVictor Minden   }
42898a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
42908a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
42918a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
42921230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
42931230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
42941230e6d1SVictor Minden     if (idx) {
42951230e6d1SVictor Minden       row = i[ii] - 1;
42961230e6d1SVictor Minden       col = j[ii] - 1;
42971230e6d1SVictor Minden     } else {
42981230e6d1SVictor Minden       row = i[ii];
42991230e6d1SVictor Minden       col = j[ii];
43008a0b0e6bSVictor Minden     }
43011230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43028a0b0e6bSVictor Minden   }
43038a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43048a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4305d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43068a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43078a0b0e6bSVictor Minden }
430836db0b34SBarry Smith 
4309acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4310acf2f550SJed Brown {
4311acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4312acf2f550SJed Brown   PetscErrorCode ierr;
4313acf2f550SJed Brown 
4314acf2f550SJed Brown   PetscFunctionBegin;
4315acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4316acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43172205254eSKarl Rupp 
4318acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4319acf2f550SJed Brown   PetscFunctionReturn(0);
4320acf2f550SJed Brown }
4321acf2f550SJed Brown 
43229c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43239c8f2541SHong Zhang {
43249c8f2541SHong Zhang   PetscErrorCode ierr;
43258761c3d6SHong Zhang   PetscMPIInt    size;
43269c8f2541SHong Zhang 
43279c8f2541SHong Zhang   PetscFunctionBegin;
43288761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43298761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43308761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43318761c3d6SHong Zhang   } else {
43329c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43338761c3d6SHong Zhang   }
43349c8f2541SHong Zhang   PetscFunctionReturn(0);
43359c8f2541SHong Zhang }
43369c8f2541SHong Zhang 
433781824310SBarry Smith /*
433853dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
433953dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
434053dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
434153dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
434253dd7562SDmitry Karpeev  */
434353dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
434453dd7562SDmitry Karpeev {
434553dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
434653dd7562SDmitry Karpeev   PetscErrorCode ierr;
434753dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
434853dd7562SDmitry Karpeev   PetscBool      seqaij;
434953dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
435053dd7562SDmitry Karpeev   PetscScalar    v;
435153dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
435253dd7562SDmitry Karpeev 
435353dd7562SDmitry Karpeev   PetscFunctionBegin;
435453dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
435553dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
435653dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
435753dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
435853dd7562SDmitry Karpeev   if (rowemb) {
435953dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
436053dd7562SDmitry 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);
436153dd7562SDmitry Karpeev   } else {
43626c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
436353dd7562SDmitry Karpeev   }
436453dd7562SDmitry Karpeev   if (colemb) {
436553dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
436653dd7562SDmitry 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);
436753dd7562SDmitry Karpeev   } else {
436853dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
436953dd7562SDmitry Karpeev   }
437053dd7562SDmitry Karpeev 
437153dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
437253dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
437353dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
437453dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
437553dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
437653dd7562SDmitry Karpeev     }
437753dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
437853dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
437953dd7562SDmitry Karpeev   }
438053dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
438153dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
438253dd7562SDmitry Karpeev   }
438353dd7562SDmitry Karpeev   count = 0;
438453dd7562SDmitry Karpeev   rowindices = NULL;
438553dd7562SDmitry Karpeev   colindices = NULL;
438653dd7562SDmitry Karpeev   if (rowemb) {
438753dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
438853dd7562SDmitry Karpeev   }
438953dd7562SDmitry Karpeev   if (colemb) {
439053dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
439153dd7562SDmitry Karpeev   }
439253dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
439353dd7562SDmitry Karpeev     PetscInt row;
439453dd7562SDmitry Karpeev     row = i;
439553dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
439653dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
439753dd7562SDmitry Karpeev       PetscInt col;
439853dd7562SDmitry Karpeev       col  = Baij->j[count];
439953dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
440053dd7562SDmitry Karpeev       v    = Baij->a[count];
440153dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
440253dd7562SDmitry Karpeev       ++count;
440353dd7562SDmitry Karpeev     }
440453dd7562SDmitry Karpeev   }
440553dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
440653dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
440753dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
440853dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
440953dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
441053dd7562SDmitry Karpeev   PetscFunctionReturn(0);
441153dd7562SDmitry Karpeev }
441253dd7562SDmitry Karpeev 
441353dd7562SDmitry Karpeev 
441453dd7562SDmitry Karpeev /*
441581824310SBarry Smith     Special version for direct calls from Fortran
441681824310SBarry Smith */
4417af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
441881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
441981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
442081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
442181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
442281824310SBarry Smith #endif
442381824310SBarry Smith 
442481824310SBarry Smith /* Change these macros so can be used in void function */
442581824310SBarry Smith #undef CHKERRQ
4426ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
442781824310SBarry Smith #undef SETERRQ2
4428e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44294994cf47SJed Brown #undef SETERRQ3
44304994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
443181824310SBarry Smith 
44328cc058d9SJed 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)
443381824310SBarry Smith {
443481824310SBarry Smith   Mat            A  = *AA;
443581824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
443681824310SBarry Smith   InsertMode     is = *isis;
443781824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
443881824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
443981824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
444081824310SBarry Smith   PetscErrorCode ierr;
444181824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
444254f21887SBarry Smith   MatScalar      *ap,value,*aa;
4443ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4444ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
444581824310SBarry Smith 
444681824310SBarry Smith   PetscFunctionBegin;
44474994cf47SJed Brown   MatCheckPreallocated(A,1);
444881824310SBarry Smith   imax  = a->imax;
444981824310SBarry Smith   ai    = a->i;
445081824310SBarry Smith   ailen = a->ilen;
445181824310SBarry Smith   aj    = a->j;
445281824310SBarry Smith   aa    = a->a;
445381824310SBarry Smith 
445481824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
445581824310SBarry Smith     row = im[k];
445681824310SBarry Smith     if (row < 0) continue;
445781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4458ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
445981824310SBarry Smith #endif
446081824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
446181824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
446281824310SBarry Smith     low  = 0;
446381824310SBarry Smith     high = nrow;
446481824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
446581824310SBarry Smith       if (in[l] < 0) continue;
446681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4467ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
446881824310SBarry Smith #endif
446981824310SBarry Smith       col = in[l];
44702205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
44712205254eSKarl Rupp       else value = v[k + l*m];
44722205254eSKarl Rupp 
447381824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
447481824310SBarry Smith 
44752205254eSKarl Rupp       if (col <= lastcol) low = 0;
44762205254eSKarl Rupp       else high = nrow;
447781824310SBarry Smith       lastcol = col;
447881824310SBarry Smith       while (high-low > 5) {
447981824310SBarry Smith         t = (low+high)/2;
448081824310SBarry Smith         if (rp[t] > col) high = t;
448181824310SBarry Smith         else             low  = t;
448281824310SBarry Smith       }
448381824310SBarry Smith       for (i=low; i<high; i++) {
448481824310SBarry Smith         if (rp[i] > col) break;
448581824310SBarry Smith         if (rp[i] == col) {
448681824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
448781824310SBarry Smith           else                  ap[i] = value;
448881824310SBarry Smith           goto noinsert;
448981824310SBarry Smith         }
449081824310SBarry Smith       }
449181824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
449281824310SBarry Smith       if (nonew == 1) goto noinsert;
4493ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4494fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
449581824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
449681824310SBarry Smith       /* shift up all the later entries in this row */
449781824310SBarry Smith       for (ii=N; ii>=i; ii--) {
449881824310SBarry Smith         rp[ii+1] = rp[ii];
449981824310SBarry Smith         ap[ii+1] = ap[ii];
450081824310SBarry Smith       }
450181824310SBarry Smith       rp[i] = col;
450281824310SBarry Smith       ap[i] = value;
4503e56f5c9eSBarry Smith       A->nonzerostate++;
450481824310SBarry Smith noinsert:;
450581824310SBarry Smith       low = i + 1;
450681824310SBarry Smith     }
450781824310SBarry Smith     ailen[row] = nrow;
450881824310SBarry Smith   }
450981824310SBarry Smith   PetscFunctionReturnVoid();
451081824310SBarry Smith }
45119f7953f8SBarry Smith 
4512