xref: /petsc/src/mat/impls/aij/seq/aij.c (revision d8cdefa3efe349d0ded8f6ffa281f06de1c81661)
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;
407*d8cdefa3SHong 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);
2642cb5b572fSBarry Smith   } else {
2643cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2644cb5b572fSBarry Smith   }
2645cb5b572fSBarry Smith   PetscFunctionReturn(0);
2646cb5b572fSBarry Smith }
2647cb5b572fSBarry Smith 
26484994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2649273d9f13SBarry Smith {
2650dfbe8321SBarry Smith   PetscErrorCode ierr;
2651273d9f13SBarry Smith 
2652273d9f13SBarry Smith   PetscFunctionBegin;
2653ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2654273d9f13SBarry Smith   PetscFunctionReturn(0);
2655273d9f13SBarry Smith }
2656273d9f13SBarry Smith 
26578c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26586c0721eeSBarry Smith {
26596c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26606e111a19SKarl Rupp 
26616c0721eeSBarry Smith   PetscFunctionBegin;
26626c0721eeSBarry Smith   *array = a->a;
26636c0721eeSBarry Smith   PetscFunctionReturn(0);
26646c0721eeSBarry Smith }
26656c0721eeSBarry Smith 
26668c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26676c0721eeSBarry Smith {
26686c0721eeSBarry Smith   PetscFunctionBegin;
26696c0721eeSBarry Smith   PetscFunctionReturn(0);
26706c0721eeSBarry Smith }
2671273d9f13SBarry Smith 
26728229c054SShri Abhyankar /*
26738229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26748229c054SShri Abhyankar    have different nonzero structure.
26758229c054SShri Abhyankar */
2676b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2677ec7775f6SShri Abhyankar {
2678b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2679ec7775f6SShri Abhyankar 
2680ec7775f6SShri Abhyankar   PetscFunctionBegin;
2681ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2682ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2683b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2684b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2685b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26868af7cee1SJed Brown     nnz[i] = 0;
26878af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2688b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2689b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26908af7cee1SJed Brown       nnz[i]++;
26918af7cee1SJed Brown     }
26928af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2693ec7775f6SShri Abhyankar   }
2694ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2695ec7775f6SShri Abhyankar }
2696ec7775f6SShri Abhyankar 
2697b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2698b264fe52SHong Zhang {
2699b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2700b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2701b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2702b264fe52SHong Zhang   PetscErrorCode ierr;
2703b264fe52SHong Zhang 
2704b264fe52SHong Zhang   PetscFunctionBegin;
2705b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2706b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2707b264fe52SHong Zhang   PetscFunctionReturn(0);
2708b264fe52SHong Zhang }
2709b264fe52SHong Zhang 
2710f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2711ac90fabeSBarry Smith {
2712dfbe8321SBarry Smith   PetscErrorCode ierr;
2713ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2714c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2715ac90fabeSBarry Smith 
2716ac90fabeSBarry Smith   PetscFunctionBegin;
2717c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2718ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2719f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27208b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2721acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2722a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2723ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2724ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2725ac90fabeSBarry Smith   } else {
27268229c054SShri Abhyankar     Mat      B;
27278229c054SShri Abhyankar     PetscInt *nnz;
2728785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2729ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2730bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27314aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
273233d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2733176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27348229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2735ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2736ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
273728be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27388229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2739ac90fabeSBarry Smith   }
2740ac90fabeSBarry Smith   PetscFunctionReturn(0);
2741ac90fabeSBarry Smith }
2742ac90fabeSBarry Smith 
27437087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2744354c94deSBarry Smith {
2745354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2746354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2747354c94deSBarry Smith   PetscInt    i,nz;
2748354c94deSBarry Smith   PetscScalar *a;
2749354c94deSBarry Smith 
2750354c94deSBarry Smith   PetscFunctionBegin;
2751354c94deSBarry Smith   nz = aij->nz;
2752354c94deSBarry Smith   a  = aij->a;
27532205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2754354c94deSBarry Smith #else
2755354c94deSBarry Smith   PetscFunctionBegin;
2756354c94deSBarry Smith #endif
2757354c94deSBarry Smith   PetscFunctionReturn(0);
2758354c94deSBarry Smith }
2759354c94deSBarry Smith 
2760985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2761e34fafa9SBarry Smith {
2762e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2763e34fafa9SBarry Smith   PetscErrorCode ierr;
2764d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2765e34fafa9SBarry Smith   PetscReal      atmp;
2766985db425SBarry Smith   PetscScalar    *x;
2767e34fafa9SBarry Smith   MatScalar      *aa;
2768e34fafa9SBarry Smith 
2769e34fafa9SBarry Smith   PetscFunctionBegin;
2770e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2771e34fafa9SBarry Smith   aa = a->a;
2772e34fafa9SBarry Smith   ai = a->i;
2773e34fafa9SBarry Smith   aj = a->j;
2774e34fafa9SBarry Smith 
2775985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2776e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2777e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2778e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2779e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2780e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27819189402eSHong Zhang     x[i]  = 0.0;
2782e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2783985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2784985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2785985db425SBarry Smith       aa++; aj++;
2786985db425SBarry Smith     }
2787985db425SBarry Smith   }
2788985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2789985db425SBarry Smith   PetscFunctionReturn(0);
2790985db425SBarry Smith }
2791985db425SBarry Smith 
2792985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2793985db425SBarry Smith {
2794985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2795985db425SBarry Smith   PetscErrorCode ierr;
2796d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2797985db425SBarry Smith   PetscScalar    *x;
2798985db425SBarry Smith   MatScalar      *aa;
2799985db425SBarry Smith 
2800985db425SBarry Smith   PetscFunctionBegin;
2801e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2802985db425SBarry Smith   aa = a->a;
2803985db425SBarry Smith   ai = a->i;
2804985db425SBarry Smith   aj = a->j;
2805985db425SBarry Smith 
2806985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2807985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2808985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2809e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2810985db425SBarry Smith   for (i=0; i<m; i++) {
2811985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2812d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2813985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2814985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2815985db425SBarry Smith       x[i] = 0.0;
2816985db425SBarry Smith       if (idx) {
2817985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2818985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2819985db425SBarry Smith           if (aj[j] > j) {
2820985db425SBarry Smith             idx[i] = j;
2821985db425SBarry Smith             break;
2822985db425SBarry Smith           }
2823985db425SBarry Smith         }
2824985db425SBarry Smith       }
2825985db425SBarry Smith     }
2826985db425SBarry Smith     for (j=0; j<ncols; j++) {
2827985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2828985db425SBarry Smith       aa++; aj++;
2829985db425SBarry Smith     }
2830985db425SBarry Smith   }
2831985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2832985db425SBarry Smith   PetscFunctionReturn(0);
2833985db425SBarry Smith }
2834985db425SBarry Smith 
2835c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2836c87e5d42SMatthew Knepley {
2837c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2838c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2839c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2840c87e5d42SMatthew Knepley   PetscReal      atmp;
2841c87e5d42SMatthew Knepley   PetscScalar    *x;
2842c87e5d42SMatthew Knepley   MatScalar      *aa;
2843c87e5d42SMatthew Knepley 
2844c87e5d42SMatthew Knepley   PetscFunctionBegin;
2845e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2846c87e5d42SMatthew Knepley   aa = a->a;
2847c87e5d42SMatthew Knepley   ai = a->i;
2848c87e5d42SMatthew Knepley   aj = a->j;
2849c87e5d42SMatthew Knepley 
2850c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2851c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2852c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
285360e0710aSBarry 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);
2854c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2855c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2856289a08f5SMatthew Knepley     if (ncols) {
2857289a08f5SMatthew Knepley       /* Get first nonzero */
2858289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2859289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28602205254eSKarl Rupp         if (atmp > 1.0e-12) {
28612205254eSKarl Rupp           x[i] = atmp;
28622205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28632205254eSKarl Rupp           break;
28642205254eSKarl Rupp         }
2865289a08f5SMatthew Knepley       }
286612431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2867289a08f5SMatthew Knepley     } else {
2868289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2869289a08f5SMatthew Knepley     }
2870c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2871c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2872289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2873c87e5d42SMatthew Knepley       aa++; aj++;
2874c87e5d42SMatthew Knepley     }
2875c87e5d42SMatthew Knepley   }
2876c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2877c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2878c87e5d42SMatthew Knepley }
2879c87e5d42SMatthew Knepley 
2880985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2881985db425SBarry Smith {
2882985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2883985db425SBarry Smith   PetscErrorCode  ierr;
2884d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2885d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2886985db425SBarry Smith   PetscScalar     *x;
2887d9ca1df4SBarry Smith   const MatScalar *aa;
2888985db425SBarry Smith 
2889985db425SBarry Smith   PetscFunctionBegin;
2890e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2891985db425SBarry Smith   aa = a->a;
2892985db425SBarry Smith   ai = a->i;
2893985db425SBarry Smith   aj = a->j;
2894985db425SBarry Smith 
2895985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2896985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2897985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2898e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2899985db425SBarry Smith   for (i=0; i<m; i++) {
2900985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2901d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2902985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2903985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2904985db425SBarry Smith       x[i] = 0.0;
2905985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2906985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2907985db425SBarry Smith         for (j=0; j<ncols; j++) {
2908985db425SBarry Smith           if (aj[j] > j) {
2909985db425SBarry Smith             idx[i] = j;
2910985db425SBarry Smith             break;
2911985db425SBarry Smith           }
2912985db425SBarry Smith         }
2913985db425SBarry Smith       }
2914985db425SBarry Smith     }
2915985db425SBarry Smith     for (j=0; j<ncols; j++) {
2916985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2917985db425SBarry Smith       aa++; aj++;
2918e34fafa9SBarry Smith     }
2919e34fafa9SBarry Smith   }
2920e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2921e34fafa9SBarry Smith   PetscFunctionReturn(0);
2922e34fafa9SBarry Smith }
2923bbead8a2SBarry Smith 
2924bbead8a2SBarry Smith #include <petscblaslapack.h>
2925af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2926bbead8a2SBarry Smith 
2927713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2928bbead8a2SBarry Smith {
2929bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2930bbead8a2SBarry Smith   PetscErrorCode ierr;
293133d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2932bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2933bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29341a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2935bbead8a2SBarry Smith 
2936bbead8a2SBarry Smith   PetscFunctionBegin;
2937a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29384a0d0026SBarry Smith   if (a->ibdiagvalid) {
29394a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29404a0d0026SBarry Smith     PetscFunctionReturn(0);
29414a0d0026SBarry Smith   }
2942bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2943bbead8a2SBarry Smith   if (!a->ibdiag) {
2944785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29453bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2946bbead8a2SBarry Smith   }
2947bbead8a2SBarry Smith   diag = a->ibdiag;
2948bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2949bbead8a2SBarry Smith   /* factor and invert each block */
2950bbead8a2SBarry Smith   switch (bs) {
2951bbead8a2SBarry Smith   case 1:
2952bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2953bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2954ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2955ec1892c8SHong Zhang         if (allowzeropivot) {
29567b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29577b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29587b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29597b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29607b6c816cSBarry 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);
2961ec1892c8SHong Zhang       }
2962bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2963bbead8a2SBarry Smith     }
2964bbead8a2SBarry Smith     break;
2965bbead8a2SBarry Smith   case 2:
2966bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2967bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2968bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2969a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29707b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2972bbead8a2SBarry Smith       diag += 4;
2973bbead8a2SBarry Smith     }
2974bbead8a2SBarry Smith     break;
2975bbead8a2SBarry Smith   case 3:
2976bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2977bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2978bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2979a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29807b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2982bbead8a2SBarry Smith       diag += 9;
2983bbead8a2SBarry Smith     }
2984bbead8a2SBarry Smith     break;
2985bbead8a2SBarry Smith   case 4:
2986bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2987bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2988bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2989a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29907b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2992bbead8a2SBarry Smith       diag += 16;
2993bbead8a2SBarry Smith     }
2994bbead8a2SBarry Smith     break;
2995bbead8a2SBarry Smith   case 5:
2996bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2997bbead8a2SBarry 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;
2998bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2999a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30007b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
300196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3002bbead8a2SBarry Smith       diag += 25;
3003bbead8a2SBarry Smith     }
3004bbead8a2SBarry Smith     break;
3005bbead8a2SBarry Smith   case 6:
3006bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3007bbead8a2SBarry 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;
3008bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
3009a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30107b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
301196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3012bbead8a2SBarry Smith       diag += 36;
3013bbead8a2SBarry Smith     }
3014bbead8a2SBarry Smith     break;
3015bbead8a2SBarry Smith   case 7:
3016bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3017bbead8a2SBarry 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;
3018bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
3019a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30207b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
302196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3022bbead8a2SBarry Smith       diag += 49;
3023bbead8a2SBarry Smith     }
3024bbead8a2SBarry Smith     break;
3025bbead8a2SBarry Smith   default:
3026dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3027bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3028bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3029bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3030bbead8a2SBarry Smith       }
3031bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30325f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30337b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
303496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3035bbead8a2SBarry Smith       diag += bs2;
3036bbead8a2SBarry Smith     }
3037bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3038bbead8a2SBarry Smith   }
3039bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3040bbead8a2SBarry Smith   PetscFunctionReturn(0);
3041bbead8a2SBarry Smith }
3042bbead8a2SBarry Smith 
304373a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
304473a71a0fSBarry Smith {
304573a71a0fSBarry Smith   PetscErrorCode ierr;
304673a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
304773a71a0fSBarry Smith   PetscScalar    a;
304873a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
304973a71a0fSBarry Smith 
305073a71a0fSBarry Smith   PetscFunctionBegin;
305173a71a0fSBarry Smith   if (!x->assembled) {
305273a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
305373a71a0fSBarry Smith     for (i=0; i<m; i++) {
305473a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
305573a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
305673a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
305773a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
305873a71a0fSBarry Smith       }
305973a71a0fSBarry Smith     }
306073a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
306173a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306273a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306373a71a0fSBarry Smith   PetscFunctionReturn(0);
306473a71a0fSBarry Smith }
306573a71a0fSBarry Smith 
30667d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30677d68702bSBarry Smith {
30687d68702bSBarry Smith   PetscErrorCode ierr;
30697d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30707d68702bSBarry Smith 
30717d68702bSBarry Smith   PetscFunctionBegin;
30726f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30737d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30747d68702bSBarry Smith   }
30757d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30767d68702bSBarry Smith   PetscFunctionReturn(0);
30777d68702bSBarry Smith }
30787d68702bSBarry Smith 
3079682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30800a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3081cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3082cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3083cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
308497304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30857c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30867c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3087db4efbfdSBarry Smith                                         0,
3088db4efbfdSBarry Smith                                         0,
3089db4efbfdSBarry Smith                                         0,
3090db4efbfdSBarry Smith                                 /* 10*/ 0,
3091cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3092cb5b572fSBarry Smith                                         0,
309341f059aeSBarry Smith                                         MatSOR_SeqAIJ,
309417ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
309597304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3096cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3097cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3098cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3099cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
310097304618SKris Buschelman                                 /* 20*/ 0,
3101cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3102cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3103cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3104d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3105db4efbfdSBarry Smith                                         0,
3106db4efbfdSBarry Smith                                         0,
3107db4efbfdSBarry Smith                                         0,
3108db4efbfdSBarry Smith                                         0,
31094994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3110db4efbfdSBarry Smith                                         0,
3111db4efbfdSBarry Smith                                         0,
31128c778c55SBarry Smith                                         0,
31138c778c55SBarry Smith                                         0,
3114d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3115cb5b572fSBarry Smith                                         0,
3116cb5b572fSBarry Smith                                         0,
3117cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3118cb5b572fSBarry Smith                                         0,
3119d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
31207dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3121cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3122cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3123cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3124d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3125cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
31267d68702bSBarry Smith                                         MatShift_SeqAIJ,
312779299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31286e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
312973a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31303b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31313b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31323b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3133a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
313493dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3135b9617806SBarry Smith                                         0,
31360513a670SBarry Smith                                         0,
3137cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3138cda55fadSBarry Smith                                         0,
3139d519adbfSMatthew Knepley                                 /* 59*/ 0,
3140b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3141b9b97703SBarry Smith                                         MatView_SeqAIJ,
3142357abbc8SBarry Smith                                         0,
3143321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3144321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3145321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3146ee4f033dSBarry Smith                                         0,
3147ee4f033dSBarry Smith                                         0,
3148ee4f033dSBarry Smith                                         0,
3149d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3150c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3151ee4f033dSBarry Smith                                         0,
3152dcf5cc72SBarry Smith                                         0,
31532c93a97aSBarry Smith                                         0,
31542c93a97aSBarry Smith                                 /* 74*/ 0,
31553acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
315697304618SKris Buschelman                                         0,
315797304618SKris Buschelman                                         0,
315897304618SKris Buschelman                                         0,
31596ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
316097304618SKris Buschelman                                         0,
316197304618SKris Buschelman                                         0,
316297304618SKris Buschelman                                         0,
3163bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3164d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31651cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31666284ec50SHong Zhang                                         0,
31676284ec50SHong Zhang                                         0,
3168bc011b1eSHong Zhang                                         0,
3169d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
317026be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
317126be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
317265e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31734a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
317465e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31756fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31766fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31776fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31782121bac1SHong Zhang                                         0,
31792121bac1SHong Zhang                                 /* 99*/ 0,
3180609c6c4dSKris Buschelman                                         0,
3181609c6c4dSKris Buschelman                                         0,
318287d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
318387d4246cSBarry Smith                                         0,
3184d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
318599cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3186f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3187f5edf698SHong Zhang                                         0,
31882bebee5dSHong Zhang                                         0,
3189cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3190985db425SBarry Smith                                         0,
31912af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31922af78befSBarry Smith                                         0,
3193599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3194d519adbfSMatthew Knepley                                 /*114*/ 0,
3195599ef60dSHong Zhang                                         0,
31963c2a7987SHong Zhang                                         0,
3197fe97e370SBarry Smith                                         0,
3198fbdbba38SShri Abhyankar                                         0,
3199fbdbba38SShri Abhyankar                                 /*119*/ 0,
3200fbdbba38SShri Abhyankar                                         0,
3201fbdbba38SShri Abhyankar                                         0,
320282d44351SHong Zhang                                         0,
3203b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32040716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3205bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
320637868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
320737868618SMatthew G Knepley                                         0,
320837868618SMatthew G Knepley                                         0,
32095df89d91SHong Zhang                                 /*129*/ 0,
321075648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
321175648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
321275648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3213b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3214b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32152b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32162b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32172b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32183964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32193964eb88SJed Brown                                  /*139*/0,
3220f9426fe0SMark Adams                                         0,
32211919a2e2SJed Brown                                         0,
32223a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
32239c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
32249c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
32259e29f15eSvictorle };
322617ab2063SBarry Smith 
32277087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3228bef8e0ddSBarry Smith {
3229bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
323097f1f81fSBarry Smith   PetscInt   i,nz,n;
3231bef8e0ddSBarry Smith 
3232bef8e0ddSBarry Smith   PetscFunctionBegin;
3233bef8e0ddSBarry Smith   nz = aij->maxnz;
3234d0f46423SBarry Smith   n  = mat->rmap->n;
3235bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3236bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3237bef8e0ddSBarry Smith   }
3238bef8e0ddSBarry Smith   aij->nz = nz;
3239bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3240bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3241bef8e0ddSBarry Smith   }
3242bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3243bef8e0ddSBarry Smith }
3244bef8e0ddSBarry Smith 
3245bef8e0ddSBarry Smith /*@
3246bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3247bef8e0ddSBarry Smith        in the matrix.
3248bef8e0ddSBarry Smith 
3249bef8e0ddSBarry Smith   Input Parameters:
3250bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3251bef8e0ddSBarry Smith -  indices - the column indices
3252bef8e0ddSBarry Smith 
325315091d37SBarry Smith   Level: advanced
325415091d37SBarry Smith 
3255bef8e0ddSBarry Smith   Notes:
3256bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3257bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3258bef8e0ddSBarry Smith   of the MatSetValues() operation.
3259bef8e0ddSBarry Smith 
3260bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3261d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3262bef8e0ddSBarry Smith 
3263bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3264bef8e0ddSBarry Smith 
3265b9617806SBarry Smith     The indices should start with zero, not one.
3266b9617806SBarry Smith 
3267bef8e0ddSBarry Smith @*/
32687087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3269bef8e0ddSBarry Smith {
32704ac538c5SBarry Smith   PetscErrorCode ierr;
3271bef8e0ddSBarry Smith 
3272bef8e0ddSBarry Smith   PetscFunctionBegin;
32730700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32744482741eSBarry Smith   PetscValidPointer(indices,2);
32754ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3276bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3277bef8e0ddSBarry Smith }
3278bef8e0ddSBarry Smith 
3279be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3280be6bf707SBarry Smith 
32817087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3282be6bf707SBarry Smith {
3283be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32846849ba73SBarry Smith   PetscErrorCode ierr;
3285d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3286be6bf707SBarry Smith 
3287be6bf707SBarry Smith   PetscFunctionBegin;
3288169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3289be6bf707SBarry Smith 
3290be6bf707SBarry Smith   /* allocate space for values if not already there */
3291be6bf707SBarry Smith   if (!aij->saved_values) {
3292854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32933bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3294be6bf707SBarry Smith   }
3295be6bf707SBarry Smith 
3296be6bf707SBarry Smith   /* copy values over */
329787828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3298be6bf707SBarry Smith   PetscFunctionReturn(0);
3299be6bf707SBarry Smith }
3300be6bf707SBarry Smith 
3301be6bf707SBarry Smith /*@
3302be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3303be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3304be6bf707SBarry Smith        nonlinear portion.
3305be6bf707SBarry Smith 
3306be6bf707SBarry Smith    Collect on Mat
3307be6bf707SBarry Smith 
3308be6bf707SBarry Smith   Input Parameters:
33090e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3310be6bf707SBarry Smith 
331115091d37SBarry Smith   Level: advanced
331215091d37SBarry Smith 
3313be6bf707SBarry Smith   Common Usage, with SNESSolve():
3314be6bf707SBarry Smith $    Create Jacobian matrix
3315be6bf707SBarry Smith $    Set linear terms into matrix
3316be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3317be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3318be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3319512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3320be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3321be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3322be6bf707SBarry Smith $    In your Jacobian routine
3323be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3324be6bf707SBarry Smith $      Set nonlinear terms in matrix
3325be6bf707SBarry Smith 
3326be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3327be6bf707SBarry Smith $    // build linear portion of Jacobian
3328512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3329be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3330be6bf707SBarry Smith $    loop over nonlinear iterations
3331be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3332be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3333be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3334be6bf707SBarry Smith $       Solve linear system with Jacobian
3335be6bf707SBarry Smith $    endloop
3336be6bf707SBarry Smith 
3337be6bf707SBarry Smith   Notes:
3338be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3339512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3340be6bf707SBarry Smith     calling this routine.
3341be6bf707SBarry Smith 
33420c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33430c468ba9SBarry Smith     and does not allocated additional space.
33440c468ba9SBarry Smith 
3345be6bf707SBarry Smith .seealso: MatRetrieveValues()
3346be6bf707SBarry Smith 
3347be6bf707SBarry Smith @*/
33487087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3349be6bf707SBarry Smith {
33504ac538c5SBarry Smith   PetscErrorCode ierr;
3351be6bf707SBarry Smith 
3352be6bf707SBarry Smith   PetscFunctionBegin;
33530700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3354e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3355e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33564ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3357be6bf707SBarry Smith   PetscFunctionReturn(0);
3358be6bf707SBarry Smith }
3359be6bf707SBarry Smith 
33607087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3361be6bf707SBarry Smith {
3362be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33636849ba73SBarry Smith   PetscErrorCode ierr;
3364d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3365be6bf707SBarry Smith 
3366be6bf707SBarry Smith   PetscFunctionBegin;
3367169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3368f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3369be6bf707SBarry Smith   /* copy values over */
337087828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3371be6bf707SBarry Smith   PetscFunctionReturn(0);
3372be6bf707SBarry Smith }
3373be6bf707SBarry Smith 
3374be6bf707SBarry Smith /*@
3375be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3376be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3377be6bf707SBarry Smith        nonlinear portion.
3378be6bf707SBarry Smith 
3379be6bf707SBarry Smith    Collect on Mat
3380be6bf707SBarry Smith 
3381be6bf707SBarry Smith   Input Parameters:
3382386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3383be6bf707SBarry Smith 
338415091d37SBarry Smith   Level: advanced
338515091d37SBarry Smith 
3386be6bf707SBarry Smith .seealso: MatStoreValues()
3387be6bf707SBarry Smith 
3388be6bf707SBarry Smith @*/
33897087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3390be6bf707SBarry Smith {
33914ac538c5SBarry Smith   PetscErrorCode ierr;
3392be6bf707SBarry Smith 
3393be6bf707SBarry Smith   PetscFunctionBegin;
33940700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3395e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3396e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33974ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3398be6bf707SBarry Smith   PetscFunctionReturn(0);
3399be6bf707SBarry Smith }
3400be6bf707SBarry Smith 
3401f83d6046SBarry Smith 
3402be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
340317ab2063SBarry Smith /*@C
3404682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34050d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34066e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
340751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34082bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
340917ab2063SBarry Smith 
3410db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3411db81eaa0SLois Curfman McInnes 
341217ab2063SBarry Smith    Input Parameters:
3413db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
341417ab2063SBarry Smith .  m - number of rows
341517ab2063SBarry Smith .  n - number of columns
341617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
341751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34180298fd71SBarry Smith          (possibly different for each row) or NULL
341917ab2063SBarry Smith 
342017ab2063SBarry Smith    Output Parameter:
3421416022c9SBarry Smith .  A - the matrix
342217ab2063SBarry Smith 
3423175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3424ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3425175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3426175b88e8SBarry Smith 
3427b259b22eSLois Curfman McInnes    Notes:
342849a6f317SBarry Smith    If nnz is given then nz is ignored
342949a6f317SBarry Smith 
343017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
343117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34320002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
343344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
343417ab2063SBarry Smith 
343517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34360298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34373d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34386da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
343917ab2063SBarry Smith 
3440682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34414fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3442682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34436c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34446c7ebb05SLois Curfman McInnes 
34456c7ebb05SLois Curfman McInnes    Options Database Keys:
3446698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34479db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
344817ab2063SBarry Smith 
3449027ccd11SLois Curfman McInnes    Level: intermediate
3450027ccd11SLois Curfman McInnes 
345169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
345236db0b34SBarry Smith 
345317ab2063SBarry Smith @*/
34547087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
345517ab2063SBarry Smith {
3456dfbe8321SBarry Smith   PetscErrorCode ierr;
34576945ee14SBarry Smith 
34583a40ed3dSBarry Smith   PetscFunctionBegin;
3459f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3460117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3461c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3462d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3463273d9f13SBarry Smith   PetscFunctionReturn(0);
3464273d9f13SBarry Smith }
3465273d9f13SBarry Smith 
3466273d9f13SBarry Smith /*@C
3467273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3468273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3469273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3470273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3471273d9f13SBarry Smith 
3472273d9f13SBarry Smith    Collective on MPI_Comm
3473273d9f13SBarry Smith 
3474273d9f13SBarry Smith    Input Parameters:
34751c4f3114SJed Brown +  B - The matrix
3476273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3477273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34780298fd71SBarry Smith          (possibly different for each row) or NULL
3479273d9f13SBarry Smith 
3480273d9f13SBarry Smith    Notes:
348149a6f317SBarry Smith      If nnz is given then nz is ignored
348249a6f317SBarry Smith 
3483273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3484273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3485273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3486273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3487273d9f13SBarry Smith 
3488273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34890298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3490273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3491273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3492273d9f13SBarry Smith 
3493aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3494aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3495aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3496aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3497aa95bbe8SBarry Smith 
3498a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3499a96a251dSBarry Smith    entries or columns indices
3500a96a251dSBarry Smith 
3501273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3502273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3503273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3504273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3505273d9f13SBarry Smith 
3506273d9f13SBarry Smith    Options Database Keys:
3507698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3508698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3509273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3510273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3511273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3512273d9f13SBarry Smith 
3513273d9f13SBarry Smith    Level: intermediate
3514273d9f13SBarry Smith 
351569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3516273d9f13SBarry Smith 
3517273d9f13SBarry Smith @*/
35187087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3519273d9f13SBarry Smith {
35204ac538c5SBarry Smith   PetscErrorCode ierr;
3521a23d5eceSKris Buschelman 
3522a23d5eceSKris Buschelman   PetscFunctionBegin;
35236ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35246ba663aaSJed Brown   PetscValidType(B,1);
35254ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3526a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3527a23d5eceSKris Buschelman }
3528a23d5eceSKris Buschelman 
35297087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3530a23d5eceSKris Buschelman {
3531273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35322576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35336849ba73SBarry Smith   PetscErrorCode ierr;
353497f1f81fSBarry Smith   PetscInt       i;
3535273d9f13SBarry Smith 
3536273d9f13SBarry Smith   PetscFunctionBegin;
35372576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3538a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3539c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3540c461c341SBarry Smith     nz             = 0;
3541c461c341SBarry Smith   }
354226283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
354326283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3544899cda47SBarry Smith 
3545435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
354660e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3547b73539f3SBarry Smith   if (nnz) {
3548d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
354960e0710aSBarry 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]);
355060e0710aSBarry 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);
3551b73539f3SBarry Smith     }
3552b73539f3SBarry Smith   }
3553b73539f3SBarry Smith 
3554273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35552205254eSKarl Rupp 
3556273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3557273d9f13SBarry Smith 
3558ab93d7beSBarry Smith   if (!skipallocation) {
35592ee49352SLisandro Dalcin     if (!b->imax) {
3560dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35613bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35622ee49352SLisandro Dalcin     }
3563273d9f13SBarry Smith     if (!nnz) {
3564435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3565c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3566d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3567d0f46423SBarry Smith       nz = nz*B->rmap->n;
3568273d9f13SBarry Smith     } else {
3569273d9f13SBarry Smith       nz = 0;
3570d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3571273d9f13SBarry Smith     }
3572ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35732205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3574ab93d7beSBarry Smith 
3575273d9f13SBarry Smith     /* allocate the matrix space */
357653dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35772ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3578396832f4SHong Zhang     if (B->structure_only) {
35795848002fSHong Zhang       ierr    = PetscMalloc1(nz,&b->j);CHKERRQ(ierr);
35805848002fSHong Zhang       ierr    = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr);
3581396832f4SHong Zhang       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr);
3582396832f4SHong Zhang     } else {
3583dcca6d9dSJed Brown       ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35843bb1ff40SBarry Smith       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3585396832f4SHong Zhang     }
3586bfeeae90SHong Zhang     b->i[0] = 0;
3587d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35885da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35895da197adSKris Buschelman     }
3590396832f4SHong Zhang     if (B->structure_only) {
3591396832f4SHong Zhang       b->singlemalloc = PETSC_FALSE;
3592396832f4SHong Zhang       b->free_a       = PETSC_FALSE;
3593396832f4SHong Zhang     } else {
3594273d9f13SBarry Smith       b->singlemalloc = PETSC_TRUE;
3595e6b907acSBarry Smith       b->free_a       = PETSC_TRUE;
3596396832f4SHong Zhang     }
3597e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3598c461c341SBarry Smith   } else {
3599e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3600e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3601c461c341SBarry Smith   }
3602273d9f13SBarry Smith 
3603273d9f13SBarry Smith   b->nz               = 0;
3604273d9f13SBarry Smith   b->maxnz            = nz;
3605273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36062205254eSKarl Rupp   if (realalloc) {
36072205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36082205254eSKarl Rupp   }
3609cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3610cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3611273d9f13SBarry Smith   PetscFunctionReturn(0);
3612273d9f13SBarry Smith }
3613273d9f13SBarry Smith 
361458d36128SBarry Smith /*@
3615a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3616a1661176SMatthew Knepley 
3617a1661176SMatthew Knepley    Input Parameters:
3618a1661176SMatthew Knepley +  B - the matrix
3619a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3620a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3621a1661176SMatthew Knepley -  v - optional values in the matrix
3622a1661176SMatthew Knepley 
3623a1661176SMatthew Knepley    Level: developer
3624a1661176SMatthew Knepley 
362558d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
362658d36128SBarry Smith 
3627a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3628a1661176SMatthew Knepley 
3629a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3630a1661176SMatthew Knepley @*/
3631a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3632a1661176SMatthew Knepley {
3633a1661176SMatthew Knepley   PetscErrorCode ierr;
3634a1661176SMatthew Knepley 
3635a1661176SMatthew Knepley   PetscFunctionBegin;
36360700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36376ba663aaSJed Brown   PetscValidType(B,1);
36384ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3639a1661176SMatthew Knepley   PetscFunctionReturn(0);
3640a1661176SMatthew Knepley }
3641a1661176SMatthew Knepley 
36427087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3643a1661176SMatthew Knepley {
3644a1661176SMatthew Knepley   PetscInt       i;
3645a1661176SMatthew Knepley   PetscInt       m,n;
3646a1661176SMatthew Knepley   PetscInt       nz;
3647a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3648a1661176SMatthew Knepley   PetscScalar    *values;
3649a1661176SMatthew Knepley   PetscErrorCode ierr;
3650a1661176SMatthew Knepley 
3651a1661176SMatthew Knepley   PetscFunctionBegin;
365265e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3653779a8d59SSatish Balay 
3654779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3655779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3656779a8d59SSatish Balay 
3657779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3658854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3659a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3660b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3661a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
366265e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3663a1661176SMatthew Knepley     nnz[i] = nz;
3664a1661176SMatthew Knepley   }
3665a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3666a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3667a1661176SMatthew Knepley 
3668a1661176SMatthew Knepley   if (v) {
3669a1661176SMatthew Knepley     values = (PetscScalar*) v;
3670a1661176SMatthew Knepley   } else {
36711795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3672a1661176SMatthew Knepley   }
3673a1661176SMatthew Knepley 
3674a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3675b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3676b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3677a1661176SMatthew Knepley   }
3678a1661176SMatthew Knepley 
3679a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3680a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3681a1661176SMatthew Knepley 
3682a1661176SMatthew Knepley   if (!v) {
3683a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3684a1661176SMatthew Knepley   }
36857827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3686a1661176SMatthew Knepley   PetscFunctionReturn(0);
3687a1661176SMatthew Knepley }
3688a1661176SMatthew Knepley 
3689c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3690af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3691170fe5c8SBarry Smith 
3692170fe5c8SBarry Smith /*
3693170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3694170fe5c8SBarry Smith 
3695170fe5c8SBarry Smith                n                       p                          p
3696170fe5c8SBarry Smith         (              )       (              )         (                  )
3697170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3698170fe5c8SBarry Smith         (              )       (              )         (                  )
3699170fe5c8SBarry Smith 
3700170fe5c8SBarry Smith */
3701170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3702170fe5c8SBarry Smith {
3703170fe5c8SBarry Smith   PetscErrorCode    ierr;
3704170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3705170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3706170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37071de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3708170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3709170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3710170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3711170fe5c8SBarry Smith 
3712170fe5c8SBarry Smith   PetscFunctionBegin;
3713d0f46423SBarry Smith   m    = A->rmap->n;
3714d0f46423SBarry Smith   n    = A->cmap->n;
3715d0f46423SBarry Smith   p    = B->cmap->n;
3716170fe5c8SBarry Smith   a    = sub_a->v;
3717170fe5c8SBarry Smith   b    = sub_b->a;
3718170fe5c8SBarry Smith   c    = sub_c->v;
3719170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3720170fe5c8SBarry Smith 
3721170fe5c8SBarry Smith   ii  = sub_b->i;
3722170fe5c8SBarry Smith   idx = sub_b->j;
3723170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3724170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3725170fe5c8SBarry Smith     while (q-->0) {
3726170fe5c8SBarry Smith       c_q = c + m*(*idx);
3727170fe5c8SBarry Smith       a_q = a + m*i;
3728854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3729170fe5c8SBarry Smith       idx++;
3730170fe5c8SBarry Smith       b++;
3731170fe5c8SBarry Smith     }
3732170fe5c8SBarry Smith   }
3733170fe5c8SBarry Smith   PetscFunctionReturn(0);
3734170fe5c8SBarry Smith }
3735170fe5c8SBarry Smith 
3736170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3737170fe5c8SBarry Smith {
3738170fe5c8SBarry Smith   PetscErrorCode ierr;
3739d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3740170fe5c8SBarry Smith   Mat            Cmat;
3741170fe5c8SBarry Smith 
3742170fe5c8SBarry Smith   PetscFunctionBegin;
374360e0710aSBarry 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);
3744ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3745170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
374633d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3747170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37480298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3749d73949e8SHong Zhang 
3750d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37512205254eSKarl Rupp 
3752170fe5c8SBarry Smith   *C = Cmat;
3753170fe5c8SBarry Smith   PetscFunctionReturn(0);
3754170fe5c8SBarry Smith }
3755170fe5c8SBarry Smith 
3756170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3757150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3758170fe5c8SBarry Smith {
3759170fe5c8SBarry Smith   PetscErrorCode ierr;
3760170fe5c8SBarry Smith 
3761170fe5c8SBarry Smith   PetscFunctionBegin;
3762170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37633ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3764170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37653ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3766170fe5c8SBarry Smith   }
37673ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3768170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37693ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3770170fe5c8SBarry Smith   PetscFunctionReturn(0);
3771170fe5c8SBarry Smith }
3772170fe5c8SBarry Smith 
3773170fe5c8SBarry Smith 
37740bad9183SKris Buschelman /*MC
3775fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37760bad9183SKris Buschelman    based on compressed sparse row format.
37770bad9183SKris Buschelman 
37780bad9183SKris Buschelman    Options Database Keys:
37790bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37800bad9183SKris Buschelman 
37810bad9183SKris Buschelman   Level: beginner
37820bad9183SKris Buschelman 
3783f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37840bad9183SKris Buschelman M*/
37850bad9183SKris Buschelman 
3786ccd284c7SBarry Smith /*MC
3787ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3788ccd284c7SBarry Smith 
3789ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3790ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3791ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3792ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3793ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3794ccd284c7SBarry Smith 
3795ccd284c7SBarry Smith    Options Database Keys:
3796ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3797ccd284c7SBarry Smith 
3798ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3799ccd284c7SBarry Smith    enough exist.
3800ccd284c7SBarry Smith 
3801ccd284c7SBarry Smith   Level: beginner
3802ccd284c7SBarry Smith 
3803ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3804ccd284c7SBarry Smith M*/
3805ccd284c7SBarry Smith 
3806ccd284c7SBarry Smith /*MC
3807ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3808ccd284c7SBarry Smith 
3809ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3810ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3811ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3812ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3813ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3814ccd284c7SBarry Smith 
3815ccd284c7SBarry Smith    Options Database Keys:
3816ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3817ccd284c7SBarry Smith 
3818ccd284c7SBarry Smith   Level: beginner
3819ccd284c7SBarry Smith 
3820ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3821ccd284c7SBarry Smith M*/
3822ccd284c7SBarry Smith 
3823cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3824af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3825cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3826af8000cdSHong Zhang #endif
382763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
382863c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
38293dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
383063c07aadSStefano Zampini #endif
3831cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
383242c9c57cSBarry Smith 
3833b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
383429b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
383529b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3836b3866ffcSBarry Smith #endif
383717667f90SBarry Smith 
3838c0c8ee5eSDmitry Karpeev 
38398c778c55SBarry Smith /*@C
38408397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38418c778c55SBarry Smith 
38428c778c55SBarry Smith    Not Collective
38438c778c55SBarry Smith 
38448c778c55SBarry Smith    Input Parameter:
3845579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38468c778c55SBarry Smith 
38478c778c55SBarry Smith    Output Parameter:
38488c778c55SBarry Smith .   array - pointer to the data
38498c778c55SBarry Smith 
38508c778c55SBarry Smith    Level: intermediate
38518c778c55SBarry Smith 
3852774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38538c778c55SBarry Smith @*/
38548c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38558c778c55SBarry Smith {
38568c778c55SBarry Smith   PetscErrorCode ierr;
38578c778c55SBarry Smith 
38588c778c55SBarry Smith   PetscFunctionBegin;
38598c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38608c778c55SBarry Smith   PetscFunctionReturn(0);
38618c778c55SBarry Smith }
38628c778c55SBarry Smith 
386321e72a00SBarry Smith /*@C
386421e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
386521e72a00SBarry Smith 
386621e72a00SBarry Smith    Not Collective
386721e72a00SBarry Smith 
386821e72a00SBarry Smith    Input Parameter:
3869579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
387021e72a00SBarry Smith 
387121e72a00SBarry Smith    Output Parameter:
387221e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
387321e72a00SBarry Smith 
387421e72a00SBarry Smith    Level: intermediate
387521e72a00SBarry Smith 
387621e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
387721e72a00SBarry Smith @*/
387821e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
387921e72a00SBarry Smith {
388021e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
388121e72a00SBarry Smith 
388221e72a00SBarry Smith   PetscFunctionBegin;
388321e72a00SBarry Smith   *nz = aij->rmax;
388421e72a00SBarry Smith   PetscFunctionReturn(0);
388521e72a00SBarry Smith }
388621e72a00SBarry Smith 
38878c778c55SBarry Smith /*@C
3888579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38898c778c55SBarry Smith 
38908c778c55SBarry Smith    Not Collective
38918c778c55SBarry Smith 
38928c778c55SBarry Smith    Input Parameters:
3893579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38948c778c55SBarry Smith .  array - pointer to the data
38958c778c55SBarry Smith 
38968c778c55SBarry Smith    Level: intermediate
38978c778c55SBarry Smith 
3898774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
38998c778c55SBarry Smith @*/
39008c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39018c778c55SBarry Smith {
39028c778c55SBarry Smith   PetscErrorCode ierr;
39038c778c55SBarry Smith 
39048c778c55SBarry Smith   PetscFunctionBegin;
39058c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39068c778c55SBarry Smith   PetscFunctionReturn(0);
39078c778c55SBarry Smith }
39088c778c55SBarry Smith 
39098cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3910273d9f13SBarry Smith {
3911273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3912dfbe8321SBarry Smith   PetscErrorCode ierr;
391338baddfdSBarry Smith   PetscMPIInt    size;
3914273d9f13SBarry Smith 
3915273d9f13SBarry Smith   PetscFunctionBegin;
3916ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3917e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3918273d9f13SBarry Smith 
3919b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39202205254eSKarl Rupp 
3921b0a32e0cSBarry Smith   B->data = (void*)b;
39222205254eSKarl Rupp 
3923549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39242205254eSKarl Rupp 
3925416022c9SBarry Smith   b->row                = 0;
3926416022c9SBarry Smith   b->col                = 0;
392782bf6240SBarry Smith   b->icol               = 0;
3928b810aeb4SBarry Smith   b->reallocs           = 0;
392936db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3930f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3931416022c9SBarry Smith   b->nonew              = 0;
3932416022c9SBarry Smith   b->diag               = 0;
3933416022c9SBarry Smith   b->solve_work         = 0;
39342a1b7f2aSHong Zhang   B->spptr              = 0;
3935be6bf707SBarry Smith   b->saved_values       = 0;
3936d7f994e1SBarry Smith   b->idiag              = 0;
393771f1c65dSBarry Smith   b->mdiag              = 0;
393871f1c65dSBarry Smith   b->ssor_work          = 0;
393971f1c65dSBarry Smith   b->omega              = 1.0;
394071f1c65dSBarry Smith   b->fshift             = 0.0;
394171f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3942bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3943a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
394417ab2063SBarry Smith 
394535d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3946bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3947bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39488c778c55SBarry Smith 
3949b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3950bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3951bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3952b3866ffcSBarry Smith #endif
395317f1a0eaSHong Zhang 
3954bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3955bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3956bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3957bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3958bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3959bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3960bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3961af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3962af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3963af8000cdSHong Zhang #endif
396463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
396563c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39663dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
396763c07aadSStefano Zampini #endif
3968b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3969bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3970bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3971bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3972bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3973bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3974bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3975bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3976bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39774108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
397817667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39793a40ed3dSBarry Smith   PetscFunctionReturn(0);
398017ab2063SBarry Smith }
398117ab2063SBarry Smith 
3982b24902e0SBarry Smith /*
3983b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3984b24902e0SBarry Smith */
3985ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
398617ab2063SBarry Smith {
3987416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39886849ba73SBarry Smith   PetscErrorCode ierr;
3989d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
399017ab2063SBarry Smith 
39913a40ed3dSBarry Smith   PetscFunctionBegin;
3992273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3993273d9f13SBarry Smith 
3994d5f3da31SBarry Smith   C->factortype = A->factortype;
3995416022c9SBarry Smith   c->row        = 0;
3996416022c9SBarry Smith   c->col        = 0;
399782bf6240SBarry Smith   c->icol       = 0;
39986ad4291fSHong Zhang   c->reallocs   = 0;
399917ab2063SBarry Smith 
40006ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
400117ab2063SBarry Smith 
4002aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4003aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4004eec197d1SBarry Smith 
4005dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40063bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
400717ab2063SBarry Smith   for (i=0; i<m; i++) {
4008416022c9SBarry Smith     c->imax[i] = a->imax[i];
4009416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
401017ab2063SBarry Smith   }
401117ab2063SBarry Smith 
401217ab2063SBarry Smith   /* allocate the matrix space */
4013f77e22a1SHong Zhang   if (mallocmatspace) {
4014dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40153bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40162205254eSKarl Rupp 
4017f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40182205254eSKarl Rupp 
401997f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
402017ab2063SBarry Smith     if (m > 0) {
402197f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4022be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4023bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4024be6bf707SBarry Smith       } else {
4025bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
402617ab2063SBarry Smith       }
402708480c60SBarry Smith     }
4028f77e22a1SHong Zhang   }
402917ab2063SBarry Smith 
40306ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4031416022c9SBarry Smith   c->roworiented       = a->roworiented;
4032416022c9SBarry Smith   c->nonew             = a->nonew;
4033416022c9SBarry Smith   if (a->diag) {
4034854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
40353bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
403617ab2063SBarry Smith     for (i=0; i<m; i++) {
4037416022c9SBarry Smith       c->diag[i] = a->diag[i];
403817ab2063SBarry Smith     }
40393a40ed3dSBarry Smith   } else c->diag = 0;
40402205254eSKarl Rupp 
40416ad4291fSHong Zhang   c->solve_work         = 0;
40426ad4291fSHong Zhang   c->saved_values       = 0;
40436ad4291fSHong Zhang   c->idiag              = 0;
404471f1c65dSBarry Smith   c->ssor_work          = 0;
4045a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4046e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4047e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40486ad4291fSHong Zhang 
4049893ad86cSHong Zhang   c->rmax         = a->rmax;
4050416022c9SBarry Smith   c->nz           = a->nz;
40518ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4052273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4053754ec7b1SSatish Balay 
40546ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40556ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4056cd6b891eSBarry Smith   if (a->compressedrow.use) {
40576ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4058dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40596ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40606ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
406127ea64f8SHong Zhang   } else {
406227ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40630298fd71SBarry Smith     c->compressedrow.i      = NULL;
40640298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40656ad4291fSHong Zhang   }
4066ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4067e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40684846f1f5SKris Buschelman 
40692205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4070140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40713a40ed3dSBarry Smith   PetscFunctionReturn(0);
407217ab2063SBarry Smith }
407317ab2063SBarry Smith 
4074b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4075b24902e0SBarry Smith {
4076b24902e0SBarry Smith   PetscErrorCode ierr;
4077b24902e0SBarry Smith 
4078b24902e0SBarry Smith   PetscFunctionBegin;
4079ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40804b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4081cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
408233d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4083cfd3f464SBarry Smith   }
4084a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4085f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4086b24902e0SBarry Smith   PetscFunctionReturn(0);
4087b24902e0SBarry Smith }
4088b24902e0SBarry Smith 
4089112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4090fbdbba38SShri Abhyankar {
4091fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4092fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4093fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4094fbdbba38SShri Abhyankar   int            fd;
4095fbdbba38SShri Abhyankar   PetscMPIInt    size;
4096fbdbba38SShri Abhyankar   MPI_Comm       comm;
40973059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4098fbdbba38SShri Abhyankar 
4099fbdbba38SShri Abhyankar   PetscFunctionBegin;
4100c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4101c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4102fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4103fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4104fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4105bbead8a2SBarry Smith 
41060298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41070298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4108bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41093059b6faSBarry Smith   if (bs < 0) bs = 1;
41103059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4111bbead8a2SBarry Smith 
4112fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4113fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4114fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4115fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4116fbdbba38SShri Abhyankar 
4117bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4118fbdbba38SShri Abhyankar 
4119fbdbba38SShri Abhyankar   /* read in row lengths */
4120785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4121fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4122fbdbba38SShri Abhyankar 
4123fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4124fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
412560e0710aSBarry 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);
4126fbdbba38SShri Abhyankar 
4127fbdbba38SShri Abhyankar   /* set global size if not set already*/
4128f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4129fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4130aabbc4fbSShri Abhyankar   } else {
41319d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4132fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41334c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41344c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41354c5b953cSHong Zhang     }
413660e0710aSBarry 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);
4137aabbc4fbSShri Abhyankar   }
4138fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4139fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4140fbdbba38SShri Abhyankar 
4141fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4142fbdbba38SShri Abhyankar 
4143fbdbba38SShri Abhyankar   /* read in nonzero values */
4144fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4145fbdbba38SShri Abhyankar 
4146fbdbba38SShri Abhyankar   /* set matrix "i" values */
4147fbdbba38SShri Abhyankar   a->i[0] = 0;
4148fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4149fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4150fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4151fbdbba38SShri Abhyankar   }
4152fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4153fbdbba38SShri Abhyankar 
4154fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4155fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4156fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4157fbdbba38SShri Abhyankar }
4158fbdbba38SShri Abhyankar 
4159ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41607264ac53SSatish Balay {
41617264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4162dfbe8321SBarry Smith   PetscErrorCode ierr;
4163eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4164eeffb40dSHong Zhang   PetscInt k;
4165eeffb40dSHong Zhang #endif
41667264ac53SSatish Balay 
41673a40ed3dSBarry Smith   PetscFunctionBegin;
4168bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4169d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4170ca44d042SBarry Smith     *flg = PETSC_FALSE;
4171ca44d042SBarry Smith     PetscFunctionReturn(0);
4172bcd2baecSBarry Smith   }
41737264ac53SSatish Balay 
41747264ac53SSatish Balay   /* if the a->i are the same */
4175d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4176abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41777264ac53SSatish Balay 
41787264ac53SSatish Balay   /* if a->j are the same */
417997f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4180abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4181bcd2baecSBarry Smith 
4182bcd2baecSBarry Smith   /* if a->a are the same */
4183eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4184eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4185eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4186eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41873a40ed3dSBarry Smith       PetscFunctionReturn(0);
4188eeffb40dSHong Zhang     }
4189eeffb40dSHong Zhang   }
4190eeffb40dSHong Zhang #else
4191eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4192eeffb40dSHong Zhang #endif
4193eeffb40dSHong Zhang   PetscFunctionReturn(0);
41947264ac53SSatish Balay }
419536db0b34SBarry Smith 
419605869f15SSatish Balay /*@
419736db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
419836db0b34SBarry Smith               provided by the user.
419936db0b34SBarry Smith 
4200c75a6043SHong Zhang       Collective on MPI_Comm
420136db0b34SBarry Smith 
420236db0b34SBarry Smith    Input Parameters:
420336db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
420436db0b34SBarry Smith .   m - number of rows
420536db0b34SBarry Smith .   n - number of columns
420636db0b34SBarry Smith .   i - row indices
420736db0b34SBarry Smith .   j - column indices
420836db0b34SBarry Smith -   a - matrix values
420936db0b34SBarry Smith 
421036db0b34SBarry Smith    Output Parameter:
421136db0b34SBarry Smith .   mat - the matrix
421236db0b34SBarry Smith 
421336db0b34SBarry Smith    Level: intermediate
421436db0b34SBarry Smith 
421536db0b34SBarry Smith    Notes:
42160551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4217292fb18eSBarry Smith     once the matrix is destroyed and not before
421836db0b34SBarry Smith 
421936db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
422036db0b34SBarry Smith 
4221bfeeae90SHong Zhang        The i and j indices are 0 based
422236db0b34SBarry Smith 
4223a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4224a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
42258eef79e4SBarry Smith     as shown
4226a4552177SSatish Balay 
42278eef79e4SBarry Smith $        1 0 0
42288eef79e4SBarry Smith $        2 0 3
42298eef79e4SBarry Smith $        4 5 6
42308eef79e4SBarry Smith $
42318eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42328eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
42338eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4234a4552177SSatish Balay 
42359985e31cSBarry Smith 
423669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
423736db0b34SBarry Smith 
423836db0b34SBarry Smith @*/
4239c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
424036db0b34SBarry Smith {
4241dfbe8321SBarry Smith   PetscErrorCode ierr;
4242cbcfb4deSHong Zhang   PetscInt       ii;
424336db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4244cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4245cbcfb4deSHong Zhang   PetscInt jj;
4246cbcfb4deSHong Zhang #endif
424736db0b34SBarry Smith 
424836db0b34SBarry Smith   PetscFunctionBegin;
424941096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4250f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4251f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4252a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4253ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4254ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4255ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4256dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4257ab93d7beSBarry Smith 
425836db0b34SBarry Smith   aij->i            = i;
425936db0b34SBarry Smith   aij->j            = j;
426036db0b34SBarry Smith   aij->a            = a;
426136db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
426236db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4263e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4264e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
426536db0b34SBarry Smith 
426636db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
426736db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42682515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
426960e0710aSBarry 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]);
42709985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4271e32f2f54SBarry 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);
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 identical to previous entry",jj-i[ii],j[jj],ii);
42739985e31cSBarry Smith     }
427436db0b34SBarry Smith #endif
427536db0b34SBarry Smith   }
42762515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
427736db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
427860e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
427960e0710aSBarry 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]);
428036db0b34SBarry Smith   }
428136db0b34SBarry Smith #endif
428236db0b34SBarry Smith 
4283b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4284b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
428536db0b34SBarry Smith   PetscFunctionReturn(0);
428636db0b34SBarry Smith }
428780ef6e79SMatthew G Knepley /*@C
4288d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42898a0b0e6bSVictor Minden               provided by the user.
42908a0b0e6bSVictor Minden 
42918a0b0e6bSVictor Minden       Collective on MPI_Comm
42928a0b0e6bSVictor Minden 
42938a0b0e6bSVictor Minden    Input Parameters:
42948a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42958a0b0e6bSVictor Minden .   m   - number of rows
42968a0b0e6bSVictor Minden .   n   - number of columns
42978a0b0e6bSVictor Minden .   i   - row indices
42988a0b0e6bSVictor Minden .   j   - column indices
42991230e6d1SVictor Minden .   a   - matrix values
43001230e6d1SVictor Minden .   nz  - number of nonzeros
43011230e6d1SVictor Minden -   idx - 0 or 1 based
43028a0b0e6bSVictor Minden 
43038a0b0e6bSVictor Minden    Output Parameter:
43048a0b0e6bSVictor Minden .   mat - the matrix
43058a0b0e6bSVictor Minden 
43068a0b0e6bSVictor Minden    Level: intermediate
43078a0b0e6bSVictor Minden 
43088a0b0e6bSVictor Minden    Notes:
43098a0b0e6bSVictor Minden        The i and j indices are 0 based
43108a0b0e6bSVictor Minden 
43118a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43128a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43138a0b0e6bSVictor Minden     as shown:
43148a0b0e6bSVictor Minden 
43158a0b0e6bSVictor Minden         1 0 0
43168a0b0e6bSVictor Minden         2 0 3
43178a0b0e6bSVictor Minden         4 5 6
43188a0b0e6bSVictor Minden 
43198a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43208a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43218a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43228a0b0e6bSVictor Minden 
43238a0b0e6bSVictor Minden 
432469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43258a0b0e6bSVictor Minden 
43268a0b0e6bSVictor Minden @*/
4327c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
43288a0b0e6bSVictor Minden {
43298a0b0e6bSVictor Minden   PetscErrorCode ierr;
4330d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43318a0b0e6bSVictor Minden 
43328a0b0e6bSVictor Minden 
43338a0b0e6bSVictor Minden   PetscFunctionBegin;
43341795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
43351230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4336c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
43371230e6d1SVictor Minden   }
43388a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43398a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43408a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43411230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43421230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43431230e6d1SVictor Minden     if (idx) {
43441230e6d1SVictor Minden       row = i[ii] - 1;
43451230e6d1SVictor Minden       col = j[ii] - 1;
43461230e6d1SVictor Minden     } else {
43471230e6d1SVictor Minden       row = i[ii];
43481230e6d1SVictor Minden       col = j[ii];
43498a0b0e6bSVictor Minden     }
43501230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43518a0b0e6bSVictor Minden   }
43528a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43538a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4354d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43558a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43568a0b0e6bSVictor Minden }
435736db0b34SBarry Smith 
4358acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4359acf2f550SJed Brown {
4360acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4361acf2f550SJed Brown   PetscErrorCode ierr;
4362acf2f550SJed Brown 
4363acf2f550SJed Brown   PetscFunctionBegin;
4364acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4365acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43662205254eSKarl Rupp 
4367acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4368acf2f550SJed Brown   PetscFunctionReturn(0);
4369acf2f550SJed Brown }
4370acf2f550SJed Brown 
43719c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43729c8f2541SHong Zhang {
43739c8f2541SHong Zhang   PetscErrorCode ierr;
43748761c3d6SHong Zhang   PetscMPIInt    size;
43759c8f2541SHong Zhang 
43769c8f2541SHong Zhang   PetscFunctionBegin;
43778761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43788761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43798761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43808761c3d6SHong Zhang   } else {
43819c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43828761c3d6SHong Zhang   }
43839c8f2541SHong Zhang   PetscFunctionReturn(0);
43849c8f2541SHong Zhang }
43859c8f2541SHong Zhang 
438681824310SBarry Smith /*
438753dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
438853dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
438953dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
439053dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
439153dd7562SDmitry Karpeev  */
439253dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
439353dd7562SDmitry Karpeev {
439453dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
439553dd7562SDmitry Karpeev   PetscErrorCode ierr;
439653dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
439753dd7562SDmitry Karpeev   PetscBool      seqaij;
439853dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
439953dd7562SDmitry Karpeev   PetscScalar    v;
440053dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
440153dd7562SDmitry Karpeev 
440253dd7562SDmitry Karpeev   PetscFunctionBegin;
440353dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
440453dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
440553dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
440653dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
440753dd7562SDmitry Karpeev   if (rowemb) {
440853dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
440953dd7562SDmitry 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);
441053dd7562SDmitry Karpeev   } else {
44116c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
441253dd7562SDmitry Karpeev   }
441353dd7562SDmitry Karpeev   if (colemb) {
441453dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
441553dd7562SDmitry 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);
441653dd7562SDmitry Karpeev   } else {
441753dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
441853dd7562SDmitry Karpeev   }
441953dd7562SDmitry Karpeev 
442053dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
442153dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
442253dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
442353dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
442453dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
442553dd7562SDmitry Karpeev     }
442653dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
442753dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
442853dd7562SDmitry Karpeev   }
442953dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
443053dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
443153dd7562SDmitry Karpeev   }
443253dd7562SDmitry Karpeev   count = 0;
443353dd7562SDmitry Karpeev   rowindices = NULL;
443453dd7562SDmitry Karpeev   colindices = NULL;
443553dd7562SDmitry Karpeev   if (rowemb) {
443653dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
443753dd7562SDmitry Karpeev   }
443853dd7562SDmitry Karpeev   if (colemb) {
443953dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
444053dd7562SDmitry Karpeev   }
444153dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
444253dd7562SDmitry Karpeev     PetscInt row;
444353dd7562SDmitry Karpeev     row = i;
444453dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
444553dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
444653dd7562SDmitry Karpeev       PetscInt col;
444753dd7562SDmitry Karpeev       col  = Baij->j[count];
444853dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
444953dd7562SDmitry Karpeev       v    = Baij->a[count];
445053dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
445153dd7562SDmitry Karpeev       ++count;
445253dd7562SDmitry Karpeev     }
445353dd7562SDmitry Karpeev   }
445453dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
445553dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
445653dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
445753dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
445853dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
445953dd7562SDmitry Karpeev   PetscFunctionReturn(0);
446053dd7562SDmitry Karpeev }
446153dd7562SDmitry Karpeev 
446253dd7562SDmitry Karpeev 
446353dd7562SDmitry Karpeev /*
446481824310SBarry Smith     Special version for direct calls from Fortran
446581824310SBarry Smith */
4466af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
446781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
446881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
446981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
447081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
447181824310SBarry Smith #endif
447281824310SBarry Smith 
447381824310SBarry Smith /* Change these macros so can be used in void function */
447481824310SBarry Smith #undef CHKERRQ
4475ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
447681824310SBarry Smith #undef SETERRQ2
4477e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44784994cf47SJed Brown #undef SETERRQ3
44794994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
448081824310SBarry Smith 
44818cc058d9SJed 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)
448281824310SBarry Smith {
448381824310SBarry Smith   Mat            A  = *AA;
448481824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
448581824310SBarry Smith   InsertMode     is = *isis;
448681824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
448781824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
448881824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
448981824310SBarry Smith   PetscErrorCode ierr;
449081824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
449154f21887SBarry Smith   MatScalar      *ap,value,*aa;
4492ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4493ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
449481824310SBarry Smith 
449581824310SBarry Smith   PetscFunctionBegin;
44964994cf47SJed Brown   MatCheckPreallocated(A,1);
449781824310SBarry Smith   imax  = a->imax;
449881824310SBarry Smith   ai    = a->i;
449981824310SBarry Smith   ailen = a->ilen;
450081824310SBarry Smith   aj    = a->j;
450181824310SBarry Smith   aa    = a->a;
450281824310SBarry Smith 
450381824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
450481824310SBarry Smith     row = im[k];
450581824310SBarry Smith     if (row < 0) continue;
450681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4507ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
450881824310SBarry Smith #endif
450981824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
451081824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
451181824310SBarry Smith     low  = 0;
451281824310SBarry Smith     high = nrow;
451381824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
451481824310SBarry Smith       if (in[l] < 0) continue;
451581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4516ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
451781824310SBarry Smith #endif
451881824310SBarry Smith       col = in[l];
45192205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45202205254eSKarl Rupp       else value = v[k + l*m];
45212205254eSKarl Rupp 
452281824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
452381824310SBarry Smith 
45242205254eSKarl Rupp       if (col <= lastcol) low = 0;
45252205254eSKarl Rupp       else high = nrow;
452681824310SBarry Smith       lastcol = col;
452781824310SBarry Smith       while (high-low > 5) {
452881824310SBarry Smith         t = (low+high)/2;
452981824310SBarry Smith         if (rp[t] > col) high = t;
453081824310SBarry Smith         else             low  = t;
453181824310SBarry Smith       }
453281824310SBarry Smith       for (i=low; i<high; i++) {
453381824310SBarry Smith         if (rp[i] > col) break;
453481824310SBarry Smith         if (rp[i] == col) {
453581824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
453681824310SBarry Smith           else                  ap[i] = value;
453781824310SBarry Smith           goto noinsert;
453881824310SBarry Smith         }
453981824310SBarry Smith       }
454081824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
454181824310SBarry Smith       if (nonew == 1) goto noinsert;
4542ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4543fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
454481824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
454581824310SBarry Smith       /* shift up all the later entries in this row */
454681824310SBarry Smith       for (ii=N; ii>=i; ii--) {
454781824310SBarry Smith         rp[ii+1] = rp[ii];
454881824310SBarry Smith         ap[ii+1] = ap[ii];
454981824310SBarry Smith       }
455081824310SBarry Smith       rp[i] = col;
455181824310SBarry Smith       ap[i] = value;
4552e56f5c9eSBarry Smith       A->nonzerostate++;
455381824310SBarry Smith noinsert:;
455481824310SBarry Smith       low = i + 1;
455581824310SBarry Smith     }
455681824310SBarry Smith     ailen[row] = nrow;
455781824310SBarry Smith   }
455881824310SBarry Smith   PetscFunctionReturnVoid();
455981824310SBarry Smith }
45609f7953f8SBarry Smith 
4561