xref: /petsc/src/mat/impls/aij/seq/aij.c (revision cdc753b64c658d532d7813e942002e67025667a6)
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;
407d8cdefa3SHong Zhang   MatScalar      *ap=NULL,value=0.0,*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 
5617dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer)
5627dc0baabSHong Zhang {
5637dc0baabSHong Zhang   PetscErrorCode ierr;
5647dc0baabSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5657dc0baabSHong Zhang   PetscInt       i,k,m=A->rmap->N;
5667dc0baabSHong Zhang 
5677dc0baabSHong Zhang   PetscFunctionBegin;
5687dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5697dc0baabSHong Zhang   for (i=0; i<m; i++) {
5707dc0baabSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
5717dc0baabSHong Zhang     for (k=a->i[i]; k<a->i[i+1]; k++) {
5727dc0baabSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr);
5737dc0baabSHong Zhang     }
5747dc0baabSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
5757dc0baabSHong Zhang   }
5767dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5777dc0baabSHong Zhang   PetscFunctionReturn(0);
5787dc0baabSHong Zhang }
5797dc0baabSHong Zhang 
58009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
581cd155464SBarry Smith 
582dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
583416022c9SBarry Smith {
584416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
585dfbe8321SBarry Smith   PetscErrorCode    ierr;
58660e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
587e060cb09SBarry Smith   const char        *name;
588f3ef73ceSBarry Smith   PetscViewerFormat format;
58917ab2063SBarry Smith 
5903a40ed3dSBarry Smith   PetscFunctionBegin;
5917dc0baabSHong Zhang   if (A->structure_only) {
5927dc0baabSHong Zhang     ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr);
5937dc0baabSHong Zhang     PetscFunctionReturn(0);
5947dc0baabSHong Zhang   }
59543e49210SHong Zhang 
596b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
59771c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
59897f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
59960e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
600c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
601d00d2cf4SBarry Smith       nofinalvalue = 1;
602d00d2cf4SBarry Smith     }
603d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
604d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
60577431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
606fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
607fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
608fbfe6fa7SJed Brown #else
60977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
610fbfe6fa7SJed Brown #endif
611b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
61217ab2063SBarry Smith 
61317ab2063SBarry Smith     for (i=0; i<m; i++) {
61460e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
615aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
616a9bf72d8SJed 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);
61717ab2063SBarry Smith #else
61860e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
61917ab2063SBarry Smith #endif
62017ab2063SBarry Smith       }
62117ab2063SBarry Smith     }
622d00d2cf4SBarry Smith     if (nofinalvalue) {
623c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
624c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
625c337ccceSJed Brown #else
626d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
627c337ccceSJed Brown #endif
628d00d2cf4SBarry Smith     }
629317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
630fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
631d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
63268369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
633cd155464SBarry Smith     PetscFunctionReturn(0);
634fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
635d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
63644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
63777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
63860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
639aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
64160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
64360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
64560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6466831982aSBarry Smith         }
64744cd7ae7SLois Curfman McInnes #else
64860e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
64944cd7ae7SLois Curfman McInnes #endif
65044cd7ae7SLois Curfman McInnes       }
651b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65244cd7ae7SLois Curfman McInnes     }
653d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
654fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
65597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
656d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
657854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
658496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
659496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
66060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
661496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
662aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
664496be53dSLois Curfman McInnes #else
665496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
666496be53dSLois Curfman McInnes #endif
667496be53dSLois Curfman McInnes         }
668496be53dSLois Curfman McInnes       }
669496be53dSLois Curfman McInnes     }
6702e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
67177431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6722e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6732205254eSKarl Rupp       if (i+4<m) {
6742205254eSKarl 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);
6752205254eSKarl Rupp       } else if (i+3<m) {
6762205254eSKarl 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);
6772205254eSKarl Rupp       } else if (i+2<m) {
6782205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6792205254eSKarl Rupp       } else if (i+1<m) {
6802205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6812205254eSKarl Rupp       } else if (i<m) {
6822205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6832205254eSKarl Rupp       } else {
6842205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6852205254eSKarl Rupp       }
686496be53dSLois Curfman McInnes     }
687b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
688606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
689496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
69060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
69177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
692496be53dSLois Curfman McInnes       }
693b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
694496be53dSLois Curfman McInnes     }
695b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
696496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
69760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
698496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
699aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
70160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7026831982aSBarry Smith           }
703496be53dSLois Curfman McInnes #else
70460e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
705496be53dSLois Curfman McInnes #endif
706496be53dSLois Curfman McInnes         }
707496be53dSLois Curfman McInnes       }
708b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
709496be53dSLois Curfman McInnes     }
710d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
711fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
71297f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
71387828ca2SBarry Smith     PetscScalar value;
71468f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
71568f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
71668f1ed48SBarry Smith 
71768f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
71868f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
71968f1ed48SBarry Smith         realonly = PETSC_FALSE;
72068f1ed48SBarry Smith         break;
72168f1ed48SBarry Smith       }
72268f1ed48SBarry Smith     }
72368f1ed48SBarry Smith #endif
72402594712SBarry Smith 
725d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
72602594712SBarry Smith     for (i=0; i<m; i++) {
72702594712SBarry Smith       jcnt = 0;
728d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
729e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
73002594712SBarry Smith           value = a->a[cnt++];
731e24b481bSBarry Smith           jcnt++;
73202594712SBarry Smith         } else {
73302594712SBarry Smith           value = 0.0;
73402594712SBarry Smith         }
735aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73668f1ed48SBarry Smith         if (realonly) {
73760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
73868f1ed48SBarry Smith         } else {
73960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
74068f1ed48SBarry Smith         }
74102594712SBarry Smith #else
74260e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
74302594712SBarry Smith #endif
74402594712SBarry Smith       }
745b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74602594712SBarry Smith     }
747d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7483c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
749150b93efSMatthew G. Knepley     PetscInt fshift=1;
750d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7513c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
75219303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7533c215bfdSMatthew Knepley #else
75419303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7553c215bfdSMatthew Knepley #endif
756d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7573c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
75860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7593c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
760a9a0e077SKarl 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);
7613c215bfdSMatthew Knepley #else
762150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7633c215bfdSMatthew Knepley #endif
7643c215bfdSMatthew Knepley       }
7653c215bfdSMatthew Knepley     }
766d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7673a40ed3dSBarry Smith   } else {
768d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
769d5f3da31SBarry Smith     if (A->factortype) {
77016cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
77116cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
77216cd7e1dSShri Abhyankar         /* L part */
77360e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
77416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
77516cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
77660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
77716cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7786712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
77916cd7e1dSShri Abhyankar           } else {
78060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
78116cd7e1dSShri Abhyankar           }
78216cd7e1dSShri Abhyankar #else
78360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
78416cd7e1dSShri Abhyankar #endif
78516cd7e1dSShri Abhyankar         }
78616cd7e1dSShri Abhyankar         /* diagonal */
78716cd7e1dSShri Abhyankar         j = a->diag[i];
78816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78916cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
79060e0710aSBarry 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);
79116cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7926712e2f1SBarry 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);
79316cd7e1dSShri Abhyankar         } else {
79460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
79516cd7e1dSShri Abhyankar         }
79616cd7e1dSShri Abhyankar #else
79760e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
79816cd7e1dSShri Abhyankar #endif
79916cd7e1dSShri Abhyankar 
80016cd7e1dSShri Abhyankar         /* U part */
80160e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
80216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
80316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
80460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
80516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
80622ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
80716cd7e1dSShri Abhyankar           } else {
80860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
80916cd7e1dSShri Abhyankar           }
81016cd7e1dSShri Abhyankar #else
81160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
81216cd7e1dSShri Abhyankar #endif
81316cd7e1dSShri Abhyankar         }
81416cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
81516cd7e1dSShri Abhyankar       }
81616cd7e1dSShri Abhyankar     } else {
81717ab2063SBarry Smith       for (i=0; i<m; i++) {
81877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
81960e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
820aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
82136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
82260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
82336db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
82460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8253a40ed3dSBarry Smith           } else {
82660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
82717ab2063SBarry Smith           }
82817ab2063SBarry Smith #else
82960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
83017ab2063SBarry Smith #endif
83117ab2063SBarry Smith         }
832b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
83317ab2063SBarry Smith       }
83416cd7e1dSShri Abhyankar     }
835d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
83617ab2063SBarry Smith   }
837b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8383a40ed3dSBarry Smith   PetscFunctionReturn(0);
839416022c9SBarry Smith }
840416022c9SBarry Smith 
8419804daf3SBarry Smith #include <petscdraw.h>
842dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
843416022c9SBarry Smith {
844480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
845416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
846dfbe8321SBarry Smith   PetscErrorCode    ierr;
847383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
848383922c3SLisandro Dalcin   int               color;
849b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
850b0a32e0cSBarry Smith   PetscViewer       viewer;
851f3ef73ceSBarry Smith   PetscViewerFormat format;
852cddf8d76SBarry Smith 
8533a40ed3dSBarry Smith   PetscFunctionBegin;
854480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
855b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
856b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
857383922c3SLisandro Dalcin 
858416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8590513a670SBarry Smith 
860fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
861383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8620513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
863b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
864416022c9SBarry Smith     for (i=0; i<m; i++) {
865cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
866bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
867bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
86836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
869b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
870cddf8d76SBarry Smith       }
871cddf8d76SBarry Smith     }
872b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
873cddf8d76SBarry Smith     for (i=0; i<m; i++) {
874cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
875bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
876bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
877cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
878b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
879cddf8d76SBarry Smith       }
880cddf8d76SBarry Smith     }
881b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
882cddf8d76SBarry Smith     for (i=0; i<m; i++) {
883cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
884bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
885bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
88636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
887b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
888416022c9SBarry Smith       }
889416022c9SBarry Smith     }
890383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8910513a670SBarry Smith   } else {
8920513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8930513a670SBarry Smith     /* first determine max of all nonzero values */
894b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
895383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
896b0a32e0cSBarry Smith     PetscDraw popup;
8970513a670SBarry Smith 
8980513a670SBarry Smith     for (i=0; i<nz; i++) {
8990513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
9000513a670SBarry Smith     }
901383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
902b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
90345f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
904383922c3SLisandro Dalcin 
905383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
9060513a670SBarry Smith     for (i=0; i<m; i++) {
907383922c3SLisandro Dalcin       y_l = m - i - 1.0;
908383922c3SLisandro Dalcin       y_r = y_l + 1.0;
909bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
910383922c3SLisandro Dalcin         x_l = a->j[j];
911383922c3SLisandro Dalcin         x_r = x_l + 1.0;
912b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
913b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
9140513a670SBarry Smith         count++;
9150513a670SBarry Smith       }
9160513a670SBarry Smith     }
917383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
9180513a670SBarry Smith   }
919480ef9eaSBarry Smith   PetscFunctionReturn(0);
920480ef9eaSBarry Smith }
921cddf8d76SBarry Smith 
9229804daf3SBarry Smith #include <petscdraw.h>
923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
924480ef9eaSBarry Smith {
925dfbe8321SBarry Smith   PetscErrorCode ierr;
926b0a32e0cSBarry Smith   PetscDraw      draw;
92736db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
928ace3abfcSBarry Smith   PetscBool      isnull;
929480ef9eaSBarry Smith 
930480ef9eaSBarry Smith   PetscFunctionBegin;
931b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
932b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
933480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
934480ef9eaSBarry Smith 
935d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
936480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
937b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
938832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
939b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9400298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
941832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9423a40ed3dSBarry Smith   PetscFunctionReturn(0);
943416022c9SBarry Smith }
944416022c9SBarry Smith 
945dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
946416022c9SBarry Smith {
947dfbe8321SBarry Smith   PetscErrorCode ierr;
948ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
949416022c9SBarry Smith 
9503a40ed3dSBarry Smith   PetscFunctionBegin;
951251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
952251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
953251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
954c45a1595SBarry Smith   if (iascii) {
9553a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9560f5bd95cSBarry Smith   } else if (isbinary) {
9573a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9580f5bd95cSBarry Smith   } else if (isdraw) {
9593a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
96011aeaf0aSBarry Smith   }
9614108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9623a40ed3dSBarry Smith   PetscFunctionReturn(0);
96317ab2063SBarry Smith }
96419bcc07fSBarry Smith 
965dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
96617ab2063SBarry Smith {
967416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9686849ba73SBarry Smith   PetscErrorCode ierr;
96997f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
970d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
97154f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9723447b6efSHong Zhang   PetscReal      ratio  = 0.6;
97317ab2063SBarry Smith 
9743a40ed3dSBarry Smith   PetscFunctionBegin;
9753a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
97617ab2063SBarry Smith 
97743ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
97817ab2063SBarry Smith   for (i=1; i<m; i++) {
979416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
98017ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
98194a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
98217ab2063SBarry Smith     if (fshift) {
983bfeeae90SHong Zhang       ip = aj + ai[i];
984bfeeae90SHong Zhang       ap = aa + ai[i];
98517ab2063SBarry Smith       N  = ailen[i];
98617ab2063SBarry Smith       for (j=0; j<N; j++) {
98717ab2063SBarry Smith         ip[j-fshift] = ip[j];
988876c6284SHong Zhang         if (!A->structure_only) ap[j-fshift] = ap[j];
98917ab2063SBarry Smith       }
99017ab2063SBarry Smith     }
99117ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
99217ab2063SBarry Smith   }
99317ab2063SBarry Smith   if (m) {
99417ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
99517ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
99617ab2063SBarry Smith   }
9977b083b7cSBarry Smith 
99817ab2063SBarry Smith   /* reset ilen and imax for each row */
9997b083b7cSBarry Smith   a->nonzerorowcnt = 0;
1000396832f4SHong Zhang   if (A->structure_only) {
1001396832f4SHong Zhang     ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
1002396832f4SHong Zhang   } else { /* !A->structure_only */
100317ab2063SBarry Smith     for (i=0; i<m; i++) {
100417ab2063SBarry Smith       ailen[i] = imax[i] = ai[i+1] - ai[i];
10057b083b7cSBarry Smith       a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
100617ab2063SBarry Smith     }
1007396832f4SHong Zhang   }
1008bfeeae90SHong Zhang   a->nz = ai[m];
100965e19b50SBarry 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);
101017ab2063SBarry Smith 
101109f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1012d0f46423SBarry 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);
1013ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
1014ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
10152205254eSKarl Rupp 
10168e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1017dd5f02e7SSatish Balay   a->reallocs         = 0;
10186712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
101936db0b34SBarry Smith   a->rmax             = rmax;
10204e220ebcSLois Curfman McInnes 
1021396832f4SHong Zhang   if (!A->structure_only) {
102211e456e1SBarry Smith     ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
1023396832f4SHong Zhang   }
10244108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
1025acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10263a40ed3dSBarry Smith   PetscFunctionReturn(0);
102717ab2063SBarry Smith }
102817ab2063SBarry Smith 
102999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
103099cafbc1SBarry Smith {
103199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
103299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
103354f21887SBarry Smith   MatScalar      *aa = a->a;
1034acf2f550SJed Brown   PetscErrorCode ierr;
103599cafbc1SBarry Smith 
103699cafbc1SBarry Smith   PetscFunctionBegin;
103799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1038acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
103999cafbc1SBarry Smith   PetscFunctionReturn(0);
104099cafbc1SBarry Smith }
104199cafbc1SBarry Smith 
104299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
104399cafbc1SBarry Smith {
104499cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
104599cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
104654f21887SBarry Smith   MatScalar      *aa = a->a;
1047acf2f550SJed Brown   PetscErrorCode ierr;
104899cafbc1SBarry Smith 
104999cafbc1SBarry Smith   PetscFunctionBegin;
105099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1051acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
105299cafbc1SBarry Smith   PetscFunctionReturn(0);
105399cafbc1SBarry Smith }
105499cafbc1SBarry Smith 
1055dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
105617ab2063SBarry Smith {
1057416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1058dfbe8321SBarry Smith   PetscErrorCode ierr;
10593a40ed3dSBarry Smith 
10603a40ed3dSBarry Smith   PetscFunctionBegin;
1061d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1062acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10633a40ed3dSBarry Smith   PetscFunctionReturn(0);
106417ab2063SBarry Smith }
1065416022c9SBarry Smith 
1066dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
106717ab2063SBarry Smith {
1068416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1069dfbe8321SBarry Smith   PetscErrorCode ierr;
1070d5d45c9bSBarry Smith 
10713a40ed3dSBarry Smith   PetscFunctionBegin;
1072aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1073d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
107417ab2063SBarry Smith #endif
1075e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10766bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10776bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
107805b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1079d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
108005b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
108171f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
108205b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10836bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
108405b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10856bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1086cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10870b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1088a30b2313SHong Zhang 
10894108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1090bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1091901853e0SKris Buschelman 
1092dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1093bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1094bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1095bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1096bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1097bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1098bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1099af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1100af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1101af8000cdSHong Zhang #endif
110263c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
110363c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
11043dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
110563c07aadSStefano Zampini #endif
1106b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1107bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1108bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1109bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1110bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
11113a40ed3dSBarry Smith   PetscFunctionReturn(0);
111217ab2063SBarry Smith }
111317ab2063SBarry Smith 
1114ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
111517ab2063SBarry Smith {
1116416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11174846f1f5SKris Buschelman   PetscErrorCode ierr;
11183a40ed3dSBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
1120a65d3064SKris Buschelman   switch (op) {
1121a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11224e0d8c25SBarry Smith     a->roworiented = flg;
1123a65d3064SKris Buschelman     break;
1124a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1125a9817697SBarry Smith     a->keepnonzeropattern = flg;
1126a65d3064SKris Buschelman     break;
1127512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1128512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1129a65d3064SKris Buschelman     break;
1130a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11314e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1132a65d3064SKris Buschelman     break;
1133a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11344e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1135a65d3064SKris Buschelman     break;
113628b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
113728b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
113828b2fa4aSMatthew Knepley     break;
1139a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11404e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11410df259c2SBarry Smith     break;
11423d472b54SHong Zhang   case MAT_SPD:
1143b1646e73SJed Brown   case MAT_SYMMETRIC:
1144b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1145b1646e73SJed Brown   case MAT_HERMITIAN:
1146b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1147957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11485021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11495021d80fSJed Brown     break;
11504e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1151a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1152a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1153290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1154a65d3064SKris Buschelman     break;
1155b87ac2d8SJed Brown   case MAT_USE_INODES:
1156b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1157b87ac2d8SJed Brown     break;
1158c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1159c10200c1SHong Zhang     A->submat_singleis = flg;
1160c10200c1SHong Zhang     break;
1161a65d3064SKris Buschelman   default:
1162e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1163a65d3064SKris Buschelman   }
11644108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11653a40ed3dSBarry Smith   PetscFunctionReturn(0);
116617ab2063SBarry Smith }
116717ab2063SBarry Smith 
1168dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
116917ab2063SBarry Smith {
1170416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11716849ba73SBarry Smith   PetscErrorCode ierr;
1172d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
117335e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
117417ab2063SBarry Smith 
11753a40ed3dSBarry Smith   PetscFunctionBegin;
1176d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1177e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
117835e7444dSHong Zhang 
1179d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1180d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
118135e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11822c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
118335e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
118435e7444dSHong Zhang     PetscFunctionReturn(0);
118535e7444dSHong Zhang   }
118635e7444dSHong Zhang 
11872dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11881ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
118935e7444dSHong Zhang   for (i=0; i<n; i++) {
119035e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11912f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
119235e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
119335e7444dSHong Zhang       if (aj[j] == i) {
119435e7444dSHong Zhang         x[i] = aa[j];
119517ab2063SBarry Smith         break;
119617ab2063SBarry Smith       }
119717ab2063SBarry Smith     }
119817ab2063SBarry Smith   }
11991ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
120117ab2063SBarry Smith }
120217ab2063SBarry Smith 
1203c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1204dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
120517ab2063SBarry Smith {
1206416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1207d9ca1df4SBarry Smith   PetscScalar       *y;
1208d9ca1df4SBarry Smith   const PetscScalar *x;
1209dfbe8321SBarry Smith   PetscErrorCode    ierr;
1210d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
12115c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1212d9ca1df4SBarry Smith   const MatScalar   *v;
1213a77337e4SBarry Smith   PetscScalar       alpha;
1214d9ca1df4SBarry Smith   PetscInt          n,i,j;
1215d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
12163447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1217ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
12185c897100SBarry Smith #endif
121917ab2063SBarry Smith 
12203a40ed3dSBarry Smith   PetscFunctionBegin;
12212e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1222d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12245c897100SBarry Smith 
12255c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1226bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12275c897100SBarry Smith #else
12283447b6efSHong Zhang   if (usecprow) {
12293447b6efSHong Zhang     m    = cprow.nrows;
12303447b6efSHong Zhang     ii   = cprow.i;
12317b2bb3b9SHong Zhang     ridx = cprow.rindex;
12323447b6efSHong Zhang   } else {
12333447b6efSHong Zhang     ii = a->i;
12343447b6efSHong Zhang   }
123517ab2063SBarry Smith   for (i=0; i<m; i++) {
12363447b6efSHong Zhang     idx = a->j + ii[i];
12373447b6efSHong Zhang     v   = a->a + ii[i];
12383447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12393447b6efSHong Zhang     if (usecprow) {
12407b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12413447b6efSHong Zhang     } else {
124217ab2063SBarry Smith       alpha = x[i];
12433447b6efSHong Zhang     }
124404fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
124517ab2063SBarry Smith   }
12465c897100SBarry Smith #endif
1247dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1248d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12491ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
125117ab2063SBarry Smith }
125217ab2063SBarry Smith 
1253dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12545c897100SBarry Smith {
1255dfbe8321SBarry Smith   PetscErrorCode ierr;
12565c897100SBarry Smith 
12575c897100SBarry Smith   PetscFunctionBegin;
1258170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12595c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12605c897100SBarry Smith   PetscFunctionReturn(0);
12615c897100SBarry Smith }
12625c897100SBarry Smith 
1263c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
126478b84d54SShri Abhyankar 
1265dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
126617ab2063SBarry Smith {
1267416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1268d9fead3dSBarry Smith   PetscScalar       *y;
126954f21887SBarry Smith   const PetscScalar *x;
127054f21887SBarry Smith   const MatScalar   *aa;
1271dfbe8321SBarry Smith   PetscErrorCode    ierr;
1272003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12730298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12747b083b7cSBarry Smith   PetscInt          n,i;
1275362ced78SSatish Balay   PetscScalar       sum;
1276ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
127717ab2063SBarry Smith 
1278b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
127997952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1280fee21e36SBarry Smith #endif
1281fee21e36SBarry Smith 
12823a40ed3dSBarry Smith   PetscFunctionBegin;
12833649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1285416022c9SBarry Smith   ii   = a->i;
12864eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12874f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
128897952fefSHong Zhang     m    = a->compressedrow.nrows;
128997952fefSHong Zhang     ii   = a->compressedrow.i;
129097952fefSHong Zhang     ridx = a->compressedrow.rindex;
129197952fefSHong Zhang     for (i=0; i<m; i++) {
129297952fefSHong Zhang       n           = ii[i+1] - ii[i];
129397952fefSHong Zhang       aj          = a->j + ii[i];
129497952fefSHong Zhang       aa          = a->a + ii[i];
129597952fefSHong Zhang       sum         = 0.0;
1296003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1297003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
129897952fefSHong Zhang       y[*ridx++] = sum;
129997952fefSHong Zhang     }
130097952fefSHong Zhang   } else { /* do not use compressed row format */
1301b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
13023d3eaba7SBarry Smith     aj   = a->j;
13033d3eaba7SBarry Smith     aa   = a->a;
1304b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1305b05257ddSBarry Smith #else
130617ab2063SBarry Smith     for (i=0; i<m; i++) {
1307003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1308003131ecSBarry Smith       aj          = a->j + ii[i];
1309003131ecSBarry Smith       aa          = a->a + ii[i];
131017ab2063SBarry Smith       sum         = 0.0;
1311003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
131217ab2063SBarry Smith       y[i] = sum;
131317ab2063SBarry Smith     }
13148d195f9aSBarry Smith #endif
1315b05257ddSBarry Smith   }
13167b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13173649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13181ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13193a40ed3dSBarry Smith   PetscFunctionReturn(0);
132017ab2063SBarry Smith }
132117ab2063SBarry Smith 
1322b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1323b434eb95SMatthew G. Knepley {
1324b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1325b434eb95SMatthew G. Knepley   PetscScalar       *y;
1326b434eb95SMatthew G. Knepley   const PetscScalar *x;
1327b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1328b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1329b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1330b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1331b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1332b434eb95SMatthew G. Knepley   PetscScalar       sum;
1333b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1334b434eb95SMatthew G. Knepley 
1335b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1336b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1337b434eb95SMatthew G. Knepley #endif
1338b434eb95SMatthew G. Knepley 
1339b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1340b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1341b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1342b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1343b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1344b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1345b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1346b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1347b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1348b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1349b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1350b434eb95SMatthew G. Knepley       sum         = 0.0;
1351b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1352b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1353b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1354b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1355b434eb95SMatthew G. Knepley     }
1356b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13573d3eaba7SBarry Smith     ii = a->i;
1358b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1359b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1360b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1361b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1362b434eb95SMatthew G. Knepley       sum         = 0.0;
1363b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1364b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1365b434eb95SMatthew G. Knepley       y[i] = sum;
1366b434eb95SMatthew G. Knepley     }
1367b434eb95SMatthew G. Knepley   }
1368b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1369b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1370b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1371b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1372b434eb95SMatthew G. Knepley }
1373b434eb95SMatthew G. Knepley 
1374b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1375b434eb95SMatthew G. Knepley {
1376b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1377b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1378b434eb95SMatthew G. Knepley   const PetscScalar *x;
1379b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1380b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1381b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1382b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1383b434eb95SMatthew G. Knepley   PetscScalar       sum;
1384b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1385b434eb95SMatthew G. Knepley 
1386b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1387b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1388d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1389b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1390b434eb95SMatthew G. Knepley     if (zz != yy) {
1391b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1392b434eb95SMatthew G. Knepley     }
1393b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1394b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1395b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1396b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1397b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1398b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1399b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1400b434eb95SMatthew G. Knepley       sum = y[*ridx];
1401b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1402b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1403b434eb95SMatthew G. Knepley     }
1404b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
14053d3eaba7SBarry Smith     ii = a->i;
1406b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1407b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1408b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1409b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1410b434eb95SMatthew G. Knepley       sum = y[i];
1411b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1412b434eb95SMatthew G. Knepley       z[i] = sum;
1413b434eb95SMatthew G. Knepley     }
1414b434eb95SMatthew G. Knepley   }
1415b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1416b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1417d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1418b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1419b434eb95SMatthew G. Knepley }
1420b434eb95SMatthew G. Knepley 
1421c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1422dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
142317ab2063SBarry Smith {
1424416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1425f15663dcSBarry Smith   PetscScalar       *y,*z;
1426f15663dcSBarry Smith   const PetscScalar *x;
142754f21887SBarry Smith   const MatScalar   *aa;
1428dfbe8321SBarry Smith   PetscErrorCode    ierr;
1429d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1430d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1431362ced78SSatish Balay   PetscScalar       sum;
1432ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14339ea0dfa2SSatish Balay 
14343a40ed3dSBarry Smith   PetscFunctionBegin;
1435f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1436d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14374eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
14384eb6d288SHong Zhang     if (zz != yy) {
14394eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14404eb6d288SHong Zhang     }
144197952fefSHong Zhang     m    = a->compressedrow.nrows;
144297952fefSHong Zhang     ii   = a->compressedrow.i;
144397952fefSHong Zhang     ridx = a->compressedrow.rindex;
144497952fefSHong Zhang     for (i=0; i<m; i++) {
144597952fefSHong Zhang       n   = ii[i+1] - ii[i];
144697952fefSHong Zhang       aj  = a->j + ii[i];
144797952fefSHong Zhang       aa  = a->a + ii[i];
144897952fefSHong Zhang       sum = y[*ridx];
1449f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
145097952fefSHong Zhang       z[*ridx++] = sum;
145197952fefSHong Zhang     }
145297952fefSHong Zhang   } else { /* do not use compressed row format */
14533d3eaba7SBarry Smith     ii = a->i;
1454f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14553d3eaba7SBarry Smith     aj = a->j;
14563d3eaba7SBarry Smith     aa = a->a;
1457f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1458f15663dcSBarry Smith #else
145917ab2063SBarry Smith     for (i=0; i<m; i++) {
1460f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1461f15663dcSBarry Smith       aj  = a->j + ii[i];
1462f15663dcSBarry Smith       aa  = a->a + ii[i];
146317ab2063SBarry Smith       sum = y[i];
1464f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
146517ab2063SBarry Smith       z[i] = sum;
146617ab2063SBarry Smith     }
146702ab625aSSatish Balay #endif
1468f15663dcSBarry Smith   }
1469dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1470f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1471d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14728154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14736b375ea7SVictor Minden   /*
1474918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1475918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1476918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14776b375ea7SVictor Minden   */
1478918e98c3SVictor Minden #endif
14793a40ed3dSBarry Smith   PetscFunctionReturn(0);
148017ab2063SBarry Smith }
148117ab2063SBarry Smith 
148217ab2063SBarry Smith /*
148317ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
148417ab2063SBarry Smith */
1485dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
148617ab2063SBarry Smith {
1487416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14886849ba73SBarry Smith   PetscErrorCode ierr;
1489d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
149017ab2063SBarry Smith 
14913a40ed3dSBarry Smith   PetscFunctionBegin;
149209f38230SBarry Smith   if (!a->diag) {
1493785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14943bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
149509f38230SBarry Smith   }
1496d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
149709f38230SBarry Smith     a->diag[i] = a->i[i+1];
1498bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1499bfeeae90SHong Zhang       if (a->j[j] == i) {
150009f38230SBarry Smith         a->diag[i] = j;
150117ab2063SBarry Smith         break;
150217ab2063SBarry Smith       }
150317ab2063SBarry Smith     }
150417ab2063SBarry Smith   }
15053a40ed3dSBarry Smith   PetscFunctionReturn(0);
150617ab2063SBarry Smith }
150717ab2063SBarry Smith 
1508be5855fcSBarry Smith /*
1509be5855fcSBarry Smith      Checks for missing diagonals
1510be5855fcSBarry Smith */
1511ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1512be5855fcSBarry Smith {
1513be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
15147734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1515be5855fcSBarry Smith 
1516be5855fcSBarry Smith   PetscFunctionBegin;
151709f38230SBarry Smith   *missing = PETSC_FALSE;
15187734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
151909f38230SBarry Smith     *missing = PETSC_TRUE;
152009f38230SBarry Smith     if (d) *d = 0;
1521955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
152209f38230SBarry Smith   } else {
1523f1e2ffcdSBarry Smith     diag = a->diag;
1524d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
15257734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
152609f38230SBarry Smith         *missing = PETSC_TRUE;
152709f38230SBarry Smith         if (d) *d = i;
1528955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1529358d2f5dSShri Abhyankar         break;
153009f38230SBarry Smith       }
1531be5855fcSBarry Smith     }
1532be5855fcSBarry Smith   }
1533be5855fcSBarry Smith   PetscFunctionReturn(0);
1534be5855fcSBarry Smith }
1535be5855fcSBarry Smith 
1536422a814eSBarry Smith /*
1537422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1538422a814eSBarry Smith */
15397087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
154071f1c65dSBarry Smith {
154171f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
154271f1c65dSBarry Smith   PetscErrorCode ierr;
1543d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
154454f21887SBarry Smith   MatScalar      *v = a->a;
154554f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
154671f1c65dSBarry Smith 
154771f1c65dSBarry Smith   PetscFunctionBegin;
154871f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
154971f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
155071f1c65dSBarry Smith   diag = a->diag;
155171f1c65dSBarry Smith   if (!a->idiag) {
1552dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15533bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
155471f1c65dSBarry Smith     v    = a->a;
155571f1c65dSBarry Smith   }
155671f1c65dSBarry Smith   mdiag = a->mdiag;
155771f1c65dSBarry Smith   idiag = a->idiag;
155871f1c65dSBarry Smith 
1559422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
156071f1c65dSBarry Smith     for (i=0; i<m; i++) {
156171f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1562899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1563899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1564899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15657b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15667b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15677b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15687b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1569899639b0SHong Zhang       }
157071f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
157171f1c65dSBarry Smith     }
157271f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
157371f1c65dSBarry Smith   } else {
157471f1c65dSBarry Smith     for (i=0; i<m; i++) {
157571f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
157671f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
157771f1c65dSBarry Smith     }
1578dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
157971f1c65dSBarry Smith   }
158071f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
158171f1c65dSBarry Smith   PetscFunctionReturn(0);
158271f1c65dSBarry Smith }
158371f1c65dSBarry Smith 
1584c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
158541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
158617ab2063SBarry Smith {
1587416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1588e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15893d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
159054f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1591dfbe8321SBarry Smith   PetscErrorCode    ierr;
15923d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
159397f1f81fSBarry Smith   const PetscInt    *idx,*diag;
159417ab2063SBarry Smith 
15953a40ed3dSBarry Smith   PetscFunctionBegin;
1596b965ef7fSBarry Smith   its = its*lits;
159791723122SBarry Smith 
159871f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
159971f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
160071f1c65dSBarry Smith   a->fshift = fshift;
160171f1c65dSBarry Smith   a->omega  = omega;
1602ed480e8bSBarry Smith 
160371f1c65dSBarry Smith   diag  = a->diag;
160471f1c65dSBarry Smith   t     = a->ssor_work;
1605ed480e8bSBarry Smith   idiag = a->idiag;
160671f1c65dSBarry Smith   mdiag = a->mdiag;
1607ed480e8bSBarry Smith 
16081ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16093649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1610ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
161117ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
161217ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1613ed480e8bSBarry Smith     bs = b;
161417ab2063SBarry Smith     for (i=0; i<m; i++) {
161571f1c65dSBarry Smith       d   = fshift + mdiag[i];
1616416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1617ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1618ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
161917ab2063SBarry Smith       sum = b[i]*d/omega;
1620003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
162117ab2063SBarry Smith       x[i] = sum;
162217ab2063SBarry Smith     }
16231ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16243649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1625efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16263a40ed3dSBarry Smith     PetscFunctionReturn(0);
162717ab2063SBarry Smith   }
1628c783ea89SBarry Smith 
16292205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16302205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
163117ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1632887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
163317ab2063SBarry Smith 
163417ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
163517ab2063SBarry Smith 
1636887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
163717ab2063SBarry Smith     */
163817ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
163917ab2063SBarry Smith 
164017ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
164117ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1642416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1643ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1644ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
164517ab2063SBarry Smith       sum = b[i];
1646e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1647ed480e8bSBarry Smith       x[i] = sum*idiag[i];
164817ab2063SBarry Smith     }
164917ab2063SBarry Smith 
165017ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1651416022c9SBarry Smith     v = a->a;
16522205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
165317ab2063SBarry Smith 
165417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1655ed480e8bSBarry Smith     ts   = t;
1656416022c9SBarry Smith     diag = a->diag;
165717ab2063SBarry Smith     for (i=0; i<m; i++) {
1658416022c9SBarry Smith       n   = diag[i] - a->i[i];
1659ed480e8bSBarry Smith       idx = a->j + a->i[i];
1660ed480e8bSBarry Smith       v   = a->a + a->i[i];
166117ab2063SBarry Smith       sum = t[i];
1662003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1663ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1664733d66baSBarry Smith       /*  x = x + t */
1665733d66baSBarry Smith       x[i] += t[i];
166617ab2063SBarry Smith     }
166717ab2063SBarry Smith 
1668dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16691ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16703649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16713a40ed3dSBarry Smith     PetscFunctionReturn(0);
167217ab2063SBarry Smith   }
167317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
167417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
167517ab2063SBarry Smith       for (i=0; i<m; i++) {
1676416022c9SBarry Smith         n   = diag[i] - a->i[i];
1677ed480e8bSBarry Smith         idx = a->j + a->i[i];
1678ed480e8bSBarry Smith         v   = a->a + a->i[i];
167917ab2063SBarry Smith         sum = b[i];
1680e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16815c99c7daSBarry Smith         t[i] = sum;
1682ed480e8bSBarry Smith         x[i] = sum*idiag[i];
168317ab2063SBarry Smith       }
16845c99c7daSBarry Smith       xb   = t;
1685efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16863a40ed3dSBarry Smith     } else xb = b;
168717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
168817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1689416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1690ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1691ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
169217ab2063SBarry Smith         sum = xb[i];
1693e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16945c99c7daSBarry Smith         if (xb == b) {
1695ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16965c99c7daSBarry Smith         } else {
1697b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
169817ab2063SBarry Smith         }
16995c99c7daSBarry Smith       }
1700b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
170117ab2063SBarry Smith     }
170217ab2063SBarry Smith     its--;
170317ab2063SBarry Smith   }
170417ab2063SBarry Smith   while (its--) {
170517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
170617ab2063SBarry Smith       for (i=0; i<m; i++) {
1707b19a5dc2SMark Adams         /* lower */
1708b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1709ed480e8bSBarry Smith         idx = a->j + a->i[i];
1710ed480e8bSBarry Smith         v   = a->a + a->i[i];
171117ab2063SBarry Smith         sum = b[i];
1712e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1713b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1714b19a5dc2SMark Adams         /* upper */
1715b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1716b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1717b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1718b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1719b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
172017ab2063SBarry Smith       }
1721b19a5dc2SMark Adams       xb   = t;
17229f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1723b19a5dc2SMark Adams     } else xb = b;
172417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
172517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1726b19a5dc2SMark Adams         sum = xb[i];
1727b19a5dc2SMark Adams         if (xb == b) {
1728b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1729416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1730ed480e8bSBarry Smith           idx = a->j + a->i[i];
1731ed480e8bSBarry Smith           v   = a->a + a->i[i];
1732e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1733ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1734b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1735b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1736b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1737b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1738b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1739b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
174017ab2063SBarry Smith         }
1741b19a5dc2SMark Adams       }
1742b19a5dc2SMark Adams       if (xb == b) {
17439f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1744b19a5dc2SMark Adams       } else {
1745b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1746b19a5dc2SMark Adams       }
174717ab2063SBarry Smith     }
174817ab2063SBarry Smith   }
17491ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17503649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1751365a8a9eSBarry Smith   PetscFunctionReturn(0);
175217ab2063SBarry Smith }
175317ab2063SBarry Smith 
17542af78befSBarry Smith 
1755dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
175617ab2063SBarry Smith {
1757416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17584e220ebcSLois Curfman McInnes 
17593a40ed3dSBarry Smith   PetscFunctionBegin;
17604e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17614e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17624e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17634e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17644e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17658e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17667adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1767d5f3da31SBarry Smith   if (A->factortype) {
17684e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17694e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17704e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17714e220ebcSLois Curfman McInnes   } else {
17724e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17734e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17744e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17754e220ebcSLois Curfman McInnes   }
17763a40ed3dSBarry Smith   PetscFunctionReturn(0);
177717ab2063SBarry Smith }
177817ab2063SBarry Smith 
17792b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
178017ab2063SBarry Smith {
1781416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1782c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17836849ba73SBarry Smith   PetscErrorCode    ierr;
178497b48c8fSBarry Smith   const PetscScalar *xx;
178597b48c8fSBarry Smith   PetscScalar       *bb;
1786c7da8527SEric Chamberland   PetscInt          d = 0;
178717ab2063SBarry Smith 
17883a40ed3dSBarry Smith   PetscFunctionBegin;
178997b48c8fSBarry Smith   if (x && b) {
179097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
179197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
179297b48c8fSBarry Smith     for (i=0; i<N; i++) {
179397b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
179497b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
179597b48c8fSBarry Smith     }
179697b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
179797b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
179897b48c8fSBarry Smith   }
179997b48c8fSBarry Smith 
1800a9817697SBarry Smith   if (a->keepnonzeropattern) {
1801f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1802e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1803bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1804f1e2ffcdSBarry Smith     }
1805f4df32b1SMatthew Knepley     if (diag != 0.0) {
1806c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1807c7da8527SEric Chamberland         d = rows[i];
1808c7da8527SEric 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);
1809c7da8527SEric Chamberland       }
1810f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1811f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1812f1e2ffcdSBarry Smith       }
1813f1e2ffcdSBarry Smith     }
1814f1e2ffcdSBarry Smith   } else {
1815f4df32b1SMatthew Knepley     if (diag != 0.0) {
181617ab2063SBarry Smith       for (i=0; i<N; i++) {
1817e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18187ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1819416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1820f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1821bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18227ae801bdSBarry Smith         } else { /* in case row was completely empty */
1823f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
182417ab2063SBarry Smith         }
182517ab2063SBarry Smith       }
18263a40ed3dSBarry Smith     } else {
182717ab2063SBarry Smith       for (i=0; i<N; i++) {
1828e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1829416022c9SBarry Smith         a->ilen[rows[i]] = 0;
183017ab2063SBarry Smith       }
183117ab2063SBarry Smith     }
1832e56f5c9eSBarry Smith     A->nonzerostate++;
1833f1e2ffcdSBarry Smith   }
183443a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18353a40ed3dSBarry Smith   PetscFunctionReturn(0);
183617ab2063SBarry Smith }
183717ab2063SBarry Smith 
18386e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18396e169961SBarry Smith {
18406e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18416e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18426e169961SBarry Smith   PetscErrorCode    ierr;
18432b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18446e169961SBarry Smith   const PetscScalar *xx;
18456e169961SBarry Smith   PetscScalar       *bb;
18466e169961SBarry Smith 
18476e169961SBarry Smith   PetscFunctionBegin;
18486e169961SBarry Smith   if (x && b) {
18496e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18506e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18512b40b63fSBarry Smith     vecs = PETSC_TRUE;
18526e169961SBarry Smith   }
18531795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18546e169961SBarry Smith   for (i=0; i<N; i++) {
18556e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18566e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18572205254eSKarl Rupp 
18586e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18596e169961SBarry Smith   }
18606e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18616e169961SBarry Smith     if (!zeroed[i]) {
18626e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18636e169961SBarry Smith         if (zeroed[a->j[j]]) {
18642b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18656e169961SBarry Smith           a->a[j] = 0.0;
18666e169961SBarry Smith         }
18676e169961SBarry Smith       }
18682b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18696e169961SBarry Smith   }
18706e169961SBarry Smith   if (x && b) {
18716e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18726e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18736e169961SBarry Smith   }
18746e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18756e169961SBarry Smith   if (diag != 0.0) {
18766e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18771d5a398dSstefano_zampini     if (missing) {
18781d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18791d5a398dSstefano_zampini       else {
18801d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18811d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18821d5a398dSstefano_zampini         }
18831d5a398dSstefano_zampini       }
18841d5a398dSstefano_zampini     } else {
18856e169961SBarry Smith       for (i=0; i<N; i++) {
18866e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18876e169961SBarry Smith       }
18886e169961SBarry Smith     }
18891d5a398dSstefano_zampini   }
18906e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18916e169961SBarry Smith   PetscFunctionReturn(0);
18926e169961SBarry Smith }
18936e169961SBarry Smith 
1894a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
189517ab2063SBarry Smith {
1896416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
189797f1f81fSBarry Smith   PetscInt   *itmp;
189817ab2063SBarry Smith 
18993a40ed3dSBarry Smith   PetscFunctionBegin;
1900e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
190117ab2063SBarry Smith 
1902416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1903bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
190417ab2063SBarry Smith   if (idx) {
1905bfeeae90SHong Zhang     itmp = a->j + a->i[row];
190626fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
190717ab2063SBarry Smith     else *idx = 0;
190817ab2063SBarry Smith   }
19093a40ed3dSBarry Smith   PetscFunctionReturn(0);
191017ab2063SBarry Smith }
191117ab2063SBarry Smith 
1912bfeeae90SHong Zhang /* remove this function? */
1913a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
191417ab2063SBarry Smith {
19153a40ed3dSBarry Smith   PetscFunctionBegin;
19163a40ed3dSBarry Smith   PetscFunctionReturn(0);
191717ab2063SBarry Smith }
191817ab2063SBarry Smith 
1919dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
192017ab2063SBarry Smith {
1921416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
192254f21887SBarry Smith   MatScalar      *v  = a->a;
192336db0b34SBarry Smith   PetscReal      sum = 0.0;
19246849ba73SBarry Smith   PetscErrorCode ierr;
192597f1f81fSBarry Smith   PetscInt       i,j;
192617ab2063SBarry Smith 
19273a40ed3dSBarry Smith   PetscFunctionBegin;
192817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1929570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1930570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1931570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1932570b7f6dSBarry Smith #else
1933416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
193436db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
193517ab2063SBarry Smith     }
19368f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1937570b7f6dSBarry Smith #endif
193851f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19393a40ed3dSBarry Smith   } else if (type == NORM_1) {
194036db0b34SBarry Smith     PetscReal *tmp;
194197f1f81fSBarry Smith     PetscInt  *jj = a->j;
19421795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1943064f8208SBarry Smith     *nrm = 0.0;
1944416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1945bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
194617ab2063SBarry Smith     }
1947d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1948064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
194917ab2063SBarry Smith     }
1950606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
195151f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19523a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1953064f8208SBarry Smith     *nrm = 0.0;
1954d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1955bfeeae90SHong Zhang       v   = a->a + a->i[j];
195617ab2063SBarry Smith       sum = 0.0;
1957416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1958cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
195917ab2063SBarry Smith       }
1960064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
196117ab2063SBarry Smith     }
196251f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1963f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19643a40ed3dSBarry Smith   PetscFunctionReturn(0);
196517ab2063SBarry Smith }
196617ab2063SBarry Smith 
19674e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19684e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19694e938277SHong Zhang {
19704e938277SHong Zhang   PetscErrorCode ierr;
19714e938277SHong Zhang   PetscInt       i,j,anzj;
19724e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19734e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19744e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19754e938277SHong Zhang 
19764e938277SHong Zhang   PetscFunctionBegin;
19774e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1978854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1979785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1980785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19814e938277SHong Zhang 
19824e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19834e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
198426fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19854e938277SHong Zhang   /* Form ati for csr format of A^T. */
198626fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19874e938277SHong Zhang 
19884e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19894e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19904e938277SHong Zhang 
19914e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19924e938277SHong Zhang   for (i=0;i<am;i++) {
19934e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19944e938277SHong Zhang     for (j=0;j<anzj;j++) {
19954e938277SHong Zhang       atj[atfill[*aj]] = i;
19964e938277SHong Zhang       atfill[*aj++]   += 1;
19974e938277SHong Zhang     }
19984e938277SHong Zhang   }
19994e938277SHong Zhang 
20004e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20014e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2002ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
200333d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
2004a2f3521dSMark F. Adams 
20054e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20064e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20074e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20084e938277SHong Zhang   b->nonew   = 0;
20094e938277SHong Zhang   PetscFunctionReturn(0);
20104e938277SHong Zhang }
20114e938277SHong Zhang 
2012fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
201317ab2063SBarry Smith {
2014416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2015416022c9SBarry Smith   Mat            C;
20166849ba73SBarry Smith   PetscErrorCode ierr;
2017d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
201854f21887SBarry Smith   MatScalar      *array = a->a;
201917ab2063SBarry Smith 
20203a40ed3dSBarry Smith   PetscFunctionBegin;
2021cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2022fc4dec0aSBarry Smith 
2023cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
2024854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
2025bfeeae90SHong Zhang 
2026bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2027ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2028d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
202933d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
20307adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2031ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2032606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2033a541d17aSBarry Smith   } else {
2034a541d17aSBarry Smith     C = *B;
2035a541d17aSBarry Smith   }
2036a541d17aSBarry Smith 
203717ab2063SBarry Smith   for (i=0; i<m; i++) {
203817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
203987d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2040b9b97703SBarry Smith     array += len;
2041b9b97703SBarry Smith     aj    += len;
204217ab2063SBarry Smith   }
20436d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20446d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
204517ab2063SBarry Smith 
2046cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2047416022c9SBarry Smith     *B = C;
204817ab2063SBarry Smith   } else {
204928be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
205017ab2063SBarry Smith   }
20513a40ed3dSBarry Smith   PetscFunctionReturn(0);
205217ab2063SBarry Smith }
205317ab2063SBarry Smith 
20547087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2055cd0d46ebSvictorle {
20563d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
205754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
205854f21887SBarry Smith   MatScalar      *va,*vb;
20596849ba73SBarry Smith   PetscErrorCode ierr;
206097f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2061cd0d46ebSvictorle 
2062cd0d46ebSvictorle   PetscFunctionBegin;
2063cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2064cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20655485867bSBarry Smith   if (ma!=nb || na!=mb) {
20665485867bSBarry Smith     *f = PETSC_FALSE;
20675485867bSBarry Smith     PetscFunctionReturn(0);
20685485867bSBarry Smith   }
2069cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2070cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2071cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2072785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2073785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2074cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2075cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2076cd0d46ebSvictorle 
2077cd0d46ebSvictorle   *f = PETSC_TRUE;
2078cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2079cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
208097f1f81fSBarry Smith       PetscInt    idc,idr;
20815485867bSBarry Smith       PetscScalar vc,vr;
2082cd0d46ebSvictorle       /* column/row index/value */
20835485867bSBarry Smith       idc = adx[aptr[i]];
20845485867bSBarry Smith       idr = bdx[bptr[idc]];
20855485867bSBarry Smith       vc  = va[aptr[i]];
20865485867bSBarry Smith       vr  = vb[bptr[idc]];
20875485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20885485867bSBarry Smith         *f = PETSC_FALSE;
20895485867bSBarry Smith         goto done;
2090cd0d46ebSvictorle       } else {
20915485867bSBarry Smith         aptr[i]++;
20925485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2093cd0d46ebSvictorle       }
2094cd0d46ebSvictorle     }
2095cd0d46ebSvictorle   }
2096cd0d46ebSvictorle done:
2097cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20983aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2099cd0d46ebSvictorle   PetscFunctionReturn(0);
2100cd0d46ebSvictorle }
2101cd0d46ebSvictorle 
21027087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21031cbb95d3SBarry Smith {
21043d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
210554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
210654f21887SBarry Smith   MatScalar      *va,*vb;
21071cbb95d3SBarry Smith   PetscErrorCode ierr;
21081cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21091cbb95d3SBarry Smith 
21101cbb95d3SBarry Smith   PetscFunctionBegin;
21111cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21121cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21131cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21141cbb95d3SBarry Smith     *f = PETSC_FALSE;
21151cbb95d3SBarry Smith     PetscFunctionReturn(0);
21161cbb95d3SBarry Smith   }
21171cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
21181cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
21191cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2120785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2121785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
21221cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
21231cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
21241cbb95d3SBarry Smith 
21251cbb95d3SBarry Smith   *f = PETSC_TRUE;
21261cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
21271cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21281cbb95d3SBarry Smith       PetscInt    idc,idr;
21291cbb95d3SBarry Smith       PetscScalar vc,vr;
21301cbb95d3SBarry Smith       /* column/row index/value */
21311cbb95d3SBarry Smith       idc = adx[aptr[i]];
21321cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
21331cbb95d3SBarry Smith       vc  = va[aptr[i]];
21341cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
21351cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
21361cbb95d3SBarry Smith         *f = PETSC_FALSE;
21371cbb95d3SBarry Smith         goto done;
21381cbb95d3SBarry Smith       } else {
21391cbb95d3SBarry Smith         aptr[i]++;
21401cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21411cbb95d3SBarry Smith       }
21421cbb95d3SBarry Smith     }
21431cbb95d3SBarry Smith   }
21441cbb95d3SBarry Smith done:
21451cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21461cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21471cbb95d3SBarry Smith   PetscFunctionReturn(0);
21481cbb95d3SBarry Smith }
21491cbb95d3SBarry Smith 
2150ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21519e29f15eSvictorle {
2152dfbe8321SBarry Smith   PetscErrorCode ierr;
21536e111a19SKarl Rupp 
21549e29f15eSvictorle   PetscFunctionBegin;
21555485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21569e29f15eSvictorle   PetscFunctionReturn(0);
21579e29f15eSvictorle }
21589e29f15eSvictorle 
2159ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21601cbb95d3SBarry Smith {
21611cbb95d3SBarry Smith   PetscErrorCode ierr;
21626e111a19SKarl Rupp 
21631cbb95d3SBarry Smith   PetscFunctionBegin;
21641cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21651cbb95d3SBarry Smith   PetscFunctionReturn(0);
21661cbb95d3SBarry Smith }
21671cbb95d3SBarry Smith 
2168dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
216917ab2063SBarry Smith {
2170416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
217154f21887SBarry Smith   PetscScalar    *l,*r,x;
217254f21887SBarry Smith   MatScalar      *v;
2173dfbe8321SBarry Smith   PetscErrorCode ierr;
2174d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
217517ab2063SBarry Smith 
21763a40ed3dSBarry Smith   PetscFunctionBegin;
217717ab2063SBarry Smith   if (ll) {
21783ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21793ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2180e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2181e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21821ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2183416022c9SBarry Smith     v    = a->a;
218417ab2063SBarry Smith     for (i=0; i<m; i++) {
218517ab2063SBarry Smith       x = l[i];
2186416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21872205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
218817ab2063SBarry Smith     }
21891ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2190efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
219117ab2063SBarry Smith   }
219217ab2063SBarry Smith   if (rr) {
2193e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2194e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21951ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2196416022c9SBarry Smith     v    = a->a; jj = a->j;
21972205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21981ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2199efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
220017ab2063SBarry Smith   }
2201acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22023a40ed3dSBarry Smith   PetscFunctionReturn(0);
220317ab2063SBarry Smith }
220417ab2063SBarry Smith 
22057dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
220617ab2063SBarry Smith {
2207db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
22086849ba73SBarry Smith   PetscErrorCode ierr;
2209d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
221097f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
22115d0c19d7SBarry Smith   const PetscInt *irow,*icol;
22125d0c19d7SBarry Smith   PetscInt       nrows,ncols;
221397f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
221454f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2215416022c9SBarry Smith   Mat            C;
2216cdc6f3adSToby Isaac   PetscBool      stride;
221717ab2063SBarry Smith 
22183a40ed3dSBarry Smith   PetscFunctionBegin;
221999141d43SSatish Balay 
222017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2221b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2222b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
222317ab2063SBarry Smith 
2224251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2225ff718158SBarry Smith   if (stride) {
2226ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2227ff718158SBarry Smith   } else {
2228ff718158SBarry Smith     first = 0;
2229ff718158SBarry Smith     step  = 0;
2230ff718158SBarry Smith   }
2231fee21e36SBarry Smith   if (stride && step == 1) {
223202834360SBarry Smith     /* special case of contiguous rows */
2233dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
223402834360SBarry Smith     /* loop over new rows determining lens and starting points */
223502834360SBarry Smith     for (i=0; i<nrows; i++) {
2236bfeeae90SHong Zhang       kstart = ai[irow[i]];
2237a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2238a91a9bebSLisandro Dalcin       starts[i] = kstart;
223902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2240bfeeae90SHong Zhang         if (aj[k] >= first) {
224102834360SBarry Smith           starts[i] = k;
224202834360SBarry Smith           break;
224302834360SBarry Smith         }
224402834360SBarry Smith       }
2245a2744918SBarry Smith       sum = 0;
224602834360SBarry Smith       while (k < kend) {
2247bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2248a2744918SBarry Smith         sum++;
224902834360SBarry Smith       }
2250a2744918SBarry Smith       lens[i] = sum;
225102834360SBarry Smith     }
225202834360SBarry Smith     /* create submatrix */
2253cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
225497f1f81fSBarry Smith       PetscInt n_cols,n_rows;
225508480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2256e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2257d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
225808480c60SBarry Smith       C    = *B;
22593a40ed3dSBarry Smith     } else {
22603bef6203SJed Brown       PetscInt rbs,cbs;
2261ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2262f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22633bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22643bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22653bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22667adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2267ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
226808480c60SBarry Smith     }
2269db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2270db02288aSLois Curfman McInnes 
227102834360SBarry Smith     /* loop over rows inserting into submatrix */
2272db02288aSLois Curfman McInnes     a_new = c->a;
2273db02288aSLois Curfman McInnes     j_new = c->j;
2274db02288aSLois Curfman McInnes     i_new = c->i;
2275bfeeae90SHong Zhang 
227602834360SBarry Smith     for (i=0; i<nrows; i++) {
2277a2744918SBarry Smith       ii    = starts[i];
2278a2744918SBarry Smith       lensi = lens[i];
2279a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2280a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
228102834360SBarry Smith       }
228287828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2283a2744918SBarry Smith       a_new     += lensi;
2284a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2285a2744918SBarry Smith       c->ilen[i] = lensi;
228602834360SBarry Smith     }
22870e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22883a40ed3dSBarry Smith   } else {
228902834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22901795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2291854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22924dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22934dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22944dcab191SBarry 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);
22954dcab191SBarry Smith #endif
22964dcab191SBarry Smith       smap[icol[i]] = i+1;
22974dcab191SBarry Smith     }
22984dcab191SBarry Smith 
229902834360SBarry Smith     /* determine lens of each row */
230002834360SBarry Smith     for (i=0; i<nrows; i++) {
2301bfeeae90SHong Zhang       kstart  = ai[irow[i]];
230202834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
230302834360SBarry Smith       lens[i] = 0;
230402834360SBarry Smith       for (k=kstart; k<kend; k++) {
2305bfeeae90SHong Zhang         if (smap[aj[k]]) {
230602834360SBarry Smith           lens[i]++;
230702834360SBarry Smith         }
230802834360SBarry Smith       }
230902834360SBarry Smith     }
231017ab2063SBarry Smith     /* Create and fill new matrix */
2311a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2312ace3abfcSBarry Smith       PetscBool equal;
23130f5bd95cSBarry Smith 
231499141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2315e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2316d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2317f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2318d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
231908480c60SBarry Smith       C    = *B;
23203a40ed3dSBarry Smith     } else {
23213bef6203SJed Brown       PetscInt rbs,cbs;
2322ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2323f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23243bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23253bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23263bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23277adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2328ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
232908480c60SBarry Smith     }
233099141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
233117ab2063SBarry Smith     for (i=0; i<nrows; i++) {
233299141d43SSatish Balay       row      = irow[i];
2333bfeeae90SHong Zhang       kstart   = ai[row];
233499141d43SSatish Balay       kend     = kstart + a->ilen[row];
2335bfeeae90SHong Zhang       mat_i    = c->i[i];
233699141d43SSatish Balay       mat_j    = c->j + mat_i;
233799141d43SSatish Balay       mat_a    = c->a + mat_i;
233899141d43SSatish Balay       mat_ilen = c->ilen + i;
233917ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2340bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2341ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
234299141d43SSatish Balay           *mat_a++ = a->a[k];
234399141d43SSatish Balay           (*mat_ilen)++;
234499141d43SSatish Balay 
234517ab2063SBarry Smith         }
234617ab2063SBarry Smith       }
234717ab2063SBarry Smith     }
234802834360SBarry Smith     /* Free work space */
234902834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2350606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2351606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2352cdc6f3adSToby Isaac     /* sort */
2353cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2354cdc6f3adSToby Isaac       PetscInt ilen;
2355cdc6f3adSToby Isaac 
2356cdc6f3adSToby Isaac       mat_i = c->i[i];
2357cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2358cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2359cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2360390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2361cdc6f3adSToby Isaac     }
236202834360SBarry Smith   }
23636d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23646d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
236517ab2063SBarry Smith 
236617ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2367416022c9SBarry Smith   *B   = C;
23683a40ed3dSBarry Smith   PetscFunctionReturn(0);
236917ab2063SBarry Smith }
237017ab2063SBarry Smith 
2371fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
237282d44351SHong Zhang {
237382d44351SHong Zhang   PetscErrorCode ierr;
237482d44351SHong Zhang   Mat            B;
237582d44351SHong Zhang 
237682d44351SHong Zhang   PetscFunctionBegin;
2377c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
237882d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
237982d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
238033d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
238182d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
238282d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
238382d44351SHong Zhang     *subMat = B;
2384c2d650bdSHong Zhang   } else {
2385c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2386c2d650bdSHong Zhang   }
238782d44351SHong Zhang   PetscFunctionReturn(0);
238882d44351SHong Zhang }
238982d44351SHong Zhang 
23909a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2391a871dcd8SBarry Smith {
239263b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2393dfbe8321SBarry Smith   PetscErrorCode ierr;
239463b91edcSBarry Smith   Mat            outA;
2395ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
239663b91edcSBarry Smith 
23973a40ed3dSBarry Smith   PetscFunctionBegin;
2398e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23991df811f5SHong Zhang 
2400b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2401b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2402a871dcd8SBarry Smith 
240363b91edcSBarry Smith   outA             = inA;
2404d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2405f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2406f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
24072205254eSKarl Rupp 
2408c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24096bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24102205254eSKarl Rupp 
2411c3122656SLisandro Dalcin   a->row = row;
24122205254eSKarl Rupp 
2413c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24146bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24152205254eSKarl Rupp 
2416c3122656SLisandro Dalcin   a->col = col;
241763b91edcSBarry Smith 
241836db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
24196bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
24204c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
24213bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2422f0ec6fceSSatish Balay 
242394a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2424854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
24253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
242694a9d846SBarry Smith   }
242763b91edcSBarry Smith 
2428f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2429137fb511SHong Zhang   if (row_identity && col_identity) {
2430ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2431137fb511SHong Zhang   } else {
2432719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2433137fb511SHong Zhang   }
24343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2435a871dcd8SBarry Smith }
2436a871dcd8SBarry Smith 
2437f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2438f0b747eeSBarry Smith {
2439f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2440f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2441efee365bSSatish Balay   PetscErrorCode ierr;
2442c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24433a40ed3dSBarry Smith 
24443a40ed3dSBarry Smith   PetscFunctionBegin;
2445c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24468b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2447efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2448acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24493a40ed3dSBarry Smith   PetscFunctionReturn(0);
2450f0b747eeSBarry Smith }
2451f0b747eeSBarry Smith 
24525c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
245316b64355SHong Zhang {
245416b64355SHong Zhang   PetscErrorCode ierr;
245516b64355SHong Zhang   PetscInt       i;
245616b64355SHong Zhang 
245716b64355SHong Zhang   PetscFunctionBegin;
245816b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
245916b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
246016b64355SHong Zhang 
246116b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
246216b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
246316b64355SHong Zhang     }
246416b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
246516b64355SHong Zhang 
246616b64355SHong Zhang     if (submatj->rbuf1) {
246716b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
246816b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
246916b64355SHong Zhang     }
247016b64355SHong Zhang 
247116b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
247216b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
247316b64355SHong Zhang     }
247416b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
247516b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
247616b64355SHong Zhang   }
247716b64355SHong Zhang 
247816b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
247916b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
248016b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
248116b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
248216b64355SHong Zhang #else
248316b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
248416b64355SHong Zhang #endif
248516b64355SHong Zhang 
248616b64355SHong Zhang   if (!submatj->allcolumns) {
248716b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
248816b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
248916b64355SHong Zhang #else
249016b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
249116b64355SHong Zhang #endif
249216b64355SHong Zhang   }
249316b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
249416b64355SHong Zhang 
249516b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
249616b64355SHong Zhang   PetscFunctionReturn(0);
249716b64355SHong Zhang }
249816b64355SHong Zhang 
249916b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
250016b64355SHong Zhang {
250116b64355SHong Zhang   PetscErrorCode ierr;
250216b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
25035c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
250416b64355SHong Zhang 
250516b64355SHong Zhang   PetscFunctionBegin;
250616b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2507e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
250816b64355SHong Zhang   PetscFunctionReturn(0);
250916b64355SHong Zhang }
251016b64355SHong Zhang 
25117dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2512cddf8d76SBarry Smith {
2513dfbe8321SBarry Smith   PetscErrorCode ierr;
251497f1f81fSBarry Smith   PetscInt       i;
2515cddf8d76SBarry Smith 
25163a40ed3dSBarry Smith   PetscFunctionBegin;
2517cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2518df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2519cddf8d76SBarry Smith   }
2520cddf8d76SBarry Smith 
2521cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25227dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2523cddf8d76SBarry Smith   }
25243a40ed3dSBarry Smith   PetscFunctionReturn(0);
2525cddf8d76SBarry Smith }
2526cddf8d76SBarry Smith 
252797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25284dcbc457SBarry Smith {
2529e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25306849ba73SBarry Smith   PetscErrorCode ierr;
25315d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25325d0c19d7SBarry Smith   const PetscInt *idx;
253397f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2534f1af5d2fSBarry Smith   PetscBT        table;
2535bbd702dbSSatish Balay 
25363a40ed3dSBarry Smith   PetscFunctionBegin;
2537d0f46423SBarry Smith   m  = A->rmap->n;
2538e4d965acSSatish Balay   ai = a->i;
2539bfeeae90SHong Zhang   aj = a->j;
25408a047759SSatish Balay 
2541e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
254206763907SSatish Balay 
2543854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
254453b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
254506763907SSatish Balay 
2546e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2547b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2548e4d965acSSatish Balay     isz  = 0;
25496831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2550e4d965acSSatish Balay 
2551e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25524dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2553b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2554e4d965acSSatish Balay 
2555dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2556e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25572205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25584dcbc457SBarry Smith     }
255906763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25606bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2561e4d965acSSatish Balay 
256204a348a9SBarry Smith     k = 0;
256304a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
256404a348a9SBarry Smith       n = isz;
256506763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2566e4d965acSSatish Balay         row   = nidx[k];
2567e4d965acSSatish Balay         start = ai[row];
2568e4d965acSSatish Balay         end   = ai[row+1];
256904a348a9SBarry Smith         for (l = start; l<end; l++) {
2570efb16452SHong Zhang           val = aj[l];
25712205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2572e4d965acSSatish Balay         }
2573e4d965acSSatish Balay       }
2574e4d965acSSatish Balay     }
257570b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2576e4d965acSSatish Balay   }
257794bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2578606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25793a40ed3dSBarry Smith   PetscFunctionReturn(0);
25804dcbc457SBarry Smith }
258117ab2063SBarry Smith 
25820513a670SBarry Smith /* -------------------------------------------------------------- */
2583dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25840513a670SBarry Smith {
25850513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25866849ba73SBarry Smith   PetscErrorCode ierr;
25873b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25885d0c19d7SBarry Smith   const PetscInt *row,*col;
25895d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
259056cd22aeSBarry Smith   IS             icolp,irowp;
25910298fd71SBarry Smith   PetscInt       *cwork = NULL;
25920298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25930513a670SBarry Smith 
25943a40ed3dSBarry Smith   PetscFunctionBegin;
25954c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
259656cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25974c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
259856cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
25990513a670SBarry Smith 
26000513a670SBarry Smith   /* determine lengths of permuted rows */
2601854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
26022205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2603ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2604f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
260533d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
26067adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2607ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2608606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26090513a670SBarry Smith 
2610785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26110513a670SBarry Smith   for (i=0; i<m; i++) {
261232ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26132205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2614cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
261532ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26160513a670SBarry Smith   }
2617606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26182205254eSKarl Rupp 
26193c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26202205254eSKarl Rupp 
26210513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26220513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
262356cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
262456cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26256bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26266bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26273a40ed3dSBarry Smith   PetscFunctionReturn(0);
26280513a670SBarry Smith }
26290513a670SBarry Smith 
2630dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2631cb5b572fSBarry Smith {
2632dfbe8321SBarry Smith   PetscErrorCode ierr;
2633cb5b572fSBarry Smith 
2634cb5b572fSBarry Smith   PetscFunctionBegin;
263533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
263633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2637be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2638be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2639be6bf707SBarry Smith 
2640700c5bfcSBarry 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");
2641d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2642*cdc753b6SBarry Smith     ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
2643cb5b572fSBarry Smith   } else {
2644cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2645cb5b572fSBarry Smith   }
2646cb5b572fSBarry Smith   PetscFunctionReturn(0);
2647cb5b572fSBarry Smith }
2648cb5b572fSBarry Smith 
26494994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2650273d9f13SBarry Smith {
2651dfbe8321SBarry Smith   PetscErrorCode ierr;
2652273d9f13SBarry Smith 
2653273d9f13SBarry Smith   PetscFunctionBegin;
2654ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2655273d9f13SBarry Smith   PetscFunctionReturn(0);
2656273d9f13SBarry Smith }
2657273d9f13SBarry Smith 
26588c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26596c0721eeSBarry Smith {
26606c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26616e111a19SKarl Rupp 
26626c0721eeSBarry Smith   PetscFunctionBegin;
26636c0721eeSBarry Smith   *array = a->a;
26646c0721eeSBarry Smith   PetscFunctionReturn(0);
26656c0721eeSBarry Smith }
26666c0721eeSBarry Smith 
26678c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26686c0721eeSBarry Smith {
26696c0721eeSBarry Smith   PetscFunctionBegin;
26706c0721eeSBarry Smith   PetscFunctionReturn(0);
26716c0721eeSBarry Smith }
2672273d9f13SBarry Smith 
26738229c054SShri Abhyankar /*
26748229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26758229c054SShri Abhyankar    have different nonzero structure.
26768229c054SShri Abhyankar */
2677b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2678ec7775f6SShri Abhyankar {
2679b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2680ec7775f6SShri Abhyankar 
2681ec7775f6SShri Abhyankar   PetscFunctionBegin;
2682ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2683ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2684b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2685b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2686b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26878af7cee1SJed Brown     nnz[i] = 0;
26888af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2689b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2690b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26918af7cee1SJed Brown       nnz[i]++;
26928af7cee1SJed Brown     }
26938af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2694ec7775f6SShri Abhyankar   }
2695ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2696ec7775f6SShri Abhyankar }
2697ec7775f6SShri Abhyankar 
2698b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2699b264fe52SHong Zhang {
2700b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2701b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2702b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2703b264fe52SHong Zhang   PetscErrorCode ierr;
2704b264fe52SHong Zhang 
2705b264fe52SHong Zhang   PetscFunctionBegin;
2706b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2707b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2708b264fe52SHong Zhang   PetscFunctionReturn(0);
2709b264fe52SHong Zhang }
2710b264fe52SHong Zhang 
2711f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2712ac90fabeSBarry Smith {
2713dfbe8321SBarry Smith   PetscErrorCode ierr;
2714ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2715c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2716ac90fabeSBarry Smith 
2717ac90fabeSBarry Smith   PetscFunctionBegin;
2718c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2719ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2720f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27218b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2722acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2723a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2724ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2725ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2726ac90fabeSBarry Smith   } else {
27278229c054SShri Abhyankar     Mat      B;
27288229c054SShri Abhyankar     PetscInt *nnz;
2729785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2730ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2731bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27324aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
273333d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2734176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27358229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2736ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2737ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
273828be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27398229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2740ac90fabeSBarry Smith   }
2741ac90fabeSBarry Smith   PetscFunctionReturn(0);
2742ac90fabeSBarry Smith }
2743ac90fabeSBarry Smith 
27447087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2745354c94deSBarry Smith {
2746354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2747354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2748354c94deSBarry Smith   PetscInt    i,nz;
2749354c94deSBarry Smith   PetscScalar *a;
2750354c94deSBarry Smith 
2751354c94deSBarry Smith   PetscFunctionBegin;
2752354c94deSBarry Smith   nz = aij->nz;
2753354c94deSBarry Smith   a  = aij->a;
27542205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2755354c94deSBarry Smith #else
2756354c94deSBarry Smith   PetscFunctionBegin;
2757354c94deSBarry Smith #endif
2758354c94deSBarry Smith   PetscFunctionReturn(0);
2759354c94deSBarry Smith }
2760354c94deSBarry Smith 
2761985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2762e34fafa9SBarry Smith {
2763e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2764e34fafa9SBarry Smith   PetscErrorCode ierr;
2765d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2766e34fafa9SBarry Smith   PetscReal      atmp;
2767985db425SBarry Smith   PetscScalar    *x;
2768e34fafa9SBarry Smith   MatScalar      *aa;
2769e34fafa9SBarry Smith 
2770e34fafa9SBarry Smith   PetscFunctionBegin;
2771e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2772e34fafa9SBarry Smith   aa = a->a;
2773e34fafa9SBarry Smith   ai = a->i;
2774e34fafa9SBarry Smith   aj = a->j;
2775e34fafa9SBarry Smith 
2776985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2777e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2778e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2779e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2780e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2781e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27829189402eSHong Zhang     x[i]  = 0.0;
2783e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2784985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2785985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2786985db425SBarry Smith       aa++; aj++;
2787985db425SBarry Smith     }
2788985db425SBarry Smith   }
2789985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2790985db425SBarry Smith   PetscFunctionReturn(0);
2791985db425SBarry Smith }
2792985db425SBarry Smith 
2793985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2794985db425SBarry Smith {
2795985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2796985db425SBarry Smith   PetscErrorCode ierr;
2797d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2798985db425SBarry Smith   PetscScalar    *x;
2799985db425SBarry Smith   MatScalar      *aa;
2800985db425SBarry Smith 
2801985db425SBarry Smith   PetscFunctionBegin;
2802e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2803985db425SBarry Smith   aa = a->a;
2804985db425SBarry Smith   ai = a->i;
2805985db425SBarry Smith   aj = a->j;
2806985db425SBarry Smith 
2807985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2808985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2809985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2810e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2811985db425SBarry Smith   for (i=0; i<m; i++) {
2812985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2813d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2814985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2815985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2816985db425SBarry Smith       x[i] = 0.0;
2817985db425SBarry Smith       if (idx) {
2818985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2819985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2820985db425SBarry Smith           if (aj[j] > j) {
2821985db425SBarry Smith             idx[i] = j;
2822985db425SBarry Smith             break;
2823985db425SBarry Smith           }
2824985db425SBarry Smith         }
2825985db425SBarry Smith       }
2826985db425SBarry Smith     }
2827985db425SBarry Smith     for (j=0; j<ncols; j++) {
2828985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2829985db425SBarry Smith       aa++; aj++;
2830985db425SBarry Smith     }
2831985db425SBarry Smith   }
2832985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2833985db425SBarry Smith   PetscFunctionReturn(0);
2834985db425SBarry Smith }
2835985db425SBarry Smith 
2836c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2837c87e5d42SMatthew Knepley {
2838c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2839c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2840c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2841c87e5d42SMatthew Knepley   PetscReal      atmp;
2842c87e5d42SMatthew Knepley   PetscScalar    *x;
2843c87e5d42SMatthew Knepley   MatScalar      *aa;
2844c87e5d42SMatthew Knepley 
2845c87e5d42SMatthew Knepley   PetscFunctionBegin;
2846e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2847c87e5d42SMatthew Knepley   aa = a->a;
2848c87e5d42SMatthew Knepley   ai = a->i;
2849c87e5d42SMatthew Knepley   aj = a->j;
2850c87e5d42SMatthew Knepley 
2851c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2852c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2853c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
285460e0710aSBarry 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);
2855c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2856c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2857289a08f5SMatthew Knepley     if (ncols) {
2858289a08f5SMatthew Knepley       /* Get first nonzero */
2859289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2860289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28612205254eSKarl Rupp         if (atmp > 1.0e-12) {
28622205254eSKarl Rupp           x[i] = atmp;
28632205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28642205254eSKarl Rupp           break;
28652205254eSKarl Rupp         }
2866289a08f5SMatthew Knepley       }
286712431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2868289a08f5SMatthew Knepley     } else {
2869289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2870289a08f5SMatthew Knepley     }
2871c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2872c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2873289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2874c87e5d42SMatthew Knepley       aa++; aj++;
2875c87e5d42SMatthew Knepley     }
2876c87e5d42SMatthew Knepley   }
2877c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2878c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2879c87e5d42SMatthew Knepley }
2880c87e5d42SMatthew Knepley 
2881985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2882985db425SBarry Smith {
2883985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2884985db425SBarry Smith   PetscErrorCode  ierr;
2885d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2886d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2887985db425SBarry Smith   PetscScalar     *x;
2888d9ca1df4SBarry Smith   const MatScalar *aa;
2889985db425SBarry Smith 
2890985db425SBarry Smith   PetscFunctionBegin;
2891e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2892985db425SBarry Smith   aa = a->a;
2893985db425SBarry Smith   ai = a->i;
2894985db425SBarry Smith   aj = a->j;
2895985db425SBarry Smith 
2896985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2897985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2898985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2899e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2900985db425SBarry Smith   for (i=0; i<m; i++) {
2901985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2902d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2903985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2904985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2905985db425SBarry Smith       x[i] = 0.0;
2906985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2907985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2908985db425SBarry Smith         for (j=0; j<ncols; j++) {
2909985db425SBarry Smith           if (aj[j] > j) {
2910985db425SBarry Smith             idx[i] = j;
2911985db425SBarry Smith             break;
2912985db425SBarry Smith           }
2913985db425SBarry Smith         }
2914985db425SBarry Smith       }
2915985db425SBarry Smith     }
2916985db425SBarry Smith     for (j=0; j<ncols; j++) {
2917985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2918985db425SBarry Smith       aa++; aj++;
2919e34fafa9SBarry Smith     }
2920e34fafa9SBarry Smith   }
2921e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2922e34fafa9SBarry Smith   PetscFunctionReturn(0);
2923e34fafa9SBarry Smith }
2924bbead8a2SBarry Smith 
2925bbead8a2SBarry Smith #include <petscblaslapack.h>
2926af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2927bbead8a2SBarry Smith 
2928713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2929bbead8a2SBarry Smith {
2930bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2931bbead8a2SBarry Smith   PetscErrorCode ierr;
293233d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2933bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2934bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29351a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2936bbead8a2SBarry Smith 
2937bbead8a2SBarry Smith   PetscFunctionBegin;
2938a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29394a0d0026SBarry Smith   if (a->ibdiagvalid) {
29404a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29414a0d0026SBarry Smith     PetscFunctionReturn(0);
29424a0d0026SBarry Smith   }
2943bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2944bbead8a2SBarry Smith   if (!a->ibdiag) {
2945785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29463bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2947bbead8a2SBarry Smith   }
2948bbead8a2SBarry Smith   diag = a->ibdiag;
2949bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2950bbead8a2SBarry Smith   /* factor and invert each block */
2951bbead8a2SBarry Smith   switch (bs) {
2952bbead8a2SBarry Smith   case 1:
2953bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2954bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2955ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2956ec1892c8SHong Zhang         if (allowzeropivot) {
29577b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29587b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29597b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29607b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29617b6c816cSBarry 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);
2962ec1892c8SHong Zhang       }
2963bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2964bbead8a2SBarry Smith     }
2965bbead8a2SBarry Smith     break;
2966bbead8a2SBarry Smith   case 2:
2967bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2968bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2969bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2970a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29717b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2973bbead8a2SBarry Smith       diag += 4;
2974bbead8a2SBarry Smith     }
2975bbead8a2SBarry Smith     break;
2976bbead8a2SBarry Smith   case 3:
2977bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2978bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2979bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2980a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29817b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2983bbead8a2SBarry Smith       diag += 9;
2984bbead8a2SBarry Smith     }
2985bbead8a2SBarry Smith     break;
2986bbead8a2SBarry Smith   case 4:
2987bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2988bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2989bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2990a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29917b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2993bbead8a2SBarry Smith       diag += 16;
2994bbead8a2SBarry Smith     }
2995bbead8a2SBarry Smith     break;
2996bbead8a2SBarry Smith   case 5:
2997bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2998bbead8a2SBarry 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;
2999bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
3000a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30017b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
300296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3003bbead8a2SBarry Smith       diag += 25;
3004bbead8a2SBarry Smith     }
3005bbead8a2SBarry Smith     break;
3006bbead8a2SBarry Smith   case 6:
3007bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3008bbead8a2SBarry 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;
3009bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
3010a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30117b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
301296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3013bbead8a2SBarry Smith       diag += 36;
3014bbead8a2SBarry Smith     }
3015bbead8a2SBarry Smith     break;
3016bbead8a2SBarry Smith   case 7:
3017bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3018bbead8a2SBarry 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;
3019bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
3020a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30217b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
302296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3023bbead8a2SBarry Smith       diag += 49;
3024bbead8a2SBarry Smith     }
3025bbead8a2SBarry Smith     break;
3026bbead8a2SBarry Smith   default:
3027dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3028bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3029bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3030bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3031bbead8a2SBarry Smith       }
3032bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30335f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30347b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
303596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3036bbead8a2SBarry Smith       diag += bs2;
3037bbead8a2SBarry Smith     }
3038bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3039bbead8a2SBarry Smith   }
3040bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3041bbead8a2SBarry Smith   PetscFunctionReturn(0);
3042bbead8a2SBarry Smith }
3043bbead8a2SBarry Smith 
304473a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
304573a71a0fSBarry Smith {
304673a71a0fSBarry Smith   PetscErrorCode ierr;
304773a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
304873a71a0fSBarry Smith   PetscScalar    a;
304973a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
305073a71a0fSBarry Smith 
305173a71a0fSBarry Smith   PetscFunctionBegin;
305273a71a0fSBarry Smith   if (!x->assembled) {
305373a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
305473a71a0fSBarry Smith     for (i=0; i<m; i++) {
305573a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
305673a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
305773a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
305873a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
305973a71a0fSBarry Smith       }
306073a71a0fSBarry Smith     }
306173a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
306273a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306373a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306473a71a0fSBarry Smith   PetscFunctionReturn(0);
306573a71a0fSBarry Smith }
306673a71a0fSBarry Smith 
30677d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30687d68702bSBarry Smith {
30697d68702bSBarry Smith   PetscErrorCode ierr;
30707d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30717d68702bSBarry Smith 
30727d68702bSBarry Smith   PetscFunctionBegin;
30736f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30747d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30757d68702bSBarry Smith   }
30767d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30777d68702bSBarry Smith   PetscFunctionReturn(0);
30787d68702bSBarry Smith }
30797d68702bSBarry Smith 
3080682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30810a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3082cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3083cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3084cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
308597304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30867c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30877c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3088db4efbfdSBarry Smith                                         0,
3089db4efbfdSBarry Smith                                         0,
3090db4efbfdSBarry Smith                                         0,
3091db4efbfdSBarry Smith                                 /* 10*/ 0,
3092cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3093cb5b572fSBarry Smith                                         0,
309441f059aeSBarry Smith                                         MatSOR_SeqAIJ,
309517ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
309697304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3097cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3098cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3099cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3100cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
310197304618SKris Buschelman                                 /* 20*/ 0,
3102cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3103cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3104cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3105d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3106db4efbfdSBarry Smith                                         0,
3107db4efbfdSBarry Smith                                         0,
3108db4efbfdSBarry Smith                                         0,
3109db4efbfdSBarry Smith                                         0,
31104994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3111db4efbfdSBarry Smith                                         0,
3112db4efbfdSBarry Smith                                         0,
31138c778c55SBarry Smith                                         0,
31148c778c55SBarry Smith                                         0,
3115d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3116cb5b572fSBarry Smith                                         0,
3117cb5b572fSBarry Smith                                         0,
3118cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3119cb5b572fSBarry Smith                                         0,
3120d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
31217dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3122cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3123cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3124cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3125d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3126cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
31277d68702bSBarry Smith                                         MatShift_SeqAIJ,
312879299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31296e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
313073a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31313b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31323b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31333b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3134a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
313593dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3136b9617806SBarry Smith                                         0,
31370513a670SBarry Smith                                         0,
3138cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3139cda55fadSBarry Smith                                         0,
3140d519adbfSMatthew Knepley                                 /* 59*/ 0,
3141b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3142b9b97703SBarry Smith                                         MatView_SeqAIJ,
3143357abbc8SBarry Smith                                         0,
3144321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3145321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3146321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3147ee4f033dSBarry Smith                                         0,
3148ee4f033dSBarry Smith                                         0,
3149ee4f033dSBarry Smith                                         0,
3150d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3151c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3152ee4f033dSBarry Smith                                         0,
3153dcf5cc72SBarry Smith                                         0,
31542c93a97aSBarry Smith                                         0,
31552c93a97aSBarry Smith                                 /* 74*/ 0,
31563acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
315797304618SKris Buschelman                                         0,
315897304618SKris Buschelman                                         0,
315997304618SKris Buschelman                                         0,
31606ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
316197304618SKris Buschelman                                         0,
316297304618SKris Buschelman                                         0,
316397304618SKris Buschelman                                         0,
3164bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3165d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31661cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31676284ec50SHong Zhang                                         0,
31686284ec50SHong Zhang                                         0,
3169bc011b1eSHong Zhang                                         0,
3170d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
317126be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
317226be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
317365e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31744a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
317565e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31766fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31776fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31786fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31792121bac1SHong Zhang                                         0,
31802121bac1SHong Zhang                                 /* 99*/ 0,
3181609c6c4dSKris Buschelman                                         0,
3182609c6c4dSKris Buschelman                                         0,
318387d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
318487d4246cSBarry Smith                                         0,
3185d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
318699cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3187f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3188f5edf698SHong Zhang                                         0,
31892bebee5dSHong Zhang                                         0,
3190cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3191985db425SBarry Smith                                         0,
31922af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31932af78befSBarry Smith                                         0,
3194599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3195d519adbfSMatthew Knepley                                 /*114*/ 0,
3196599ef60dSHong Zhang                                         0,
31973c2a7987SHong Zhang                                         0,
3198fe97e370SBarry Smith                                         0,
3199fbdbba38SShri Abhyankar                                         0,
3200fbdbba38SShri Abhyankar                                 /*119*/ 0,
3201fbdbba38SShri Abhyankar                                         0,
3202fbdbba38SShri Abhyankar                                         0,
320382d44351SHong Zhang                                         0,
3204b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32050716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3206bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
320737868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
320837868618SMatthew G Knepley                                         0,
320937868618SMatthew G Knepley                                         0,
32105df89d91SHong Zhang                                 /*129*/ 0,
321175648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
321275648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
321375648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3214b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3215b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32162b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32172b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32182b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32193964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32203964eb88SJed Brown                                  /*139*/0,
3221f9426fe0SMark Adams                                         0,
32221919a2e2SJed Brown                                         0,
32233a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
32249c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
32259c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
32269e29f15eSvictorle };
322717ab2063SBarry Smith 
32287087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3229bef8e0ddSBarry Smith {
3230bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
323197f1f81fSBarry Smith   PetscInt   i,nz,n;
3232bef8e0ddSBarry Smith 
3233bef8e0ddSBarry Smith   PetscFunctionBegin;
3234bef8e0ddSBarry Smith   nz = aij->maxnz;
3235d0f46423SBarry Smith   n  = mat->rmap->n;
3236bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3237bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3238bef8e0ddSBarry Smith   }
3239bef8e0ddSBarry Smith   aij->nz = nz;
3240bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3241bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3242bef8e0ddSBarry Smith   }
3243bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3244bef8e0ddSBarry Smith }
3245bef8e0ddSBarry Smith 
3246bef8e0ddSBarry Smith /*@
3247bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3248bef8e0ddSBarry Smith        in the matrix.
3249bef8e0ddSBarry Smith 
3250bef8e0ddSBarry Smith   Input Parameters:
3251bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3252bef8e0ddSBarry Smith -  indices - the column indices
3253bef8e0ddSBarry Smith 
325415091d37SBarry Smith   Level: advanced
325515091d37SBarry Smith 
3256bef8e0ddSBarry Smith   Notes:
3257bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3258bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3259bef8e0ddSBarry Smith   of the MatSetValues() operation.
3260bef8e0ddSBarry Smith 
3261bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3262d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3263bef8e0ddSBarry Smith 
3264bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3265bef8e0ddSBarry Smith 
3266b9617806SBarry Smith     The indices should start with zero, not one.
3267b9617806SBarry Smith 
3268bef8e0ddSBarry Smith @*/
32697087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3270bef8e0ddSBarry Smith {
32714ac538c5SBarry Smith   PetscErrorCode ierr;
3272bef8e0ddSBarry Smith 
3273bef8e0ddSBarry Smith   PetscFunctionBegin;
32740700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32754482741eSBarry Smith   PetscValidPointer(indices,2);
32764ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3277bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3278bef8e0ddSBarry Smith }
3279bef8e0ddSBarry Smith 
3280be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3281be6bf707SBarry Smith 
32827087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3283be6bf707SBarry Smith {
3284be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32856849ba73SBarry Smith   PetscErrorCode ierr;
3286d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3287be6bf707SBarry Smith 
3288be6bf707SBarry Smith   PetscFunctionBegin;
3289169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3290be6bf707SBarry Smith 
3291be6bf707SBarry Smith   /* allocate space for values if not already there */
3292be6bf707SBarry Smith   if (!aij->saved_values) {
3293854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32943bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3295be6bf707SBarry Smith   }
3296be6bf707SBarry Smith 
3297be6bf707SBarry Smith   /* copy values over */
329887828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3299be6bf707SBarry Smith   PetscFunctionReturn(0);
3300be6bf707SBarry Smith }
3301be6bf707SBarry Smith 
3302be6bf707SBarry Smith /*@
3303be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3304be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3305be6bf707SBarry Smith        nonlinear portion.
3306be6bf707SBarry Smith 
3307be6bf707SBarry Smith    Collect on Mat
3308be6bf707SBarry Smith 
3309be6bf707SBarry Smith   Input Parameters:
33100e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3311be6bf707SBarry Smith 
331215091d37SBarry Smith   Level: advanced
331315091d37SBarry Smith 
3314be6bf707SBarry Smith   Common Usage, with SNESSolve():
3315be6bf707SBarry Smith $    Create Jacobian matrix
3316be6bf707SBarry Smith $    Set linear terms into matrix
3317be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3318be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3319be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3320512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3321be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3322be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3323be6bf707SBarry Smith $    In your Jacobian routine
3324be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3325be6bf707SBarry Smith $      Set nonlinear terms in matrix
3326be6bf707SBarry Smith 
3327be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3328be6bf707SBarry Smith $    // build linear portion of Jacobian
3329512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3330be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3331be6bf707SBarry Smith $    loop over nonlinear iterations
3332be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3333be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3334be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3335be6bf707SBarry Smith $       Solve linear system with Jacobian
3336be6bf707SBarry Smith $    endloop
3337be6bf707SBarry Smith 
3338be6bf707SBarry Smith   Notes:
3339be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3340512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3341be6bf707SBarry Smith     calling this routine.
3342be6bf707SBarry Smith 
33430c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33440c468ba9SBarry Smith     and does not allocated additional space.
33450c468ba9SBarry Smith 
3346be6bf707SBarry Smith .seealso: MatRetrieveValues()
3347be6bf707SBarry Smith 
3348be6bf707SBarry Smith @*/
33497087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3350be6bf707SBarry Smith {
33514ac538c5SBarry Smith   PetscErrorCode ierr;
3352be6bf707SBarry Smith 
3353be6bf707SBarry Smith   PetscFunctionBegin;
33540700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3355e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3356e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33574ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3358be6bf707SBarry Smith   PetscFunctionReturn(0);
3359be6bf707SBarry Smith }
3360be6bf707SBarry Smith 
33617087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3362be6bf707SBarry Smith {
3363be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33646849ba73SBarry Smith   PetscErrorCode ierr;
3365d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3366be6bf707SBarry Smith 
3367be6bf707SBarry Smith   PetscFunctionBegin;
3368169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3369f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3370be6bf707SBarry Smith   /* copy values over */
337187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3372be6bf707SBarry Smith   PetscFunctionReturn(0);
3373be6bf707SBarry Smith }
3374be6bf707SBarry Smith 
3375be6bf707SBarry Smith /*@
3376be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3377be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3378be6bf707SBarry Smith        nonlinear portion.
3379be6bf707SBarry Smith 
3380be6bf707SBarry Smith    Collect on Mat
3381be6bf707SBarry Smith 
3382be6bf707SBarry Smith   Input Parameters:
3383386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3384be6bf707SBarry Smith 
338515091d37SBarry Smith   Level: advanced
338615091d37SBarry Smith 
3387be6bf707SBarry Smith .seealso: MatStoreValues()
3388be6bf707SBarry Smith 
3389be6bf707SBarry Smith @*/
33907087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3391be6bf707SBarry Smith {
33924ac538c5SBarry Smith   PetscErrorCode ierr;
3393be6bf707SBarry Smith 
3394be6bf707SBarry Smith   PetscFunctionBegin;
33950700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3396e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3397e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33984ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3399be6bf707SBarry Smith   PetscFunctionReturn(0);
3400be6bf707SBarry Smith }
3401be6bf707SBarry Smith 
3402f83d6046SBarry Smith 
3403be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
340417ab2063SBarry Smith /*@C
3405682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34060d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34076e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
340851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34092bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
341017ab2063SBarry Smith 
3411db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3412db81eaa0SLois Curfman McInnes 
341317ab2063SBarry Smith    Input Parameters:
3414db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
341517ab2063SBarry Smith .  m - number of rows
341617ab2063SBarry Smith .  n - number of columns
341717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
341851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34190298fd71SBarry Smith          (possibly different for each row) or NULL
342017ab2063SBarry Smith 
342117ab2063SBarry Smith    Output Parameter:
3422416022c9SBarry Smith .  A - the matrix
342317ab2063SBarry Smith 
3424175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3425ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3426175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3427175b88e8SBarry Smith 
3428b259b22eSLois Curfman McInnes    Notes:
342949a6f317SBarry Smith    If nnz is given then nz is ignored
343049a6f317SBarry Smith 
343117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
343217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34330002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
343444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
343517ab2063SBarry Smith 
343617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34370298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34383d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34396da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
344017ab2063SBarry Smith 
3441682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34424fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3443682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34446c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34456c7ebb05SLois Curfman McInnes 
34466c7ebb05SLois Curfman McInnes    Options Database Keys:
3447698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34489db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
344917ab2063SBarry Smith 
3450027ccd11SLois Curfman McInnes    Level: intermediate
3451027ccd11SLois Curfman McInnes 
345269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
345336db0b34SBarry Smith 
345417ab2063SBarry Smith @*/
34557087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
345617ab2063SBarry Smith {
3457dfbe8321SBarry Smith   PetscErrorCode ierr;
34586945ee14SBarry Smith 
34593a40ed3dSBarry Smith   PetscFunctionBegin;
3460f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3461117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3462c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3463d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3464273d9f13SBarry Smith   PetscFunctionReturn(0);
3465273d9f13SBarry Smith }
3466273d9f13SBarry Smith 
3467273d9f13SBarry Smith /*@C
3468273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3469273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3470273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3471273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3472273d9f13SBarry Smith 
3473273d9f13SBarry Smith    Collective on MPI_Comm
3474273d9f13SBarry Smith 
3475273d9f13SBarry Smith    Input Parameters:
34761c4f3114SJed Brown +  B - The matrix
3477273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3478273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34790298fd71SBarry Smith          (possibly different for each row) or NULL
3480273d9f13SBarry Smith 
3481273d9f13SBarry Smith    Notes:
348249a6f317SBarry Smith      If nnz is given then nz is ignored
348349a6f317SBarry Smith 
3484273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3485273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3486273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3487273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3488273d9f13SBarry Smith 
3489273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34900298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3491273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3492273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3493273d9f13SBarry Smith 
3494aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3495aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3496aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3497aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3498aa95bbe8SBarry Smith 
3499a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3500a96a251dSBarry Smith    entries or columns indices
3501a96a251dSBarry Smith 
3502273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3503273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3504273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3505273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3506273d9f13SBarry Smith 
3507273d9f13SBarry Smith    Options Database Keys:
3508698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3509698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3510273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3511273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3512273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith    Level: intermediate
3515273d9f13SBarry Smith 
351669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3517273d9f13SBarry Smith 
3518273d9f13SBarry Smith @*/
35197087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3520273d9f13SBarry Smith {
35214ac538c5SBarry Smith   PetscErrorCode ierr;
3522a23d5eceSKris Buschelman 
3523a23d5eceSKris Buschelman   PetscFunctionBegin;
35246ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35256ba663aaSJed Brown   PetscValidType(B,1);
35264ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3527a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3528a23d5eceSKris Buschelman }
3529a23d5eceSKris Buschelman 
35307087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3531a23d5eceSKris Buschelman {
3532273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35332576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35346849ba73SBarry Smith   PetscErrorCode ierr;
353597f1f81fSBarry Smith   PetscInt       i;
3536273d9f13SBarry Smith 
3537273d9f13SBarry Smith   PetscFunctionBegin;
35382576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3539a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3540c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3541c461c341SBarry Smith     nz             = 0;
3542c461c341SBarry Smith   }
354326283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
354426283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3545899cda47SBarry Smith 
3546435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
354760e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3548b73539f3SBarry Smith   if (nnz) {
3549d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
355060e0710aSBarry 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]);
355160e0710aSBarry 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);
3552b73539f3SBarry Smith     }
3553b73539f3SBarry Smith   }
3554b73539f3SBarry Smith 
3555273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35562205254eSKarl Rupp 
3557273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3558273d9f13SBarry Smith 
3559ab93d7beSBarry Smith   if (!skipallocation) {
35602ee49352SLisandro Dalcin     if (!b->imax) {
3561dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35623bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35632ee49352SLisandro Dalcin     }
3564273d9f13SBarry Smith     if (!nnz) {
3565435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3566c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3567d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3568d0f46423SBarry Smith       nz = nz*B->rmap->n;
3569273d9f13SBarry Smith     } else {
3570273d9f13SBarry Smith       nz = 0;
3571d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3572273d9f13SBarry Smith     }
3573ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35742205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3575ab93d7beSBarry Smith 
3576273d9f13SBarry Smith     /* allocate the matrix space */
357753dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35782ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3579396832f4SHong Zhang     if (B->structure_only) {
35805848002fSHong Zhang       ierr    = PetscMalloc1(nz,&b->j);CHKERRQ(ierr);
35815848002fSHong Zhang       ierr    = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr);
3582396832f4SHong Zhang       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr);
3583396832f4SHong Zhang     } else {
3584dcca6d9dSJed Brown       ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35853bb1ff40SBarry Smith       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3586396832f4SHong Zhang     }
3587bfeeae90SHong Zhang     b->i[0] = 0;
3588d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35895da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35905da197adSKris Buschelman     }
3591396832f4SHong Zhang     if (B->structure_only) {
3592396832f4SHong Zhang       b->singlemalloc = PETSC_FALSE;
3593396832f4SHong Zhang       b->free_a       = PETSC_FALSE;
3594396832f4SHong Zhang     } else {
3595273d9f13SBarry Smith       b->singlemalloc = PETSC_TRUE;
3596e6b907acSBarry Smith       b->free_a       = PETSC_TRUE;
3597396832f4SHong Zhang     }
3598e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3599c461c341SBarry Smith   } else {
3600e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3601e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3602c461c341SBarry Smith   }
3603273d9f13SBarry Smith 
3604273d9f13SBarry Smith   b->nz               = 0;
3605273d9f13SBarry Smith   b->maxnz            = nz;
3606273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36072205254eSKarl Rupp   if (realalloc) {
36082205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36092205254eSKarl Rupp   }
3610cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3611cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3612273d9f13SBarry Smith   PetscFunctionReturn(0);
3613273d9f13SBarry Smith }
3614273d9f13SBarry Smith 
361558d36128SBarry Smith /*@
3616a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3617a1661176SMatthew Knepley 
3618a1661176SMatthew Knepley    Input Parameters:
3619a1661176SMatthew Knepley +  B - the matrix
3620a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3621a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3622a1661176SMatthew Knepley -  v - optional values in the matrix
3623a1661176SMatthew Knepley 
3624a1661176SMatthew Knepley    Level: developer
3625a1661176SMatthew Knepley 
362658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
362758d36128SBarry Smith 
3628a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3629a1661176SMatthew Knepley 
3630a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3631a1661176SMatthew Knepley @*/
3632a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3633a1661176SMatthew Knepley {
3634a1661176SMatthew Knepley   PetscErrorCode ierr;
3635a1661176SMatthew Knepley 
3636a1661176SMatthew Knepley   PetscFunctionBegin;
36370700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36386ba663aaSJed Brown   PetscValidType(B,1);
36394ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3640a1661176SMatthew Knepley   PetscFunctionReturn(0);
3641a1661176SMatthew Knepley }
3642a1661176SMatthew Knepley 
36437087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3644a1661176SMatthew Knepley {
3645a1661176SMatthew Knepley   PetscInt       i;
3646a1661176SMatthew Knepley   PetscInt       m,n;
3647a1661176SMatthew Knepley   PetscInt       nz;
3648a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3649a1661176SMatthew Knepley   PetscScalar    *values;
3650a1661176SMatthew Knepley   PetscErrorCode ierr;
3651a1661176SMatthew Knepley 
3652a1661176SMatthew Knepley   PetscFunctionBegin;
365365e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3654779a8d59SSatish Balay 
3655779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3656779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3657779a8d59SSatish Balay 
3658779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3659854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3660a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3661b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3662a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
366365e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3664a1661176SMatthew Knepley     nnz[i] = nz;
3665a1661176SMatthew Knepley   }
3666a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3667a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3668a1661176SMatthew Knepley 
3669a1661176SMatthew Knepley   if (v) {
3670a1661176SMatthew Knepley     values = (PetscScalar*) v;
3671a1661176SMatthew Knepley   } else {
36721795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3673a1661176SMatthew Knepley   }
3674a1661176SMatthew Knepley 
3675a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3676b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3677b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3678a1661176SMatthew Knepley   }
3679a1661176SMatthew Knepley 
3680a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3681a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3682a1661176SMatthew Knepley 
3683a1661176SMatthew Knepley   if (!v) {
3684a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3685a1661176SMatthew Knepley   }
36867827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3687a1661176SMatthew Knepley   PetscFunctionReturn(0);
3688a1661176SMatthew Knepley }
3689a1661176SMatthew Knepley 
3690c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3691af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3692170fe5c8SBarry Smith 
3693170fe5c8SBarry Smith /*
3694170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3695170fe5c8SBarry Smith 
3696170fe5c8SBarry Smith                n                       p                          p
3697170fe5c8SBarry Smith         (              )       (              )         (                  )
3698170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3699170fe5c8SBarry Smith         (              )       (              )         (                  )
3700170fe5c8SBarry Smith 
3701170fe5c8SBarry Smith */
3702170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3703170fe5c8SBarry Smith {
3704170fe5c8SBarry Smith   PetscErrorCode    ierr;
3705170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3706170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3707170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37081de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3709170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3710170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3711170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3712170fe5c8SBarry Smith 
3713170fe5c8SBarry Smith   PetscFunctionBegin;
3714d0f46423SBarry Smith   m    = A->rmap->n;
3715d0f46423SBarry Smith   n    = A->cmap->n;
3716d0f46423SBarry Smith   p    = B->cmap->n;
3717170fe5c8SBarry Smith   a    = sub_a->v;
3718170fe5c8SBarry Smith   b    = sub_b->a;
3719170fe5c8SBarry Smith   c    = sub_c->v;
3720170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3721170fe5c8SBarry Smith 
3722170fe5c8SBarry Smith   ii  = sub_b->i;
3723170fe5c8SBarry Smith   idx = sub_b->j;
3724170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3725170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3726170fe5c8SBarry Smith     while (q-->0) {
3727170fe5c8SBarry Smith       c_q = c + m*(*idx);
3728170fe5c8SBarry Smith       a_q = a + m*i;
3729854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3730170fe5c8SBarry Smith       idx++;
3731170fe5c8SBarry Smith       b++;
3732170fe5c8SBarry Smith     }
3733170fe5c8SBarry Smith   }
3734170fe5c8SBarry Smith   PetscFunctionReturn(0);
3735170fe5c8SBarry Smith }
3736170fe5c8SBarry Smith 
3737170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3738170fe5c8SBarry Smith {
3739170fe5c8SBarry Smith   PetscErrorCode ierr;
3740d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3741170fe5c8SBarry Smith   Mat            Cmat;
3742170fe5c8SBarry Smith 
3743170fe5c8SBarry Smith   PetscFunctionBegin;
374460e0710aSBarry 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);
3745ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3746170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
374733d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3748170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37490298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3750d73949e8SHong Zhang 
3751d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37522205254eSKarl Rupp 
3753170fe5c8SBarry Smith   *C = Cmat;
3754170fe5c8SBarry Smith   PetscFunctionReturn(0);
3755170fe5c8SBarry Smith }
3756170fe5c8SBarry Smith 
3757170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3758150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3759170fe5c8SBarry Smith {
3760170fe5c8SBarry Smith   PetscErrorCode ierr;
3761170fe5c8SBarry Smith 
3762170fe5c8SBarry Smith   PetscFunctionBegin;
3763170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37643ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3765170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37663ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3767170fe5c8SBarry Smith   }
37683ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3769170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37703ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3771170fe5c8SBarry Smith   PetscFunctionReturn(0);
3772170fe5c8SBarry Smith }
3773170fe5c8SBarry Smith 
3774170fe5c8SBarry Smith 
37750bad9183SKris Buschelman /*MC
3776fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37770bad9183SKris Buschelman    based on compressed sparse row format.
37780bad9183SKris Buschelman 
37790bad9183SKris Buschelman    Options Database Keys:
37800bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37810bad9183SKris Buschelman 
37820bad9183SKris Buschelman   Level: beginner
37830bad9183SKris Buschelman 
3784f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37850bad9183SKris Buschelman M*/
37860bad9183SKris Buschelman 
3787ccd284c7SBarry Smith /*MC
3788ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3789ccd284c7SBarry Smith 
3790ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3791ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3792ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3793ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3794ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3795ccd284c7SBarry Smith 
3796ccd284c7SBarry Smith    Options Database Keys:
3797ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3798ccd284c7SBarry Smith 
3799ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3800ccd284c7SBarry Smith    enough exist.
3801ccd284c7SBarry Smith 
3802ccd284c7SBarry Smith   Level: beginner
3803ccd284c7SBarry Smith 
3804ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3805ccd284c7SBarry Smith M*/
3806ccd284c7SBarry Smith 
3807ccd284c7SBarry Smith /*MC
3808ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3809ccd284c7SBarry Smith 
3810ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3811ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3812ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3813ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3814ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3815ccd284c7SBarry Smith 
3816ccd284c7SBarry Smith    Options Database Keys:
3817ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3818ccd284c7SBarry Smith 
3819ccd284c7SBarry Smith   Level: beginner
3820ccd284c7SBarry Smith 
3821ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3822ccd284c7SBarry Smith M*/
3823ccd284c7SBarry Smith 
3824cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3825af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3826cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3827af8000cdSHong Zhang #endif
382863c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
382963c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
38303dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
383163c07aadSStefano Zampini #endif
3832cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
383342c9c57cSBarry Smith 
3834b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
383529b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
383629b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3837b3866ffcSBarry Smith #endif
383817667f90SBarry Smith 
3839c0c8ee5eSDmitry Karpeev 
38408c778c55SBarry Smith /*@C
38418397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38428c778c55SBarry Smith 
38438c778c55SBarry Smith    Not Collective
38448c778c55SBarry Smith 
38458c778c55SBarry Smith    Input Parameter:
3846579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38478c778c55SBarry Smith 
38488c778c55SBarry Smith    Output Parameter:
38498c778c55SBarry Smith .   array - pointer to the data
38508c778c55SBarry Smith 
38518c778c55SBarry Smith    Level: intermediate
38528c778c55SBarry Smith 
3853774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38548c778c55SBarry Smith @*/
38558c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38568c778c55SBarry Smith {
38578c778c55SBarry Smith   PetscErrorCode ierr;
38588c778c55SBarry Smith 
38598c778c55SBarry Smith   PetscFunctionBegin;
38608c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38618c778c55SBarry Smith   PetscFunctionReturn(0);
38628c778c55SBarry Smith }
38638c778c55SBarry Smith 
386421e72a00SBarry Smith /*@C
386521e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
386621e72a00SBarry Smith 
386721e72a00SBarry Smith    Not Collective
386821e72a00SBarry Smith 
386921e72a00SBarry Smith    Input Parameter:
3870579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
387121e72a00SBarry Smith 
387221e72a00SBarry Smith    Output Parameter:
387321e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
387421e72a00SBarry Smith 
387521e72a00SBarry Smith    Level: intermediate
387621e72a00SBarry Smith 
387721e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
387821e72a00SBarry Smith @*/
387921e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
388021e72a00SBarry Smith {
388121e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
388221e72a00SBarry Smith 
388321e72a00SBarry Smith   PetscFunctionBegin;
388421e72a00SBarry Smith   *nz = aij->rmax;
388521e72a00SBarry Smith   PetscFunctionReturn(0);
388621e72a00SBarry Smith }
388721e72a00SBarry Smith 
38888c778c55SBarry Smith /*@C
3889579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38908c778c55SBarry Smith 
38918c778c55SBarry Smith    Not Collective
38928c778c55SBarry Smith 
38938c778c55SBarry Smith    Input Parameters:
3894579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38958c778c55SBarry Smith .  array - pointer to the data
38968c778c55SBarry Smith 
38978c778c55SBarry Smith    Level: intermediate
38988c778c55SBarry Smith 
3899774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39008c778c55SBarry Smith @*/
39018c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39028c778c55SBarry Smith {
39038c778c55SBarry Smith   PetscErrorCode ierr;
39048c778c55SBarry Smith 
39058c778c55SBarry Smith   PetscFunctionBegin;
39068c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39078c778c55SBarry Smith   PetscFunctionReturn(0);
39088c778c55SBarry Smith }
39098c778c55SBarry Smith 
39108cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3911273d9f13SBarry Smith {
3912273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3913dfbe8321SBarry Smith   PetscErrorCode ierr;
391438baddfdSBarry Smith   PetscMPIInt    size;
3915273d9f13SBarry Smith 
3916273d9f13SBarry Smith   PetscFunctionBegin;
3917ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3918e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3919273d9f13SBarry Smith 
3920b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39212205254eSKarl Rupp 
3922b0a32e0cSBarry Smith   B->data = (void*)b;
39232205254eSKarl Rupp 
3924549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39252205254eSKarl Rupp 
3926416022c9SBarry Smith   b->row                = 0;
3927416022c9SBarry Smith   b->col                = 0;
392882bf6240SBarry Smith   b->icol               = 0;
3929b810aeb4SBarry Smith   b->reallocs           = 0;
393036db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3931f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3932416022c9SBarry Smith   b->nonew              = 0;
3933416022c9SBarry Smith   b->diag               = 0;
3934416022c9SBarry Smith   b->solve_work         = 0;
39352a1b7f2aSHong Zhang   B->spptr              = 0;
3936be6bf707SBarry Smith   b->saved_values       = 0;
3937d7f994e1SBarry Smith   b->idiag              = 0;
393871f1c65dSBarry Smith   b->mdiag              = 0;
393971f1c65dSBarry Smith   b->ssor_work          = 0;
394071f1c65dSBarry Smith   b->omega              = 1.0;
394171f1c65dSBarry Smith   b->fshift             = 0.0;
394271f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3943bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3944a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
394517ab2063SBarry Smith 
394635d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3947bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3948bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39498c778c55SBarry Smith 
3950b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3951bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3952bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3953b3866ffcSBarry Smith #endif
395417f1a0eaSHong Zhang 
3955bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3956bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3957bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3958bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3959bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3960bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3961bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3962af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3963af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3964af8000cdSHong Zhang #endif
396563c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
396663c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39673dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
396863c07aadSStefano Zampini #endif
3969b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3970bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3971bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3972bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3973bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3974bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3975bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3976bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3977bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39784108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
397917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39803a40ed3dSBarry Smith   PetscFunctionReturn(0);
398117ab2063SBarry Smith }
398217ab2063SBarry Smith 
3983b24902e0SBarry Smith /*
3984b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3985b24902e0SBarry Smith */
3986ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
398717ab2063SBarry Smith {
3988416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39896849ba73SBarry Smith   PetscErrorCode ierr;
3990d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
399117ab2063SBarry Smith 
39923a40ed3dSBarry Smith   PetscFunctionBegin;
3993273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3994273d9f13SBarry Smith 
3995d5f3da31SBarry Smith   C->factortype = A->factortype;
3996416022c9SBarry Smith   c->row        = 0;
3997416022c9SBarry Smith   c->col        = 0;
399882bf6240SBarry Smith   c->icol       = 0;
39996ad4291fSHong Zhang   c->reallocs   = 0;
400017ab2063SBarry Smith 
40016ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
400217ab2063SBarry Smith 
4003aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4004aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4005eec197d1SBarry Smith 
4006dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40073bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
400817ab2063SBarry Smith   for (i=0; i<m; i++) {
4009416022c9SBarry Smith     c->imax[i] = a->imax[i];
4010416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
401117ab2063SBarry Smith   }
401217ab2063SBarry Smith 
401317ab2063SBarry Smith   /* allocate the matrix space */
4014f77e22a1SHong Zhang   if (mallocmatspace) {
4015dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40163bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40172205254eSKarl Rupp 
4018f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40192205254eSKarl Rupp 
402097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
402117ab2063SBarry Smith     if (m > 0) {
402297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4023be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4024bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4025be6bf707SBarry Smith       } else {
4026bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
402717ab2063SBarry Smith       }
402808480c60SBarry Smith     }
4029f77e22a1SHong Zhang   }
403017ab2063SBarry Smith 
40316ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4032416022c9SBarry Smith   c->roworiented       = a->roworiented;
4033416022c9SBarry Smith   c->nonew             = a->nonew;
4034416022c9SBarry Smith   if (a->diag) {
4035854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
40363bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
403717ab2063SBarry Smith     for (i=0; i<m; i++) {
4038416022c9SBarry Smith       c->diag[i] = a->diag[i];
403917ab2063SBarry Smith     }
40403a40ed3dSBarry Smith   } else c->diag = 0;
40412205254eSKarl Rupp 
40426ad4291fSHong Zhang   c->solve_work         = 0;
40436ad4291fSHong Zhang   c->saved_values       = 0;
40446ad4291fSHong Zhang   c->idiag              = 0;
404571f1c65dSBarry Smith   c->ssor_work          = 0;
4046a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4047e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4048e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40496ad4291fSHong Zhang 
4050893ad86cSHong Zhang   c->rmax         = a->rmax;
4051416022c9SBarry Smith   c->nz           = a->nz;
40528ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4053273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4054754ec7b1SSatish Balay 
40556ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40566ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4057cd6b891eSBarry Smith   if (a->compressedrow.use) {
40586ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4059dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40606ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40616ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
406227ea64f8SHong Zhang   } else {
406327ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40640298fd71SBarry Smith     c->compressedrow.i      = NULL;
40650298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40666ad4291fSHong Zhang   }
4067ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4068e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40694846f1f5SKris Buschelman 
40702205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4071140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40723a40ed3dSBarry Smith   PetscFunctionReturn(0);
407317ab2063SBarry Smith }
407417ab2063SBarry Smith 
4075b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4076b24902e0SBarry Smith {
4077b24902e0SBarry Smith   PetscErrorCode ierr;
4078b24902e0SBarry Smith 
4079b24902e0SBarry Smith   PetscFunctionBegin;
4080ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40814b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4082cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
408333d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4084cfd3f464SBarry Smith   }
4085a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4086f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4087b24902e0SBarry Smith   PetscFunctionReturn(0);
4088b24902e0SBarry Smith }
4089b24902e0SBarry Smith 
4090112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4091fbdbba38SShri Abhyankar {
4092fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4093fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4094fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4095fbdbba38SShri Abhyankar   int            fd;
4096fbdbba38SShri Abhyankar   PetscMPIInt    size;
4097fbdbba38SShri Abhyankar   MPI_Comm       comm;
40983059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4099fbdbba38SShri Abhyankar 
4100fbdbba38SShri Abhyankar   PetscFunctionBegin;
4101c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4102c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4103fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4104fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4105fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4106bbead8a2SBarry Smith 
41070298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41080298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4109bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41103059b6faSBarry Smith   if (bs < 0) bs = 1;
41113059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4112bbead8a2SBarry Smith 
4113fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4114fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4115fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4116fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4117fbdbba38SShri Abhyankar 
4118bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4119fbdbba38SShri Abhyankar 
4120fbdbba38SShri Abhyankar   /* read in row lengths */
4121785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4122fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4123fbdbba38SShri Abhyankar 
4124fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4125fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
412660e0710aSBarry 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);
4127fbdbba38SShri Abhyankar 
4128fbdbba38SShri Abhyankar   /* set global size if not set already*/
4129f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4130fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4131aabbc4fbSShri Abhyankar   } else {
41329d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4133fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41344c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41354c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41364c5b953cSHong Zhang     }
413760e0710aSBarry 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);
4138aabbc4fbSShri Abhyankar   }
4139fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4140fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4141fbdbba38SShri Abhyankar 
4142fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4143fbdbba38SShri Abhyankar 
4144fbdbba38SShri Abhyankar   /* read in nonzero values */
4145fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4146fbdbba38SShri Abhyankar 
4147fbdbba38SShri Abhyankar   /* set matrix "i" values */
4148fbdbba38SShri Abhyankar   a->i[0] = 0;
4149fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4150fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4151fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4152fbdbba38SShri Abhyankar   }
4153fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4154fbdbba38SShri Abhyankar 
4155fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4156fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4157fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4158fbdbba38SShri Abhyankar }
4159fbdbba38SShri Abhyankar 
4160ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41617264ac53SSatish Balay {
41627264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4163dfbe8321SBarry Smith   PetscErrorCode ierr;
4164eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4165eeffb40dSHong Zhang   PetscInt k;
4166eeffb40dSHong Zhang #endif
41677264ac53SSatish Balay 
41683a40ed3dSBarry Smith   PetscFunctionBegin;
4169bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4170d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4171ca44d042SBarry Smith     *flg = PETSC_FALSE;
4172ca44d042SBarry Smith     PetscFunctionReturn(0);
4173bcd2baecSBarry Smith   }
41747264ac53SSatish Balay 
41757264ac53SSatish Balay   /* if the a->i are the same */
4176d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4177abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41787264ac53SSatish Balay 
41797264ac53SSatish Balay   /* if a->j are the same */
418097f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4181abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4182bcd2baecSBarry Smith 
4183bcd2baecSBarry Smith   /* if a->a are the same */
4184eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4185eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4186eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4187eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41883a40ed3dSBarry Smith       PetscFunctionReturn(0);
4189eeffb40dSHong Zhang     }
4190eeffb40dSHong Zhang   }
4191eeffb40dSHong Zhang #else
4192eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4193eeffb40dSHong Zhang #endif
4194eeffb40dSHong Zhang   PetscFunctionReturn(0);
41957264ac53SSatish Balay }
419636db0b34SBarry Smith 
419705869f15SSatish Balay /*@
419836db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
419936db0b34SBarry Smith               provided by the user.
420036db0b34SBarry Smith 
4201c75a6043SHong Zhang       Collective on MPI_Comm
420236db0b34SBarry Smith 
420336db0b34SBarry Smith    Input Parameters:
420436db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
420536db0b34SBarry Smith .   m - number of rows
420636db0b34SBarry Smith .   n - number of columns
420736db0b34SBarry Smith .   i - row indices
420836db0b34SBarry Smith .   j - column indices
420936db0b34SBarry Smith -   a - matrix values
421036db0b34SBarry Smith 
421136db0b34SBarry Smith    Output Parameter:
421236db0b34SBarry Smith .   mat - the matrix
421336db0b34SBarry Smith 
421436db0b34SBarry Smith    Level: intermediate
421536db0b34SBarry Smith 
421636db0b34SBarry Smith    Notes:
42170551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4218292fb18eSBarry Smith     once the matrix is destroyed and not before
421936db0b34SBarry Smith 
422036db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
422136db0b34SBarry Smith 
4222bfeeae90SHong Zhang        The i and j indices are 0 based
422336db0b34SBarry Smith 
4224a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4225a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
42268eef79e4SBarry Smith     as shown
4227a4552177SSatish Balay 
42288eef79e4SBarry Smith $        1 0 0
42298eef79e4SBarry Smith $        2 0 3
42308eef79e4SBarry Smith $        4 5 6
42318eef79e4SBarry Smith $
42328eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42338eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
42348eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4235a4552177SSatish Balay 
42369985e31cSBarry Smith 
423769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
423836db0b34SBarry Smith 
423936db0b34SBarry Smith @*/
4240c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
424136db0b34SBarry Smith {
4242dfbe8321SBarry Smith   PetscErrorCode ierr;
4243cbcfb4deSHong Zhang   PetscInt       ii;
424436db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4245cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4246cbcfb4deSHong Zhang   PetscInt jj;
4247cbcfb4deSHong Zhang #endif
424836db0b34SBarry Smith 
424936db0b34SBarry Smith   PetscFunctionBegin;
425041096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4251f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4252f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4253a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4254ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4255ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4256ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4257dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4258ab93d7beSBarry Smith 
425936db0b34SBarry Smith   aij->i            = i;
426036db0b34SBarry Smith   aij->j            = j;
426136db0b34SBarry Smith   aij->a            = a;
426236db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
426336db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4264e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4265e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
426636db0b34SBarry Smith 
426736db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
426836db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42692515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
427060e0710aSBarry 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]);
42719985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4272e32f2f54SBarry 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);
4273e32f2f54SBarry 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);
42749985e31cSBarry Smith     }
427536db0b34SBarry Smith #endif
427636db0b34SBarry Smith   }
42772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
427836db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
427960e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
428060e0710aSBarry 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]);
428136db0b34SBarry Smith   }
428236db0b34SBarry Smith #endif
428336db0b34SBarry Smith 
4284b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4285b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
428636db0b34SBarry Smith   PetscFunctionReturn(0);
428736db0b34SBarry Smith }
428880ef6e79SMatthew G Knepley /*@C
4289d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42908a0b0e6bSVictor Minden               provided by the user.
42918a0b0e6bSVictor Minden 
42928a0b0e6bSVictor Minden       Collective on MPI_Comm
42938a0b0e6bSVictor Minden 
42948a0b0e6bSVictor Minden    Input Parameters:
42958a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42968a0b0e6bSVictor Minden .   m   - number of rows
42978a0b0e6bSVictor Minden .   n   - number of columns
42988a0b0e6bSVictor Minden .   i   - row indices
42998a0b0e6bSVictor Minden .   j   - column indices
43001230e6d1SVictor Minden .   a   - matrix values
43011230e6d1SVictor Minden .   nz  - number of nonzeros
43021230e6d1SVictor Minden -   idx - 0 or 1 based
43038a0b0e6bSVictor Minden 
43048a0b0e6bSVictor Minden    Output Parameter:
43058a0b0e6bSVictor Minden .   mat - the matrix
43068a0b0e6bSVictor Minden 
43078a0b0e6bSVictor Minden    Level: intermediate
43088a0b0e6bSVictor Minden 
43098a0b0e6bSVictor Minden    Notes:
43108a0b0e6bSVictor Minden        The i and j indices are 0 based
43118a0b0e6bSVictor Minden 
43128a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43138a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43148a0b0e6bSVictor Minden     as shown:
43158a0b0e6bSVictor Minden 
43168a0b0e6bSVictor Minden         1 0 0
43178a0b0e6bSVictor Minden         2 0 3
43188a0b0e6bSVictor Minden         4 5 6
43198a0b0e6bSVictor Minden 
43208a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43218a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43228a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43238a0b0e6bSVictor Minden 
43248a0b0e6bSVictor Minden 
432569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43268a0b0e6bSVictor Minden 
43278a0b0e6bSVictor Minden @*/
4328c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
43298a0b0e6bSVictor Minden {
43308a0b0e6bSVictor Minden   PetscErrorCode ierr;
4331d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43328a0b0e6bSVictor Minden 
43338a0b0e6bSVictor Minden 
43348a0b0e6bSVictor Minden   PetscFunctionBegin;
43351795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
43361230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4337c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
43381230e6d1SVictor Minden   }
43398a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43408a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43418a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43421230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43431230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43441230e6d1SVictor Minden     if (idx) {
43451230e6d1SVictor Minden       row = i[ii] - 1;
43461230e6d1SVictor Minden       col = j[ii] - 1;
43471230e6d1SVictor Minden     } else {
43481230e6d1SVictor Minden       row = i[ii];
43491230e6d1SVictor Minden       col = j[ii];
43508a0b0e6bSVictor Minden     }
43511230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43528a0b0e6bSVictor Minden   }
43538a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43548a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4355d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43568a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43578a0b0e6bSVictor Minden }
435836db0b34SBarry Smith 
4359acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4360acf2f550SJed Brown {
4361acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4362acf2f550SJed Brown   PetscErrorCode ierr;
4363acf2f550SJed Brown 
4364acf2f550SJed Brown   PetscFunctionBegin;
4365acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4366acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43672205254eSKarl Rupp 
4368acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4369acf2f550SJed Brown   PetscFunctionReturn(0);
4370acf2f550SJed Brown }
4371acf2f550SJed Brown 
43729c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43739c8f2541SHong Zhang {
43749c8f2541SHong Zhang   PetscErrorCode ierr;
43758761c3d6SHong Zhang   PetscMPIInt    size;
43769c8f2541SHong Zhang 
43779c8f2541SHong Zhang   PetscFunctionBegin;
43788761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43798761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43808761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43818761c3d6SHong Zhang   } else {
43829c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43838761c3d6SHong Zhang   }
43849c8f2541SHong Zhang   PetscFunctionReturn(0);
43859c8f2541SHong Zhang }
43869c8f2541SHong Zhang 
438781824310SBarry Smith /*
438853dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
438953dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
439053dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
439153dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
439253dd7562SDmitry Karpeev  */
439353dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
439453dd7562SDmitry Karpeev {
439553dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
439653dd7562SDmitry Karpeev   PetscErrorCode ierr;
439753dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
439853dd7562SDmitry Karpeev   PetscBool      seqaij;
439953dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
440053dd7562SDmitry Karpeev   PetscScalar    v;
440153dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
440253dd7562SDmitry Karpeev 
440353dd7562SDmitry Karpeev   PetscFunctionBegin;
440453dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
440553dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
440653dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
440753dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
440853dd7562SDmitry Karpeev   if (rowemb) {
440953dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
441053dd7562SDmitry 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);
441153dd7562SDmitry Karpeev   } else {
44126c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
441353dd7562SDmitry Karpeev   }
441453dd7562SDmitry Karpeev   if (colemb) {
441553dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
441653dd7562SDmitry 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);
441753dd7562SDmitry Karpeev   } else {
441853dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
441953dd7562SDmitry Karpeev   }
442053dd7562SDmitry Karpeev 
442153dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
442253dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
442353dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
442453dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
442553dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
442653dd7562SDmitry Karpeev     }
442753dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
442853dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
442953dd7562SDmitry Karpeev   }
443053dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
443153dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
443253dd7562SDmitry Karpeev   }
443353dd7562SDmitry Karpeev   count = 0;
443453dd7562SDmitry Karpeev   rowindices = NULL;
443553dd7562SDmitry Karpeev   colindices = NULL;
443653dd7562SDmitry Karpeev   if (rowemb) {
443753dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
443853dd7562SDmitry Karpeev   }
443953dd7562SDmitry Karpeev   if (colemb) {
444053dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
444153dd7562SDmitry Karpeev   }
444253dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
444353dd7562SDmitry Karpeev     PetscInt row;
444453dd7562SDmitry Karpeev     row = i;
444553dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
444653dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
444753dd7562SDmitry Karpeev       PetscInt col;
444853dd7562SDmitry Karpeev       col  = Baij->j[count];
444953dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
445053dd7562SDmitry Karpeev       v    = Baij->a[count];
445153dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
445253dd7562SDmitry Karpeev       ++count;
445353dd7562SDmitry Karpeev     }
445453dd7562SDmitry Karpeev   }
445553dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
445653dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
445753dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
445853dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
445953dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
446053dd7562SDmitry Karpeev   PetscFunctionReturn(0);
446153dd7562SDmitry Karpeev }
446253dd7562SDmitry Karpeev 
446353dd7562SDmitry Karpeev 
446453dd7562SDmitry Karpeev /*
446581824310SBarry Smith     Special version for direct calls from Fortran
446681824310SBarry Smith */
4467af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
446881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
446981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
447081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
447181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
447281824310SBarry Smith #endif
447381824310SBarry Smith 
447481824310SBarry Smith /* Change these macros so can be used in void function */
447581824310SBarry Smith #undef CHKERRQ
4476ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
447781824310SBarry Smith #undef SETERRQ2
4478e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44794994cf47SJed Brown #undef SETERRQ3
44804994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
448181824310SBarry Smith 
44828cc058d9SJed 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)
448381824310SBarry Smith {
448481824310SBarry Smith   Mat            A  = *AA;
448581824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
448681824310SBarry Smith   InsertMode     is = *isis;
448781824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
448881824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
448981824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
449081824310SBarry Smith   PetscErrorCode ierr;
449181824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
449254f21887SBarry Smith   MatScalar      *ap,value,*aa;
4493ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4494ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
449581824310SBarry Smith 
449681824310SBarry Smith   PetscFunctionBegin;
44974994cf47SJed Brown   MatCheckPreallocated(A,1);
449881824310SBarry Smith   imax  = a->imax;
449981824310SBarry Smith   ai    = a->i;
450081824310SBarry Smith   ailen = a->ilen;
450181824310SBarry Smith   aj    = a->j;
450281824310SBarry Smith   aa    = a->a;
450381824310SBarry Smith 
450481824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
450581824310SBarry Smith     row = im[k];
450681824310SBarry Smith     if (row < 0) continue;
450781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4508ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
450981824310SBarry Smith #endif
451081824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
451181824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
451281824310SBarry Smith     low  = 0;
451381824310SBarry Smith     high = nrow;
451481824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
451581824310SBarry Smith       if (in[l] < 0) continue;
451681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4517ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
451881824310SBarry Smith #endif
451981824310SBarry Smith       col = in[l];
45202205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45212205254eSKarl Rupp       else value = v[k + l*m];
45222205254eSKarl Rupp 
452381824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
452481824310SBarry Smith 
45252205254eSKarl Rupp       if (col <= lastcol) low = 0;
45262205254eSKarl Rupp       else high = nrow;
452781824310SBarry Smith       lastcol = col;
452881824310SBarry Smith       while (high-low > 5) {
452981824310SBarry Smith         t = (low+high)/2;
453081824310SBarry Smith         if (rp[t] > col) high = t;
453181824310SBarry Smith         else             low  = t;
453281824310SBarry Smith       }
453381824310SBarry Smith       for (i=low; i<high; i++) {
453481824310SBarry Smith         if (rp[i] > col) break;
453581824310SBarry Smith         if (rp[i] == col) {
453681824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
453781824310SBarry Smith           else                  ap[i] = value;
453881824310SBarry Smith           goto noinsert;
453981824310SBarry Smith         }
454081824310SBarry Smith       }
454181824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
454281824310SBarry Smith       if (nonew == 1) goto noinsert;
4543ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4544fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
454581824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
454681824310SBarry Smith       /* shift up all the later entries in this row */
454781824310SBarry Smith       for (ii=N; ii>=i; ii--) {
454881824310SBarry Smith         rp[ii+1] = rp[ii];
454981824310SBarry Smith         ap[ii+1] = ap[ii];
455081824310SBarry Smith       }
455181824310SBarry Smith       rp[i] = col;
455281824310SBarry Smith       ap[i] = value;
4553e56f5c9eSBarry Smith       A->nonzerostate++;
455481824310SBarry Smith noinsert:;
455581824310SBarry Smith       low = i + 1;
455681824310SBarry Smith     }
455781824310SBarry Smith     ailen[row] = nrow;
455881824310SBarry Smith   }
455981824310SBarry Smith   PetscFunctionReturnVoid();
456081824310SBarry Smith }
45619f7953f8SBarry Smith 
4562