xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 396832f4eb76c91485bdccdc3da25c0fe0234b6e)
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
418720833daSHong Zhang     rp   = aj + ai[row];
419876c6284SHong Zhang     if (!A->structure_only) ap = aa + ai[row];
42017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
421416022c9SBarry Smith     low  = 0;
422c71e6ed7SBarry Smith     high = nrow;
42317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4245ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4252515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
426e32f2f54SBarry 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);
4273b2fbd54SBarry Smith #endif
428bfeeae90SHong Zhang       col = in[l];
429720833daSHong Zhang       if (!A->structure_only) {
4304b0e389bSBarry Smith         if (roworiented) {
4315ef9f2a5SBarry Smith           value = v[l + k*n];
432bef8e0ddSBarry Smith         } else {
4334b0e389bSBarry Smith           value = v[k + l*m];
4344b0e389bSBarry Smith         }
435720833daSHong Zhang       } else { /* A->structure_only */
436720833daSHong Zhang         value = 1; /* avoid 'continue' below?  */
437720833daSHong Zhang       }
438dcd36c23SBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue;
43936db0b34SBarry Smith 
4402205254eSKarl Rupp       if (col <= lastcol) low = 0;
4412205254eSKarl Rupp       else high = nrow;
442e2ee6c50SBarry Smith       lastcol = col;
443416022c9SBarry Smith       while (high-low > 5) {
444416022c9SBarry Smith         t = (low+high)/2;
445416022c9SBarry Smith         if (rp[t] > col) high = t;
446416022c9SBarry Smith         else low = t;
44717ab2063SBarry Smith       }
448416022c9SBarry Smith       for (i=low; i<high; i++) {
44917ab2063SBarry Smith         if (rp[i] > col) break;
45017ab2063SBarry Smith         if (rp[i] == col) {
451876c6284SHong Zhang           if (!A->structure_only) {
452416022c9SBarry Smith             if (is == ADD_VALUES) ap[i] += value;
45317ab2063SBarry Smith             else ap[i] = value;
454720833daSHong Zhang           }
455e44c0bd4SBarry Smith           low = i + 1;
45617ab2063SBarry Smith           goto noinsert;
45717ab2063SBarry Smith         }
45817ab2063SBarry Smith       }
459dcd36c23SBarry Smith       if (value == 0.0 && ignorezeroentries && row != col) goto noinsert;
460c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
461e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
462720833daSHong Zhang       if (A->structure_only) {
463876c6284SHong Zhang         MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar);
464720833daSHong Zhang       } else {
465fef13f97SBarry Smith         MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
466720833daSHong Zhang       }
467c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
468416022c9SBarry Smith       /* shift up all the later entries in this row */
469416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
47017ab2063SBarry Smith         rp[ii+1] = rp[ii];
471876c6284SHong Zhang         if (!A->structure_only) ap[ii+1] = ap[ii];
472720833daSHong Zhang       }
47317ab2063SBarry Smith       rp[i] = col;
474876c6284SHong Zhang       if (!A->structure_only) ap[i] = value;
475416022c9SBarry Smith       low   = i + 1;
476e56f5c9eSBarry Smith       A->nonzerostate++;
477e44c0bd4SBarry Smith noinsert:;
47817ab2063SBarry Smith     }
47917ab2063SBarry Smith     ailen[row] = nrow;
48017ab2063SBarry Smith   }
4813a40ed3dSBarry Smith   PetscFunctionReturn(0);
48217ab2063SBarry Smith }
48317ab2063SBarry Smith 
48481824310SBarry Smith 
485a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4867eb43aa7SLois Curfman McInnes {
4877eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
48897f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
48997f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
49054f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4917eb43aa7SLois Curfman McInnes 
4923a40ed3dSBarry Smith   PetscFunctionBegin;
4937eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4947eb43aa7SLois Curfman McInnes     row = im[k];
495e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
496e32f2f54SBarry 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);
497bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4987eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4997eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
500e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
501e32f2f54SBarry 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);
502bfeeae90SHong Zhang       col  = in[l];
5037eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5047eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5057eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5067eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5077eb43aa7SLois Curfman McInnes         else low = t;
5087eb43aa7SLois Curfman McInnes       }
5097eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5107eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5117eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
512b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5137eb43aa7SLois Curfman McInnes           goto finished;
5147eb43aa7SLois Curfman McInnes         }
5157eb43aa7SLois Curfman McInnes       }
51697e567efSBarry Smith       *v++ = 0.0;
5177eb43aa7SLois Curfman McInnes finished:;
5187eb43aa7SLois Curfman McInnes     }
5197eb43aa7SLois Curfman McInnes   }
5203a40ed3dSBarry Smith   PetscFunctionReturn(0);
5217eb43aa7SLois Curfman McInnes }
5227eb43aa7SLois Curfman McInnes 
52317ab2063SBarry Smith 
524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
52517ab2063SBarry Smith {
526416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5276849ba73SBarry Smith   PetscErrorCode ierr;
5286f69ff64SBarry Smith   PetscInt       i,*col_lens;
5296f69ff64SBarry Smith   int            fd;
530b37d52dbSMark F. Adams   FILE           *file;
53117ab2063SBarry Smith 
5323a40ed3dSBarry Smith   PetscFunctionBegin;
533b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
534854ce69bSBarry Smith   ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr);
5352205254eSKarl Rupp 
5360700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
537d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
538d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
539416022c9SBarry Smith   col_lens[3] = a->nz;
540416022c9SBarry Smith 
541416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
542d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
543416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
54417ab2063SBarry Smith   }
545d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
546606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
547416022c9SBarry Smith 
548416022c9SBarry Smith   /* store column indices (zero start index) */
5496f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
550416022c9SBarry Smith 
551416022c9SBarry Smith   /* store nonzero values */
5526f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
553b37d52dbSMark F. Adams 
554b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
555b37d52dbSMark F. Adams   if (file) {
55633d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
557b37d52dbSMark F. Adams   }
5583a40ed3dSBarry Smith   PetscFunctionReturn(0);
55917ab2063SBarry Smith }
560416022c9SBarry Smith 
56109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
562cd155464SBarry Smith 
563dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
564416022c9SBarry Smith {
565416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
566dfbe8321SBarry Smith   PetscErrorCode    ierr;
56760e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
568e060cb09SBarry Smith   const char        *name;
569f3ef73ceSBarry Smith   PetscViewerFormat format;
57017ab2063SBarry Smith 
5713a40ed3dSBarry Smith   PetscFunctionBegin;
57243e49210SHong Zhang   if (!a->a) PetscFunctionReturn(0);
57343e49210SHong Zhang 
574b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
57571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
57697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
57760e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
578c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
579d00d2cf4SBarry Smith       nofinalvalue = 1;
580d00d2cf4SBarry Smith     }
581d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
582d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
58377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
584fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
585fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
586fbfe6fa7SJed Brown #else
58777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
588fbfe6fa7SJed Brown #endif
589b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
59017ab2063SBarry Smith 
59117ab2063SBarry Smith     for (i=0; i<m; i++) {
59260e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
593aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
594a9bf72d8SJed 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);
59517ab2063SBarry Smith #else
59660e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
59717ab2063SBarry Smith #endif
59817ab2063SBarry Smith       }
59917ab2063SBarry Smith     }
600d00d2cf4SBarry Smith     if (nofinalvalue) {
601c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
602c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
603c337ccceSJed Brown #else
604d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
605c337ccceSJed Brown #endif
606d00d2cf4SBarry Smith     }
607317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
608fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
609d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
61068369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
611cd155464SBarry Smith     PetscFunctionReturn(0);
612fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
613d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
61444cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
61577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
61660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
617aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
61836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
61960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
62160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62236db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
62360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6246831982aSBarry Smith         }
62544cd7ae7SLois Curfman McInnes #else
62660e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
62744cd7ae7SLois Curfman McInnes #endif
62844cd7ae7SLois Curfman McInnes       }
629b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
63044cd7ae7SLois Curfman McInnes     }
631d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
632fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
63397f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
634d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
635854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
636496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
637496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
63860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
639496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
640aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
642496be53dSLois Curfman McInnes #else
643496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
644496be53dSLois Curfman McInnes #endif
645496be53dSLois Curfman McInnes         }
646496be53dSLois Curfman McInnes       }
647496be53dSLois Curfman McInnes     }
6482e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
64977431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6502e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6512205254eSKarl Rupp       if (i+4<m) {
6522205254eSKarl 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);
6532205254eSKarl Rupp       } else if (i+3<m) {
6542205254eSKarl 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);
6552205254eSKarl Rupp       } else if (i+2<m) {
6562205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6572205254eSKarl Rupp       } else if (i+1<m) {
6582205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6592205254eSKarl Rupp       } else if (i<m) {
6602205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6612205254eSKarl Rupp       } else {
6622205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6632205254eSKarl Rupp       }
664496be53dSLois Curfman McInnes     }
665b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
666606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
667496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
66860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
66977431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
670496be53dSLois Curfman McInnes       }
671b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
672496be53dSLois Curfman McInnes     }
673b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
674496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
67560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
676496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
677aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
67836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
67960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6806831982aSBarry Smith           }
681496be53dSLois Curfman McInnes #else
68260e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
683496be53dSLois Curfman McInnes #endif
684496be53dSLois Curfman McInnes         }
685496be53dSLois Curfman McInnes       }
686b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
687496be53dSLois Curfman McInnes     }
688d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
689fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
69097f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
69187828ca2SBarry Smith     PetscScalar value;
69268f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
69368f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
69468f1ed48SBarry Smith 
69568f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
69668f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
69768f1ed48SBarry Smith         realonly = PETSC_FALSE;
69868f1ed48SBarry Smith         break;
69968f1ed48SBarry Smith       }
70068f1ed48SBarry Smith     }
70168f1ed48SBarry Smith #endif
70202594712SBarry Smith 
703d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
70402594712SBarry Smith     for (i=0; i<m; i++) {
70502594712SBarry Smith       jcnt = 0;
706d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
707e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
70802594712SBarry Smith           value = a->a[cnt++];
709e24b481bSBarry Smith           jcnt++;
71002594712SBarry Smith         } else {
71102594712SBarry Smith           value = 0.0;
71202594712SBarry Smith         }
713aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
71468f1ed48SBarry Smith         if (realonly) {
71560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
71668f1ed48SBarry Smith         } else {
71760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
71868f1ed48SBarry Smith         }
71902594712SBarry Smith #else
72060e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
72102594712SBarry Smith #endif
72202594712SBarry Smith       }
723b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
72402594712SBarry Smith     }
725d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7263c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
727150b93efSMatthew G. Knepley     PetscInt fshift=1;
728d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7293c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
73019303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7313c215bfdSMatthew Knepley #else
73219303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7333c215bfdSMatthew Knepley #endif
734d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7353c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
73660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7373c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
738a9a0e077SKarl 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);
7393c215bfdSMatthew Knepley #else
740150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7413c215bfdSMatthew Knepley #endif
7423c215bfdSMatthew Knepley       }
7433c215bfdSMatthew Knepley     }
744d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7453a40ed3dSBarry Smith   } else {
746d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
747d5f3da31SBarry Smith     if (A->factortype) {
74816cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
74916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
75016cd7e1dSShri Abhyankar         /* L part */
75160e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
75216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
75316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
75460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
75516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7566712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
75716cd7e1dSShri Abhyankar           } else {
75860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
75916cd7e1dSShri Abhyankar           }
76016cd7e1dSShri Abhyankar #else
76160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
76216cd7e1dSShri Abhyankar #endif
76316cd7e1dSShri Abhyankar         }
76416cd7e1dSShri Abhyankar         /* diagonal */
76516cd7e1dSShri Abhyankar         j = a->diag[i];
76616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
76716cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
76860e0710aSBarry 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);
76916cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7706712e2f1SBarry 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);
77116cd7e1dSShri Abhyankar         } else {
77260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
77316cd7e1dSShri Abhyankar         }
77416cd7e1dSShri Abhyankar #else
77560e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
77616cd7e1dSShri Abhyankar #endif
77716cd7e1dSShri Abhyankar 
77816cd7e1dSShri Abhyankar         /* U part */
77960e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
78016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
78260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
78316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
78422ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
78516cd7e1dSShri Abhyankar           } else {
78660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
78716cd7e1dSShri Abhyankar           }
78816cd7e1dSShri Abhyankar #else
78960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
79016cd7e1dSShri Abhyankar #endif
79116cd7e1dSShri Abhyankar         }
79216cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
79316cd7e1dSShri Abhyankar       }
79416cd7e1dSShri Abhyankar     } else {
79517ab2063SBarry Smith       for (i=0; i<m; i++) {
79677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
79760e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
798aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
79936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
80060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
80136db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
80260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8033a40ed3dSBarry Smith           } else {
80460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
80517ab2063SBarry Smith           }
80617ab2063SBarry Smith #else
80760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
80817ab2063SBarry Smith #endif
80917ab2063SBarry Smith         }
810b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
81117ab2063SBarry Smith       }
81216cd7e1dSShri Abhyankar     }
813d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
81417ab2063SBarry Smith   }
815b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8163a40ed3dSBarry Smith   PetscFunctionReturn(0);
817416022c9SBarry Smith }
818416022c9SBarry Smith 
8199804daf3SBarry Smith #include <petscdraw.h>
820dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
821416022c9SBarry Smith {
822480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
823416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
824dfbe8321SBarry Smith   PetscErrorCode    ierr;
825383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
826383922c3SLisandro Dalcin   int               color;
827b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
828b0a32e0cSBarry Smith   PetscViewer       viewer;
829f3ef73ceSBarry Smith   PetscViewerFormat format;
830cddf8d76SBarry Smith 
8313a40ed3dSBarry Smith   PetscFunctionBegin;
832480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
833b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
834b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
835383922c3SLisandro Dalcin 
836416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8370513a670SBarry Smith 
838fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
839383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8400513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
841b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
842416022c9SBarry Smith     for (i=0; i<m; i++) {
843cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
844bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
845bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
84636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
847b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
848cddf8d76SBarry Smith       }
849cddf8d76SBarry Smith     }
850b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
851cddf8d76SBarry Smith     for (i=0; i<m; i++) {
852cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
853bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
854bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
855cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
856b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
857cddf8d76SBarry Smith       }
858cddf8d76SBarry Smith     }
859b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
860cddf8d76SBarry Smith     for (i=0; i<m; i++) {
861cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
862bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
863bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
86436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
865b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
866416022c9SBarry Smith       }
867416022c9SBarry Smith     }
868383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8690513a670SBarry Smith   } else {
8700513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8710513a670SBarry Smith     /* first determine max of all nonzero values */
872b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
873383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
874b0a32e0cSBarry Smith     PetscDraw popup;
8750513a670SBarry Smith 
8760513a670SBarry Smith     for (i=0; i<nz; i++) {
8770513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8780513a670SBarry Smith     }
879383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
880b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
88145f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
882383922c3SLisandro Dalcin 
883383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8840513a670SBarry Smith     for (i=0; i<m; i++) {
885383922c3SLisandro Dalcin       y_l = m - i - 1.0;
886383922c3SLisandro Dalcin       y_r = y_l + 1.0;
887bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
888383922c3SLisandro Dalcin         x_l = a->j[j];
889383922c3SLisandro Dalcin         x_r = x_l + 1.0;
890b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
891b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8920513a670SBarry Smith         count++;
8930513a670SBarry Smith       }
8940513a670SBarry Smith     }
895383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8960513a670SBarry Smith   }
897480ef9eaSBarry Smith   PetscFunctionReturn(0);
898480ef9eaSBarry Smith }
899cddf8d76SBarry Smith 
9009804daf3SBarry Smith #include <petscdraw.h>
901dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
902480ef9eaSBarry Smith {
903dfbe8321SBarry Smith   PetscErrorCode ierr;
904b0a32e0cSBarry Smith   PetscDraw      draw;
90536db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
906ace3abfcSBarry Smith   PetscBool      isnull;
907480ef9eaSBarry Smith 
908480ef9eaSBarry Smith   PetscFunctionBegin;
909b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
910b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
911480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
912480ef9eaSBarry Smith 
913d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
914480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
915b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
916832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
917b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9180298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
919832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9203a40ed3dSBarry Smith   PetscFunctionReturn(0);
921416022c9SBarry Smith }
922416022c9SBarry Smith 
923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
924416022c9SBarry Smith {
925dfbe8321SBarry Smith   PetscErrorCode ierr;
926ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
927416022c9SBarry Smith 
9283a40ed3dSBarry Smith   PetscFunctionBegin;
929251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
930251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
931251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
932c45a1595SBarry Smith   if (iascii) {
9333a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9340f5bd95cSBarry Smith   } else if (isbinary) {
9353a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9360f5bd95cSBarry Smith   } else if (isdraw) {
9373a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
93811aeaf0aSBarry Smith   }
9394108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9403a40ed3dSBarry Smith   PetscFunctionReturn(0);
94117ab2063SBarry Smith }
94219bcc07fSBarry Smith 
943dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
94417ab2063SBarry Smith {
945416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9466849ba73SBarry Smith   PetscErrorCode ierr;
94797f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
948d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
94954f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9503447b6efSHong Zhang   PetscReal      ratio  = 0.6;
95117ab2063SBarry Smith 
9523a40ed3dSBarry Smith   PetscFunctionBegin;
9533a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
95417ab2063SBarry Smith 
95543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
95617ab2063SBarry Smith   for (i=1; i<m; i++) {
957416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
95817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
95994a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
96017ab2063SBarry Smith     if (fshift) {
961bfeeae90SHong Zhang       ip = aj + ai[i];
962bfeeae90SHong Zhang       ap = aa + ai[i];
96317ab2063SBarry Smith       N  = ailen[i];
96417ab2063SBarry Smith       for (j=0; j<N; j++) {
96517ab2063SBarry Smith         ip[j-fshift] = ip[j];
966876c6284SHong Zhang         if (!A->structure_only) ap[j-fshift] = ap[j];
96717ab2063SBarry Smith       }
96817ab2063SBarry Smith     }
96917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
97017ab2063SBarry Smith   }
97117ab2063SBarry Smith   if (m) {
97217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
97317ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
97417ab2063SBarry Smith   }
9757b083b7cSBarry Smith 
97617ab2063SBarry Smith   /* reset ilen and imax for each row */
9777b083b7cSBarry Smith   a->nonzerorowcnt = 0;
978*396832f4SHong Zhang   if (A->structure_only) {
979*396832f4SHong Zhang     ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
980*396832f4SHong Zhang   } else { /* !A->structure_only */
98117ab2063SBarry Smith     for (i=0; i<m; i++) {
98217ab2063SBarry Smith       ailen[i] = imax[i] = ai[i+1] - ai[i];
9837b083b7cSBarry Smith       a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
98417ab2063SBarry Smith     }
985*396832f4SHong Zhang   }
986bfeeae90SHong Zhang   a->nz = ai[m];
98765e19b50SBarry 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);
98817ab2063SBarry Smith 
98909f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
990d0f46423SBarry 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);
991ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
992ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9932205254eSKarl Rupp 
9948e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
995dd5f02e7SSatish Balay   a->reallocs         = 0;
9966712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
99736db0b34SBarry Smith   a->rmax             = rmax;
9984e220ebcSLois Curfman McInnes 
999*396832f4SHong Zhang   if (!A->structure_only) {
100011e456e1SBarry Smith     ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
1001*396832f4SHong Zhang   }
10024108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
1003acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10043a40ed3dSBarry Smith   PetscFunctionReturn(0);
100517ab2063SBarry Smith }
100617ab2063SBarry Smith 
100799cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
100899cafbc1SBarry Smith {
100999cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
101099cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
101154f21887SBarry Smith   MatScalar      *aa = a->a;
1012acf2f550SJed Brown   PetscErrorCode ierr;
101399cafbc1SBarry Smith 
101499cafbc1SBarry Smith   PetscFunctionBegin;
101599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1016acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101799cafbc1SBarry Smith   PetscFunctionReturn(0);
101899cafbc1SBarry Smith }
101999cafbc1SBarry Smith 
102099cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
102199cafbc1SBarry Smith {
102299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
102399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
102454f21887SBarry Smith   MatScalar      *aa = a->a;
1025acf2f550SJed Brown   PetscErrorCode ierr;
102699cafbc1SBarry Smith 
102799cafbc1SBarry Smith   PetscFunctionBegin;
102899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1029acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
103099cafbc1SBarry Smith   PetscFunctionReturn(0);
103199cafbc1SBarry Smith }
103299cafbc1SBarry Smith 
1033dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
103417ab2063SBarry Smith {
1035416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1036dfbe8321SBarry Smith   PetscErrorCode ierr;
10373a40ed3dSBarry Smith 
10383a40ed3dSBarry Smith   PetscFunctionBegin;
1039d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1040acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10413a40ed3dSBarry Smith   PetscFunctionReturn(0);
104217ab2063SBarry Smith }
1043416022c9SBarry Smith 
1044dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
104517ab2063SBarry Smith {
1046416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1047dfbe8321SBarry Smith   PetscErrorCode ierr;
1048d5d45c9bSBarry Smith 
10493a40ed3dSBarry Smith   PetscFunctionBegin;
1050aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1051d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
105217ab2063SBarry Smith #endif
1053e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10546bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10556bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
105605b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1057d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
105805b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
105971f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
106005b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10616bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
106205b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10636bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1064cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10650b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1066a30b2313SHong Zhang 
10674108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1068bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1069901853e0SKris Buschelman 
1070dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1071bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1072bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1073bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1074bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1075bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1076bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1077af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1078af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1079af8000cdSHong Zhang #endif
108063c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
108163c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
10823dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
108363c07aadSStefano Zampini #endif
1084b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1085bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1086bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1087bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1088bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10893a40ed3dSBarry Smith   PetscFunctionReturn(0);
109017ab2063SBarry Smith }
109117ab2063SBarry Smith 
1092ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
109317ab2063SBarry Smith {
1094416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10954846f1f5SKris Buschelman   PetscErrorCode ierr;
10963a40ed3dSBarry Smith 
10973a40ed3dSBarry Smith   PetscFunctionBegin;
1098a65d3064SKris Buschelman   switch (op) {
1099a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11004e0d8c25SBarry Smith     a->roworiented = flg;
1101a65d3064SKris Buschelman     break;
1102a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1103a9817697SBarry Smith     a->keepnonzeropattern = flg;
1104a65d3064SKris Buschelman     break;
1105512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1106512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1107a65d3064SKris Buschelman     break;
1108a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11094e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1110a65d3064SKris Buschelman     break;
1111a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11124e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1113a65d3064SKris Buschelman     break;
111428b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
111528b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
111628b2fa4aSMatthew Knepley     break;
1117a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11184e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11190df259c2SBarry Smith     break;
11203d472b54SHong Zhang   case MAT_SPD:
1121b1646e73SJed Brown   case MAT_SYMMETRIC:
1122b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1123b1646e73SJed Brown   case MAT_HERMITIAN:
1124b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1125957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11265021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11275021d80fSJed Brown     break;
11284e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1129a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1130a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1131290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1132a65d3064SKris Buschelman     break;
1133b87ac2d8SJed Brown   case MAT_USE_INODES:
1134b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1135b87ac2d8SJed Brown     break;
1136c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1137c10200c1SHong Zhang     A->submat_singleis = flg;
1138c10200c1SHong Zhang     break;
1139a65d3064SKris Buschelman   default:
1140e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1141a65d3064SKris Buschelman   }
11424108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11433a40ed3dSBarry Smith   PetscFunctionReturn(0);
114417ab2063SBarry Smith }
114517ab2063SBarry Smith 
1146dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
114717ab2063SBarry Smith {
1148416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11496849ba73SBarry Smith   PetscErrorCode ierr;
1150d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
115135e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
115217ab2063SBarry Smith 
11533a40ed3dSBarry Smith   PetscFunctionBegin;
1154d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1155e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
115635e7444dSHong Zhang 
1157d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1158d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
115935e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11602c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
116135e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
116235e7444dSHong Zhang     PetscFunctionReturn(0);
116335e7444dSHong Zhang   }
116435e7444dSHong Zhang 
11652dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11661ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
116735e7444dSHong Zhang   for (i=0; i<n; i++) {
116835e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11692f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
117035e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
117135e7444dSHong Zhang       if (aj[j] == i) {
117235e7444dSHong Zhang         x[i] = aa[j];
117317ab2063SBarry Smith         break;
117417ab2063SBarry Smith       }
117517ab2063SBarry Smith     }
117617ab2063SBarry Smith   }
11771ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11783a40ed3dSBarry Smith   PetscFunctionReturn(0);
117917ab2063SBarry Smith }
118017ab2063SBarry Smith 
1181c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1182dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
118317ab2063SBarry Smith {
1184416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1185d9ca1df4SBarry Smith   PetscScalar       *y;
1186d9ca1df4SBarry Smith   const PetscScalar *x;
1187dfbe8321SBarry Smith   PetscErrorCode    ierr;
1188d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
11895c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1190d9ca1df4SBarry Smith   const MatScalar   *v;
1191a77337e4SBarry Smith   PetscScalar       alpha;
1192d9ca1df4SBarry Smith   PetscInt          n,i,j;
1193d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
11943447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1195ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11965c897100SBarry Smith #endif
119717ab2063SBarry Smith 
11983a40ed3dSBarry Smith   PetscFunctionBegin;
11992e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1200d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12011ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12025c897100SBarry Smith 
12035c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1204bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12055c897100SBarry Smith #else
12063447b6efSHong Zhang   if (usecprow) {
12073447b6efSHong Zhang     m    = cprow.nrows;
12083447b6efSHong Zhang     ii   = cprow.i;
12097b2bb3b9SHong Zhang     ridx = cprow.rindex;
12103447b6efSHong Zhang   } else {
12113447b6efSHong Zhang     ii = a->i;
12123447b6efSHong Zhang   }
121317ab2063SBarry Smith   for (i=0; i<m; i++) {
12143447b6efSHong Zhang     idx = a->j + ii[i];
12153447b6efSHong Zhang     v   = a->a + ii[i];
12163447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12173447b6efSHong Zhang     if (usecprow) {
12187b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12193447b6efSHong Zhang     } else {
122017ab2063SBarry Smith       alpha = x[i];
12213447b6efSHong Zhang     }
122204fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
122317ab2063SBarry Smith   }
12245c897100SBarry Smith #endif
1225dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1226d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12271ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12283a40ed3dSBarry Smith   PetscFunctionReturn(0);
122917ab2063SBarry Smith }
123017ab2063SBarry Smith 
1231dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12325c897100SBarry Smith {
1233dfbe8321SBarry Smith   PetscErrorCode ierr;
12345c897100SBarry Smith 
12355c897100SBarry Smith   PetscFunctionBegin;
1236170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12375c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12385c897100SBarry Smith   PetscFunctionReturn(0);
12395c897100SBarry Smith }
12405c897100SBarry Smith 
1241c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
124278b84d54SShri Abhyankar 
1243dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
124417ab2063SBarry Smith {
1245416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1246d9fead3dSBarry Smith   PetscScalar       *y;
124754f21887SBarry Smith   const PetscScalar *x;
124854f21887SBarry Smith   const MatScalar   *aa;
1249dfbe8321SBarry Smith   PetscErrorCode    ierr;
1250003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12510298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12527b083b7cSBarry Smith   PetscInt          n,i;
1253362ced78SSatish Balay   PetscScalar       sum;
1254ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
125517ab2063SBarry Smith 
1256b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
125797952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1258fee21e36SBarry Smith #endif
1259fee21e36SBarry Smith 
12603a40ed3dSBarry Smith   PetscFunctionBegin;
12613649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12621ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1263416022c9SBarry Smith   ii   = a->i;
12644eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12654f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
126697952fefSHong Zhang     m    = a->compressedrow.nrows;
126797952fefSHong Zhang     ii   = a->compressedrow.i;
126897952fefSHong Zhang     ridx = a->compressedrow.rindex;
126997952fefSHong Zhang     for (i=0; i<m; i++) {
127097952fefSHong Zhang       n           = ii[i+1] - ii[i];
127197952fefSHong Zhang       aj          = a->j + ii[i];
127297952fefSHong Zhang       aa          = a->a + ii[i];
127397952fefSHong Zhang       sum         = 0.0;
1274003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1275003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
127697952fefSHong Zhang       y[*ridx++] = sum;
127797952fefSHong Zhang     }
127897952fefSHong Zhang   } else { /* do not use compressed row format */
1279b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
12803d3eaba7SBarry Smith     aj   = a->j;
12813d3eaba7SBarry Smith     aa   = a->a;
1282b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1283b05257ddSBarry Smith #else
128417ab2063SBarry Smith     for (i=0; i<m; i++) {
1285003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1286003131ecSBarry Smith       aj          = a->j + ii[i];
1287003131ecSBarry Smith       aa          = a->a + ii[i];
128817ab2063SBarry Smith       sum         = 0.0;
1289003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
129017ab2063SBarry Smith       y[i] = sum;
129117ab2063SBarry Smith     }
12928d195f9aSBarry Smith #endif
1293b05257ddSBarry Smith   }
12947b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
12953649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12961ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12973a40ed3dSBarry Smith   PetscFunctionReturn(0);
129817ab2063SBarry Smith }
129917ab2063SBarry Smith 
1300b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1301b434eb95SMatthew G. Knepley {
1302b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1303b434eb95SMatthew G. Knepley   PetscScalar       *y;
1304b434eb95SMatthew G. Knepley   const PetscScalar *x;
1305b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1306b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1307b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1308b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1309b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1310b434eb95SMatthew G. Knepley   PetscScalar       sum;
1311b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1312b434eb95SMatthew G. Knepley 
1313b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1314b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1315b434eb95SMatthew G. Knepley #endif
1316b434eb95SMatthew G. Knepley 
1317b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1318b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1319b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1320b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1321b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1322b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1323b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1324b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1325b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1326b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1327b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1328b434eb95SMatthew G. Knepley       sum         = 0.0;
1329b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1330b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1331b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1332b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1333b434eb95SMatthew G. Knepley     }
1334b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13353d3eaba7SBarry Smith     ii = a->i;
1336b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1337b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1338b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1339b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1340b434eb95SMatthew G. Knepley       sum         = 0.0;
1341b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1342b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1343b434eb95SMatthew G. Knepley       y[i] = sum;
1344b434eb95SMatthew G. Knepley     }
1345b434eb95SMatthew G. Knepley   }
1346b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1347b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1348b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1349b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1350b434eb95SMatthew G. Knepley }
1351b434eb95SMatthew G. Knepley 
1352b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1353b434eb95SMatthew G. Knepley {
1354b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1355b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1356b434eb95SMatthew G. Knepley   const PetscScalar *x;
1357b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1358b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1359b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1360b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1361b434eb95SMatthew G. Knepley   PetscScalar       sum;
1362b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1363b434eb95SMatthew G. Knepley 
1364b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1365b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1366d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1367b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1368b434eb95SMatthew G. Knepley     if (zz != yy) {
1369b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1370b434eb95SMatthew G. Knepley     }
1371b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1372b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1373b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1374b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1375b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1376b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1377b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1378b434eb95SMatthew G. Knepley       sum = y[*ridx];
1379b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1380b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1381b434eb95SMatthew G. Knepley     }
1382b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13833d3eaba7SBarry Smith     ii = a->i;
1384b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1385b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1386b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1387b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1388b434eb95SMatthew G. Knepley       sum = y[i];
1389b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1390b434eb95SMatthew G. Knepley       z[i] = sum;
1391b434eb95SMatthew G. Knepley     }
1392b434eb95SMatthew G. Knepley   }
1393b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1394b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1395d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1396b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1397b434eb95SMatthew G. Knepley }
1398b434eb95SMatthew G. Knepley 
1399c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1400dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
140117ab2063SBarry Smith {
1402416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1403f15663dcSBarry Smith   PetscScalar       *y,*z;
1404f15663dcSBarry Smith   const PetscScalar *x;
140554f21887SBarry Smith   const MatScalar   *aa;
1406dfbe8321SBarry Smith   PetscErrorCode    ierr;
1407d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1408d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1409362ced78SSatish Balay   PetscScalar       sum;
1410ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14119ea0dfa2SSatish Balay 
14123a40ed3dSBarry Smith   PetscFunctionBegin;
1413f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1414d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14154eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
14164eb6d288SHong Zhang     if (zz != yy) {
14174eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14184eb6d288SHong Zhang     }
141997952fefSHong Zhang     m    = a->compressedrow.nrows;
142097952fefSHong Zhang     ii   = a->compressedrow.i;
142197952fefSHong Zhang     ridx = a->compressedrow.rindex;
142297952fefSHong Zhang     for (i=0; i<m; i++) {
142397952fefSHong Zhang       n   = ii[i+1] - ii[i];
142497952fefSHong Zhang       aj  = a->j + ii[i];
142597952fefSHong Zhang       aa  = a->a + ii[i];
142697952fefSHong Zhang       sum = y[*ridx];
1427f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142897952fefSHong Zhang       z[*ridx++] = sum;
142997952fefSHong Zhang     }
143097952fefSHong Zhang   } else { /* do not use compressed row format */
14313d3eaba7SBarry Smith     ii = a->i;
1432f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14333d3eaba7SBarry Smith     aj = a->j;
14343d3eaba7SBarry Smith     aa = a->a;
1435f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1436f15663dcSBarry Smith #else
143717ab2063SBarry Smith     for (i=0; i<m; i++) {
1438f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1439f15663dcSBarry Smith       aj  = a->j + ii[i];
1440f15663dcSBarry Smith       aa  = a->a + ii[i];
144117ab2063SBarry Smith       sum = y[i];
1442f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
144317ab2063SBarry Smith       z[i] = sum;
144417ab2063SBarry Smith     }
144502ab625aSSatish Balay #endif
1446f15663dcSBarry Smith   }
1447dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1448f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1449d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14508154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14516b375ea7SVictor Minden   /*
1452918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1453918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1454918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14556b375ea7SVictor Minden   */
1456918e98c3SVictor Minden #endif
14573a40ed3dSBarry Smith   PetscFunctionReturn(0);
145817ab2063SBarry Smith }
145917ab2063SBarry Smith 
146017ab2063SBarry Smith /*
146117ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
146217ab2063SBarry Smith */
1463dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
146417ab2063SBarry Smith {
1465416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14666849ba73SBarry Smith   PetscErrorCode ierr;
1467d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
146817ab2063SBarry Smith 
14693a40ed3dSBarry Smith   PetscFunctionBegin;
147009f38230SBarry Smith   if (!a->diag) {
1471785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14723bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
147309f38230SBarry Smith   }
1474d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
147509f38230SBarry Smith     a->diag[i] = a->i[i+1];
1476bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1477bfeeae90SHong Zhang       if (a->j[j] == i) {
147809f38230SBarry Smith         a->diag[i] = j;
147917ab2063SBarry Smith         break;
148017ab2063SBarry Smith       }
148117ab2063SBarry Smith     }
148217ab2063SBarry Smith   }
14833a40ed3dSBarry Smith   PetscFunctionReturn(0);
148417ab2063SBarry Smith }
148517ab2063SBarry Smith 
1486be5855fcSBarry Smith /*
1487be5855fcSBarry Smith      Checks for missing diagonals
1488be5855fcSBarry Smith */
1489ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1490be5855fcSBarry Smith {
1491be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14927734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1493be5855fcSBarry Smith 
1494be5855fcSBarry Smith   PetscFunctionBegin;
149509f38230SBarry Smith   *missing = PETSC_FALSE;
14967734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
149709f38230SBarry Smith     *missing = PETSC_TRUE;
149809f38230SBarry Smith     if (d) *d = 0;
1499955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
150009f38230SBarry Smith   } else {
1501f1e2ffcdSBarry Smith     diag = a->diag;
1502d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
15037734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
150409f38230SBarry Smith         *missing = PETSC_TRUE;
150509f38230SBarry Smith         if (d) *d = i;
1506955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1507358d2f5dSShri Abhyankar         break;
150809f38230SBarry Smith       }
1509be5855fcSBarry Smith     }
1510be5855fcSBarry Smith   }
1511be5855fcSBarry Smith   PetscFunctionReturn(0);
1512be5855fcSBarry Smith }
1513be5855fcSBarry Smith 
1514422a814eSBarry Smith /*
1515422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1516422a814eSBarry Smith */
15177087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
151871f1c65dSBarry Smith {
151971f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
152071f1c65dSBarry Smith   PetscErrorCode ierr;
1521d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
152254f21887SBarry Smith   MatScalar      *v = a->a;
152354f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
152471f1c65dSBarry Smith 
152571f1c65dSBarry Smith   PetscFunctionBegin;
152671f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
152771f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
152871f1c65dSBarry Smith   diag = a->diag;
152971f1c65dSBarry Smith   if (!a->idiag) {
1530dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15313bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
153271f1c65dSBarry Smith     v    = a->a;
153371f1c65dSBarry Smith   }
153471f1c65dSBarry Smith   mdiag = a->mdiag;
153571f1c65dSBarry Smith   idiag = a->idiag;
153671f1c65dSBarry Smith 
1537422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
153871f1c65dSBarry Smith     for (i=0; i<m; i++) {
153971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1540899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1541899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1542899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15437b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15447b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15457b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15467b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1547899639b0SHong Zhang       }
154871f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
154971f1c65dSBarry Smith     }
155071f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
155171f1c65dSBarry Smith   } else {
155271f1c65dSBarry Smith     for (i=0; i<m; i++) {
155371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
155471f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
155571f1c65dSBarry Smith     }
1556dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
155771f1c65dSBarry Smith   }
155871f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
155971f1c65dSBarry Smith   PetscFunctionReturn(0);
156071f1c65dSBarry Smith }
156171f1c65dSBarry Smith 
1562c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
156341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
156417ab2063SBarry Smith {
1565416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1566e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15673d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
156854f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1569dfbe8321SBarry Smith   PetscErrorCode    ierr;
15703d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
157197f1f81fSBarry Smith   const PetscInt    *idx,*diag;
157217ab2063SBarry Smith 
15733a40ed3dSBarry Smith   PetscFunctionBegin;
1574b965ef7fSBarry Smith   its = its*lits;
157591723122SBarry Smith 
157671f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
157771f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
157871f1c65dSBarry Smith   a->fshift = fshift;
157971f1c65dSBarry Smith   a->omega  = omega;
1580ed480e8bSBarry Smith 
158171f1c65dSBarry Smith   diag  = a->diag;
158271f1c65dSBarry Smith   t     = a->ssor_work;
1583ed480e8bSBarry Smith   idiag = a->idiag;
158471f1c65dSBarry Smith   mdiag = a->mdiag;
1585ed480e8bSBarry Smith 
15861ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15873649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1588ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
158917ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
159017ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1591ed480e8bSBarry Smith     bs = b;
159217ab2063SBarry Smith     for (i=0; i<m; i++) {
159371f1c65dSBarry Smith       d   = fshift + mdiag[i];
1594416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1595ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1596ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
159717ab2063SBarry Smith       sum = b[i]*d/omega;
1598003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
159917ab2063SBarry Smith       x[i] = sum;
160017ab2063SBarry Smith     }
16011ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16023649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1603efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16043a40ed3dSBarry Smith     PetscFunctionReturn(0);
160517ab2063SBarry Smith   }
1606c783ea89SBarry Smith 
16072205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16082205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
160917ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1610887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
161117ab2063SBarry Smith 
161217ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
161317ab2063SBarry Smith 
1614887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
161517ab2063SBarry Smith     */
161617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
161717ab2063SBarry Smith 
161817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
161917ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1620416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1621ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1622ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
162317ab2063SBarry Smith       sum = b[i];
1624e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1625ed480e8bSBarry Smith       x[i] = sum*idiag[i];
162617ab2063SBarry Smith     }
162717ab2063SBarry Smith 
162817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1629416022c9SBarry Smith     v = a->a;
16302205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
163117ab2063SBarry Smith 
163217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1633ed480e8bSBarry Smith     ts   = t;
1634416022c9SBarry Smith     diag = a->diag;
163517ab2063SBarry Smith     for (i=0; i<m; i++) {
1636416022c9SBarry Smith       n   = diag[i] - a->i[i];
1637ed480e8bSBarry Smith       idx = a->j + a->i[i];
1638ed480e8bSBarry Smith       v   = a->a + a->i[i];
163917ab2063SBarry Smith       sum = t[i];
1640003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1641ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1642733d66baSBarry Smith       /*  x = x + t */
1643733d66baSBarry Smith       x[i] += t[i];
164417ab2063SBarry Smith     }
164517ab2063SBarry Smith 
1646dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16471ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16483649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16493a40ed3dSBarry Smith     PetscFunctionReturn(0);
165017ab2063SBarry Smith   }
165117ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
165217ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
165317ab2063SBarry Smith       for (i=0; i<m; i++) {
1654416022c9SBarry Smith         n   = diag[i] - a->i[i];
1655ed480e8bSBarry Smith         idx = a->j + a->i[i];
1656ed480e8bSBarry Smith         v   = a->a + a->i[i];
165717ab2063SBarry Smith         sum = b[i];
1658e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16595c99c7daSBarry Smith         t[i] = sum;
1660ed480e8bSBarry Smith         x[i] = sum*idiag[i];
166117ab2063SBarry Smith       }
16625c99c7daSBarry Smith       xb   = t;
1663efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16643a40ed3dSBarry Smith     } else xb = b;
166517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
166617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1667416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1668ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1669ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
167017ab2063SBarry Smith         sum = xb[i];
1671e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16725c99c7daSBarry Smith         if (xb == b) {
1673ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16745c99c7daSBarry Smith         } else {
1675b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
167617ab2063SBarry Smith         }
16775c99c7daSBarry Smith       }
1678b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
167917ab2063SBarry Smith     }
168017ab2063SBarry Smith     its--;
168117ab2063SBarry Smith   }
168217ab2063SBarry Smith   while (its--) {
168317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
168417ab2063SBarry Smith       for (i=0; i<m; i++) {
1685b19a5dc2SMark Adams         /* lower */
1686b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1687ed480e8bSBarry Smith         idx = a->j + a->i[i];
1688ed480e8bSBarry Smith         v   = a->a + a->i[i];
168917ab2063SBarry Smith         sum = b[i];
1690e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1691b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1692b19a5dc2SMark Adams         /* upper */
1693b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1694b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1695b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1696b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1697b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
169817ab2063SBarry Smith       }
1699b19a5dc2SMark Adams       xb   = t;
17009f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1701b19a5dc2SMark Adams     } else xb = b;
170217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
170317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1704b19a5dc2SMark Adams         sum = xb[i];
1705b19a5dc2SMark Adams         if (xb == b) {
1706b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1707416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1708ed480e8bSBarry Smith           idx = a->j + a->i[i];
1709ed480e8bSBarry Smith           v   = a->a + a->i[i];
1710e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1711ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1712b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1713b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1714b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1715b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1716b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1717b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
171817ab2063SBarry Smith         }
1719b19a5dc2SMark Adams       }
1720b19a5dc2SMark Adams       if (xb == b) {
17219f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1722b19a5dc2SMark Adams       } else {
1723b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1724b19a5dc2SMark Adams       }
172517ab2063SBarry Smith     }
172617ab2063SBarry Smith   }
17271ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17283649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1729365a8a9eSBarry Smith   PetscFunctionReturn(0);
173017ab2063SBarry Smith }
173117ab2063SBarry Smith 
17322af78befSBarry Smith 
1733dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
173417ab2063SBarry Smith {
1735416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17364e220ebcSLois Curfman McInnes 
17373a40ed3dSBarry Smith   PetscFunctionBegin;
17384e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17394e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17404e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17414e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17424e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17438e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17447adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1745d5f3da31SBarry Smith   if (A->factortype) {
17464e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17474e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17484e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17494e220ebcSLois Curfman McInnes   } else {
17504e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17514e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17524e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17534e220ebcSLois Curfman McInnes   }
17543a40ed3dSBarry Smith   PetscFunctionReturn(0);
175517ab2063SBarry Smith }
175617ab2063SBarry Smith 
17572b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
175817ab2063SBarry Smith {
1759416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1760c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17616849ba73SBarry Smith   PetscErrorCode    ierr;
176297b48c8fSBarry Smith   const PetscScalar *xx;
176397b48c8fSBarry Smith   PetscScalar       *bb;
1764c7da8527SEric Chamberland   PetscInt          d = 0;
176517ab2063SBarry Smith 
17663a40ed3dSBarry Smith   PetscFunctionBegin;
176797b48c8fSBarry Smith   if (x && b) {
176897b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
176997b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
177097b48c8fSBarry Smith     for (i=0; i<N; i++) {
177197b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
177297b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
177397b48c8fSBarry Smith     }
177497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
177597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
177697b48c8fSBarry Smith   }
177797b48c8fSBarry Smith 
1778a9817697SBarry Smith   if (a->keepnonzeropattern) {
1779f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1780e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1781bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1782f1e2ffcdSBarry Smith     }
1783f4df32b1SMatthew Knepley     if (diag != 0.0) {
1784c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1785c7da8527SEric Chamberland         d = rows[i];
1786c7da8527SEric 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);
1787c7da8527SEric Chamberland       }
1788f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1789f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1790f1e2ffcdSBarry Smith       }
1791f1e2ffcdSBarry Smith     }
1792f1e2ffcdSBarry Smith   } else {
1793f4df32b1SMatthew Knepley     if (diag != 0.0) {
179417ab2063SBarry Smith       for (i=0; i<N; i++) {
1795e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17967ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1797416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1798f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1799bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18007ae801bdSBarry Smith         } else { /* in case row was completely empty */
1801f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
180217ab2063SBarry Smith         }
180317ab2063SBarry Smith       }
18043a40ed3dSBarry Smith     } else {
180517ab2063SBarry Smith       for (i=0; i<N; i++) {
1806e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1807416022c9SBarry Smith         a->ilen[rows[i]] = 0;
180817ab2063SBarry Smith       }
180917ab2063SBarry Smith     }
1810e56f5c9eSBarry Smith     A->nonzerostate++;
1811f1e2ffcdSBarry Smith   }
181243a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18133a40ed3dSBarry Smith   PetscFunctionReturn(0);
181417ab2063SBarry Smith }
181517ab2063SBarry Smith 
18166e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18176e169961SBarry Smith {
18186e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18196e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18206e169961SBarry Smith   PetscErrorCode    ierr;
18212b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18226e169961SBarry Smith   const PetscScalar *xx;
18236e169961SBarry Smith   PetscScalar       *bb;
18246e169961SBarry Smith 
18256e169961SBarry Smith   PetscFunctionBegin;
18266e169961SBarry Smith   if (x && b) {
18276e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18286e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18292b40b63fSBarry Smith     vecs = PETSC_TRUE;
18306e169961SBarry Smith   }
18311795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18326e169961SBarry Smith   for (i=0; i<N; i++) {
18336e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18346e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18352205254eSKarl Rupp 
18366e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18376e169961SBarry Smith   }
18386e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18396e169961SBarry Smith     if (!zeroed[i]) {
18406e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18416e169961SBarry Smith         if (zeroed[a->j[j]]) {
18422b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18436e169961SBarry Smith           a->a[j] = 0.0;
18446e169961SBarry Smith         }
18456e169961SBarry Smith       }
18462b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18476e169961SBarry Smith   }
18486e169961SBarry Smith   if (x && b) {
18496e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18506e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18516e169961SBarry Smith   }
18526e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18536e169961SBarry Smith   if (diag != 0.0) {
18546e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18551d5a398dSstefano_zampini     if (missing) {
18561d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18571d5a398dSstefano_zampini       else {
18581d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18591d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18601d5a398dSstefano_zampini         }
18611d5a398dSstefano_zampini       }
18621d5a398dSstefano_zampini     } else {
18636e169961SBarry Smith       for (i=0; i<N; i++) {
18646e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18656e169961SBarry Smith       }
18666e169961SBarry Smith     }
18671d5a398dSstefano_zampini   }
18686e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18696e169961SBarry Smith   PetscFunctionReturn(0);
18706e169961SBarry Smith }
18716e169961SBarry Smith 
1872a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187317ab2063SBarry Smith {
1874416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
187597f1f81fSBarry Smith   PetscInt   *itmp;
187617ab2063SBarry Smith 
18773a40ed3dSBarry Smith   PetscFunctionBegin;
1878e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
187917ab2063SBarry Smith 
1880416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1881bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
188217ab2063SBarry Smith   if (idx) {
1883bfeeae90SHong Zhang     itmp = a->j + a->i[row];
188426fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
188517ab2063SBarry Smith     else *idx = 0;
188617ab2063SBarry Smith   }
18873a40ed3dSBarry Smith   PetscFunctionReturn(0);
188817ab2063SBarry Smith }
188917ab2063SBarry Smith 
1890bfeeae90SHong Zhang /* remove this function? */
1891a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
189217ab2063SBarry Smith {
18933a40ed3dSBarry Smith   PetscFunctionBegin;
18943a40ed3dSBarry Smith   PetscFunctionReturn(0);
189517ab2063SBarry Smith }
189617ab2063SBarry Smith 
1897dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
189817ab2063SBarry Smith {
1899416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
190054f21887SBarry Smith   MatScalar      *v  = a->a;
190136db0b34SBarry Smith   PetscReal      sum = 0.0;
19026849ba73SBarry Smith   PetscErrorCode ierr;
190397f1f81fSBarry Smith   PetscInt       i,j;
190417ab2063SBarry Smith 
19053a40ed3dSBarry Smith   PetscFunctionBegin;
190617ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1907570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1908570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1909570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1910570b7f6dSBarry Smith #else
1911416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
191236db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
191317ab2063SBarry Smith     }
19148f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1915570b7f6dSBarry Smith #endif
191651f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19173a40ed3dSBarry Smith   } else if (type == NORM_1) {
191836db0b34SBarry Smith     PetscReal *tmp;
191997f1f81fSBarry Smith     PetscInt  *jj = a->j;
19201795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1921064f8208SBarry Smith     *nrm = 0.0;
1922416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1923bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
192417ab2063SBarry Smith     }
1925d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1926064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
192717ab2063SBarry Smith     }
1928606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
192951f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19303a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1931064f8208SBarry Smith     *nrm = 0.0;
1932d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1933bfeeae90SHong Zhang       v   = a->a + a->i[j];
193417ab2063SBarry Smith       sum = 0.0;
1935416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1936cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
193717ab2063SBarry Smith       }
1938064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
193917ab2063SBarry Smith     }
194051f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1941f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19423a40ed3dSBarry Smith   PetscFunctionReturn(0);
194317ab2063SBarry Smith }
194417ab2063SBarry Smith 
19454e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19464e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19474e938277SHong Zhang {
19484e938277SHong Zhang   PetscErrorCode ierr;
19494e938277SHong Zhang   PetscInt       i,j,anzj;
19504e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19514e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19524e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19534e938277SHong Zhang 
19544e938277SHong Zhang   PetscFunctionBegin;
19554e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1956854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1957785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1958785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19594e938277SHong Zhang 
19604e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19614e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
196226fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19634e938277SHong Zhang   /* Form ati for csr format of A^T. */
196426fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19654e938277SHong Zhang 
19664e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19674e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19684e938277SHong Zhang 
19694e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19704e938277SHong Zhang   for (i=0;i<am;i++) {
19714e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19724e938277SHong Zhang     for (j=0;j<anzj;j++) {
19734e938277SHong Zhang       atj[atfill[*aj]] = i;
19744e938277SHong Zhang       atfill[*aj++]   += 1;
19754e938277SHong Zhang     }
19764e938277SHong Zhang   }
19774e938277SHong Zhang 
19784e938277SHong Zhang   /* Clean up temporary space and complete requests. */
19794e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
1980ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
198133d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
1982a2f3521dSMark F. Adams 
19834e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
19844e938277SHong Zhang   b->free_a  = PETSC_FALSE;
19854e938277SHong Zhang   b->free_ij = PETSC_TRUE;
19864e938277SHong Zhang   b->nonew   = 0;
19874e938277SHong Zhang   PetscFunctionReturn(0);
19884e938277SHong Zhang }
19894e938277SHong Zhang 
1990fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
199117ab2063SBarry Smith {
1992416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1993416022c9SBarry Smith   Mat            C;
19946849ba73SBarry Smith   PetscErrorCode ierr;
1995d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
199654f21887SBarry Smith   MatScalar      *array = a->a;
199717ab2063SBarry Smith 
19983a40ed3dSBarry Smith   PetscFunctionBegin;
1999cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2000fc4dec0aSBarry Smith 
2001cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
2002854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
2003bfeeae90SHong Zhang 
2004bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2005ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2006d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
200733d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
20087adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2009ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2010606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2011a541d17aSBarry Smith   } else {
2012a541d17aSBarry Smith     C = *B;
2013a541d17aSBarry Smith   }
2014a541d17aSBarry Smith 
201517ab2063SBarry Smith   for (i=0; i<m; i++) {
201617ab2063SBarry Smith     len    = ai[i+1]-ai[i];
201787d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2018b9b97703SBarry Smith     array += len;
2019b9b97703SBarry Smith     aj    += len;
202017ab2063SBarry Smith   }
20216d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20226d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
202317ab2063SBarry Smith 
2024cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2025416022c9SBarry Smith     *B = C;
202617ab2063SBarry Smith   } else {
202728be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
202817ab2063SBarry Smith   }
20293a40ed3dSBarry Smith   PetscFunctionReturn(0);
203017ab2063SBarry Smith }
203117ab2063SBarry Smith 
20327087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2033cd0d46ebSvictorle {
20343d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
203554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
203654f21887SBarry Smith   MatScalar      *va,*vb;
20376849ba73SBarry Smith   PetscErrorCode ierr;
203897f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2039cd0d46ebSvictorle 
2040cd0d46ebSvictorle   PetscFunctionBegin;
2041cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2042cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20435485867bSBarry Smith   if (ma!=nb || na!=mb) {
20445485867bSBarry Smith     *f = PETSC_FALSE;
20455485867bSBarry Smith     PetscFunctionReturn(0);
20465485867bSBarry Smith   }
2047cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2048cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2049cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2050785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2051785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2052cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2053cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2054cd0d46ebSvictorle 
2055cd0d46ebSvictorle   *f = PETSC_TRUE;
2056cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2057cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
205897f1f81fSBarry Smith       PetscInt    idc,idr;
20595485867bSBarry Smith       PetscScalar vc,vr;
2060cd0d46ebSvictorle       /* column/row index/value */
20615485867bSBarry Smith       idc = adx[aptr[i]];
20625485867bSBarry Smith       idr = bdx[bptr[idc]];
20635485867bSBarry Smith       vc  = va[aptr[i]];
20645485867bSBarry Smith       vr  = vb[bptr[idc]];
20655485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20665485867bSBarry Smith         *f = PETSC_FALSE;
20675485867bSBarry Smith         goto done;
2068cd0d46ebSvictorle       } else {
20695485867bSBarry Smith         aptr[i]++;
20705485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2071cd0d46ebSvictorle       }
2072cd0d46ebSvictorle     }
2073cd0d46ebSvictorle   }
2074cd0d46ebSvictorle done:
2075cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20763aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2077cd0d46ebSvictorle   PetscFunctionReturn(0);
2078cd0d46ebSvictorle }
2079cd0d46ebSvictorle 
20807087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20811cbb95d3SBarry Smith {
20823d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
208354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
208454f21887SBarry Smith   MatScalar      *va,*vb;
20851cbb95d3SBarry Smith   PetscErrorCode ierr;
20861cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20871cbb95d3SBarry Smith 
20881cbb95d3SBarry Smith   PetscFunctionBegin;
20891cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20901cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20911cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
20921cbb95d3SBarry Smith     *f = PETSC_FALSE;
20931cbb95d3SBarry Smith     PetscFunctionReturn(0);
20941cbb95d3SBarry Smith   }
20951cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
20961cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
20971cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2098785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2099785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
21001cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
21011cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
21021cbb95d3SBarry Smith 
21031cbb95d3SBarry Smith   *f = PETSC_TRUE;
21041cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
21051cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21061cbb95d3SBarry Smith       PetscInt    idc,idr;
21071cbb95d3SBarry Smith       PetscScalar vc,vr;
21081cbb95d3SBarry Smith       /* column/row index/value */
21091cbb95d3SBarry Smith       idc = adx[aptr[i]];
21101cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
21111cbb95d3SBarry Smith       vc  = va[aptr[i]];
21121cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
21131cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
21141cbb95d3SBarry Smith         *f = PETSC_FALSE;
21151cbb95d3SBarry Smith         goto done;
21161cbb95d3SBarry Smith       } else {
21171cbb95d3SBarry Smith         aptr[i]++;
21181cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21191cbb95d3SBarry Smith       }
21201cbb95d3SBarry Smith     }
21211cbb95d3SBarry Smith   }
21221cbb95d3SBarry Smith done:
21231cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21241cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21251cbb95d3SBarry Smith   PetscFunctionReturn(0);
21261cbb95d3SBarry Smith }
21271cbb95d3SBarry Smith 
2128ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21299e29f15eSvictorle {
2130dfbe8321SBarry Smith   PetscErrorCode ierr;
21316e111a19SKarl Rupp 
21329e29f15eSvictorle   PetscFunctionBegin;
21335485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21349e29f15eSvictorle   PetscFunctionReturn(0);
21359e29f15eSvictorle }
21369e29f15eSvictorle 
2137ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21381cbb95d3SBarry Smith {
21391cbb95d3SBarry Smith   PetscErrorCode ierr;
21406e111a19SKarl Rupp 
21411cbb95d3SBarry Smith   PetscFunctionBegin;
21421cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21431cbb95d3SBarry Smith   PetscFunctionReturn(0);
21441cbb95d3SBarry Smith }
21451cbb95d3SBarry Smith 
2146dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
214717ab2063SBarry Smith {
2148416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
214954f21887SBarry Smith   PetscScalar    *l,*r,x;
215054f21887SBarry Smith   MatScalar      *v;
2151dfbe8321SBarry Smith   PetscErrorCode ierr;
2152d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
215317ab2063SBarry Smith 
21543a40ed3dSBarry Smith   PetscFunctionBegin;
215517ab2063SBarry Smith   if (ll) {
21563ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21573ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2158e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2159e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21601ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2161416022c9SBarry Smith     v    = a->a;
216217ab2063SBarry Smith     for (i=0; i<m; i++) {
216317ab2063SBarry Smith       x = l[i];
2164416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21652205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
216617ab2063SBarry Smith     }
21671ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2168efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
216917ab2063SBarry Smith   }
217017ab2063SBarry Smith   if (rr) {
2171e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2172e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21731ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2174416022c9SBarry Smith     v    = a->a; jj = a->j;
21752205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21761ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2177efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
217817ab2063SBarry Smith   }
2179acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
21803a40ed3dSBarry Smith   PetscFunctionReturn(0);
218117ab2063SBarry Smith }
218217ab2063SBarry Smith 
21837dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
218417ab2063SBarry Smith {
2185db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21866849ba73SBarry Smith   PetscErrorCode ierr;
2187d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
218897f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21895d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21905d0c19d7SBarry Smith   PetscInt       nrows,ncols;
219197f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
219254f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2193416022c9SBarry Smith   Mat            C;
2194cdc6f3adSToby Isaac   PetscBool      stride;
219517ab2063SBarry Smith 
21963a40ed3dSBarry Smith   PetscFunctionBegin;
219799141d43SSatish Balay 
219817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2199b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2200b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
220117ab2063SBarry Smith 
2202251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2203ff718158SBarry Smith   if (stride) {
2204ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2205ff718158SBarry Smith   } else {
2206ff718158SBarry Smith     first = 0;
2207ff718158SBarry Smith     step  = 0;
2208ff718158SBarry Smith   }
2209fee21e36SBarry Smith   if (stride && step == 1) {
221002834360SBarry Smith     /* special case of contiguous rows */
2211dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
221202834360SBarry Smith     /* loop over new rows determining lens and starting points */
221302834360SBarry Smith     for (i=0; i<nrows; i++) {
2214bfeeae90SHong Zhang       kstart = ai[irow[i]];
2215a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2216a91a9bebSLisandro Dalcin       starts[i] = kstart;
221702834360SBarry Smith       for (k=kstart; k<kend; k++) {
2218bfeeae90SHong Zhang         if (aj[k] >= first) {
221902834360SBarry Smith           starts[i] = k;
222002834360SBarry Smith           break;
222102834360SBarry Smith         }
222202834360SBarry Smith       }
2223a2744918SBarry Smith       sum = 0;
222402834360SBarry Smith       while (k < kend) {
2225bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2226a2744918SBarry Smith         sum++;
222702834360SBarry Smith       }
2228a2744918SBarry Smith       lens[i] = sum;
222902834360SBarry Smith     }
223002834360SBarry Smith     /* create submatrix */
2231cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
223297f1f81fSBarry Smith       PetscInt n_cols,n_rows;
223308480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2234e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2235d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
223608480c60SBarry Smith       C    = *B;
22373a40ed3dSBarry Smith     } else {
22383bef6203SJed Brown       PetscInt rbs,cbs;
2239ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2240f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22413bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22423bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22433bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22447adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2245ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
224608480c60SBarry Smith     }
2247db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2248db02288aSLois Curfman McInnes 
224902834360SBarry Smith     /* loop over rows inserting into submatrix */
2250db02288aSLois Curfman McInnes     a_new = c->a;
2251db02288aSLois Curfman McInnes     j_new = c->j;
2252db02288aSLois Curfman McInnes     i_new = c->i;
2253bfeeae90SHong Zhang 
225402834360SBarry Smith     for (i=0; i<nrows; i++) {
2255a2744918SBarry Smith       ii    = starts[i];
2256a2744918SBarry Smith       lensi = lens[i];
2257a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2258a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
225902834360SBarry Smith       }
226087828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2261a2744918SBarry Smith       a_new     += lensi;
2262a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2263a2744918SBarry Smith       c->ilen[i] = lensi;
226402834360SBarry Smith     }
22650e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22663a40ed3dSBarry Smith   } else {
226702834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22681795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2269854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22704dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22714dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22724dcab191SBarry 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);
22734dcab191SBarry Smith #endif
22744dcab191SBarry Smith       smap[icol[i]] = i+1;
22754dcab191SBarry Smith     }
22764dcab191SBarry Smith 
227702834360SBarry Smith     /* determine lens of each row */
227802834360SBarry Smith     for (i=0; i<nrows; i++) {
2279bfeeae90SHong Zhang       kstart  = ai[irow[i]];
228002834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
228102834360SBarry Smith       lens[i] = 0;
228202834360SBarry Smith       for (k=kstart; k<kend; k++) {
2283bfeeae90SHong Zhang         if (smap[aj[k]]) {
228402834360SBarry Smith           lens[i]++;
228502834360SBarry Smith         }
228602834360SBarry Smith       }
228702834360SBarry Smith     }
228817ab2063SBarry Smith     /* Create and fill new matrix */
2289a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2290ace3abfcSBarry Smith       PetscBool equal;
22910f5bd95cSBarry Smith 
229299141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2293e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2294d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2295f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2296d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
229708480c60SBarry Smith       C    = *B;
22983a40ed3dSBarry Smith     } else {
22993bef6203SJed Brown       PetscInt rbs,cbs;
2300ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2301f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23023bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23033bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23043bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23057adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2306ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
230708480c60SBarry Smith     }
230899141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
230917ab2063SBarry Smith     for (i=0; i<nrows; i++) {
231099141d43SSatish Balay       row      = irow[i];
2311bfeeae90SHong Zhang       kstart   = ai[row];
231299141d43SSatish Balay       kend     = kstart + a->ilen[row];
2313bfeeae90SHong Zhang       mat_i    = c->i[i];
231499141d43SSatish Balay       mat_j    = c->j + mat_i;
231599141d43SSatish Balay       mat_a    = c->a + mat_i;
231699141d43SSatish Balay       mat_ilen = c->ilen + i;
231717ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2318bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2319ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
232099141d43SSatish Balay           *mat_a++ = a->a[k];
232199141d43SSatish Balay           (*mat_ilen)++;
232299141d43SSatish Balay 
232317ab2063SBarry Smith         }
232417ab2063SBarry Smith       }
232517ab2063SBarry Smith     }
232602834360SBarry Smith     /* Free work space */
232702834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2328606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2329606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2330cdc6f3adSToby Isaac     /* sort */
2331cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2332cdc6f3adSToby Isaac       PetscInt ilen;
2333cdc6f3adSToby Isaac 
2334cdc6f3adSToby Isaac       mat_i = c->i[i];
2335cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2336cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2337cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2338390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2339cdc6f3adSToby Isaac     }
234002834360SBarry Smith   }
23416d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23426d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
234317ab2063SBarry Smith 
234417ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2345416022c9SBarry Smith   *B   = C;
23463a40ed3dSBarry Smith   PetscFunctionReturn(0);
234717ab2063SBarry Smith }
234817ab2063SBarry Smith 
2349fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
235082d44351SHong Zhang {
235182d44351SHong Zhang   PetscErrorCode ierr;
235282d44351SHong Zhang   Mat            B;
235382d44351SHong Zhang 
235482d44351SHong Zhang   PetscFunctionBegin;
2355c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
235682d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
235782d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
235833d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
235982d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
236082d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
236182d44351SHong Zhang     *subMat = B;
2362c2d650bdSHong Zhang   } else {
2363c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2364c2d650bdSHong Zhang   }
236582d44351SHong Zhang   PetscFunctionReturn(0);
236682d44351SHong Zhang }
236782d44351SHong Zhang 
23689a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2369a871dcd8SBarry Smith {
237063b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2371dfbe8321SBarry Smith   PetscErrorCode ierr;
237263b91edcSBarry Smith   Mat            outA;
2373ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
237463b91edcSBarry Smith 
23753a40ed3dSBarry Smith   PetscFunctionBegin;
2376e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23771df811f5SHong Zhang 
2378b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2379b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2380a871dcd8SBarry Smith 
238163b91edcSBarry Smith   outA             = inA;
2382d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2383f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2384f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
23852205254eSKarl Rupp 
2386c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23876bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
23882205254eSKarl Rupp 
2389c3122656SLisandro Dalcin   a->row = row;
23902205254eSKarl Rupp 
2391c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23926bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
23932205254eSKarl Rupp 
2394c3122656SLisandro Dalcin   a->col = col;
239563b91edcSBarry Smith 
239636db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23976bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23984c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
23993bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2400f0ec6fceSSatish Balay 
240194a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2402854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
24033bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
240494a9d846SBarry Smith   }
240563b91edcSBarry Smith 
2406f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2407137fb511SHong Zhang   if (row_identity && col_identity) {
2408ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2409137fb511SHong Zhang   } else {
2410719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2411137fb511SHong Zhang   }
24123a40ed3dSBarry Smith   PetscFunctionReturn(0);
2413a871dcd8SBarry Smith }
2414a871dcd8SBarry Smith 
2415f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2416f0b747eeSBarry Smith {
2417f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2418f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2419efee365bSSatish Balay   PetscErrorCode ierr;
2420c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24213a40ed3dSBarry Smith 
24223a40ed3dSBarry Smith   PetscFunctionBegin;
2423c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24248b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2425efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2426acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24273a40ed3dSBarry Smith   PetscFunctionReturn(0);
2428f0b747eeSBarry Smith }
2429f0b747eeSBarry Smith 
24305c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
243116b64355SHong Zhang {
243216b64355SHong Zhang   PetscErrorCode ierr;
243316b64355SHong Zhang   PetscInt       i;
243416b64355SHong Zhang 
243516b64355SHong Zhang   PetscFunctionBegin;
243616b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
243716b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
243816b64355SHong Zhang 
243916b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
244016b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
244116b64355SHong Zhang     }
244216b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
244316b64355SHong Zhang 
244416b64355SHong Zhang     if (submatj->rbuf1) {
244516b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
244616b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
244716b64355SHong Zhang     }
244816b64355SHong Zhang 
244916b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
245016b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
245116b64355SHong Zhang     }
245216b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
245316b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
245416b64355SHong Zhang   }
245516b64355SHong Zhang 
245616b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
245716b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
245816b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
245916b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
246016b64355SHong Zhang #else
246116b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
246216b64355SHong Zhang #endif
246316b64355SHong Zhang 
246416b64355SHong Zhang   if (!submatj->allcolumns) {
246516b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
246616b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
246716b64355SHong Zhang #else
246816b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
246916b64355SHong Zhang #endif
247016b64355SHong Zhang   }
247116b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
247216b64355SHong Zhang 
247316b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
247416b64355SHong Zhang   PetscFunctionReturn(0);
247516b64355SHong Zhang }
247616b64355SHong Zhang 
247716b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
247816b64355SHong Zhang {
247916b64355SHong Zhang   PetscErrorCode ierr;
248016b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
24815c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
248216b64355SHong Zhang 
248316b64355SHong Zhang   PetscFunctionBegin;
248416b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2485e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
248616b64355SHong Zhang   PetscFunctionReturn(0);
248716b64355SHong Zhang }
248816b64355SHong Zhang 
24897dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2490cddf8d76SBarry Smith {
2491dfbe8321SBarry Smith   PetscErrorCode ierr;
249297f1f81fSBarry Smith   PetscInt       i;
2493cddf8d76SBarry Smith 
24943a40ed3dSBarry Smith   PetscFunctionBegin;
2495cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2496df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2497cddf8d76SBarry Smith   }
2498cddf8d76SBarry Smith 
2499cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25007dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2501cddf8d76SBarry Smith   }
25023a40ed3dSBarry Smith   PetscFunctionReturn(0);
2503cddf8d76SBarry Smith }
2504cddf8d76SBarry Smith 
250597f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25064dcbc457SBarry Smith {
2507e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25086849ba73SBarry Smith   PetscErrorCode ierr;
25095d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25105d0c19d7SBarry Smith   const PetscInt *idx;
251197f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2512f1af5d2fSBarry Smith   PetscBT        table;
2513bbd702dbSSatish Balay 
25143a40ed3dSBarry Smith   PetscFunctionBegin;
2515d0f46423SBarry Smith   m  = A->rmap->n;
2516e4d965acSSatish Balay   ai = a->i;
2517bfeeae90SHong Zhang   aj = a->j;
25188a047759SSatish Balay 
2519e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
252006763907SSatish Balay 
2521854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
252253b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
252306763907SSatish Balay 
2524e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2525b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2526e4d965acSSatish Balay     isz  = 0;
25276831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2528e4d965acSSatish Balay 
2529e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25304dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2531b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2532e4d965acSSatish Balay 
2533dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2534e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25352205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25364dcbc457SBarry Smith     }
253706763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25386bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2539e4d965acSSatish Balay 
254004a348a9SBarry Smith     k = 0;
254104a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
254204a348a9SBarry Smith       n = isz;
254306763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2544e4d965acSSatish Balay         row   = nidx[k];
2545e4d965acSSatish Balay         start = ai[row];
2546e4d965acSSatish Balay         end   = ai[row+1];
254704a348a9SBarry Smith         for (l = start; l<end; l++) {
2548efb16452SHong Zhang           val = aj[l];
25492205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2550e4d965acSSatish Balay         }
2551e4d965acSSatish Balay       }
2552e4d965acSSatish Balay     }
255370b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2554e4d965acSSatish Balay   }
255594bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2556606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25573a40ed3dSBarry Smith   PetscFunctionReturn(0);
25584dcbc457SBarry Smith }
255917ab2063SBarry Smith 
25600513a670SBarry Smith /* -------------------------------------------------------------- */
2561dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25620513a670SBarry Smith {
25630513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25646849ba73SBarry Smith   PetscErrorCode ierr;
25653b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25665d0c19d7SBarry Smith   const PetscInt *row,*col;
25675d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
256856cd22aeSBarry Smith   IS             icolp,irowp;
25690298fd71SBarry Smith   PetscInt       *cwork = NULL;
25700298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25710513a670SBarry Smith 
25723a40ed3dSBarry Smith   PetscFunctionBegin;
25734c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
257456cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25754c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
257656cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
25770513a670SBarry Smith 
25780513a670SBarry Smith   /* determine lengths of permuted rows */
2579854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
25802205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2581ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2582f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
258333d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
25847adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2585ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2586606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
25870513a670SBarry Smith 
2588785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
25890513a670SBarry Smith   for (i=0; i<m; i++) {
259032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25912205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2592cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
259332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25940513a670SBarry Smith   }
2595606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
25962205254eSKarl Rupp 
25973c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
25982205254eSKarl Rupp 
25990513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26000513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
260156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
260256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26036bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26046bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26053a40ed3dSBarry Smith   PetscFunctionReturn(0);
26060513a670SBarry Smith }
26070513a670SBarry Smith 
2608dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2609cb5b572fSBarry Smith {
2610dfbe8321SBarry Smith   PetscErrorCode ierr;
2611cb5b572fSBarry Smith 
2612cb5b572fSBarry Smith   PetscFunctionBegin;
261333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
261433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2615be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2616be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2617be6bf707SBarry Smith 
2618700c5bfcSBarry 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");
2619d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2620cb5b572fSBarry Smith   } else {
2621cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2622cb5b572fSBarry Smith   }
2623cb5b572fSBarry Smith   PetscFunctionReturn(0);
2624cb5b572fSBarry Smith }
2625cb5b572fSBarry Smith 
26264994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2627273d9f13SBarry Smith {
2628dfbe8321SBarry Smith   PetscErrorCode ierr;
2629273d9f13SBarry Smith 
2630273d9f13SBarry Smith   PetscFunctionBegin;
2631ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2632273d9f13SBarry Smith   PetscFunctionReturn(0);
2633273d9f13SBarry Smith }
2634273d9f13SBarry Smith 
26358c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26366c0721eeSBarry Smith {
26376c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26386e111a19SKarl Rupp 
26396c0721eeSBarry Smith   PetscFunctionBegin;
26406c0721eeSBarry Smith   *array = a->a;
26416c0721eeSBarry Smith   PetscFunctionReturn(0);
26426c0721eeSBarry Smith }
26436c0721eeSBarry Smith 
26448c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26456c0721eeSBarry Smith {
26466c0721eeSBarry Smith   PetscFunctionBegin;
26476c0721eeSBarry Smith   PetscFunctionReturn(0);
26486c0721eeSBarry Smith }
2649273d9f13SBarry Smith 
26508229c054SShri Abhyankar /*
26518229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26528229c054SShri Abhyankar    have different nonzero structure.
26538229c054SShri Abhyankar */
2654b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2655ec7775f6SShri Abhyankar {
2656b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2657ec7775f6SShri Abhyankar 
2658ec7775f6SShri Abhyankar   PetscFunctionBegin;
2659ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2660ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2661b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2662b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2663b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26648af7cee1SJed Brown     nnz[i] = 0;
26658af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2666b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2667b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26688af7cee1SJed Brown       nnz[i]++;
26698af7cee1SJed Brown     }
26708af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2671ec7775f6SShri Abhyankar   }
2672ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2673ec7775f6SShri Abhyankar }
2674ec7775f6SShri Abhyankar 
2675b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2676b264fe52SHong Zhang {
2677b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2678b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2679b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2680b264fe52SHong Zhang   PetscErrorCode ierr;
2681b264fe52SHong Zhang 
2682b264fe52SHong Zhang   PetscFunctionBegin;
2683b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2684b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2685b264fe52SHong Zhang   PetscFunctionReturn(0);
2686b264fe52SHong Zhang }
2687b264fe52SHong Zhang 
2688f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2689ac90fabeSBarry Smith {
2690dfbe8321SBarry Smith   PetscErrorCode ierr;
2691ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2692c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2693ac90fabeSBarry Smith 
2694ac90fabeSBarry Smith   PetscFunctionBegin;
2695c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2696ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2697f4df32b1SMatthew Knepley     PetscScalar alpha = a;
26988b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2699acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2700a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2701ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2702ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2703ac90fabeSBarry Smith   } else {
27048229c054SShri Abhyankar     Mat      B;
27058229c054SShri Abhyankar     PetscInt *nnz;
2706785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2707ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2708bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27094aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
271033d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2711176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27128229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2713ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2714ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
271528be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27168229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2717ac90fabeSBarry Smith   }
2718ac90fabeSBarry Smith   PetscFunctionReturn(0);
2719ac90fabeSBarry Smith }
2720ac90fabeSBarry Smith 
27217087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2722354c94deSBarry Smith {
2723354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2724354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2725354c94deSBarry Smith   PetscInt    i,nz;
2726354c94deSBarry Smith   PetscScalar *a;
2727354c94deSBarry Smith 
2728354c94deSBarry Smith   PetscFunctionBegin;
2729354c94deSBarry Smith   nz = aij->nz;
2730354c94deSBarry Smith   a  = aij->a;
27312205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2732354c94deSBarry Smith #else
2733354c94deSBarry Smith   PetscFunctionBegin;
2734354c94deSBarry Smith #endif
2735354c94deSBarry Smith   PetscFunctionReturn(0);
2736354c94deSBarry Smith }
2737354c94deSBarry Smith 
2738985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2739e34fafa9SBarry Smith {
2740e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2741e34fafa9SBarry Smith   PetscErrorCode ierr;
2742d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2743e34fafa9SBarry Smith   PetscReal      atmp;
2744985db425SBarry Smith   PetscScalar    *x;
2745e34fafa9SBarry Smith   MatScalar      *aa;
2746e34fafa9SBarry Smith 
2747e34fafa9SBarry Smith   PetscFunctionBegin;
2748e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2749e34fafa9SBarry Smith   aa = a->a;
2750e34fafa9SBarry Smith   ai = a->i;
2751e34fafa9SBarry Smith   aj = a->j;
2752e34fafa9SBarry Smith 
2753985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2754e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2755e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2756e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2757e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2758e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27599189402eSHong Zhang     x[i]  = 0.0;
2760e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2761985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2762985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2763985db425SBarry Smith       aa++; aj++;
2764985db425SBarry Smith     }
2765985db425SBarry Smith   }
2766985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2767985db425SBarry Smith   PetscFunctionReturn(0);
2768985db425SBarry Smith }
2769985db425SBarry Smith 
2770985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2771985db425SBarry Smith {
2772985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2773985db425SBarry Smith   PetscErrorCode ierr;
2774d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2775985db425SBarry Smith   PetscScalar    *x;
2776985db425SBarry Smith   MatScalar      *aa;
2777985db425SBarry Smith 
2778985db425SBarry Smith   PetscFunctionBegin;
2779e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2780985db425SBarry Smith   aa = a->a;
2781985db425SBarry Smith   ai = a->i;
2782985db425SBarry Smith   aj = a->j;
2783985db425SBarry Smith 
2784985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2785985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2786985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2787e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2788985db425SBarry Smith   for (i=0; i<m; i++) {
2789985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2790d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2791985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2792985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2793985db425SBarry Smith       x[i] = 0.0;
2794985db425SBarry Smith       if (idx) {
2795985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2796985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2797985db425SBarry Smith           if (aj[j] > j) {
2798985db425SBarry Smith             idx[i] = j;
2799985db425SBarry Smith             break;
2800985db425SBarry Smith           }
2801985db425SBarry Smith         }
2802985db425SBarry Smith       }
2803985db425SBarry Smith     }
2804985db425SBarry Smith     for (j=0; j<ncols; j++) {
2805985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2806985db425SBarry Smith       aa++; aj++;
2807985db425SBarry Smith     }
2808985db425SBarry Smith   }
2809985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2810985db425SBarry Smith   PetscFunctionReturn(0);
2811985db425SBarry Smith }
2812985db425SBarry Smith 
2813c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2814c87e5d42SMatthew Knepley {
2815c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2816c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2817c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2818c87e5d42SMatthew Knepley   PetscReal      atmp;
2819c87e5d42SMatthew Knepley   PetscScalar    *x;
2820c87e5d42SMatthew Knepley   MatScalar      *aa;
2821c87e5d42SMatthew Knepley 
2822c87e5d42SMatthew Knepley   PetscFunctionBegin;
2823e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2824c87e5d42SMatthew Knepley   aa = a->a;
2825c87e5d42SMatthew Knepley   ai = a->i;
2826c87e5d42SMatthew Knepley   aj = a->j;
2827c87e5d42SMatthew Knepley 
2828c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2829c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2830c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
283160e0710aSBarry 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);
2832c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2833c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2834289a08f5SMatthew Knepley     if (ncols) {
2835289a08f5SMatthew Knepley       /* Get first nonzero */
2836289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2837289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28382205254eSKarl Rupp         if (atmp > 1.0e-12) {
28392205254eSKarl Rupp           x[i] = atmp;
28402205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28412205254eSKarl Rupp           break;
28422205254eSKarl Rupp         }
2843289a08f5SMatthew Knepley       }
284412431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2845289a08f5SMatthew Knepley     } else {
2846289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2847289a08f5SMatthew Knepley     }
2848c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2849c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2850289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2851c87e5d42SMatthew Knepley       aa++; aj++;
2852c87e5d42SMatthew Knepley     }
2853c87e5d42SMatthew Knepley   }
2854c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2855c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2856c87e5d42SMatthew Knepley }
2857c87e5d42SMatthew Knepley 
2858985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2859985db425SBarry Smith {
2860985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2861985db425SBarry Smith   PetscErrorCode  ierr;
2862d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2863d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2864985db425SBarry Smith   PetscScalar     *x;
2865d9ca1df4SBarry Smith   const MatScalar *aa;
2866985db425SBarry Smith 
2867985db425SBarry Smith   PetscFunctionBegin;
2868e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2869985db425SBarry Smith   aa = a->a;
2870985db425SBarry Smith   ai = a->i;
2871985db425SBarry Smith   aj = a->j;
2872985db425SBarry Smith 
2873985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2874985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2875985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2876e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2877985db425SBarry Smith   for (i=0; i<m; i++) {
2878985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2879d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2880985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2881985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2882985db425SBarry Smith       x[i] = 0.0;
2883985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2884985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2885985db425SBarry Smith         for (j=0; j<ncols; j++) {
2886985db425SBarry Smith           if (aj[j] > j) {
2887985db425SBarry Smith             idx[i] = j;
2888985db425SBarry Smith             break;
2889985db425SBarry Smith           }
2890985db425SBarry Smith         }
2891985db425SBarry Smith       }
2892985db425SBarry Smith     }
2893985db425SBarry Smith     for (j=0; j<ncols; j++) {
2894985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2895985db425SBarry Smith       aa++; aj++;
2896e34fafa9SBarry Smith     }
2897e34fafa9SBarry Smith   }
2898e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2899e34fafa9SBarry Smith   PetscFunctionReturn(0);
2900e34fafa9SBarry Smith }
2901bbead8a2SBarry Smith 
2902bbead8a2SBarry Smith #include <petscblaslapack.h>
2903af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2904bbead8a2SBarry Smith 
2905713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2906bbead8a2SBarry Smith {
2907bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2908bbead8a2SBarry Smith   PetscErrorCode ierr;
290933d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2910bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2911bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29121a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2913bbead8a2SBarry Smith 
2914bbead8a2SBarry Smith   PetscFunctionBegin;
2915a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29164a0d0026SBarry Smith   if (a->ibdiagvalid) {
29174a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29184a0d0026SBarry Smith     PetscFunctionReturn(0);
29194a0d0026SBarry Smith   }
2920bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2921bbead8a2SBarry Smith   if (!a->ibdiag) {
2922785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29233bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2924bbead8a2SBarry Smith   }
2925bbead8a2SBarry Smith   diag = a->ibdiag;
2926bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2927bbead8a2SBarry Smith   /* factor and invert each block */
2928bbead8a2SBarry Smith   switch (bs) {
2929bbead8a2SBarry Smith   case 1:
2930bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2931bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2932ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2933ec1892c8SHong Zhang         if (allowzeropivot) {
29347b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29357b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29367b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29377b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29387b6c816cSBarry 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);
2939ec1892c8SHong Zhang       }
2940bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2941bbead8a2SBarry Smith     }
2942bbead8a2SBarry Smith     break;
2943bbead8a2SBarry Smith   case 2:
2944bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2945bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2946bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2947a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29487b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
294996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2950bbead8a2SBarry Smith       diag += 4;
2951bbead8a2SBarry Smith     }
2952bbead8a2SBarry Smith     break;
2953bbead8a2SBarry Smith   case 3:
2954bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2955bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2956bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2957a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29587b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
295996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2960bbead8a2SBarry Smith       diag += 9;
2961bbead8a2SBarry Smith     }
2962bbead8a2SBarry Smith     break;
2963bbead8a2SBarry Smith   case 4:
2964bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2965bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2966bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2967a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29687b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
296996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2970bbead8a2SBarry Smith       diag += 16;
2971bbead8a2SBarry Smith     }
2972bbead8a2SBarry Smith     break;
2973bbead8a2SBarry Smith   case 5:
2974bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2975bbead8a2SBarry 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;
2976bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2977a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29787b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2980bbead8a2SBarry Smith       diag += 25;
2981bbead8a2SBarry Smith     }
2982bbead8a2SBarry Smith     break;
2983bbead8a2SBarry Smith   case 6:
2984bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2985bbead8a2SBarry 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;
2986bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
2987a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29887b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2990bbead8a2SBarry Smith       diag += 36;
2991bbead8a2SBarry Smith     }
2992bbead8a2SBarry Smith     break;
2993bbead8a2SBarry Smith   case 7:
2994bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2995bbead8a2SBarry 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;
2996bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
2997a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29987b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3000bbead8a2SBarry Smith       diag += 49;
3001bbead8a2SBarry Smith     }
3002bbead8a2SBarry Smith     break;
3003bbead8a2SBarry Smith   default:
3004dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3005bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3006bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3007bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3008bbead8a2SBarry Smith       }
3009bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30105f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30117b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
301296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3013bbead8a2SBarry Smith       diag += bs2;
3014bbead8a2SBarry Smith     }
3015bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3016bbead8a2SBarry Smith   }
3017bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3018bbead8a2SBarry Smith   PetscFunctionReturn(0);
3019bbead8a2SBarry Smith }
3020bbead8a2SBarry Smith 
302173a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
302273a71a0fSBarry Smith {
302373a71a0fSBarry Smith   PetscErrorCode ierr;
302473a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
302573a71a0fSBarry Smith   PetscScalar    a;
302673a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
302773a71a0fSBarry Smith 
302873a71a0fSBarry Smith   PetscFunctionBegin;
302973a71a0fSBarry Smith   if (!x->assembled) {
303073a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
303173a71a0fSBarry Smith     for (i=0; i<m; i++) {
303273a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
303373a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
303473a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
303573a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
303673a71a0fSBarry Smith       }
303773a71a0fSBarry Smith     }
303873a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
303973a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304073a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304173a71a0fSBarry Smith   PetscFunctionReturn(0);
304273a71a0fSBarry Smith }
304373a71a0fSBarry Smith 
30447d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30457d68702bSBarry Smith {
30467d68702bSBarry Smith   PetscErrorCode ierr;
30477d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30487d68702bSBarry Smith 
30497d68702bSBarry Smith   PetscFunctionBegin;
30506f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30517d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30527d68702bSBarry Smith   }
30537d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30547d68702bSBarry Smith   PetscFunctionReturn(0);
30557d68702bSBarry Smith }
30567d68702bSBarry Smith 
3057682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30580a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3059cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3060cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3061cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
306297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30637c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30647c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3065db4efbfdSBarry Smith                                         0,
3066db4efbfdSBarry Smith                                         0,
3067db4efbfdSBarry Smith                                         0,
3068db4efbfdSBarry Smith                                 /* 10*/ 0,
3069cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3070cb5b572fSBarry Smith                                         0,
307141f059aeSBarry Smith                                         MatSOR_SeqAIJ,
307217ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
307397304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3074cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3075cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3076cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3077cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
307897304618SKris Buschelman                                 /* 20*/ 0,
3079cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3080cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3081cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3082d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3083db4efbfdSBarry Smith                                         0,
3084db4efbfdSBarry Smith                                         0,
3085db4efbfdSBarry Smith                                         0,
3086db4efbfdSBarry Smith                                         0,
30874994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3088db4efbfdSBarry Smith                                         0,
3089db4efbfdSBarry Smith                                         0,
30908c778c55SBarry Smith                                         0,
30918c778c55SBarry Smith                                         0,
3092d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3093cb5b572fSBarry Smith                                         0,
3094cb5b572fSBarry Smith                                         0,
3095cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3096cb5b572fSBarry Smith                                         0,
3097d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
30987dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3099cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3100cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3101cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3102d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3103cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
31047d68702bSBarry Smith                                         MatShift_SeqAIJ,
310579299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31066e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
310773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31083b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31093b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31103b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3111a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
311293dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3113b9617806SBarry Smith                                         0,
31140513a670SBarry Smith                                         0,
3115cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3116cda55fadSBarry Smith                                         0,
3117d519adbfSMatthew Knepley                                 /* 59*/ 0,
3118b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3119b9b97703SBarry Smith                                         MatView_SeqAIJ,
3120357abbc8SBarry Smith                                         0,
3121321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3122321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3123321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3124ee4f033dSBarry Smith                                         0,
3125ee4f033dSBarry Smith                                         0,
3126ee4f033dSBarry Smith                                         0,
3127d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3128c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3129ee4f033dSBarry Smith                                         0,
3130dcf5cc72SBarry Smith                                         0,
31312c93a97aSBarry Smith                                         0,
31322c93a97aSBarry Smith                                 /* 74*/ 0,
31333acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
313497304618SKris Buschelman                                         0,
313597304618SKris Buschelman                                         0,
313697304618SKris Buschelman                                         0,
31376ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
313897304618SKris Buschelman                                         0,
313997304618SKris Buschelman                                         0,
314097304618SKris Buschelman                                         0,
3141bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3142d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31431cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31446284ec50SHong Zhang                                         0,
31456284ec50SHong Zhang                                         0,
3146bc011b1eSHong Zhang                                         0,
3147d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
314826be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
314926be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
315065e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31514a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
315265e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31536fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31546fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31556fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31562121bac1SHong Zhang                                         0,
31572121bac1SHong Zhang                                 /* 99*/ 0,
3158609c6c4dSKris Buschelman                                         0,
3159609c6c4dSKris Buschelman                                         0,
316087d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
316187d4246cSBarry Smith                                         0,
3162d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
316399cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3164f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3165f5edf698SHong Zhang                                         0,
31662bebee5dSHong Zhang                                         0,
3167cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3168985db425SBarry Smith                                         0,
31692af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31702af78befSBarry Smith                                         0,
3171599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3172d519adbfSMatthew Knepley                                 /*114*/ 0,
3173599ef60dSHong Zhang                                         0,
31743c2a7987SHong Zhang                                         0,
3175fe97e370SBarry Smith                                         0,
3176fbdbba38SShri Abhyankar                                         0,
3177fbdbba38SShri Abhyankar                                 /*119*/ 0,
3178fbdbba38SShri Abhyankar                                         0,
3179fbdbba38SShri Abhyankar                                         0,
318082d44351SHong Zhang                                         0,
3181b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
31820716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3183bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
318437868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
318537868618SMatthew G Knepley                                         0,
318637868618SMatthew G Knepley                                         0,
31875df89d91SHong Zhang                                 /*129*/ 0,
318875648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
318975648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
319075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3191b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3192b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
31932b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
31942b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
31952b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
31963964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
31973964eb88SJed Brown                                  /*139*/0,
3198f9426fe0SMark Adams                                         0,
31991919a2e2SJed Brown                                         0,
32003a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
32019c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
32029c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
32039e29f15eSvictorle };
320417ab2063SBarry Smith 
32057087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3206bef8e0ddSBarry Smith {
3207bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
320897f1f81fSBarry Smith   PetscInt   i,nz,n;
3209bef8e0ddSBarry Smith 
3210bef8e0ddSBarry Smith   PetscFunctionBegin;
3211bef8e0ddSBarry Smith   nz = aij->maxnz;
3212d0f46423SBarry Smith   n  = mat->rmap->n;
3213bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3214bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3215bef8e0ddSBarry Smith   }
3216bef8e0ddSBarry Smith   aij->nz = nz;
3217bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3218bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3219bef8e0ddSBarry Smith   }
3220bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3221bef8e0ddSBarry Smith }
3222bef8e0ddSBarry Smith 
3223bef8e0ddSBarry Smith /*@
3224bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3225bef8e0ddSBarry Smith        in the matrix.
3226bef8e0ddSBarry Smith 
3227bef8e0ddSBarry Smith   Input Parameters:
3228bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3229bef8e0ddSBarry Smith -  indices - the column indices
3230bef8e0ddSBarry Smith 
323115091d37SBarry Smith   Level: advanced
323215091d37SBarry Smith 
3233bef8e0ddSBarry Smith   Notes:
3234bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3235bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3236bef8e0ddSBarry Smith   of the MatSetValues() operation.
3237bef8e0ddSBarry Smith 
3238bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3239d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3240bef8e0ddSBarry Smith 
3241bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3242bef8e0ddSBarry Smith 
3243b9617806SBarry Smith     The indices should start with zero, not one.
3244b9617806SBarry Smith 
3245bef8e0ddSBarry Smith @*/
32467087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3247bef8e0ddSBarry Smith {
32484ac538c5SBarry Smith   PetscErrorCode ierr;
3249bef8e0ddSBarry Smith 
3250bef8e0ddSBarry Smith   PetscFunctionBegin;
32510700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32524482741eSBarry Smith   PetscValidPointer(indices,2);
32534ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3254bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3255bef8e0ddSBarry Smith }
3256bef8e0ddSBarry Smith 
3257be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3258be6bf707SBarry Smith 
32597087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3260be6bf707SBarry Smith {
3261be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32626849ba73SBarry Smith   PetscErrorCode ierr;
3263d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3264be6bf707SBarry Smith 
3265be6bf707SBarry Smith   PetscFunctionBegin;
3266169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3267be6bf707SBarry Smith 
3268be6bf707SBarry Smith   /* allocate space for values if not already there */
3269be6bf707SBarry Smith   if (!aij->saved_values) {
3270854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32713bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3272be6bf707SBarry Smith   }
3273be6bf707SBarry Smith 
3274be6bf707SBarry Smith   /* copy values over */
327587828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3276be6bf707SBarry Smith   PetscFunctionReturn(0);
3277be6bf707SBarry Smith }
3278be6bf707SBarry Smith 
3279be6bf707SBarry Smith /*@
3280be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3281be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3282be6bf707SBarry Smith        nonlinear portion.
3283be6bf707SBarry Smith 
3284be6bf707SBarry Smith    Collect on Mat
3285be6bf707SBarry Smith 
3286be6bf707SBarry Smith   Input Parameters:
32870e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3288be6bf707SBarry Smith 
328915091d37SBarry Smith   Level: advanced
329015091d37SBarry Smith 
3291be6bf707SBarry Smith   Common Usage, with SNESSolve():
3292be6bf707SBarry Smith $    Create Jacobian matrix
3293be6bf707SBarry Smith $    Set linear terms into matrix
3294be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3295be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3296be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3297512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3298be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3299be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3300be6bf707SBarry Smith $    In your Jacobian routine
3301be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3302be6bf707SBarry Smith $      Set nonlinear terms in matrix
3303be6bf707SBarry Smith 
3304be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3305be6bf707SBarry Smith $    // build linear portion of Jacobian
3306512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3307be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3308be6bf707SBarry Smith $    loop over nonlinear iterations
3309be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3310be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3311be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3312be6bf707SBarry Smith $       Solve linear system with Jacobian
3313be6bf707SBarry Smith $    endloop
3314be6bf707SBarry Smith 
3315be6bf707SBarry Smith   Notes:
3316be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3317512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3318be6bf707SBarry Smith     calling this routine.
3319be6bf707SBarry Smith 
33200c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33210c468ba9SBarry Smith     and does not allocated additional space.
33220c468ba9SBarry Smith 
3323be6bf707SBarry Smith .seealso: MatRetrieveValues()
3324be6bf707SBarry Smith 
3325be6bf707SBarry Smith @*/
33267087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3327be6bf707SBarry Smith {
33284ac538c5SBarry Smith   PetscErrorCode ierr;
3329be6bf707SBarry Smith 
3330be6bf707SBarry Smith   PetscFunctionBegin;
33310700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3332e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3333e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33344ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3335be6bf707SBarry Smith   PetscFunctionReturn(0);
3336be6bf707SBarry Smith }
3337be6bf707SBarry Smith 
33387087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3339be6bf707SBarry Smith {
3340be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33416849ba73SBarry Smith   PetscErrorCode ierr;
3342d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3343be6bf707SBarry Smith 
3344be6bf707SBarry Smith   PetscFunctionBegin;
3345169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3346f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3347be6bf707SBarry Smith   /* copy values over */
334887828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3349be6bf707SBarry Smith   PetscFunctionReturn(0);
3350be6bf707SBarry Smith }
3351be6bf707SBarry Smith 
3352be6bf707SBarry Smith /*@
3353be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3354be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3355be6bf707SBarry Smith        nonlinear portion.
3356be6bf707SBarry Smith 
3357be6bf707SBarry Smith    Collect on Mat
3358be6bf707SBarry Smith 
3359be6bf707SBarry Smith   Input Parameters:
3360386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3361be6bf707SBarry Smith 
336215091d37SBarry Smith   Level: advanced
336315091d37SBarry Smith 
3364be6bf707SBarry Smith .seealso: MatStoreValues()
3365be6bf707SBarry Smith 
3366be6bf707SBarry Smith @*/
33677087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3368be6bf707SBarry Smith {
33694ac538c5SBarry Smith   PetscErrorCode ierr;
3370be6bf707SBarry Smith 
3371be6bf707SBarry Smith   PetscFunctionBegin;
33720700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3373e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3374e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33754ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3376be6bf707SBarry Smith   PetscFunctionReturn(0);
3377be6bf707SBarry Smith }
3378be6bf707SBarry Smith 
3379f83d6046SBarry Smith 
3380be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
338117ab2063SBarry Smith /*@C
3382682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33830d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33846e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
338551c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33862bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
338717ab2063SBarry Smith 
3388db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3389db81eaa0SLois Curfman McInnes 
339017ab2063SBarry Smith    Input Parameters:
3391db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
339217ab2063SBarry Smith .  m - number of rows
339317ab2063SBarry Smith .  n - number of columns
339417ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
339551c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33960298fd71SBarry Smith          (possibly different for each row) or NULL
339717ab2063SBarry Smith 
339817ab2063SBarry Smith    Output Parameter:
3399416022c9SBarry Smith .  A - the matrix
340017ab2063SBarry Smith 
3401175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3402ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3403175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3404175b88e8SBarry Smith 
3405b259b22eSLois Curfman McInnes    Notes:
340649a6f317SBarry Smith    If nnz is given then nz is ignored
340749a6f317SBarry Smith 
340817ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
340917ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34100002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
341144cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
341217ab2063SBarry Smith 
341317ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34140298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34153d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34166da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
341717ab2063SBarry Smith 
3418682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34194fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3420682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34216c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34226c7ebb05SLois Curfman McInnes 
34236c7ebb05SLois Curfman McInnes    Options Database Keys:
3424698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34259db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
342617ab2063SBarry Smith 
3427027ccd11SLois Curfman McInnes    Level: intermediate
3428027ccd11SLois Curfman McInnes 
342969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
343036db0b34SBarry Smith 
343117ab2063SBarry Smith @*/
34327087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
343317ab2063SBarry Smith {
3434dfbe8321SBarry Smith   PetscErrorCode ierr;
34356945ee14SBarry Smith 
34363a40ed3dSBarry Smith   PetscFunctionBegin;
3437f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3438117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3439c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3440d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3441273d9f13SBarry Smith   PetscFunctionReturn(0);
3442273d9f13SBarry Smith }
3443273d9f13SBarry Smith 
3444273d9f13SBarry Smith /*@C
3445273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3446273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3447273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3448273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3449273d9f13SBarry Smith 
3450273d9f13SBarry Smith    Collective on MPI_Comm
3451273d9f13SBarry Smith 
3452273d9f13SBarry Smith    Input Parameters:
34531c4f3114SJed Brown +  B - The matrix
3454273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3455273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34560298fd71SBarry Smith          (possibly different for each row) or NULL
3457273d9f13SBarry Smith 
3458273d9f13SBarry Smith    Notes:
345949a6f317SBarry Smith      If nnz is given then nz is ignored
346049a6f317SBarry Smith 
3461273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3462273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3463273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3464273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3465273d9f13SBarry Smith 
3466273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34670298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3468273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3469273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3470273d9f13SBarry Smith 
3471aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3472aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3473aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3474aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3475aa95bbe8SBarry Smith 
3476a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3477a96a251dSBarry Smith    entries or columns indices
3478a96a251dSBarry Smith 
3479273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3480273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3481273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3482273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3483273d9f13SBarry Smith 
3484273d9f13SBarry Smith    Options Database Keys:
3485698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3486698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3487273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3488273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3489273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3490273d9f13SBarry Smith 
3491273d9f13SBarry Smith    Level: intermediate
3492273d9f13SBarry Smith 
349369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3494273d9f13SBarry Smith 
3495273d9f13SBarry Smith @*/
34967087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3497273d9f13SBarry Smith {
34984ac538c5SBarry Smith   PetscErrorCode ierr;
3499a23d5eceSKris Buschelman 
3500a23d5eceSKris Buschelman   PetscFunctionBegin;
35016ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35026ba663aaSJed Brown   PetscValidType(B,1);
35034ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3504a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3505a23d5eceSKris Buschelman }
3506a23d5eceSKris Buschelman 
35077087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3508a23d5eceSKris Buschelman {
3509273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35102576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35116849ba73SBarry Smith   PetscErrorCode ierr;
351297f1f81fSBarry Smith   PetscInt       i;
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith   PetscFunctionBegin;
35152576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3516a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3517c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3518c461c341SBarry Smith     nz             = 0;
3519c461c341SBarry Smith   }
352026283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
352126283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3522899cda47SBarry Smith 
3523435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
352460e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3525b73539f3SBarry Smith   if (nnz) {
3526d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
352760e0710aSBarry 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]);
352860e0710aSBarry 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);
3529b73539f3SBarry Smith     }
3530b73539f3SBarry Smith   }
3531b73539f3SBarry Smith 
3532273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35332205254eSKarl Rupp 
3534273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3535273d9f13SBarry Smith 
3536ab93d7beSBarry Smith   if (!skipallocation) {
35372ee49352SLisandro Dalcin     if (!b->imax) {
3538dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35393bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35402ee49352SLisandro Dalcin     }
3541273d9f13SBarry Smith     if (!nnz) {
3542435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3543c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3544d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3545d0f46423SBarry Smith       nz = nz*B->rmap->n;
3546273d9f13SBarry Smith     } else {
3547273d9f13SBarry Smith       nz = 0;
3548d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3549273d9f13SBarry Smith     }
3550ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35512205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3552ab93d7beSBarry Smith 
3553273d9f13SBarry Smith     /* allocate the matrix space */
355453dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35552ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3556*396832f4SHong Zhang     if (B->structure_only) {
3557*396832f4SHong Zhang       ierr    = PetscMalloc2(nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
3558*396832f4SHong Zhang       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr);
3559*396832f4SHong Zhang     } else {
3560dcca6d9dSJed Brown       ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35613bb1ff40SBarry Smith       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3562*396832f4SHong Zhang     }
3563bfeeae90SHong Zhang     b->i[0] = 0;
3564d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35655da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35665da197adSKris Buschelman     }
3567*396832f4SHong Zhang     if (B->structure_only) {
3568*396832f4SHong Zhang       b->singlemalloc = PETSC_FALSE;
3569*396832f4SHong Zhang       b->free_a       = PETSC_FALSE;
3570*396832f4SHong Zhang     } else {
3571273d9f13SBarry Smith       b->singlemalloc = PETSC_TRUE;
3572e6b907acSBarry Smith       b->free_a       = PETSC_TRUE;
3573*396832f4SHong Zhang     }
3574e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3575c461c341SBarry Smith   } else {
3576e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3577e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3578c461c341SBarry Smith   }
3579273d9f13SBarry Smith 
3580273d9f13SBarry Smith   b->nz               = 0;
3581273d9f13SBarry Smith   b->maxnz            = nz;
3582273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
35832205254eSKarl Rupp   if (realalloc) {
35842205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
35852205254eSKarl Rupp   }
3586cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3587cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3588273d9f13SBarry Smith   PetscFunctionReturn(0);
3589273d9f13SBarry Smith }
3590273d9f13SBarry Smith 
359158d36128SBarry Smith /*@
3592a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3593a1661176SMatthew Knepley 
3594a1661176SMatthew Knepley    Input Parameters:
3595a1661176SMatthew Knepley +  B - the matrix
3596a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3597a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3598a1661176SMatthew Knepley -  v - optional values in the matrix
3599a1661176SMatthew Knepley 
3600a1661176SMatthew Knepley    Level: developer
3601a1661176SMatthew Knepley 
360258d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
360358d36128SBarry Smith 
3604a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3605a1661176SMatthew Knepley 
3606a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3607a1661176SMatthew Knepley @*/
3608a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3609a1661176SMatthew Knepley {
3610a1661176SMatthew Knepley   PetscErrorCode ierr;
3611a1661176SMatthew Knepley 
3612a1661176SMatthew Knepley   PetscFunctionBegin;
36130700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36146ba663aaSJed Brown   PetscValidType(B,1);
36154ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3616a1661176SMatthew Knepley   PetscFunctionReturn(0);
3617a1661176SMatthew Knepley }
3618a1661176SMatthew Knepley 
36197087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3620a1661176SMatthew Knepley {
3621a1661176SMatthew Knepley   PetscInt       i;
3622a1661176SMatthew Knepley   PetscInt       m,n;
3623a1661176SMatthew Knepley   PetscInt       nz;
3624a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3625a1661176SMatthew Knepley   PetscScalar    *values;
3626a1661176SMatthew Knepley   PetscErrorCode ierr;
3627a1661176SMatthew Knepley 
3628a1661176SMatthew Knepley   PetscFunctionBegin;
362965e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3630779a8d59SSatish Balay 
3631779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3632779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3633779a8d59SSatish Balay 
3634779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3635854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3636a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3637b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3638a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
363965e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3640a1661176SMatthew Knepley     nnz[i] = nz;
3641a1661176SMatthew Knepley   }
3642a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3643a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3644a1661176SMatthew Knepley 
3645a1661176SMatthew Knepley   if (v) {
3646a1661176SMatthew Knepley     values = (PetscScalar*) v;
3647a1661176SMatthew Knepley   } else {
36481795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3649a1661176SMatthew Knepley   }
3650a1661176SMatthew Knepley 
3651a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3652b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3653b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3654a1661176SMatthew Knepley   }
3655a1661176SMatthew Knepley 
3656a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3657a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3658a1661176SMatthew Knepley 
3659a1661176SMatthew Knepley   if (!v) {
3660a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3661a1661176SMatthew Knepley   }
36627827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3663a1661176SMatthew Knepley   PetscFunctionReturn(0);
3664a1661176SMatthew Knepley }
3665a1661176SMatthew Knepley 
3666c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3667af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3668170fe5c8SBarry Smith 
3669170fe5c8SBarry Smith /*
3670170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3671170fe5c8SBarry Smith 
3672170fe5c8SBarry Smith                n                       p                          p
3673170fe5c8SBarry Smith         (              )       (              )         (                  )
3674170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3675170fe5c8SBarry Smith         (              )       (              )         (                  )
3676170fe5c8SBarry Smith 
3677170fe5c8SBarry Smith */
3678170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3679170fe5c8SBarry Smith {
3680170fe5c8SBarry Smith   PetscErrorCode    ierr;
3681170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3682170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3683170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
36841de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3685170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3686170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3687170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3688170fe5c8SBarry Smith 
3689170fe5c8SBarry Smith   PetscFunctionBegin;
3690d0f46423SBarry Smith   m    = A->rmap->n;
3691d0f46423SBarry Smith   n    = A->cmap->n;
3692d0f46423SBarry Smith   p    = B->cmap->n;
3693170fe5c8SBarry Smith   a    = sub_a->v;
3694170fe5c8SBarry Smith   b    = sub_b->a;
3695170fe5c8SBarry Smith   c    = sub_c->v;
3696170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3697170fe5c8SBarry Smith 
3698170fe5c8SBarry Smith   ii  = sub_b->i;
3699170fe5c8SBarry Smith   idx = sub_b->j;
3700170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3701170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3702170fe5c8SBarry Smith     while (q-->0) {
3703170fe5c8SBarry Smith       c_q = c + m*(*idx);
3704170fe5c8SBarry Smith       a_q = a + m*i;
3705854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3706170fe5c8SBarry Smith       idx++;
3707170fe5c8SBarry Smith       b++;
3708170fe5c8SBarry Smith     }
3709170fe5c8SBarry Smith   }
3710170fe5c8SBarry Smith   PetscFunctionReturn(0);
3711170fe5c8SBarry Smith }
3712170fe5c8SBarry Smith 
3713170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3714170fe5c8SBarry Smith {
3715170fe5c8SBarry Smith   PetscErrorCode ierr;
3716d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3717170fe5c8SBarry Smith   Mat            Cmat;
3718170fe5c8SBarry Smith 
3719170fe5c8SBarry Smith   PetscFunctionBegin;
372060e0710aSBarry 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);
3721ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3722170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
372333d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3724170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37250298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3726d73949e8SHong Zhang 
3727d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37282205254eSKarl Rupp 
3729170fe5c8SBarry Smith   *C = Cmat;
3730170fe5c8SBarry Smith   PetscFunctionReturn(0);
3731170fe5c8SBarry Smith }
3732170fe5c8SBarry Smith 
3733170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3734150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3735170fe5c8SBarry Smith {
3736170fe5c8SBarry Smith   PetscErrorCode ierr;
3737170fe5c8SBarry Smith 
3738170fe5c8SBarry Smith   PetscFunctionBegin;
3739170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37403ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3741170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37423ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3743170fe5c8SBarry Smith   }
37443ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3745170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37463ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3747170fe5c8SBarry Smith   PetscFunctionReturn(0);
3748170fe5c8SBarry Smith }
3749170fe5c8SBarry Smith 
3750170fe5c8SBarry Smith 
37510bad9183SKris Buschelman /*MC
3752fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37530bad9183SKris Buschelman    based on compressed sparse row format.
37540bad9183SKris Buschelman 
37550bad9183SKris Buschelman    Options Database Keys:
37560bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37570bad9183SKris Buschelman 
37580bad9183SKris Buschelman   Level: beginner
37590bad9183SKris Buschelman 
3760f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37610bad9183SKris Buschelman M*/
37620bad9183SKris Buschelman 
3763ccd284c7SBarry Smith /*MC
3764ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3765ccd284c7SBarry Smith 
3766ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3767ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3768ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3769ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3770ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3771ccd284c7SBarry Smith 
3772ccd284c7SBarry Smith    Options Database Keys:
3773ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3774ccd284c7SBarry Smith 
3775ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3776ccd284c7SBarry Smith    enough exist.
3777ccd284c7SBarry Smith 
3778ccd284c7SBarry Smith   Level: beginner
3779ccd284c7SBarry Smith 
3780ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3781ccd284c7SBarry Smith M*/
3782ccd284c7SBarry Smith 
3783ccd284c7SBarry Smith /*MC
3784ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3785ccd284c7SBarry Smith 
3786ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3787ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3788ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3789ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3790ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3791ccd284c7SBarry Smith 
3792ccd284c7SBarry Smith    Options Database Keys:
3793ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3794ccd284c7SBarry Smith 
3795ccd284c7SBarry Smith   Level: beginner
3796ccd284c7SBarry Smith 
3797ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3798ccd284c7SBarry Smith M*/
3799ccd284c7SBarry Smith 
3800cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3801af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3802cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3803af8000cdSHong Zhang #endif
380463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
380563c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
38063dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
380763c07aadSStefano Zampini #endif
3808cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
380942c9c57cSBarry Smith 
3810b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
381129b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
381229b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3813b3866ffcSBarry Smith #endif
381417667f90SBarry Smith 
3815c0c8ee5eSDmitry Karpeev 
38168c778c55SBarry Smith /*@C
38178397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38188c778c55SBarry Smith 
38198c778c55SBarry Smith    Not Collective
38208c778c55SBarry Smith 
38218c778c55SBarry Smith    Input Parameter:
3822579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38238c778c55SBarry Smith 
38248c778c55SBarry Smith    Output Parameter:
38258c778c55SBarry Smith .   array - pointer to the data
38268c778c55SBarry Smith 
38278c778c55SBarry Smith    Level: intermediate
38288c778c55SBarry Smith 
3829774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38308c778c55SBarry Smith @*/
38318c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38328c778c55SBarry Smith {
38338c778c55SBarry Smith   PetscErrorCode ierr;
38348c778c55SBarry Smith 
38358c778c55SBarry Smith   PetscFunctionBegin;
38368c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38378c778c55SBarry Smith   PetscFunctionReturn(0);
38388c778c55SBarry Smith }
38398c778c55SBarry Smith 
384021e72a00SBarry Smith /*@C
384121e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
384221e72a00SBarry Smith 
384321e72a00SBarry Smith    Not Collective
384421e72a00SBarry Smith 
384521e72a00SBarry Smith    Input Parameter:
3846579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
384721e72a00SBarry Smith 
384821e72a00SBarry Smith    Output Parameter:
384921e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
385021e72a00SBarry Smith 
385121e72a00SBarry Smith    Level: intermediate
385221e72a00SBarry Smith 
385321e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
385421e72a00SBarry Smith @*/
385521e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
385621e72a00SBarry Smith {
385721e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
385821e72a00SBarry Smith 
385921e72a00SBarry Smith   PetscFunctionBegin;
386021e72a00SBarry Smith   *nz = aij->rmax;
386121e72a00SBarry Smith   PetscFunctionReturn(0);
386221e72a00SBarry Smith }
386321e72a00SBarry Smith 
38648c778c55SBarry Smith /*@C
3865579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38668c778c55SBarry Smith 
38678c778c55SBarry Smith    Not Collective
38688c778c55SBarry Smith 
38698c778c55SBarry Smith    Input Parameters:
3870579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38718c778c55SBarry Smith .  array - pointer to the data
38728c778c55SBarry Smith 
38738c778c55SBarry Smith    Level: intermediate
38748c778c55SBarry Smith 
3875774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
38768c778c55SBarry Smith @*/
38778c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
38788c778c55SBarry Smith {
38798c778c55SBarry Smith   PetscErrorCode ierr;
38808c778c55SBarry Smith 
38818c778c55SBarry Smith   PetscFunctionBegin;
38828c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38838c778c55SBarry Smith   PetscFunctionReturn(0);
38848c778c55SBarry Smith }
38858c778c55SBarry Smith 
38868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3887273d9f13SBarry Smith {
3888273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3889dfbe8321SBarry Smith   PetscErrorCode ierr;
389038baddfdSBarry Smith   PetscMPIInt    size;
3891273d9f13SBarry Smith 
3892273d9f13SBarry Smith   PetscFunctionBegin;
3893ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3894e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3895273d9f13SBarry Smith 
3896b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
38972205254eSKarl Rupp 
3898b0a32e0cSBarry Smith   B->data = (void*)b;
38992205254eSKarl Rupp 
3900549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39012205254eSKarl Rupp 
3902416022c9SBarry Smith   b->row                = 0;
3903416022c9SBarry Smith   b->col                = 0;
390482bf6240SBarry Smith   b->icol               = 0;
3905b810aeb4SBarry Smith   b->reallocs           = 0;
390636db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3907f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3908416022c9SBarry Smith   b->nonew              = 0;
3909416022c9SBarry Smith   b->diag               = 0;
3910416022c9SBarry Smith   b->solve_work         = 0;
39112a1b7f2aSHong Zhang   B->spptr              = 0;
3912be6bf707SBarry Smith   b->saved_values       = 0;
3913d7f994e1SBarry Smith   b->idiag              = 0;
391471f1c65dSBarry Smith   b->mdiag              = 0;
391571f1c65dSBarry Smith   b->ssor_work          = 0;
391671f1c65dSBarry Smith   b->omega              = 1.0;
391771f1c65dSBarry Smith   b->fshift             = 0.0;
391871f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3919bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3920a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
392117ab2063SBarry Smith 
392235d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3923bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3924bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39258c778c55SBarry Smith 
3926b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3927bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3928bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3929b3866ffcSBarry Smith #endif
393017f1a0eaSHong Zhang 
3931bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3932bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3933bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3934bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3935bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3936bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3937bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3938af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3939af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3940af8000cdSHong Zhang #endif
394163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
394263c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39433dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
394463c07aadSStefano Zampini #endif
3945b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3946bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3947bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3948bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3949bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3950bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3951bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3952bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3953bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39544108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
395517667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39563a40ed3dSBarry Smith   PetscFunctionReturn(0);
395717ab2063SBarry Smith }
395817ab2063SBarry Smith 
3959b24902e0SBarry Smith /*
3960b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3961b24902e0SBarry Smith */
3962ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
396317ab2063SBarry Smith {
3964416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39656849ba73SBarry Smith   PetscErrorCode ierr;
3966d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
396717ab2063SBarry Smith 
39683a40ed3dSBarry Smith   PetscFunctionBegin;
3969273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3970273d9f13SBarry Smith 
3971d5f3da31SBarry Smith   C->factortype = A->factortype;
3972416022c9SBarry Smith   c->row        = 0;
3973416022c9SBarry Smith   c->col        = 0;
397482bf6240SBarry Smith   c->icol       = 0;
39756ad4291fSHong Zhang   c->reallocs   = 0;
397617ab2063SBarry Smith 
39776ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
397817ab2063SBarry Smith 
3979aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3980aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3981eec197d1SBarry Smith 
3982dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
39833bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
398417ab2063SBarry Smith   for (i=0; i<m; i++) {
3985416022c9SBarry Smith     c->imax[i] = a->imax[i];
3986416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
398717ab2063SBarry Smith   }
398817ab2063SBarry Smith 
398917ab2063SBarry Smith   /* allocate the matrix space */
3990f77e22a1SHong Zhang   if (mallocmatspace) {
3991dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
39923bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
39932205254eSKarl Rupp 
3994f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
39952205254eSKarl Rupp 
399697f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
399717ab2063SBarry Smith     if (m > 0) {
399897f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3999be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4000bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4001be6bf707SBarry Smith       } else {
4002bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
400317ab2063SBarry Smith       }
400408480c60SBarry Smith     }
4005f77e22a1SHong Zhang   }
400617ab2063SBarry Smith 
40076ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4008416022c9SBarry Smith   c->roworiented       = a->roworiented;
4009416022c9SBarry Smith   c->nonew             = a->nonew;
4010416022c9SBarry Smith   if (a->diag) {
4011854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
40123bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
401317ab2063SBarry Smith     for (i=0; i<m; i++) {
4014416022c9SBarry Smith       c->diag[i] = a->diag[i];
401517ab2063SBarry Smith     }
40163a40ed3dSBarry Smith   } else c->diag = 0;
40172205254eSKarl Rupp 
40186ad4291fSHong Zhang   c->solve_work         = 0;
40196ad4291fSHong Zhang   c->saved_values       = 0;
40206ad4291fSHong Zhang   c->idiag              = 0;
402171f1c65dSBarry Smith   c->ssor_work          = 0;
4022a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4023e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4024e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40256ad4291fSHong Zhang 
4026893ad86cSHong Zhang   c->rmax         = a->rmax;
4027416022c9SBarry Smith   c->nz           = a->nz;
40288ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4029273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4030754ec7b1SSatish Balay 
40316ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40326ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4033cd6b891eSBarry Smith   if (a->compressedrow.use) {
40346ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4035dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40366ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40376ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
403827ea64f8SHong Zhang   } else {
403927ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40400298fd71SBarry Smith     c->compressedrow.i      = NULL;
40410298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40426ad4291fSHong Zhang   }
4043ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4044e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40454846f1f5SKris Buschelman 
40462205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4047140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40483a40ed3dSBarry Smith   PetscFunctionReturn(0);
404917ab2063SBarry Smith }
405017ab2063SBarry Smith 
4051b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4052b24902e0SBarry Smith {
4053b24902e0SBarry Smith   PetscErrorCode ierr;
4054b24902e0SBarry Smith 
4055b24902e0SBarry Smith   PetscFunctionBegin;
4056ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40574b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4058cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
405933d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4060cfd3f464SBarry Smith   }
4061a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4062f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4063b24902e0SBarry Smith   PetscFunctionReturn(0);
4064b24902e0SBarry Smith }
4065b24902e0SBarry Smith 
4066112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4067fbdbba38SShri Abhyankar {
4068fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4069fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4070fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4071fbdbba38SShri Abhyankar   int            fd;
4072fbdbba38SShri Abhyankar   PetscMPIInt    size;
4073fbdbba38SShri Abhyankar   MPI_Comm       comm;
40743059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4075fbdbba38SShri Abhyankar 
4076fbdbba38SShri Abhyankar   PetscFunctionBegin;
4077c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4078c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4079fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4080fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4081fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4082bbead8a2SBarry Smith 
40830298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
40840298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4085bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40863059b6faSBarry Smith   if (bs < 0) bs = 1;
40873059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4088bbead8a2SBarry Smith 
4089fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4090fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4091fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4092fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4093fbdbba38SShri Abhyankar 
4094bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4095fbdbba38SShri Abhyankar 
4096fbdbba38SShri Abhyankar   /* read in row lengths */
4097785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4098fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4099fbdbba38SShri Abhyankar 
4100fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4101fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
410260e0710aSBarry 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);
4103fbdbba38SShri Abhyankar 
4104fbdbba38SShri Abhyankar   /* set global size if not set already*/
4105f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4106fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4107aabbc4fbSShri Abhyankar   } else {
41089d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4109fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41104c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41114c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41124c5b953cSHong Zhang     }
411360e0710aSBarry 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);
4114aabbc4fbSShri Abhyankar   }
4115fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4116fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4117fbdbba38SShri Abhyankar 
4118fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4119fbdbba38SShri Abhyankar 
4120fbdbba38SShri Abhyankar   /* read in nonzero values */
4121fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4122fbdbba38SShri Abhyankar 
4123fbdbba38SShri Abhyankar   /* set matrix "i" values */
4124fbdbba38SShri Abhyankar   a->i[0] = 0;
4125fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4126fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4127fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4128fbdbba38SShri Abhyankar   }
4129fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4130fbdbba38SShri Abhyankar 
4131fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4132fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4133fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4134fbdbba38SShri Abhyankar }
4135fbdbba38SShri Abhyankar 
4136ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41377264ac53SSatish Balay {
41387264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4139dfbe8321SBarry Smith   PetscErrorCode ierr;
4140eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4141eeffb40dSHong Zhang   PetscInt k;
4142eeffb40dSHong Zhang #endif
41437264ac53SSatish Balay 
41443a40ed3dSBarry Smith   PetscFunctionBegin;
4145bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4146d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4147ca44d042SBarry Smith     *flg = PETSC_FALSE;
4148ca44d042SBarry Smith     PetscFunctionReturn(0);
4149bcd2baecSBarry Smith   }
41507264ac53SSatish Balay 
41517264ac53SSatish Balay   /* if the a->i are the same */
4152d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4153abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41547264ac53SSatish Balay 
41557264ac53SSatish Balay   /* if a->j are the same */
415697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4157abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4158bcd2baecSBarry Smith 
4159bcd2baecSBarry Smith   /* if a->a are the same */
4160eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4161eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4162eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4163eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41643a40ed3dSBarry Smith       PetscFunctionReturn(0);
4165eeffb40dSHong Zhang     }
4166eeffb40dSHong Zhang   }
4167eeffb40dSHong Zhang #else
4168eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4169eeffb40dSHong Zhang #endif
4170eeffb40dSHong Zhang   PetscFunctionReturn(0);
41717264ac53SSatish Balay }
417236db0b34SBarry Smith 
417305869f15SSatish Balay /*@
417436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
417536db0b34SBarry Smith               provided by the user.
417636db0b34SBarry Smith 
4177c75a6043SHong Zhang       Collective on MPI_Comm
417836db0b34SBarry Smith 
417936db0b34SBarry Smith    Input Parameters:
418036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
418136db0b34SBarry Smith .   m - number of rows
418236db0b34SBarry Smith .   n - number of columns
418336db0b34SBarry Smith .   i - row indices
418436db0b34SBarry Smith .   j - column indices
418536db0b34SBarry Smith -   a - matrix values
418636db0b34SBarry Smith 
418736db0b34SBarry Smith    Output Parameter:
418836db0b34SBarry Smith .   mat - the matrix
418936db0b34SBarry Smith 
419036db0b34SBarry Smith    Level: intermediate
419136db0b34SBarry Smith 
419236db0b34SBarry Smith    Notes:
41930551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4194292fb18eSBarry Smith     once the matrix is destroyed and not before
419536db0b34SBarry Smith 
419636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
419736db0b34SBarry Smith 
4198bfeeae90SHong Zhang        The i and j indices are 0 based
419936db0b34SBarry Smith 
4200a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4201a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
42028eef79e4SBarry Smith     as shown
4203a4552177SSatish Balay 
42048eef79e4SBarry Smith $        1 0 0
42058eef79e4SBarry Smith $        2 0 3
42068eef79e4SBarry Smith $        4 5 6
42078eef79e4SBarry Smith $
42088eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42098eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
42108eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4211a4552177SSatish Balay 
42129985e31cSBarry Smith 
421369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
421436db0b34SBarry Smith 
421536db0b34SBarry Smith @*/
4216c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
421736db0b34SBarry Smith {
4218dfbe8321SBarry Smith   PetscErrorCode ierr;
4219cbcfb4deSHong Zhang   PetscInt       ii;
422036db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4221cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4222cbcfb4deSHong Zhang   PetscInt jj;
4223cbcfb4deSHong Zhang #endif
422436db0b34SBarry Smith 
422536db0b34SBarry Smith   PetscFunctionBegin;
422641096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4227f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4228f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4229a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4230ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4231ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4232ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4233dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4234ab93d7beSBarry Smith 
423536db0b34SBarry Smith   aij->i            = i;
423636db0b34SBarry Smith   aij->j            = j;
423736db0b34SBarry Smith   aij->a            = a;
423836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
423936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4240e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4241e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
424236db0b34SBarry Smith 
424336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
424436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42452515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
424660e0710aSBarry 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]);
42479985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4248e32f2f54SBarry 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);
4249e32f2f54SBarry 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);
42509985e31cSBarry Smith     }
425136db0b34SBarry Smith #endif
425236db0b34SBarry Smith   }
42532515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
425436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
425560e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
425660e0710aSBarry 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]);
425736db0b34SBarry Smith   }
425836db0b34SBarry Smith #endif
425936db0b34SBarry Smith 
4260b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4261b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
426236db0b34SBarry Smith   PetscFunctionReturn(0);
426336db0b34SBarry Smith }
426480ef6e79SMatthew G Knepley /*@C
4265d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42668a0b0e6bSVictor Minden               provided by the user.
42678a0b0e6bSVictor Minden 
42688a0b0e6bSVictor Minden       Collective on MPI_Comm
42698a0b0e6bSVictor Minden 
42708a0b0e6bSVictor Minden    Input Parameters:
42718a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42728a0b0e6bSVictor Minden .   m   - number of rows
42738a0b0e6bSVictor Minden .   n   - number of columns
42748a0b0e6bSVictor Minden .   i   - row indices
42758a0b0e6bSVictor Minden .   j   - column indices
42761230e6d1SVictor Minden .   a   - matrix values
42771230e6d1SVictor Minden .   nz  - number of nonzeros
42781230e6d1SVictor Minden -   idx - 0 or 1 based
42798a0b0e6bSVictor Minden 
42808a0b0e6bSVictor Minden    Output Parameter:
42818a0b0e6bSVictor Minden .   mat - the matrix
42828a0b0e6bSVictor Minden 
42838a0b0e6bSVictor Minden    Level: intermediate
42848a0b0e6bSVictor Minden 
42858a0b0e6bSVictor Minden    Notes:
42868a0b0e6bSVictor Minden        The i and j indices are 0 based
42878a0b0e6bSVictor Minden 
42888a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
42898a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
42908a0b0e6bSVictor Minden     as shown:
42918a0b0e6bSVictor Minden 
42928a0b0e6bSVictor Minden         1 0 0
42938a0b0e6bSVictor Minden         2 0 3
42948a0b0e6bSVictor Minden         4 5 6
42958a0b0e6bSVictor Minden 
42968a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
42978a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
42988a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
42998a0b0e6bSVictor Minden 
43008a0b0e6bSVictor Minden 
430169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43028a0b0e6bSVictor Minden 
43038a0b0e6bSVictor Minden @*/
4304c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
43058a0b0e6bSVictor Minden {
43068a0b0e6bSVictor Minden   PetscErrorCode ierr;
4307d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43088a0b0e6bSVictor Minden 
43098a0b0e6bSVictor Minden 
43108a0b0e6bSVictor Minden   PetscFunctionBegin;
43111795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
43121230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4313c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
43141230e6d1SVictor Minden   }
43158a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43168a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43178a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43181230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43191230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43201230e6d1SVictor Minden     if (idx) {
43211230e6d1SVictor Minden       row = i[ii] - 1;
43221230e6d1SVictor Minden       col = j[ii] - 1;
43231230e6d1SVictor Minden     } else {
43241230e6d1SVictor Minden       row = i[ii];
43251230e6d1SVictor Minden       col = j[ii];
43268a0b0e6bSVictor Minden     }
43271230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43288a0b0e6bSVictor Minden   }
43298a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43308a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4331d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43328a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43338a0b0e6bSVictor Minden }
433436db0b34SBarry Smith 
4335acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4336acf2f550SJed Brown {
4337acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4338acf2f550SJed Brown   PetscErrorCode ierr;
4339acf2f550SJed Brown 
4340acf2f550SJed Brown   PetscFunctionBegin;
4341acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4342acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43432205254eSKarl Rupp 
4344acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4345acf2f550SJed Brown   PetscFunctionReturn(0);
4346acf2f550SJed Brown }
4347acf2f550SJed Brown 
43489c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43499c8f2541SHong Zhang {
43509c8f2541SHong Zhang   PetscErrorCode ierr;
43518761c3d6SHong Zhang   PetscMPIInt    size;
43529c8f2541SHong Zhang 
43539c8f2541SHong Zhang   PetscFunctionBegin;
43548761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43558761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43568761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43578761c3d6SHong Zhang   } else {
43589c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43598761c3d6SHong Zhang   }
43609c8f2541SHong Zhang   PetscFunctionReturn(0);
43619c8f2541SHong Zhang }
43629c8f2541SHong Zhang 
436381824310SBarry Smith /*
436453dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
436553dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
436653dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
436753dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
436853dd7562SDmitry Karpeev  */
436953dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
437053dd7562SDmitry Karpeev {
437153dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
437253dd7562SDmitry Karpeev   PetscErrorCode ierr;
437353dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
437453dd7562SDmitry Karpeev   PetscBool      seqaij;
437553dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
437653dd7562SDmitry Karpeev   PetscScalar    v;
437753dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
437853dd7562SDmitry Karpeev 
437953dd7562SDmitry Karpeev   PetscFunctionBegin;
438053dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
438153dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
438253dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
438353dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
438453dd7562SDmitry Karpeev   if (rowemb) {
438553dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
438653dd7562SDmitry 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);
438753dd7562SDmitry Karpeev   } else {
43886c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
438953dd7562SDmitry Karpeev   }
439053dd7562SDmitry Karpeev   if (colemb) {
439153dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
439253dd7562SDmitry 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);
439353dd7562SDmitry Karpeev   } else {
439453dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
439553dd7562SDmitry Karpeev   }
439653dd7562SDmitry Karpeev 
439753dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
439853dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
439953dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
440053dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
440153dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
440253dd7562SDmitry Karpeev     }
440353dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
440453dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
440553dd7562SDmitry Karpeev   }
440653dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
440753dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
440853dd7562SDmitry Karpeev   }
440953dd7562SDmitry Karpeev   count = 0;
441053dd7562SDmitry Karpeev   rowindices = NULL;
441153dd7562SDmitry Karpeev   colindices = NULL;
441253dd7562SDmitry Karpeev   if (rowemb) {
441353dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
441453dd7562SDmitry Karpeev   }
441553dd7562SDmitry Karpeev   if (colemb) {
441653dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
441753dd7562SDmitry Karpeev   }
441853dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
441953dd7562SDmitry Karpeev     PetscInt row;
442053dd7562SDmitry Karpeev     row = i;
442153dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
442253dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
442353dd7562SDmitry Karpeev       PetscInt col;
442453dd7562SDmitry Karpeev       col  = Baij->j[count];
442553dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
442653dd7562SDmitry Karpeev       v    = Baij->a[count];
442753dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
442853dd7562SDmitry Karpeev       ++count;
442953dd7562SDmitry Karpeev     }
443053dd7562SDmitry Karpeev   }
443153dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
443253dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
443353dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
443453dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
443553dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
443653dd7562SDmitry Karpeev   PetscFunctionReturn(0);
443753dd7562SDmitry Karpeev }
443853dd7562SDmitry Karpeev 
443953dd7562SDmitry Karpeev 
444053dd7562SDmitry Karpeev /*
444181824310SBarry Smith     Special version for direct calls from Fortran
444281824310SBarry Smith */
4443af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
444481824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
444581824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
444681824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
444781824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
444881824310SBarry Smith #endif
444981824310SBarry Smith 
445081824310SBarry Smith /* Change these macros so can be used in void function */
445181824310SBarry Smith #undef CHKERRQ
4452ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
445381824310SBarry Smith #undef SETERRQ2
4454e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44554994cf47SJed Brown #undef SETERRQ3
44564994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
445781824310SBarry Smith 
44588cc058d9SJed 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)
445981824310SBarry Smith {
446081824310SBarry Smith   Mat            A  = *AA;
446181824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
446281824310SBarry Smith   InsertMode     is = *isis;
446381824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
446481824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
446581824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
446681824310SBarry Smith   PetscErrorCode ierr;
446781824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
446854f21887SBarry Smith   MatScalar      *ap,value,*aa;
4469ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4470ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
447181824310SBarry Smith 
447281824310SBarry Smith   PetscFunctionBegin;
44734994cf47SJed Brown   MatCheckPreallocated(A,1);
447481824310SBarry Smith   imax  = a->imax;
447581824310SBarry Smith   ai    = a->i;
447681824310SBarry Smith   ailen = a->ilen;
447781824310SBarry Smith   aj    = a->j;
447881824310SBarry Smith   aa    = a->a;
447981824310SBarry Smith 
448081824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
448181824310SBarry Smith     row = im[k];
448281824310SBarry Smith     if (row < 0) continue;
448381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4484ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
448581824310SBarry Smith #endif
448681824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
448781824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
448881824310SBarry Smith     low  = 0;
448981824310SBarry Smith     high = nrow;
449081824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
449181824310SBarry Smith       if (in[l] < 0) continue;
449281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4493ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
449481824310SBarry Smith #endif
449581824310SBarry Smith       col = in[l];
44962205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
44972205254eSKarl Rupp       else value = v[k + l*m];
44982205254eSKarl Rupp 
449981824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
450081824310SBarry Smith 
45012205254eSKarl Rupp       if (col <= lastcol) low = 0;
45022205254eSKarl Rupp       else high = nrow;
450381824310SBarry Smith       lastcol = col;
450481824310SBarry Smith       while (high-low > 5) {
450581824310SBarry Smith         t = (low+high)/2;
450681824310SBarry Smith         if (rp[t] > col) high = t;
450781824310SBarry Smith         else             low  = t;
450881824310SBarry Smith       }
450981824310SBarry Smith       for (i=low; i<high; i++) {
451081824310SBarry Smith         if (rp[i] > col) break;
451181824310SBarry Smith         if (rp[i] == col) {
451281824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
451381824310SBarry Smith           else                  ap[i] = value;
451481824310SBarry Smith           goto noinsert;
451581824310SBarry Smith         }
451681824310SBarry Smith       }
451781824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
451881824310SBarry Smith       if (nonew == 1) goto noinsert;
4519ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4520fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
452181824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
452281824310SBarry Smith       /* shift up all the later entries in this row */
452381824310SBarry Smith       for (ii=N; ii>=i; ii--) {
452481824310SBarry Smith         rp[ii+1] = rp[ii];
452581824310SBarry Smith         ap[ii+1] = ap[ii];
452681824310SBarry Smith       }
452781824310SBarry Smith       rp[i] = col;
452881824310SBarry Smith       ap[i] = value;
4529e56f5c9eSBarry Smith       A->nonzerostate++;
453081824310SBarry Smith noinsert:;
453181824310SBarry Smith       low = i + 1;
453281824310SBarry Smith     }
453381824310SBarry Smith     ailen[row] = nrow;
453481824310SBarry Smith   }
453581824310SBarry Smith   PetscFunctionReturnVoid();
453681824310SBarry Smith }
45379f7953f8SBarry Smith 
4538