xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 876c6284d71f19a3dafb664beac5b5663a154d27)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h>
120716a85fSBarry Smith 
130716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
140716a85fSBarry Smith {
150716a85fSBarry Smith   PetscErrorCode ierr;
160716a85fSBarry Smith   PetscInt       i,m,n;
170716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
180716a85fSBarry Smith 
190716a85fSBarry Smith   PetscFunctionBegin;
200716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
210716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
220716a85fSBarry Smith   if (type == NORM_2) {
230716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
240716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
250716a85fSBarry Smith     }
260716a85fSBarry Smith   } else if (type == NORM_1) {
270716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
280716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
290716a85fSBarry Smith     }
300716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
310716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
320716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
330716a85fSBarry Smith     }
340716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
350716a85fSBarry Smith 
360716a85fSBarry Smith   if (type == NORM_2) {
378f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
380716a85fSBarry Smith   }
390716a85fSBarry Smith   PetscFunctionReturn(0);
400716a85fSBarry Smith }
410716a85fSBarry Smith 
423a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
433a062f41SBarry Smith {
443a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
453a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
463a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
473a062f41SBarry Smith   PetscInt        *rows;
483a062f41SBarry Smith   PetscErrorCode  ierr;
493a062f41SBarry Smith 
503a062f41SBarry Smith   PetscFunctionBegin;
513a062f41SBarry Smith   for (i=0; i<m; i++) {
523a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
533a062f41SBarry Smith       cnt++;
543a062f41SBarry Smith     }
553a062f41SBarry Smith   }
563a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
573a062f41SBarry Smith   cnt  = 0;
583a062f41SBarry Smith   for (i=0; i<m; i++) {
593a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
603a062f41SBarry Smith       rows[cnt] = i;
613a062f41SBarry Smith       cnt++;
623a062f41SBarry Smith     }
633a062f41SBarry Smith   }
643a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
653a062f41SBarry Smith   PetscFunctionReturn(0);
663a062f41SBarry Smith }
673a062f41SBarry Smith 
68f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
696ce1633cSBarry Smith {
706ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
716ce1633cSBarry Smith   const MatScalar *aa = a->a;
726ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
73b2db7409Sstefano_zampini   const PetscInt  *ii = a->i,*jj = a->j,*diag;
746ce1633cSBarry Smith   PetscInt        *rows;
756ce1633cSBarry Smith   PetscErrorCode  ierr;
766ce1633cSBarry Smith 
776ce1633cSBarry Smith   PetscFunctionBegin;
786ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
796ce1633cSBarry Smith   diag = a->diag;
806ce1633cSBarry Smith   for (i=0; i<m; i++) {
81b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
826ce1633cSBarry Smith       cnt++;
836ce1633cSBarry Smith     }
846ce1633cSBarry Smith   }
85785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
866ce1633cSBarry Smith   cnt  = 0;
876ce1633cSBarry Smith   for (i=0; i<m; i++) {
88b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
896ce1633cSBarry Smith       rows[cnt++] = i;
906ce1633cSBarry Smith     }
916ce1633cSBarry Smith   }
92f1f41ecbSJed Brown   *nrows = cnt;
93f1f41ecbSJed Brown   *zrows = rows;
94f1f41ecbSJed Brown   PetscFunctionReturn(0);
95f1f41ecbSJed Brown }
96f1f41ecbSJed Brown 
97f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
98f1f41ecbSJed Brown {
99f1f41ecbSJed Brown   PetscInt       nrows,*rows;
100f1f41ecbSJed Brown   PetscErrorCode ierr;
101f1f41ecbSJed Brown 
102f1f41ecbSJed Brown   PetscFunctionBegin;
1030298fd71SBarry Smith   *zrows = NULL;
104f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
105ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1066ce1633cSBarry Smith   PetscFunctionReturn(0);
1076ce1633cSBarry Smith }
1086ce1633cSBarry Smith 
109b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
110b3a44c85SBarry Smith {
111b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
112b3a44c85SBarry Smith   const MatScalar *aa;
113b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
114b3a44c85SBarry Smith   const PetscInt  *ii;
115b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
116b3a44c85SBarry Smith   PetscErrorCode  ierr;
117b3a44c85SBarry Smith 
118b3a44c85SBarry Smith   PetscFunctionBegin;
119b3a44c85SBarry Smith   *keptrows = 0;
120b3a44c85SBarry Smith   ii        = a->i;
121b3a44c85SBarry Smith   for (i=0; i<m; i++) {
122b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
123b3a44c85SBarry Smith     if (!n) {
124b3a44c85SBarry Smith       cnt++;
125b3a44c85SBarry Smith       goto ok1;
126b3a44c85SBarry Smith     }
127b3a44c85SBarry Smith     aa = a->a + ii[i];
128b3a44c85SBarry Smith     for (j=0; j<n; j++) {
129b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
130b3a44c85SBarry Smith     }
131b3a44c85SBarry Smith     cnt++;
132b3a44c85SBarry Smith ok1:;
133b3a44c85SBarry Smith   }
134b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
135854ce69bSBarry Smith   ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr);
136b3a44c85SBarry Smith   cnt  = 0;
137b3a44c85SBarry Smith   for (i=0; i<m; i++) {
138b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
139b3a44c85SBarry Smith     if (!n) continue;
140b3a44c85SBarry Smith     aa = a->a + ii[i];
141b3a44c85SBarry Smith     for (j=0; j<n; j++) {
142b3a44c85SBarry Smith       if (aa[j] != 0.0) {
143b3a44c85SBarry Smith         rows[cnt++] = i;
144b3a44c85SBarry Smith         break;
145b3a44c85SBarry Smith       }
146b3a44c85SBarry Smith     }
147b3a44c85SBarry Smith   }
148b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
149b3a44c85SBarry Smith   PetscFunctionReturn(0);
150b3a44c85SBarry Smith }
151b3a44c85SBarry Smith 
1527087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
15379299369SBarry Smith {
15479299369SBarry Smith   PetscErrorCode    ierr;
15579299369SBarry Smith   Mat_SeqAIJ        *aij = (Mat_SeqAIJ*) Y->data;
15699e65526SBarry Smith   PetscInt          i,m = Y->rmap->n;
15799e65526SBarry Smith   const PetscInt    *diag;
15854f21887SBarry Smith   MatScalar         *aa = aij->a;
15999e65526SBarry Smith   const PetscScalar *v;
160ace3abfcSBarry Smith   PetscBool         missing;
16179299369SBarry Smith 
16279299369SBarry Smith   PetscFunctionBegin;
16309f38230SBarry Smith   if (Y->assembled) {
1640298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
16509f38230SBarry Smith     if (!missing) {
16679299369SBarry Smith       diag = aij->diag;
16799e65526SBarry Smith       ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr);
16879299369SBarry Smith       if (is == INSERT_VALUES) {
16979299369SBarry Smith         for (i=0; i<m; i++) {
17079299369SBarry Smith           aa[diag[i]] = v[i];
17179299369SBarry Smith         }
17279299369SBarry Smith       } else {
17379299369SBarry Smith         for (i=0; i<m; i++) {
17479299369SBarry Smith           aa[diag[i]] += v[i];
17579299369SBarry Smith         }
17679299369SBarry Smith       }
17799e65526SBarry Smith       ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr);
17879299369SBarry Smith       PetscFunctionReturn(0);
17979299369SBarry Smith     }
180acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
18109f38230SBarry Smith   }
18209f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
18309f38230SBarry Smith   PetscFunctionReturn(0);
18409f38230SBarry Smith }
18579299369SBarry Smith 
1861a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
18717ab2063SBarry Smith {
188416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
189dfbe8321SBarry Smith   PetscErrorCode ierr;
19097f1f81fSBarry Smith   PetscInt       i,ishift;
19117ab2063SBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionBegin;
193d0f46423SBarry Smith   *m = A->rmap->n;
1943a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
195bfeeae90SHong Zhang   ishift = 0;
19653e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
1972462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
198bfeeae90SHong Zhang   } else if (oshift == 1) {
1991a83f524SJed Brown     PetscInt *tia;
200d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2013b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
202854ce69bSBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr);
2031a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2041a83f524SJed Brown     *ia = tia;
205ecc77c7aSBarry Smith     if (ja) {
2061a83f524SJed Brown       PetscInt *tja;
207854ce69bSBarry Smith       ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr);
2081a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2091a83f524SJed Brown       *ja = tja;
210ecc77c7aSBarry Smith     }
2116945ee14SBarry Smith   } else {
212ecc77c7aSBarry Smith     *ia = a->i;
213ecc77c7aSBarry Smith     if (ja) *ja = a->j;
214a2ce50c7SBarry Smith   }
2153a40ed3dSBarry Smith   PetscFunctionReturn(0);
216a2744918SBarry Smith }
217a2744918SBarry Smith 
2181a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2196945ee14SBarry Smith {
220dfbe8321SBarry Smith   PetscErrorCode ierr;
2216945ee14SBarry Smith 
2223a40ed3dSBarry Smith   PetscFunctionBegin;
2233a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
224bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
225606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
226ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
227bcd2baecSBarry Smith   }
2283a40ed3dSBarry Smith   PetscFunctionReturn(0);
22917ab2063SBarry Smith }
23017ab2063SBarry Smith 
2311a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2323b2fbd54SBarry Smith {
2333b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
234dfbe8321SBarry Smith   PetscErrorCode ierr;
235d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
23697f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2373b2fbd54SBarry Smith 
2383a40ed3dSBarry Smith   PetscFunctionBegin;
239899cda47SBarry Smith   *nn = n;
2403a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2413b2fbd54SBarry Smith   if (symmetric) {
2422462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2433b2fbd54SBarry Smith   } else {
2441795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
245854ce69bSBarry Smith     ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
246854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
2473b2fbd54SBarry Smith     jj   = a->j;
2483b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
249bfeeae90SHong Zhang       collengths[jj[i]]++;
2503b2fbd54SBarry Smith     }
2513b2fbd54SBarry Smith     cia[0] = oshift;
2523b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2533b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2543b2fbd54SBarry Smith     }
25597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2563b2fbd54SBarry Smith     jj   = a->j;
257a93ec695SBarry Smith     for (row=0; row<m; row++) {
258a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
259a93ec695SBarry Smith       for (i=0; i<mr; i++) {
260bfeeae90SHong Zhang         col = *jj++;
2612205254eSKarl Rupp 
2623b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2633b2fbd54SBarry Smith       }
2643b2fbd54SBarry Smith     }
265606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2663b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2673b2fbd54SBarry Smith   }
2683a40ed3dSBarry Smith   PetscFunctionReturn(0);
2693b2fbd54SBarry Smith }
2703b2fbd54SBarry Smith 
2711a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2723b2fbd54SBarry Smith {
273dfbe8321SBarry Smith   PetscErrorCode ierr;
274606d414cSSatish Balay 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2763a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2773b2fbd54SBarry Smith 
278606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
279606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2813b2fbd54SBarry Smith }
2823b2fbd54SBarry Smith 
2837cee066cSHong Zhang /*
2847cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2857cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
286040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2877cee066cSHong Zhang */
2887cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
2897cee066cSHong Zhang {
2907cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2917cee066cSHong Zhang   PetscErrorCode ierr;
2927cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2937cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2947cee066cSHong Zhang   PetscInt       *cspidx;
2957cee066cSHong Zhang 
2967cee066cSHong Zhang   PetscFunctionBegin;
2977cee066cSHong Zhang   *nn = n;
2987cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
299625f6d37SHong Zhang 
3001795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
301854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
302854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
303854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cspidx);CHKERRQ(ierr);
3047cee066cSHong Zhang   jj   = a->j;
3057cee066cSHong Zhang   for (i=0; i<nz; i++) {
3067cee066cSHong Zhang     collengths[jj[i]]++;
3077cee066cSHong Zhang   }
3087cee066cSHong Zhang   cia[0] = oshift;
3097cee066cSHong Zhang   for (i=0; i<n; i++) {
3107cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3117cee066cSHong Zhang   }
3127cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3137cee066cSHong Zhang   jj   = a->j;
3147cee066cSHong Zhang   for (row=0; row<m; row++) {
3157cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3167cee066cSHong Zhang     for (i=0; i<mr; i++) {
3177cee066cSHong Zhang       col = *jj++;
3187cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3197cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3207cee066cSHong Zhang     }
3217cee066cSHong Zhang   }
3227cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3237cee066cSHong Zhang   *ia    = cia; *ja = cja;
3247cee066cSHong Zhang   *spidx = cspidx;
3257cee066cSHong Zhang   PetscFunctionReturn(0);
3267cee066cSHong Zhang }
3277cee066cSHong Zhang 
3287cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3297cee066cSHong Zhang {
3307cee066cSHong Zhang   PetscErrorCode ierr;
3317cee066cSHong Zhang 
3327cee066cSHong Zhang   PetscFunctionBegin;
3335243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3347cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3357cee066cSHong Zhang   PetscFunctionReturn(0);
3367cee066cSHong Zhang }
3377cee066cSHong Zhang 
33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
33987d4246cSBarry Smith {
34087d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34187d4246cSBarry Smith   PetscInt       *ai = a->i;
34287d4246cSBarry Smith   PetscErrorCode ierr;
34387d4246cSBarry Smith 
34487d4246cSBarry Smith   PetscFunctionBegin;
34587d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
34687d4246cSBarry Smith   PetscFunctionReturn(0);
34787d4246cSBarry Smith }
34887d4246cSBarry Smith 
349bd04181cSBarry Smith /*
350bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
351bd04181cSBarry Smith 
352bd04181cSBarry Smith       -   a single row of values is set with each call
353bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
354bd04181cSBarry Smith       -   the values are always added to the matrix, not set
355bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
356bd04181cSBarry Smith 
3571f763a69SBarry Smith      This does NOT assume the global column indices are sorted
358bd04181cSBarry Smith 
3591f763a69SBarry Smith */
360bd04181cSBarry Smith 
361af0996ceSBarry Smith #include <petsc/private/isimpl.h>
362189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
363189e4007SBarry Smith {
364189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3651f763a69SBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
3661f763a69SBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j;
3671f763a69SBarry Smith   PetscInt       lastcol = -1;
368189e4007SBarry Smith   MatScalar      *ap,value,*aa = a->a;
369189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
370189e4007SBarry Smith 
371f38dd0b8SBarry Smith   row = ridx[im[0]];
3721f763a69SBarry Smith   rp   = aj + ai[row];
3731f763a69SBarry Smith   ap = aa + ai[row];
3741f763a69SBarry Smith   nrow = ailen[row];
375189e4007SBarry Smith   low  = 0;
376189e4007SBarry Smith   high = nrow;
377189e4007SBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
378189e4007SBarry Smith     col = cidx[in[l]];
379f38dd0b8SBarry Smith     value = v[l];
380189e4007SBarry Smith 
381189e4007SBarry Smith     if (col <= lastcol) low = 0;
382189e4007SBarry Smith     else high = nrow;
383189e4007SBarry Smith     lastcol = col;
384189e4007SBarry Smith     while (high-low > 5) {
385189e4007SBarry Smith       t = (low+high)/2;
386189e4007SBarry Smith       if (rp[t] > col) high = t;
387189e4007SBarry Smith       else low = t;
388189e4007SBarry Smith     }
389189e4007SBarry Smith     for (i=low; i<high; i++) {
390189e4007SBarry Smith       if (rp[i] == col) {
3911f763a69SBarry Smith         ap[i] += value;
392189e4007SBarry Smith         low = i + 1;
3931f763a69SBarry Smith         break;
394189e4007SBarry Smith       }
395189e4007SBarry Smith     }
396189e4007SBarry Smith   }
397f38dd0b8SBarry Smith   return 0;
398189e4007SBarry Smith }
399189e4007SBarry Smith 
40097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
40117ab2063SBarry Smith {
402416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
403e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
40497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
4056849ba73SBarry Smith   PetscErrorCode ierr;
406e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
40754f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
408ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
409ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
41017ab2063SBarry Smith 
4113a40ed3dSBarry Smith   PetscFunctionBegin;
41217ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
413416022c9SBarry Smith     row = im[k];
4145ef9f2a5SBarry Smith     if (row < 0) continue;
4152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
416e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
4173b2fbd54SBarry Smith #endif
418720833daSHong Zhang     rp   = aj + ai[row];
419*876c6284SHong 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) {
451*876c6284SHong 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) {
463*876c6284SHong 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];
471*876c6284SHong Zhang         if (!A->structure_only) ap[ii+1] = ap[ii];
472720833daSHong Zhang       }
47317ab2063SBarry Smith       rp[i] = col;
474*876c6284SHong Zhang       if (!A->structure_only) ap[i] = value;
475416022c9SBarry Smith       low   = i + 1;
476e56f5c9eSBarry Smith       A->nonzerostate++;
477e44c0bd4SBarry Smith noinsert:;
47817ab2063SBarry Smith     }
47917ab2063SBarry Smith     ailen[row] = nrow;
48017ab2063SBarry Smith   }
4813a40ed3dSBarry Smith   PetscFunctionReturn(0);
48217ab2063SBarry Smith }
48317ab2063SBarry Smith 
48481824310SBarry Smith 
485a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4867eb43aa7SLois Curfman McInnes {
4877eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
48897f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
48997f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
49054f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4917eb43aa7SLois Curfman McInnes 
4923a40ed3dSBarry Smith   PetscFunctionBegin;
4937eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4947eb43aa7SLois Curfman McInnes     row = im[k];
495e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
496e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
497bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4987eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4997eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
500e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
501e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
502bfeeae90SHong Zhang       col  = in[l];
5037eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5047eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5057eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5067eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5077eb43aa7SLois Curfman McInnes         else low = t;
5087eb43aa7SLois Curfman McInnes       }
5097eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5107eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5117eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
512b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5137eb43aa7SLois Curfman McInnes           goto finished;
5147eb43aa7SLois Curfman McInnes         }
5157eb43aa7SLois Curfman McInnes       }
51697e567efSBarry Smith       *v++ = 0.0;
5177eb43aa7SLois Curfman McInnes finished:;
5187eb43aa7SLois Curfman McInnes     }
5197eb43aa7SLois Curfman McInnes   }
5203a40ed3dSBarry Smith   PetscFunctionReturn(0);
5217eb43aa7SLois Curfman McInnes }
5227eb43aa7SLois Curfman McInnes 
52317ab2063SBarry Smith 
524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
52517ab2063SBarry Smith {
526416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5276849ba73SBarry Smith   PetscErrorCode ierr;
5286f69ff64SBarry Smith   PetscInt       i,*col_lens;
5296f69ff64SBarry Smith   int            fd;
530b37d52dbSMark F. Adams   FILE           *file;
53117ab2063SBarry Smith 
5323a40ed3dSBarry Smith   PetscFunctionBegin;
533b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
534854ce69bSBarry Smith   ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr);
5352205254eSKarl Rupp 
5360700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
537d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
538d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
539416022c9SBarry Smith   col_lens[3] = a->nz;
540416022c9SBarry Smith 
541416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
542d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
543416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
54417ab2063SBarry Smith   }
545d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
546606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
547416022c9SBarry Smith 
548416022c9SBarry Smith   /* store column indices (zero start index) */
5496f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
550416022c9SBarry Smith 
551416022c9SBarry Smith   /* store nonzero values */
5526f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
553b37d52dbSMark F. Adams 
554b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
555b37d52dbSMark F. Adams   if (file) {
55633d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
557b37d52dbSMark F. Adams   }
5583a40ed3dSBarry Smith   PetscFunctionReturn(0);
55917ab2063SBarry Smith }
560416022c9SBarry Smith 
56109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
562cd155464SBarry Smith 
563dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
564416022c9SBarry Smith {
565416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
566dfbe8321SBarry Smith   PetscErrorCode    ierr;
56760e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
568e060cb09SBarry Smith   const char        *name;
569f3ef73ceSBarry Smith   PetscViewerFormat format;
57017ab2063SBarry Smith 
5713a40ed3dSBarry Smith   PetscFunctionBegin;
57243e49210SHong Zhang   if (!a->a) PetscFunctionReturn(0);
57343e49210SHong Zhang 
574b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
57571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
57697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
57760e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
578c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
579d00d2cf4SBarry Smith       nofinalvalue = 1;
580d00d2cf4SBarry Smith     }
581d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
582d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
58377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
584fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
585fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
586fbfe6fa7SJed Brown #else
58777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
588fbfe6fa7SJed Brown #endif
589b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
59017ab2063SBarry Smith 
59117ab2063SBarry Smith     for (i=0; i<m; i++) {
59260e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
593aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
594a9bf72d8SJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59517ab2063SBarry Smith #else
59660e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
59717ab2063SBarry Smith #endif
59817ab2063SBarry Smith       }
59917ab2063SBarry Smith     }
600d00d2cf4SBarry Smith     if (nofinalvalue) {
601c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
602c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
603c337ccceSJed Brown #else
604d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
605c337ccceSJed Brown #endif
606d00d2cf4SBarry Smith     }
607317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
608fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
609d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
61068369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
611cd155464SBarry Smith     PetscFunctionReturn(0);
612fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
613d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
61444cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
61577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
61660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
617aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
61836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
61960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
62160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62236db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
62360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6246831982aSBarry Smith         }
62544cd7ae7SLois Curfman McInnes #else
62660e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
62744cd7ae7SLois Curfman McInnes #endif
62844cd7ae7SLois Curfman McInnes       }
629b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
63044cd7ae7SLois Curfman McInnes     }
631d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
632fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
63397f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
634d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
635854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
636496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
637496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
63860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
639496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
640aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
642496be53dSLois Curfman McInnes #else
643496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
644496be53dSLois Curfman McInnes #endif
645496be53dSLois Curfman McInnes         }
646496be53dSLois Curfman McInnes       }
647496be53dSLois Curfman McInnes     }
6482e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
64977431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6502e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6512205254eSKarl Rupp       if (i+4<m) {
6522205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);
6532205254eSKarl Rupp       } else if (i+3<m) {
6542205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);
6552205254eSKarl Rupp       } else if (i+2<m) {
6562205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6572205254eSKarl Rupp       } else if (i+1<m) {
6582205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6592205254eSKarl Rupp       } else if (i<m) {
6602205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6612205254eSKarl Rupp       } else {
6622205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6632205254eSKarl Rupp       }
664496be53dSLois Curfman McInnes     }
665b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
666606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
667496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
66860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
66977431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
670496be53dSLois Curfman McInnes       }
671b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
672496be53dSLois Curfman McInnes     }
673b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
674496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
67560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
676496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
677aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
67836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
67960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6806831982aSBarry Smith           }
681496be53dSLois Curfman McInnes #else
68260e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
683496be53dSLois Curfman McInnes #endif
684496be53dSLois Curfman McInnes         }
685496be53dSLois Curfman McInnes       }
686b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
687496be53dSLois Curfman McInnes     }
688d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
689fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
69097f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
69187828ca2SBarry Smith     PetscScalar value;
69268f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
69368f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
69468f1ed48SBarry Smith 
69568f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
69668f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
69768f1ed48SBarry Smith         realonly = PETSC_FALSE;
69868f1ed48SBarry Smith         break;
69968f1ed48SBarry Smith       }
70068f1ed48SBarry Smith     }
70168f1ed48SBarry Smith #endif
70202594712SBarry Smith 
703d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
70402594712SBarry Smith     for (i=0; i<m; i++) {
70502594712SBarry Smith       jcnt = 0;
706d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
707e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
70802594712SBarry Smith           value = a->a[cnt++];
709e24b481bSBarry Smith           jcnt++;
71002594712SBarry Smith         } else {
71102594712SBarry Smith           value = 0.0;
71202594712SBarry Smith         }
713aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
71468f1ed48SBarry Smith         if (realonly) {
71560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
71668f1ed48SBarry Smith         } else {
71760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
71868f1ed48SBarry Smith         }
71902594712SBarry Smith #else
72060e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
72102594712SBarry Smith #endif
72202594712SBarry Smith       }
723b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
72402594712SBarry Smith     }
725d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7263c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
727150b93efSMatthew G. Knepley     PetscInt fshift=1;
728d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7293c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
73019303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7313c215bfdSMatthew Knepley #else
73219303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7333c215bfdSMatthew Knepley #endif
734d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7353c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
73660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7373c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
738a9a0e077SKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7393c215bfdSMatthew Knepley #else
740150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7413c215bfdSMatthew Knepley #endif
7423c215bfdSMatthew Knepley       }
7433c215bfdSMatthew Knepley     }
744d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7453a40ed3dSBarry Smith   } else {
746d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
747d5f3da31SBarry Smith     if (A->factortype) {
74816cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
74916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
75016cd7e1dSShri Abhyankar         /* L part */
75160e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
75216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
75316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
75460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
75516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7566712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
75716cd7e1dSShri Abhyankar           } else {
75860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
75916cd7e1dSShri Abhyankar           }
76016cd7e1dSShri Abhyankar #else
76160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
76216cd7e1dSShri Abhyankar #endif
76316cd7e1dSShri Abhyankar         }
76416cd7e1dSShri Abhyankar         /* diagonal */
76516cd7e1dSShri Abhyankar         j = a->diag[i];
76616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
76716cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
76860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
76916cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7706712e2f1SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr);
77116cd7e1dSShri Abhyankar         } else {
77260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
77316cd7e1dSShri Abhyankar         }
77416cd7e1dSShri Abhyankar #else
77560e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
77616cd7e1dSShri Abhyankar #endif
77716cd7e1dSShri Abhyankar 
77816cd7e1dSShri Abhyankar         /* U part */
77960e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
78016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
78260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
78316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
78422ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
78516cd7e1dSShri Abhyankar           } else {
78660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
78716cd7e1dSShri Abhyankar           }
78816cd7e1dSShri Abhyankar #else
78960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
79016cd7e1dSShri Abhyankar #endif
79116cd7e1dSShri Abhyankar         }
79216cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
79316cd7e1dSShri Abhyankar       }
79416cd7e1dSShri Abhyankar     } else {
79517ab2063SBarry Smith       for (i=0; i<m; i++) {
79677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
79760e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
798aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
79936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
80060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
80136db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
80260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8033a40ed3dSBarry Smith           } else {
80460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
80517ab2063SBarry Smith           }
80617ab2063SBarry Smith #else
80760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
80817ab2063SBarry Smith #endif
80917ab2063SBarry Smith         }
810b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
81117ab2063SBarry Smith       }
81216cd7e1dSShri Abhyankar     }
813d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
81417ab2063SBarry Smith   }
815b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8163a40ed3dSBarry Smith   PetscFunctionReturn(0);
817416022c9SBarry Smith }
818416022c9SBarry Smith 
8199804daf3SBarry Smith #include <petscdraw.h>
820dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
821416022c9SBarry Smith {
822480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
823416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
824dfbe8321SBarry Smith   PetscErrorCode    ierr;
825383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
826383922c3SLisandro Dalcin   int               color;
827b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
828b0a32e0cSBarry Smith   PetscViewer       viewer;
829f3ef73ceSBarry Smith   PetscViewerFormat format;
830cddf8d76SBarry Smith 
8313a40ed3dSBarry Smith   PetscFunctionBegin;
832480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
833b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
834b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
835383922c3SLisandro Dalcin 
836416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8370513a670SBarry Smith 
838fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
839383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8400513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
841b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
842416022c9SBarry Smith     for (i=0; i<m; i++) {
843cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
844bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
845bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
84636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
847b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
848cddf8d76SBarry Smith       }
849cddf8d76SBarry Smith     }
850b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
851cddf8d76SBarry Smith     for (i=0; i<m; i++) {
852cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
853bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
854bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
855cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
856b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
857cddf8d76SBarry Smith       }
858cddf8d76SBarry Smith     }
859b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
860cddf8d76SBarry Smith     for (i=0; i<m; i++) {
861cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
862bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
863bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
86436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
865b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
866416022c9SBarry Smith       }
867416022c9SBarry Smith     }
868383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8690513a670SBarry Smith   } else {
8700513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8710513a670SBarry Smith     /* first determine max of all nonzero values */
872b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
873383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
874b0a32e0cSBarry Smith     PetscDraw popup;
8750513a670SBarry Smith 
8760513a670SBarry Smith     for (i=0; i<nz; i++) {
8770513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8780513a670SBarry Smith     }
879383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
880b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
88145f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
882383922c3SLisandro Dalcin 
883383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8840513a670SBarry Smith     for (i=0; i<m; i++) {
885383922c3SLisandro Dalcin       y_l = m - i - 1.0;
886383922c3SLisandro Dalcin       y_r = y_l + 1.0;
887bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
888383922c3SLisandro Dalcin         x_l = a->j[j];
889383922c3SLisandro Dalcin         x_r = x_l + 1.0;
890b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
891b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8920513a670SBarry Smith         count++;
8930513a670SBarry Smith       }
8940513a670SBarry Smith     }
895383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8960513a670SBarry Smith   }
897480ef9eaSBarry Smith   PetscFunctionReturn(0);
898480ef9eaSBarry Smith }
899cddf8d76SBarry Smith 
9009804daf3SBarry Smith #include <petscdraw.h>
901dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
902480ef9eaSBarry Smith {
903dfbe8321SBarry Smith   PetscErrorCode ierr;
904b0a32e0cSBarry Smith   PetscDraw      draw;
90536db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
906ace3abfcSBarry Smith   PetscBool      isnull;
907480ef9eaSBarry Smith 
908480ef9eaSBarry Smith   PetscFunctionBegin;
909b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
910b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
911480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
912480ef9eaSBarry Smith 
913d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
914480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
915b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
916832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
917b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9180298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
919832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9203a40ed3dSBarry Smith   PetscFunctionReturn(0);
921416022c9SBarry Smith }
922416022c9SBarry Smith 
923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
924416022c9SBarry Smith {
925dfbe8321SBarry Smith   PetscErrorCode ierr;
926ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
927416022c9SBarry Smith 
9283a40ed3dSBarry Smith   PetscFunctionBegin;
929251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
930251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
931251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
932c45a1595SBarry Smith   if (iascii) {
9333a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9340f5bd95cSBarry Smith   } else if (isbinary) {
9353a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9360f5bd95cSBarry Smith   } else if (isdraw) {
9373a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
93811aeaf0aSBarry Smith   }
9394108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9403a40ed3dSBarry Smith   PetscFunctionReturn(0);
94117ab2063SBarry Smith }
94219bcc07fSBarry Smith 
943dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
94417ab2063SBarry Smith {
945416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9466849ba73SBarry Smith   PetscErrorCode ierr;
94797f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
948d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
94954f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9503447b6efSHong Zhang   PetscReal      ratio  = 0.6;
95117ab2063SBarry Smith 
9523a40ed3dSBarry Smith   PetscFunctionBegin;
9533a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
95417ab2063SBarry Smith 
95543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
95617ab2063SBarry Smith   for (i=1; i<m; i++) {
957416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
95817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
95994a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
96017ab2063SBarry Smith     if (fshift) {
961bfeeae90SHong Zhang       ip = aj + ai[i];
962bfeeae90SHong Zhang       ap = aa + ai[i];
96317ab2063SBarry Smith       N  = ailen[i];
96417ab2063SBarry Smith       for (j=0; j<N; j++) {
96517ab2063SBarry Smith         ip[j-fshift] = ip[j];
966*876c6284SHong Zhang         if (!A->structure_only) ap[j-fshift] = ap[j];
96717ab2063SBarry Smith       }
96817ab2063SBarry Smith     }
96917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
97017ab2063SBarry Smith   }
97117ab2063SBarry Smith   if (m) {
97217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
97317ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
97417ab2063SBarry Smith   }
9757b083b7cSBarry Smith 
97617ab2063SBarry Smith   /* reset ilen and imax for each row */
9777b083b7cSBarry Smith   a->nonzerorowcnt = 0;
97817ab2063SBarry Smith   for (i=0; i<m; i++) {
97917ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9807b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
98117ab2063SBarry Smith   }
982bfeeae90SHong Zhang   a->nz = ai[m];
98365e19b50SBarry 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);
98417ab2063SBarry Smith 
98509f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
986d0f46423SBarry 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);
987ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
988ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9892205254eSKarl Rupp 
9908e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
991dd5f02e7SSatish Balay   a->reallocs         = 0;
9926712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
99336db0b34SBarry Smith   a->rmax             = rmax;
9944e220ebcSLois Curfman McInnes 
99511e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9964108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
997acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9983a40ed3dSBarry Smith   PetscFunctionReturn(0);
99917ab2063SBarry Smith }
100017ab2063SBarry Smith 
100199cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
100299cafbc1SBarry Smith {
100399cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
100499cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
100554f21887SBarry Smith   MatScalar      *aa = a->a;
1006acf2f550SJed Brown   PetscErrorCode ierr;
100799cafbc1SBarry Smith 
100899cafbc1SBarry Smith   PetscFunctionBegin;
100999cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1010acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101199cafbc1SBarry Smith   PetscFunctionReturn(0);
101299cafbc1SBarry Smith }
101399cafbc1SBarry Smith 
101499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
101599cafbc1SBarry Smith {
101699cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
101799cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
101854f21887SBarry Smith   MatScalar      *aa = a->a;
1019acf2f550SJed Brown   PetscErrorCode ierr;
102099cafbc1SBarry Smith 
102199cafbc1SBarry Smith   PetscFunctionBegin;
102299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1023acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
102499cafbc1SBarry Smith   PetscFunctionReturn(0);
102599cafbc1SBarry Smith }
102699cafbc1SBarry Smith 
1027dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
102817ab2063SBarry Smith {
1029416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1030dfbe8321SBarry Smith   PetscErrorCode ierr;
10313a40ed3dSBarry Smith 
10323a40ed3dSBarry Smith   PetscFunctionBegin;
1033d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1034acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10353a40ed3dSBarry Smith   PetscFunctionReturn(0);
103617ab2063SBarry Smith }
1037416022c9SBarry Smith 
1038dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
103917ab2063SBarry Smith {
1040416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1041dfbe8321SBarry Smith   PetscErrorCode ierr;
1042d5d45c9bSBarry Smith 
10433a40ed3dSBarry Smith   PetscFunctionBegin;
1044aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1045d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
104617ab2063SBarry Smith #endif
1047e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10486bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10496bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
105005b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1051d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
105205b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
105371f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
105405b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10556bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
105605b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10576bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1058cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10590b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1060a30b2313SHong Zhang 
10614108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1062bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1063901853e0SKris Buschelman 
1064dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1065bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1066bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1067bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1069bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1070bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1071af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1072af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1073af8000cdSHong Zhang #endif
107463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
107563c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
10763dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
107763c07aadSStefano Zampini #endif
1078b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1079bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1080bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1081bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1082bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10833a40ed3dSBarry Smith   PetscFunctionReturn(0);
108417ab2063SBarry Smith }
108517ab2063SBarry Smith 
1086ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
108717ab2063SBarry Smith {
1088416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10894846f1f5SKris Buschelman   PetscErrorCode ierr;
10903a40ed3dSBarry Smith 
10913a40ed3dSBarry Smith   PetscFunctionBegin;
1092a65d3064SKris Buschelman   switch (op) {
1093a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10944e0d8c25SBarry Smith     a->roworiented = flg;
1095a65d3064SKris Buschelman     break;
1096a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1097a9817697SBarry Smith     a->keepnonzeropattern = flg;
1098a65d3064SKris Buschelman     break;
1099512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1100512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1101a65d3064SKris Buschelman     break;
1102a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11034e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1104a65d3064SKris Buschelman     break;
1105a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11064e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1107a65d3064SKris Buschelman     break;
110828b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
110928b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
111028b2fa4aSMatthew Knepley     break;
1111a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11124e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11130df259c2SBarry Smith     break;
11143d472b54SHong Zhang   case MAT_SPD:
1115b1646e73SJed Brown   case MAT_SYMMETRIC:
1116b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1117b1646e73SJed Brown   case MAT_HERMITIAN:
1118b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1119957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11205021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11215021d80fSJed Brown     break;
11224e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1123a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1124a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1125290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1126a65d3064SKris Buschelman     break;
1127b87ac2d8SJed Brown   case MAT_USE_INODES:
1128b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1129b87ac2d8SJed Brown     break;
1130c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1131c10200c1SHong Zhang     A->submat_singleis = flg;
1132c10200c1SHong Zhang     break;
1133a65d3064SKris Buschelman   default:
1134e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1135a65d3064SKris Buschelman   }
11364108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11373a40ed3dSBarry Smith   PetscFunctionReturn(0);
113817ab2063SBarry Smith }
113917ab2063SBarry Smith 
1140dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
114117ab2063SBarry Smith {
1142416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11436849ba73SBarry Smith   PetscErrorCode ierr;
1144d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
114535e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
114617ab2063SBarry Smith 
11473a40ed3dSBarry Smith   PetscFunctionBegin;
1148d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1149e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
115035e7444dSHong Zhang 
1151d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1152d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
115335e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11542c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
115535e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
115635e7444dSHong Zhang     PetscFunctionReturn(0);
115735e7444dSHong Zhang   }
115835e7444dSHong Zhang 
11592dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11601ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
116135e7444dSHong Zhang   for (i=0; i<n; i++) {
116235e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11632f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
116435e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
116535e7444dSHong Zhang       if (aj[j] == i) {
116635e7444dSHong Zhang         x[i] = aa[j];
116717ab2063SBarry Smith         break;
116817ab2063SBarry Smith       }
116917ab2063SBarry Smith     }
117017ab2063SBarry Smith   }
11711ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11723a40ed3dSBarry Smith   PetscFunctionReturn(0);
117317ab2063SBarry Smith }
117417ab2063SBarry Smith 
1175c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1176dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
117717ab2063SBarry Smith {
1178416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1179d9ca1df4SBarry Smith   PetscScalar       *y;
1180d9ca1df4SBarry Smith   const PetscScalar *x;
1181dfbe8321SBarry Smith   PetscErrorCode    ierr;
1182d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
11835c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1184d9ca1df4SBarry Smith   const MatScalar   *v;
1185a77337e4SBarry Smith   PetscScalar       alpha;
1186d9ca1df4SBarry Smith   PetscInt          n,i,j;
1187d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
11883447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1189ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11905c897100SBarry Smith #endif
119117ab2063SBarry Smith 
11923a40ed3dSBarry Smith   PetscFunctionBegin;
11932e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1194d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11951ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11965c897100SBarry Smith 
11975c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1198bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11995c897100SBarry Smith #else
12003447b6efSHong Zhang   if (usecprow) {
12013447b6efSHong Zhang     m    = cprow.nrows;
12023447b6efSHong Zhang     ii   = cprow.i;
12037b2bb3b9SHong Zhang     ridx = cprow.rindex;
12043447b6efSHong Zhang   } else {
12053447b6efSHong Zhang     ii = a->i;
12063447b6efSHong Zhang   }
120717ab2063SBarry Smith   for (i=0; i<m; i++) {
12083447b6efSHong Zhang     idx = a->j + ii[i];
12093447b6efSHong Zhang     v   = a->a + ii[i];
12103447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12113447b6efSHong Zhang     if (usecprow) {
12127b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12133447b6efSHong Zhang     } else {
121417ab2063SBarry Smith       alpha = x[i];
12153447b6efSHong Zhang     }
121604fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
121717ab2063SBarry Smith   }
12185c897100SBarry Smith #endif
1219dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1220d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12211ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12223a40ed3dSBarry Smith   PetscFunctionReturn(0);
122317ab2063SBarry Smith }
122417ab2063SBarry Smith 
1225dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12265c897100SBarry Smith {
1227dfbe8321SBarry Smith   PetscErrorCode ierr;
12285c897100SBarry Smith 
12295c897100SBarry Smith   PetscFunctionBegin;
1230170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12315c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12325c897100SBarry Smith   PetscFunctionReturn(0);
12335c897100SBarry Smith }
12345c897100SBarry Smith 
1235c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
123678b84d54SShri Abhyankar 
1237dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
123817ab2063SBarry Smith {
1239416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1240d9fead3dSBarry Smith   PetscScalar       *y;
124154f21887SBarry Smith   const PetscScalar *x;
124254f21887SBarry Smith   const MatScalar   *aa;
1243dfbe8321SBarry Smith   PetscErrorCode    ierr;
1244003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12450298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12467b083b7cSBarry Smith   PetscInt          n,i;
1247362ced78SSatish Balay   PetscScalar       sum;
1248ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
124917ab2063SBarry Smith 
1250b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
125197952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1252fee21e36SBarry Smith #endif
1253fee21e36SBarry Smith 
12543a40ed3dSBarry Smith   PetscFunctionBegin;
12553649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12561ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1257416022c9SBarry Smith   ii   = a->i;
12584eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12594f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
126097952fefSHong Zhang     m    = a->compressedrow.nrows;
126197952fefSHong Zhang     ii   = a->compressedrow.i;
126297952fefSHong Zhang     ridx = a->compressedrow.rindex;
126397952fefSHong Zhang     for (i=0; i<m; i++) {
126497952fefSHong Zhang       n           = ii[i+1] - ii[i];
126597952fefSHong Zhang       aj          = a->j + ii[i];
126697952fefSHong Zhang       aa          = a->a + ii[i];
126797952fefSHong Zhang       sum         = 0.0;
1268003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1269003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
127097952fefSHong Zhang       y[*ridx++] = sum;
127197952fefSHong Zhang     }
127297952fefSHong Zhang   } else { /* do not use compressed row format */
1273b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
12743d3eaba7SBarry Smith     aj   = a->j;
12753d3eaba7SBarry Smith     aa   = a->a;
1276b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1277b05257ddSBarry Smith #else
127817ab2063SBarry Smith     for (i=0; i<m; i++) {
1279003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1280003131ecSBarry Smith       aj          = a->j + ii[i];
1281003131ecSBarry Smith       aa          = a->a + ii[i];
128217ab2063SBarry Smith       sum         = 0.0;
1283003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128417ab2063SBarry Smith       y[i] = sum;
128517ab2063SBarry Smith     }
12868d195f9aSBarry Smith #endif
1287b05257ddSBarry Smith   }
12887b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
12893649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12901ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12913a40ed3dSBarry Smith   PetscFunctionReturn(0);
129217ab2063SBarry Smith }
129317ab2063SBarry Smith 
1294b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1295b434eb95SMatthew G. Knepley {
1296b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1297b434eb95SMatthew G. Knepley   PetscScalar       *y;
1298b434eb95SMatthew G. Knepley   const PetscScalar *x;
1299b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1300b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1301b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1302b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1303b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1304b434eb95SMatthew G. Knepley   PetscScalar       sum;
1305b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1306b434eb95SMatthew G. Knepley 
1307b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1308b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1309b434eb95SMatthew G. Knepley #endif
1310b434eb95SMatthew G. Knepley 
1311b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1312b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1313b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1314b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1315b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1316b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1317b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1318b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1319b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1320b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1321b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1322b434eb95SMatthew G. Knepley       sum         = 0.0;
1323b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1324b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1325b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1326b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1327b434eb95SMatthew G. Knepley     }
1328b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13293d3eaba7SBarry Smith     ii = a->i;
1330b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1331b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1332b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1333b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1334b434eb95SMatthew G. Knepley       sum         = 0.0;
1335b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1336b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1337b434eb95SMatthew G. Knepley       y[i] = sum;
1338b434eb95SMatthew G. Knepley     }
1339b434eb95SMatthew G. Knepley   }
1340b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1341b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1342b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1343b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1344b434eb95SMatthew G. Knepley }
1345b434eb95SMatthew G. Knepley 
1346b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1347b434eb95SMatthew G. Knepley {
1348b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1349b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1350b434eb95SMatthew G. Knepley   const PetscScalar *x;
1351b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1352b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1353b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1354b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1355b434eb95SMatthew G. Knepley   PetscScalar       sum;
1356b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1357b434eb95SMatthew G. Knepley 
1358b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1359b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1360d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1361b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1362b434eb95SMatthew G. Knepley     if (zz != yy) {
1363b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1364b434eb95SMatthew G. Knepley     }
1365b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1366b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1367b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1368b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1369b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1370b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1371b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1372b434eb95SMatthew G. Knepley       sum = y[*ridx];
1373b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1374b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1375b434eb95SMatthew G. Knepley     }
1376b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13773d3eaba7SBarry Smith     ii = a->i;
1378b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1379b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1380b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1381b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1382b434eb95SMatthew G. Knepley       sum = y[i];
1383b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1384b434eb95SMatthew G. Knepley       z[i] = sum;
1385b434eb95SMatthew G. Knepley     }
1386b434eb95SMatthew G. Knepley   }
1387b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1388b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1389d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1390b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1391b434eb95SMatthew G. Knepley }
1392b434eb95SMatthew G. Knepley 
1393c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1394dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
139517ab2063SBarry Smith {
1396416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1397f15663dcSBarry Smith   PetscScalar       *y,*z;
1398f15663dcSBarry Smith   const PetscScalar *x;
139954f21887SBarry Smith   const MatScalar   *aa;
1400dfbe8321SBarry Smith   PetscErrorCode    ierr;
1401d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1402d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1403362ced78SSatish Balay   PetscScalar       sum;
1404ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14059ea0dfa2SSatish Balay 
14063a40ed3dSBarry Smith   PetscFunctionBegin;
1407f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1408d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14094eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
14104eb6d288SHong Zhang     if (zz != yy) {
14114eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14124eb6d288SHong Zhang     }
141397952fefSHong Zhang     m    = a->compressedrow.nrows;
141497952fefSHong Zhang     ii   = a->compressedrow.i;
141597952fefSHong Zhang     ridx = a->compressedrow.rindex;
141697952fefSHong Zhang     for (i=0; i<m; i++) {
141797952fefSHong Zhang       n   = ii[i+1] - ii[i];
141897952fefSHong Zhang       aj  = a->j + ii[i];
141997952fefSHong Zhang       aa  = a->a + ii[i];
142097952fefSHong Zhang       sum = y[*ridx];
1421f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142297952fefSHong Zhang       z[*ridx++] = sum;
142397952fefSHong Zhang     }
142497952fefSHong Zhang   } else { /* do not use compressed row format */
14253d3eaba7SBarry Smith     ii = a->i;
1426f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14273d3eaba7SBarry Smith     aj = a->j;
14283d3eaba7SBarry Smith     aa = a->a;
1429f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1430f15663dcSBarry Smith #else
143117ab2063SBarry Smith     for (i=0; i<m; i++) {
1432f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1433f15663dcSBarry Smith       aj  = a->j + ii[i];
1434f15663dcSBarry Smith       aa  = a->a + ii[i];
143517ab2063SBarry Smith       sum = y[i];
1436f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
143717ab2063SBarry Smith       z[i] = sum;
143817ab2063SBarry Smith     }
143902ab625aSSatish Balay #endif
1440f15663dcSBarry Smith   }
1441dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1442f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1443d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14448154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14456b375ea7SVictor Minden   /*
1446918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1447918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1448918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14496b375ea7SVictor Minden   */
1450918e98c3SVictor Minden #endif
14513a40ed3dSBarry Smith   PetscFunctionReturn(0);
145217ab2063SBarry Smith }
145317ab2063SBarry Smith 
145417ab2063SBarry Smith /*
145517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
145617ab2063SBarry Smith */
1457dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
145817ab2063SBarry Smith {
1459416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14606849ba73SBarry Smith   PetscErrorCode ierr;
1461d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
146217ab2063SBarry Smith 
14633a40ed3dSBarry Smith   PetscFunctionBegin;
146409f38230SBarry Smith   if (!a->diag) {
1465785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14663bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
146709f38230SBarry Smith   }
1468d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
146909f38230SBarry Smith     a->diag[i] = a->i[i+1];
1470bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1471bfeeae90SHong Zhang       if (a->j[j] == i) {
147209f38230SBarry Smith         a->diag[i] = j;
147317ab2063SBarry Smith         break;
147417ab2063SBarry Smith       }
147517ab2063SBarry Smith     }
147617ab2063SBarry Smith   }
14773a40ed3dSBarry Smith   PetscFunctionReturn(0);
147817ab2063SBarry Smith }
147917ab2063SBarry Smith 
1480be5855fcSBarry Smith /*
1481be5855fcSBarry Smith      Checks for missing diagonals
1482be5855fcSBarry Smith */
1483ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1484be5855fcSBarry Smith {
1485be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14867734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1487be5855fcSBarry Smith 
1488be5855fcSBarry Smith   PetscFunctionBegin;
148909f38230SBarry Smith   *missing = PETSC_FALSE;
14907734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
149109f38230SBarry Smith     *missing = PETSC_TRUE;
149209f38230SBarry Smith     if (d) *d = 0;
1493955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
149409f38230SBarry Smith   } else {
1495f1e2ffcdSBarry Smith     diag = a->diag;
1496d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
14977734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
149809f38230SBarry Smith         *missing = PETSC_TRUE;
149909f38230SBarry Smith         if (d) *d = i;
1500955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1501358d2f5dSShri Abhyankar         break;
150209f38230SBarry Smith       }
1503be5855fcSBarry Smith     }
1504be5855fcSBarry Smith   }
1505be5855fcSBarry Smith   PetscFunctionReturn(0);
1506be5855fcSBarry Smith }
1507be5855fcSBarry Smith 
1508422a814eSBarry Smith /*
1509422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1510422a814eSBarry Smith */
15117087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
151271f1c65dSBarry Smith {
151371f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
151471f1c65dSBarry Smith   PetscErrorCode ierr;
1515d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
151654f21887SBarry Smith   MatScalar      *v = a->a;
151754f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
151871f1c65dSBarry Smith 
151971f1c65dSBarry Smith   PetscFunctionBegin;
152071f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
152171f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
152271f1c65dSBarry Smith   diag = a->diag;
152371f1c65dSBarry Smith   if (!a->idiag) {
1524dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
152671f1c65dSBarry Smith     v    = a->a;
152771f1c65dSBarry Smith   }
152871f1c65dSBarry Smith   mdiag = a->mdiag;
152971f1c65dSBarry Smith   idiag = a->idiag;
153071f1c65dSBarry Smith 
1531422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
153271f1c65dSBarry Smith     for (i=0; i<m; i++) {
153371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1534899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1535899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1536899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15377b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15387b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15397b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15407b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1541899639b0SHong Zhang       }
154271f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
154371f1c65dSBarry Smith     }
154471f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
154571f1c65dSBarry Smith   } else {
154671f1c65dSBarry Smith     for (i=0; i<m; i++) {
154771f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
154871f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
154971f1c65dSBarry Smith     }
1550dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
155171f1c65dSBarry Smith   }
155271f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
155371f1c65dSBarry Smith   PetscFunctionReturn(0);
155471f1c65dSBarry Smith }
155571f1c65dSBarry Smith 
1556c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
155741f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
155817ab2063SBarry Smith {
1559416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1560e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15613d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
156254f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1563dfbe8321SBarry Smith   PetscErrorCode    ierr;
15643d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
156597f1f81fSBarry Smith   const PetscInt    *idx,*diag;
156617ab2063SBarry Smith 
15673a40ed3dSBarry Smith   PetscFunctionBegin;
1568b965ef7fSBarry Smith   its = its*lits;
156991723122SBarry Smith 
157071f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
157171f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
157271f1c65dSBarry Smith   a->fshift = fshift;
157371f1c65dSBarry Smith   a->omega  = omega;
1574ed480e8bSBarry Smith 
157571f1c65dSBarry Smith   diag  = a->diag;
157671f1c65dSBarry Smith   t     = a->ssor_work;
1577ed480e8bSBarry Smith   idiag = a->idiag;
157871f1c65dSBarry Smith   mdiag = a->mdiag;
1579ed480e8bSBarry Smith 
15801ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15813649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1582ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
158317ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
158417ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1585ed480e8bSBarry Smith     bs = b;
158617ab2063SBarry Smith     for (i=0; i<m; i++) {
158771f1c65dSBarry Smith       d   = fshift + mdiag[i];
1588416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1589ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1590ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
159117ab2063SBarry Smith       sum = b[i]*d/omega;
1592003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
159317ab2063SBarry Smith       x[i] = sum;
159417ab2063SBarry Smith     }
15951ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
15963649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1597efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
15983a40ed3dSBarry Smith     PetscFunctionReturn(0);
159917ab2063SBarry Smith   }
1600c783ea89SBarry Smith 
16012205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16022205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
160317ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1604887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
160517ab2063SBarry Smith 
160617ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
160717ab2063SBarry Smith 
1608887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
160917ab2063SBarry Smith     */
161017ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
161117ab2063SBarry Smith 
161217ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
161317ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1614416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1615ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1616ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
161717ab2063SBarry Smith       sum = b[i];
1618e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1619ed480e8bSBarry Smith       x[i] = sum*idiag[i];
162017ab2063SBarry Smith     }
162117ab2063SBarry Smith 
162217ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1623416022c9SBarry Smith     v = a->a;
16242205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
162517ab2063SBarry Smith 
162617ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1627ed480e8bSBarry Smith     ts   = t;
1628416022c9SBarry Smith     diag = a->diag;
162917ab2063SBarry Smith     for (i=0; i<m; i++) {
1630416022c9SBarry Smith       n   = diag[i] - a->i[i];
1631ed480e8bSBarry Smith       idx = a->j + a->i[i];
1632ed480e8bSBarry Smith       v   = a->a + a->i[i];
163317ab2063SBarry Smith       sum = t[i];
1634003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1635ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1636733d66baSBarry Smith       /*  x = x + t */
1637733d66baSBarry Smith       x[i] += t[i];
163817ab2063SBarry Smith     }
163917ab2063SBarry Smith 
1640dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16411ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16423649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16433a40ed3dSBarry Smith     PetscFunctionReturn(0);
164417ab2063SBarry Smith   }
164517ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
164617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
164717ab2063SBarry Smith       for (i=0; i<m; i++) {
1648416022c9SBarry Smith         n   = diag[i] - a->i[i];
1649ed480e8bSBarry Smith         idx = a->j + a->i[i];
1650ed480e8bSBarry Smith         v   = a->a + a->i[i];
165117ab2063SBarry Smith         sum = b[i];
1652e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16535c99c7daSBarry Smith         t[i] = sum;
1654ed480e8bSBarry Smith         x[i] = sum*idiag[i];
165517ab2063SBarry Smith       }
16565c99c7daSBarry Smith       xb   = t;
1657efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16583a40ed3dSBarry Smith     } else xb = b;
165917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
166017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1661416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1662ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1663ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
166417ab2063SBarry Smith         sum = xb[i];
1665e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16665c99c7daSBarry Smith         if (xb == b) {
1667ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16685c99c7daSBarry Smith         } else {
1669b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
167017ab2063SBarry Smith         }
16715c99c7daSBarry Smith       }
1672b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
167317ab2063SBarry Smith     }
167417ab2063SBarry Smith     its--;
167517ab2063SBarry Smith   }
167617ab2063SBarry Smith   while (its--) {
167717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
167817ab2063SBarry Smith       for (i=0; i<m; i++) {
1679b19a5dc2SMark Adams         /* lower */
1680b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1681ed480e8bSBarry Smith         idx = a->j + a->i[i];
1682ed480e8bSBarry Smith         v   = a->a + a->i[i];
168317ab2063SBarry Smith         sum = b[i];
1684e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1685b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1686b19a5dc2SMark Adams         /* upper */
1687b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1688b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1689b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1690b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1691b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
169217ab2063SBarry Smith       }
1693b19a5dc2SMark Adams       xb   = t;
16949f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1695b19a5dc2SMark Adams     } else xb = b;
169617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
169717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1698b19a5dc2SMark Adams         sum = xb[i];
1699b19a5dc2SMark Adams         if (xb == b) {
1700b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1701416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1702ed480e8bSBarry Smith           idx = a->j + a->i[i];
1703ed480e8bSBarry Smith           v   = a->a + a->i[i];
1704e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1705ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1706b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1707b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1708b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1709b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1710b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1711b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
171217ab2063SBarry Smith         }
1713b19a5dc2SMark Adams       }
1714b19a5dc2SMark Adams       if (xb == b) {
17159f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1716b19a5dc2SMark Adams       } else {
1717b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1718b19a5dc2SMark Adams       }
171917ab2063SBarry Smith     }
172017ab2063SBarry Smith   }
17211ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17223649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1723365a8a9eSBarry Smith   PetscFunctionReturn(0);
172417ab2063SBarry Smith }
172517ab2063SBarry Smith 
17262af78befSBarry Smith 
1727dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
172817ab2063SBarry Smith {
1729416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17304e220ebcSLois Curfman McInnes 
17313a40ed3dSBarry Smith   PetscFunctionBegin;
17324e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17334e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17344e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17354e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17364e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17378e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17387adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1739d5f3da31SBarry Smith   if (A->factortype) {
17404e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17414e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17424e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17434e220ebcSLois Curfman McInnes   } else {
17444e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17454e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17464e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17474e220ebcSLois Curfman McInnes   }
17483a40ed3dSBarry Smith   PetscFunctionReturn(0);
174917ab2063SBarry Smith }
175017ab2063SBarry Smith 
17512b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
175217ab2063SBarry Smith {
1753416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1754c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17556849ba73SBarry Smith   PetscErrorCode    ierr;
175697b48c8fSBarry Smith   const PetscScalar *xx;
175797b48c8fSBarry Smith   PetscScalar       *bb;
1758c7da8527SEric Chamberland   PetscInt          d = 0;
175917ab2063SBarry Smith 
17603a40ed3dSBarry Smith   PetscFunctionBegin;
176197b48c8fSBarry Smith   if (x && b) {
176297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
176397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
176497b48c8fSBarry Smith     for (i=0; i<N; i++) {
176597b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
176697b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
176797b48c8fSBarry Smith     }
176897b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
176997b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
177097b48c8fSBarry Smith   }
177197b48c8fSBarry Smith 
1772a9817697SBarry Smith   if (a->keepnonzeropattern) {
1773f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1774e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1775bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1776f1e2ffcdSBarry Smith     }
1777f4df32b1SMatthew Knepley     if (diag != 0.0) {
1778c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1779c7da8527SEric Chamberland         d = rows[i];
1780c7da8527SEric 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);
1781c7da8527SEric Chamberland       }
1782f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1783f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1784f1e2ffcdSBarry Smith       }
1785f1e2ffcdSBarry Smith     }
1786f1e2ffcdSBarry Smith   } else {
1787f4df32b1SMatthew Knepley     if (diag != 0.0) {
178817ab2063SBarry Smith       for (i=0; i<N; i++) {
1789e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17907ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1791416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1792f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1793bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
17947ae801bdSBarry Smith         } else { /* in case row was completely empty */
1795f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
179617ab2063SBarry Smith         }
179717ab2063SBarry Smith       }
17983a40ed3dSBarry Smith     } else {
179917ab2063SBarry Smith       for (i=0; i<N; i++) {
1800e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1801416022c9SBarry Smith         a->ilen[rows[i]] = 0;
180217ab2063SBarry Smith       }
180317ab2063SBarry Smith     }
1804e56f5c9eSBarry Smith     A->nonzerostate++;
1805f1e2ffcdSBarry Smith   }
180643a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18073a40ed3dSBarry Smith   PetscFunctionReturn(0);
180817ab2063SBarry Smith }
180917ab2063SBarry Smith 
18106e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18116e169961SBarry Smith {
18126e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18136e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18146e169961SBarry Smith   PetscErrorCode    ierr;
18152b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18166e169961SBarry Smith   const PetscScalar *xx;
18176e169961SBarry Smith   PetscScalar       *bb;
18186e169961SBarry Smith 
18196e169961SBarry Smith   PetscFunctionBegin;
18206e169961SBarry Smith   if (x && b) {
18216e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18226e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18232b40b63fSBarry Smith     vecs = PETSC_TRUE;
18246e169961SBarry Smith   }
18251795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18266e169961SBarry Smith   for (i=0; i<N; i++) {
18276e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18286e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18292205254eSKarl Rupp 
18306e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18316e169961SBarry Smith   }
18326e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18336e169961SBarry Smith     if (!zeroed[i]) {
18346e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18356e169961SBarry Smith         if (zeroed[a->j[j]]) {
18362b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18376e169961SBarry Smith           a->a[j] = 0.0;
18386e169961SBarry Smith         }
18396e169961SBarry Smith       }
18402b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18416e169961SBarry Smith   }
18426e169961SBarry Smith   if (x && b) {
18436e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18446e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18456e169961SBarry Smith   }
18466e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18476e169961SBarry Smith   if (diag != 0.0) {
18486e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18491d5a398dSstefano_zampini     if (missing) {
18501d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18511d5a398dSstefano_zampini       else {
18521d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18531d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18541d5a398dSstefano_zampini         }
18551d5a398dSstefano_zampini       }
18561d5a398dSstefano_zampini     } else {
18576e169961SBarry Smith       for (i=0; i<N; i++) {
18586e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18596e169961SBarry Smith       }
18606e169961SBarry Smith     }
18611d5a398dSstefano_zampini   }
18626e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18636e169961SBarry Smith   PetscFunctionReturn(0);
18646e169961SBarry Smith }
18656e169961SBarry Smith 
1866a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
186717ab2063SBarry Smith {
1868416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
186997f1f81fSBarry Smith   PetscInt   *itmp;
187017ab2063SBarry Smith 
18713a40ed3dSBarry Smith   PetscFunctionBegin;
1872e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
187317ab2063SBarry Smith 
1874416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1875bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
187617ab2063SBarry Smith   if (idx) {
1877bfeeae90SHong Zhang     itmp = a->j + a->i[row];
187826fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
187917ab2063SBarry Smith     else *idx = 0;
188017ab2063SBarry Smith   }
18813a40ed3dSBarry Smith   PetscFunctionReturn(0);
188217ab2063SBarry Smith }
188317ab2063SBarry Smith 
1884bfeeae90SHong Zhang /* remove this function? */
1885a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
188617ab2063SBarry Smith {
18873a40ed3dSBarry Smith   PetscFunctionBegin;
18883a40ed3dSBarry Smith   PetscFunctionReturn(0);
188917ab2063SBarry Smith }
189017ab2063SBarry Smith 
1891dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
189217ab2063SBarry Smith {
1893416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
189454f21887SBarry Smith   MatScalar      *v  = a->a;
189536db0b34SBarry Smith   PetscReal      sum = 0.0;
18966849ba73SBarry Smith   PetscErrorCode ierr;
189797f1f81fSBarry Smith   PetscInt       i,j;
189817ab2063SBarry Smith 
18993a40ed3dSBarry Smith   PetscFunctionBegin;
190017ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1901570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1902570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1903570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1904570b7f6dSBarry Smith #else
1905416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
190636db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
190717ab2063SBarry Smith     }
19088f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1909570b7f6dSBarry Smith #endif
191051f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19113a40ed3dSBarry Smith   } else if (type == NORM_1) {
191236db0b34SBarry Smith     PetscReal *tmp;
191397f1f81fSBarry Smith     PetscInt  *jj = a->j;
19141795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1915064f8208SBarry Smith     *nrm = 0.0;
1916416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1917bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
191817ab2063SBarry Smith     }
1919d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1920064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
192117ab2063SBarry Smith     }
1922606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
192351f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19243a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1925064f8208SBarry Smith     *nrm = 0.0;
1926d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1927bfeeae90SHong Zhang       v   = a->a + a->i[j];
192817ab2063SBarry Smith       sum = 0.0;
1929416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1930cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
193117ab2063SBarry Smith       }
1932064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
193317ab2063SBarry Smith     }
193451f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1935f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19363a40ed3dSBarry Smith   PetscFunctionReturn(0);
193717ab2063SBarry Smith }
193817ab2063SBarry Smith 
19394e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19404e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19414e938277SHong Zhang {
19424e938277SHong Zhang   PetscErrorCode ierr;
19434e938277SHong Zhang   PetscInt       i,j,anzj;
19444e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19454e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19464e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19474e938277SHong Zhang 
19484e938277SHong Zhang   PetscFunctionBegin;
19494e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1950854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1951785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1952785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19534e938277SHong Zhang 
19544e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19554e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
195626fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19574e938277SHong Zhang   /* Form ati for csr format of A^T. */
195826fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19594e938277SHong Zhang 
19604e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19614e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19624e938277SHong Zhang 
19634e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19644e938277SHong Zhang   for (i=0;i<am;i++) {
19654e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19664e938277SHong Zhang     for (j=0;j<anzj;j++) {
19674e938277SHong Zhang       atj[atfill[*aj]] = i;
19684e938277SHong Zhang       atfill[*aj++]   += 1;
19694e938277SHong Zhang     }
19704e938277SHong Zhang   }
19714e938277SHong Zhang 
19724e938277SHong Zhang   /* Clean up temporary space and complete requests. */
19734e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
1974ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
197533d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
1976a2f3521dSMark F. Adams 
19774e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
19784e938277SHong Zhang   b->free_a  = PETSC_FALSE;
19794e938277SHong Zhang   b->free_ij = PETSC_TRUE;
19804e938277SHong Zhang   b->nonew   = 0;
19814e938277SHong Zhang   PetscFunctionReturn(0);
19824e938277SHong Zhang }
19834e938277SHong Zhang 
1984fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
198517ab2063SBarry Smith {
1986416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1987416022c9SBarry Smith   Mat            C;
19886849ba73SBarry Smith   PetscErrorCode ierr;
1989d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
199054f21887SBarry Smith   MatScalar      *array = a->a;
199117ab2063SBarry Smith 
19923a40ed3dSBarry Smith   PetscFunctionBegin;
1993cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1994fc4dec0aSBarry Smith 
1995cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
1996854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
1997bfeeae90SHong Zhang 
1998bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
1999ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2000d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
200133d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
20027adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2003ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2004606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2005a541d17aSBarry Smith   } else {
2006a541d17aSBarry Smith     C = *B;
2007a541d17aSBarry Smith   }
2008a541d17aSBarry Smith 
200917ab2063SBarry Smith   for (i=0; i<m; i++) {
201017ab2063SBarry Smith     len    = ai[i+1]-ai[i];
201187d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2012b9b97703SBarry Smith     array += len;
2013b9b97703SBarry Smith     aj    += len;
201417ab2063SBarry Smith   }
20156d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20166d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
201717ab2063SBarry Smith 
2018cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2019416022c9SBarry Smith     *B = C;
202017ab2063SBarry Smith   } else {
202128be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
202217ab2063SBarry Smith   }
20233a40ed3dSBarry Smith   PetscFunctionReturn(0);
202417ab2063SBarry Smith }
202517ab2063SBarry Smith 
20267087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2027cd0d46ebSvictorle {
20283d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
202954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
203054f21887SBarry Smith   MatScalar      *va,*vb;
20316849ba73SBarry Smith   PetscErrorCode ierr;
203297f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2033cd0d46ebSvictorle 
2034cd0d46ebSvictorle   PetscFunctionBegin;
2035cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2036cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20375485867bSBarry Smith   if (ma!=nb || na!=mb) {
20385485867bSBarry Smith     *f = PETSC_FALSE;
20395485867bSBarry Smith     PetscFunctionReturn(0);
20405485867bSBarry Smith   }
2041cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2042cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2043cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2044785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2045785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2046cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2047cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2048cd0d46ebSvictorle 
2049cd0d46ebSvictorle   *f = PETSC_TRUE;
2050cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2051cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
205297f1f81fSBarry Smith       PetscInt    idc,idr;
20535485867bSBarry Smith       PetscScalar vc,vr;
2054cd0d46ebSvictorle       /* column/row index/value */
20555485867bSBarry Smith       idc = adx[aptr[i]];
20565485867bSBarry Smith       idr = bdx[bptr[idc]];
20575485867bSBarry Smith       vc  = va[aptr[i]];
20585485867bSBarry Smith       vr  = vb[bptr[idc]];
20595485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20605485867bSBarry Smith         *f = PETSC_FALSE;
20615485867bSBarry Smith         goto done;
2062cd0d46ebSvictorle       } else {
20635485867bSBarry Smith         aptr[i]++;
20645485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2065cd0d46ebSvictorle       }
2066cd0d46ebSvictorle     }
2067cd0d46ebSvictorle   }
2068cd0d46ebSvictorle done:
2069cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20703aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2071cd0d46ebSvictorle   PetscFunctionReturn(0);
2072cd0d46ebSvictorle }
2073cd0d46ebSvictorle 
20747087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20751cbb95d3SBarry Smith {
20763d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
207754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
207854f21887SBarry Smith   MatScalar      *va,*vb;
20791cbb95d3SBarry Smith   PetscErrorCode ierr;
20801cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20811cbb95d3SBarry Smith 
20821cbb95d3SBarry Smith   PetscFunctionBegin;
20831cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20841cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20851cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
20861cbb95d3SBarry Smith     *f = PETSC_FALSE;
20871cbb95d3SBarry Smith     PetscFunctionReturn(0);
20881cbb95d3SBarry Smith   }
20891cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
20901cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
20911cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2092785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2093785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
20941cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
20951cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
20961cbb95d3SBarry Smith 
20971cbb95d3SBarry Smith   *f = PETSC_TRUE;
20981cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
20991cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21001cbb95d3SBarry Smith       PetscInt    idc,idr;
21011cbb95d3SBarry Smith       PetscScalar vc,vr;
21021cbb95d3SBarry Smith       /* column/row index/value */
21031cbb95d3SBarry Smith       idc = adx[aptr[i]];
21041cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
21051cbb95d3SBarry Smith       vc  = va[aptr[i]];
21061cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
21071cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
21081cbb95d3SBarry Smith         *f = PETSC_FALSE;
21091cbb95d3SBarry Smith         goto done;
21101cbb95d3SBarry Smith       } else {
21111cbb95d3SBarry Smith         aptr[i]++;
21121cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21131cbb95d3SBarry Smith       }
21141cbb95d3SBarry Smith     }
21151cbb95d3SBarry Smith   }
21161cbb95d3SBarry Smith done:
21171cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21181cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21191cbb95d3SBarry Smith   PetscFunctionReturn(0);
21201cbb95d3SBarry Smith }
21211cbb95d3SBarry Smith 
2122ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21239e29f15eSvictorle {
2124dfbe8321SBarry Smith   PetscErrorCode ierr;
21256e111a19SKarl Rupp 
21269e29f15eSvictorle   PetscFunctionBegin;
21275485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21289e29f15eSvictorle   PetscFunctionReturn(0);
21299e29f15eSvictorle }
21309e29f15eSvictorle 
2131ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21321cbb95d3SBarry Smith {
21331cbb95d3SBarry Smith   PetscErrorCode ierr;
21346e111a19SKarl Rupp 
21351cbb95d3SBarry Smith   PetscFunctionBegin;
21361cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21371cbb95d3SBarry Smith   PetscFunctionReturn(0);
21381cbb95d3SBarry Smith }
21391cbb95d3SBarry Smith 
2140dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
214117ab2063SBarry Smith {
2142416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
214354f21887SBarry Smith   PetscScalar    *l,*r,x;
214454f21887SBarry Smith   MatScalar      *v;
2145dfbe8321SBarry Smith   PetscErrorCode ierr;
2146d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
214717ab2063SBarry Smith 
21483a40ed3dSBarry Smith   PetscFunctionBegin;
214917ab2063SBarry Smith   if (ll) {
21503ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21513ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2152e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2153e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21541ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2155416022c9SBarry Smith     v    = a->a;
215617ab2063SBarry Smith     for (i=0; i<m; i++) {
215717ab2063SBarry Smith       x = l[i];
2158416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21592205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
216017ab2063SBarry Smith     }
21611ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2162efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
216317ab2063SBarry Smith   }
216417ab2063SBarry Smith   if (rr) {
2165e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2166e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21671ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2168416022c9SBarry Smith     v    = a->a; jj = a->j;
21692205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21701ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2171efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
217217ab2063SBarry Smith   }
2173acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
21743a40ed3dSBarry Smith   PetscFunctionReturn(0);
217517ab2063SBarry Smith }
217617ab2063SBarry Smith 
21777dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
217817ab2063SBarry Smith {
2179db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21806849ba73SBarry Smith   PetscErrorCode ierr;
2181d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
218297f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21835d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21845d0c19d7SBarry Smith   PetscInt       nrows,ncols;
218597f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
218654f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2187416022c9SBarry Smith   Mat            C;
2188cdc6f3adSToby Isaac   PetscBool      stride;
218917ab2063SBarry Smith 
21903a40ed3dSBarry Smith   PetscFunctionBegin;
219199141d43SSatish Balay 
219217ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2193b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2194b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
219517ab2063SBarry Smith 
2196251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2197ff718158SBarry Smith   if (stride) {
2198ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2199ff718158SBarry Smith   } else {
2200ff718158SBarry Smith     first = 0;
2201ff718158SBarry Smith     step  = 0;
2202ff718158SBarry Smith   }
2203fee21e36SBarry Smith   if (stride && step == 1) {
220402834360SBarry Smith     /* special case of contiguous rows */
2205dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
220602834360SBarry Smith     /* loop over new rows determining lens and starting points */
220702834360SBarry Smith     for (i=0; i<nrows; i++) {
2208bfeeae90SHong Zhang       kstart = ai[irow[i]];
2209a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2210a91a9bebSLisandro Dalcin       starts[i] = kstart;
221102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2212bfeeae90SHong Zhang         if (aj[k] >= first) {
221302834360SBarry Smith           starts[i] = k;
221402834360SBarry Smith           break;
221502834360SBarry Smith         }
221602834360SBarry Smith       }
2217a2744918SBarry Smith       sum = 0;
221802834360SBarry Smith       while (k < kend) {
2219bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2220a2744918SBarry Smith         sum++;
222102834360SBarry Smith       }
2222a2744918SBarry Smith       lens[i] = sum;
222302834360SBarry Smith     }
222402834360SBarry Smith     /* create submatrix */
2225cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
222697f1f81fSBarry Smith       PetscInt n_cols,n_rows;
222708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2228e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2229d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
223008480c60SBarry Smith       C    = *B;
22313a40ed3dSBarry Smith     } else {
22323bef6203SJed Brown       PetscInt rbs,cbs;
2233ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2234f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22353bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22363bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22373bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22387adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2239ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
224008480c60SBarry Smith     }
2241db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2242db02288aSLois Curfman McInnes 
224302834360SBarry Smith     /* loop over rows inserting into submatrix */
2244db02288aSLois Curfman McInnes     a_new = c->a;
2245db02288aSLois Curfman McInnes     j_new = c->j;
2246db02288aSLois Curfman McInnes     i_new = c->i;
2247bfeeae90SHong Zhang 
224802834360SBarry Smith     for (i=0; i<nrows; i++) {
2249a2744918SBarry Smith       ii    = starts[i];
2250a2744918SBarry Smith       lensi = lens[i];
2251a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2252a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
225302834360SBarry Smith       }
225487828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2255a2744918SBarry Smith       a_new     += lensi;
2256a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2257a2744918SBarry Smith       c->ilen[i] = lensi;
225802834360SBarry Smith     }
22590e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22603a40ed3dSBarry Smith   } else {
226102834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22621795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2263854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22644dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22654dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22664dcab191SBarry 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);
22674dcab191SBarry Smith #endif
22684dcab191SBarry Smith       smap[icol[i]] = i+1;
22694dcab191SBarry Smith     }
22704dcab191SBarry Smith 
227102834360SBarry Smith     /* determine lens of each row */
227202834360SBarry Smith     for (i=0; i<nrows; i++) {
2273bfeeae90SHong Zhang       kstart  = ai[irow[i]];
227402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
227502834360SBarry Smith       lens[i] = 0;
227602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2277bfeeae90SHong Zhang         if (smap[aj[k]]) {
227802834360SBarry Smith           lens[i]++;
227902834360SBarry Smith         }
228002834360SBarry Smith       }
228102834360SBarry Smith     }
228217ab2063SBarry Smith     /* Create and fill new matrix */
2283a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2284ace3abfcSBarry Smith       PetscBool equal;
22850f5bd95cSBarry Smith 
228699141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2287e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2288d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2289f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2290d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
229108480c60SBarry Smith       C    = *B;
22923a40ed3dSBarry Smith     } else {
22933bef6203SJed Brown       PetscInt rbs,cbs;
2294ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2295f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22963bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22973bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22983bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22997adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2300ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
230108480c60SBarry Smith     }
230299141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
230317ab2063SBarry Smith     for (i=0; i<nrows; i++) {
230499141d43SSatish Balay       row      = irow[i];
2305bfeeae90SHong Zhang       kstart   = ai[row];
230699141d43SSatish Balay       kend     = kstart + a->ilen[row];
2307bfeeae90SHong Zhang       mat_i    = c->i[i];
230899141d43SSatish Balay       mat_j    = c->j + mat_i;
230999141d43SSatish Balay       mat_a    = c->a + mat_i;
231099141d43SSatish Balay       mat_ilen = c->ilen + i;
231117ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2312bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2313ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
231499141d43SSatish Balay           *mat_a++ = a->a[k];
231599141d43SSatish Balay           (*mat_ilen)++;
231699141d43SSatish Balay 
231717ab2063SBarry Smith         }
231817ab2063SBarry Smith       }
231917ab2063SBarry Smith     }
232002834360SBarry Smith     /* Free work space */
232102834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2322606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2323606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2324cdc6f3adSToby Isaac     /* sort */
2325cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2326cdc6f3adSToby Isaac       PetscInt ilen;
2327cdc6f3adSToby Isaac 
2328cdc6f3adSToby Isaac       mat_i = c->i[i];
2329cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2330cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2331cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2332390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2333cdc6f3adSToby Isaac     }
233402834360SBarry Smith   }
23356d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23366d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
233717ab2063SBarry Smith 
233817ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2339416022c9SBarry Smith   *B   = C;
23403a40ed3dSBarry Smith   PetscFunctionReturn(0);
234117ab2063SBarry Smith }
234217ab2063SBarry Smith 
2343fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
234482d44351SHong Zhang {
234582d44351SHong Zhang   PetscErrorCode ierr;
234682d44351SHong Zhang   Mat            B;
234782d44351SHong Zhang 
234882d44351SHong Zhang   PetscFunctionBegin;
2349c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
235082d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
235182d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
235233d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
235382d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
235482d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
235582d44351SHong Zhang     *subMat = B;
2356c2d650bdSHong Zhang   } else {
2357c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2358c2d650bdSHong Zhang   }
235982d44351SHong Zhang   PetscFunctionReturn(0);
236082d44351SHong Zhang }
236182d44351SHong Zhang 
23629a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2363a871dcd8SBarry Smith {
236463b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2365dfbe8321SBarry Smith   PetscErrorCode ierr;
236663b91edcSBarry Smith   Mat            outA;
2367ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
236863b91edcSBarry Smith 
23693a40ed3dSBarry Smith   PetscFunctionBegin;
2370e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23711df811f5SHong Zhang 
2372b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2373b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2374a871dcd8SBarry Smith 
237563b91edcSBarry Smith   outA             = inA;
2376d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2377f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2378f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
23792205254eSKarl Rupp 
2380c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23816bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
23822205254eSKarl Rupp 
2383c3122656SLisandro Dalcin   a->row = row;
23842205254eSKarl Rupp 
2385c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23866bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
23872205254eSKarl Rupp 
2388c3122656SLisandro Dalcin   a->col = col;
238963b91edcSBarry Smith 
239036db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23916bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23924c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
23933bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2394f0ec6fceSSatish Balay 
239594a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2396854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
23973bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
239894a9d846SBarry Smith   }
239963b91edcSBarry Smith 
2400f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2401137fb511SHong Zhang   if (row_identity && col_identity) {
2402ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2403137fb511SHong Zhang   } else {
2404719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2405137fb511SHong Zhang   }
24063a40ed3dSBarry Smith   PetscFunctionReturn(0);
2407a871dcd8SBarry Smith }
2408a871dcd8SBarry Smith 
2409f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2410f0b747eeSBarry Smith {
2411f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2412f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2413efee365bSSatish Balay   PetscErrorCode ierr;
2414c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24153a40ed3dSBarry Smith 
24163a40ed3dSBarry Smith   PetscFunctionBegin;
2417c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24188b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2419efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2420acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24213a40ed3dSBarry Smith   PetscFunctionReturn(0);
2422f0b747eeSBarry Smith }
2423f0b747eeSBarry Smith 
24245c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
242516b64355SHong Zhang {
242616b64355SHong Zhang   PetscErrorCode ierr;
242716b64355SHong Zhang   PetscInt       i;
242816b64355SHong Zhang 
242916b64355SHong Zhang   PetscFunctionBegin;
243016b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
243116b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
243216b64355SHong Zhang 
243316b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
243416b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
243516b64355SHong Zhang     }
243616b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
243716b64355SHong Zhang 
243816b64355SHong Zhang     if (submatj->rbuf1) {
243916b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
244016b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
244116b64355SHong Zhang     }
244216b64355SHong Zhang 
244316b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
244416b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
244516b64355SHong Zhang     }
244616b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
244716b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
244816b64355SHong Zhang   }
244916b64355SHong Zhang 
245016b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
245116b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
245216b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
245316b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
245416b64355SHong Zhang #else
245516b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
245616b64355SHong Zhang #endif
245716b64355SHong Zhang 
245816b64355SHong Zhang   if (!submatj->allcolumns) {
245916b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
246016b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
246116b64355SHong Zhang #else
246216b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
246316b64355SHong Zhang #endif
246416b64355SHong Zhang   }
246516b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
246616b64355SHong Zhang 
246716b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
246816b64355SHong Zhang   PetscFunctionReturn(0);
246916b64355SHong Zhang }
247016b64355SHong Zhang 
247116b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
247216b64355SHong Zhang {
247316b64355SHong Zhang   PetscErrorCode ierr;
247416b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
24755c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
247616b64355SHong Zhang 
247716b64355SHong Zhang   PetscFunctionBegin;
247816b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2479e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
248016b64355SHong Zhang   PetscFunctionReturn(0);
248116b64355SHong Zhang }
248216b64355SHong Zhang 
24837dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2484cddf8d76SBarry Smith {
2485dfbe8321SBarry Smith   PetscErrorCode ierr;
248697f1f81fSBarry Smith   PetscInt       i;
2487cddf8d76SBarry Smith 
24883a40ed3dSBarry Smith   PetscFunctionBegin;
2489cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2490df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2491cddf8d76SBarry Smith   }
2492cddf8d76SBarry Smith 
2493cddf8d76SBarry Smith   for (i=0; i<n; i++) {
24947dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2495cddf8d76SBarry Smith   }
24963a40ed3dSBarry Smith   PetscFunctionReturn(0);
2497cddf8d76SBarry Smith }
2498cddf8d76SBarry Smith 
249997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25004dcbc457SBarry Smith {
2501e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25026849ba73SBarry Smith   PetscErrorCode ierr;
25035d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25045d0c19d7SBarry Smith   const PetscInt *idx;
250597f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2506f1af5d2fSBarry Smith   PetscBT        table;
2507bbd702dbSSatish Balay 
25083a40ed3dSBarry Smith   PetscFunctionBegin;
2509d0f46423SBarry Smith   m  = A->rmap->n;
2510e4d965acSSatish Balay   ai = a->i;
2511bfeeae90SHong Zhang   aj = a->j;
25128a047759SSatish Balay 
2513e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
251406763907SSatish Balay 
2515854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
251653b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
251706763907SSatish Balay 
2518e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2519b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2520e4d965acSSatish Balay     isz  = 0;
25216831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2522e4d965acSSatish Balay 
2523e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25244dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2525b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2526e4d965acSSatish Balay 
2527dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2528e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25292205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25304dcbc457SBarry Smith     }
253106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25326bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2533e4d965acSSatish Balay 
253404a348a9SBarry Smith     k = 0;
253504a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
253604a348a9SBarry Smith       n = isz;
253706763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2538e4d965acSSatish Balay         row   = nidx[k];
2539e4d965acSSatish Balay         start = ai[row];
2540e4d965acSSatish Balay         end   = ai[row+1];
254104a348a9SBarry Smith         for (l = start; l<end; l++) {
2542efb16452SHong Zhang           val = aj[l];
25432205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2544e4d965acSSatish Balay         }
2545e4d965acSSatish Balay       }
2546e4d965acSSatish Balay     }
254770b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2548e4d965acSSatish Balay   }
254994bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2550606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25513a40ed3dSBarry Smith   PetscFunctionReturn(0);
25524dcbc457SBarry Smith }
255317ab2063SBarry Smith 
25540513a670SBarry Smith /* -------------------------------------------------------------- */
2555dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25560513a670SBarry Smith {
25570513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25586849ba73SBarry Smith   PetscErrorCode ierr;
25593b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25605d0c19d7SBarry Smith   const PetscInt *row,*col;
25615d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
256256cd22aeSBarry Smith   IS             icolp,irowp;
25630298fd71SBarry Smith   PetscInt       *cwork = NULL;
25640298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25650513a670SBarry Smith 
25663a40ed3dSBarry Smith   PetscFunctionBegin;
25674c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
256856cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25694c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
257056cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
25710513a670SBarry Smith 
25720513a670SBarry Smith   /* determine lengths of permuted rows */
2573854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
25742205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2575ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2576f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
257733d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
25787adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2579ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2580606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
25810513a670SBarry Smith 
2582785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
25830513a670SBarry Smith   for (i=0; i<m; i++) {
258432ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25852205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2586cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
258732ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25880513a670SBarry Smith   }
2589606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
25902205254eSKarl Rupp 
25913c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
25922205254eSKarl Rupp 
25930513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25940513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
259556cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
259656cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
25976bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
25986bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
25993a40ed3dSBarry Smith   PetscFunctionReturn(0);
26000513a670SBarry Smith }
26010513a670SBarry Smith 
2602dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2603cb5b572fSBarry Smith {
2604dfbe8321SBarry Smith   PetscErrorCode ierr;
2605cb5b572fSBarry Smith 
2606cb5b572fSBarry Smith   PetscFunctionBegin;
260733f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
260833f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2609be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2610be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2611be6bf707SBarry Smith 
2612700c5bfcSBarry 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");
2613d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2614cb5b572fSBarry Smith   } else {
2615cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2616cb5b572fSBarry Smith   }
2617cb5b572fSBarry Smith   PetscFunctionReturn(0);
2618cb5b572fSBarry Smith }
2619cb5b572fSBarry Smith 
26204994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2621273d9f13SBarry Smith {
2622dfbe8321SBarry Smith   PetscErrorCode ierr;
2623273d9f13SBarry Smith 
2624273d9f13SBarry Smith   PetscFunctionBegin;
2625ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2626273d9f13SBarry Smith   PetscFunctionReturn(0);
2627273d9f13SBarry Smith }
2628273d9f13SBarry Smith 
26298c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26306c0721eeSBarry Smith {
26316c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26326e111a19SKarl Rupp 
26336c0721eeSBarry Smith   PetscFunctionBegin;
26346c0721eeSBarry Smith   *array = a->a;
26356c0721eeSBarry Smith   PetscFunctionReturn(0);
26366c0721eeSBarry Smith }
26376c0721eeSBarry Smith 
26388c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26396c0721eeSBarry Smith {
26406c0721eeSBarry Smith   PetscFunctionBegin;
26416c0721eeSBarry Smith   PetscFunctionReturn(0);
26426c0721eeSBarry Smith }
2643273d9f13SBarry Smith 
26448229c054SShri Abhyankar /*
26458229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26468229c054SShri Abhyankar    have different nonzero structure.
26478229c054SShri Abhyankar */
2648b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2649ec7775f6SShri Abhyankar {
2650b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2651ec7775f6SShri Abhyankar 
2652ec7775f6SShri Abhyankar   PetscFunctionBegin;
2653ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2654ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2655b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2656b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2657b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26588af7cee1SJed Brown     nnz[i] = 0;
26598af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2660b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2661b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26628af7cee1SJed Brown       nnz[i]++;
26638af7cee1SJed Brown     }
26648af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2665ec7775f6SShri Abhyankar   }
2666ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2667ec7775f6SShri Abhyankar }
2668ec7775f6SShri Abhyankar 
2669b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2670b264fe52SHong Zhang {
2671b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2672b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2673b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2674b264fe52SHong Zhang   PetscErrorCode ierr;
2675b264fe52SHong Zhang 
2676b264fe52SHong Zhang   PetscFunctionBegin;
2677b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2678b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2679b264fe52SHong Zhang   PetscFunctionReturn(0);
2680b264fe52SHong Zhang }
2681b264fe52SHong Zhang 
2682f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2683ac90fabeSBarry Smith {
2684dfbe8321SBarry Smith   PetscErrorCode ierr;
2685ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2686c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2687ac90fabeSBarry Smith 
2688ac90fabeSBarry Smith   PetscFunctionBegin;
2689c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2690ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2691f4df32b1SMatthew Knepley     PetscScalar alpha = a;
26928b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2693acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2694a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2695ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2696ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2697ac90fabeSBarry Smith   } else {
26988229c054SShri Abhyankar     Mat      B;
26998229c054SShri Abhyankar     PetscInt *nnz;
2700785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2701ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2702bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27034aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
270433d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2705176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27068229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2707ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2708ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
270928be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27108229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2711ac90fabeSBarry Smith   }
2712ac90fabeSBarry Smith   PetscFunctionReturn(0);
2713ac90fabeSBarry Smith }
2714ac90fabeSBarry Smith 
27157087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2716354c94deSBarry Smith {
2717354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2718354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2719354c94deSBarry Smith   PetscInt    i,nz;
2720354c94deSBarry Smith   PetscScalar *a;
2721354c94deSBarry Smith 
2722354c94deSBarry Smith   PetscFunctionBegin;
2723354c94deSBarry Smith   nz = aij->nz;
2724354c94deSBarry Smith   a  = aij->a;
27252205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2726354c94deSBarry Smith #else
2727354c94deSBarry Smith   PetscFunctionBegin;
2728354c94deSBarry Smith #endif
2729354c94deSBarry Smith   PetscFunctionReturn(0);
2730354c94deSBarry Smith }
2731354c94deSBarry Smith 
2732985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2733e34fafa9SBarry Smith {
2734e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2735e34fafa9SBarry Smith   PetscErrorCode ierr;
2736d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2737e34fafa9SBarry Smith   PetscReal      atmp;
2738985db425SBarry Smith   PetscScalar    *x;
2739e34fafa9SBarry Smith   MatScalar      *aa;
2740e34fafa9SBarry Smith 
2741e34fafa9SBarry Smith   PetscFunctionBegin;
2742e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2743e34fafa9SBarry Smith   aa = a->a;
2744e34fafa9SBarry Smith   ai = a->i;
2745e34fafa9SBarry Smith   aj = a->j;
2746e34fafa9SBarry Smith 
2747985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2748e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2749e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2750e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2751e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2752e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27539189402eSHong Zhang     x[i]  = 0.0;
2754e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2755985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2756985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2757985db425SBarry Smith       aa++; aj++;
2758985db425SBarry Smith     }
2759985db425SBarry Smith   }
2760985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2761985db425SBarry Smith   PetscFunctionReturn(0);
2762985db425SBarry Smith }
2763985db425SBarry Smith 
2764985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2765985db425SBarry Smith {
2766985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2767985db425SBarry Smith   PetscErrorCode ierr;
2768d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2769985db425SBarry Smith   PetscScalar    *x;
2770985db425SBarry Smith   MatScalar      *aa;
2771985db425SBarry Smith 
2772985db425SBarry Smith   PetscFunctionBegin;
2773e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2774985db425SBarry Smith   aa = a->a;
2775985db425SBarry Smith   ai = a->i;
2776985db425SBarry Smith   aj = a->j;
2777985db425SBarry Smith 
2778985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2779985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2780985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2781e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2782985db425SBarry Smith   for (i=0; i<m; i++) {
2783985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2784d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2785985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2786985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2787985db425SBarry Smith       x[i] = 0.0;
2788985db425SBarry Smith       if (idx) {
2789985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2790985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2791985db425SBarry Smith           if (aj[j] > j) {
2792985db425SBarry Smith             idx[i] = j;
2793985db425SBarry Smith             break;
2794985db425SBarry Smith           }
2795985db425SBarry Smith         }
2796985db425SBarry Smith       }
2797985db425SBarry Smith     }
2798985db425SBarry Smith     for (j=0; j<ncols; j++) {
2799985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2800985db425SBarry Smith       aa++; aj++;
2801985db425SBarry Smith     }
2802985db425SBarry Smith   }
2803985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2804985db425SBarry Smith   PetscFunctionReturn(0);
2805985db425SBarry Smith }
2806985db425SBarry Smith 
2807c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2808c87e5d42SMatthew Knepley {
2809c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2810c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2811c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2812c87e5d42SMatthew Knepley   PetscReal      atmp;
2813c87e5d42SMatthew Knepley   PetscScalar    *x;
2814c87e5d42SMatthew Knepley   MatScalar      *aa;
2815c87e5d42SMatthew Knepley 
2816c87e5d42SMatthew Knepley   PetscFunctionBegin;
2817e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2818c87e5d42SMatthew Knepley   aa = a->a;
2819c87e5d42SMatthew Knepley   ai = a->i;
2820c87e5d42SMatthew Knepley   aj = a->j;
2821c87e5d42SMatthew Knepley 
2822c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2823c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2824c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
282560e0710aSBarry 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);
2826c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2827c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2828289a08f5SMatthew Knepley     if (ncols) {
2829289a08f5SMatthew Knepley       /* Get first nonzero */
2830289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2831289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28322205254eSKarl Rupp         if (atmp > 1.0e-12) {
28332205254eSKarl Rupp           x[i] = atmp;
28342205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28352205254eSKarl Rupp           break;
28362205254eSKarl Rupp         }
2837289a08f5SMatthew Knepley       }
283812431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2839289a08f5SMatthew Knepley     } else {
2840289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2841289a08f5SMatthew Knepley     }
2842c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2843c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2844289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2845c87e5d42SMatthew Knepley       aa++; aj++;
2846c87e5d42SMatthew Knepley     }
2847c87e5d42SMatthew Knepley   }
2848c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2849c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2850c87e5d42SMatthew Knepley }
2851c87e5d42SMatthew Knepley 
2852985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2853985db425SBarry Smith {
2854985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2855985db425SBarry Smith   PetscErrorCode  ierr;
2856d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2857d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2858985db425SBarry Smith   PetscScalar     *x;
2859d9ca1df4SBarry Smith   const MatScalar *aa;
2860985db425SBarry Smith 
2861985db425SBarry Smith   PetscFunctionBegin;
2862e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2863985db425SBarry Smith   aa = a->a;
2864985db425SBarry Smith   ai = a->i;
2865985db425SBarry Smith   aj = a->j;
2866985db425SBarry Smith 
2867985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2868985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2869985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2870e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2871985db425SBarry Smith   for (i=0; i<m; i++) {
2872985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2873d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2874985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2875985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2876985db425SBarry Smith       x[i] = 0.0;
2877985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2878985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2879985db425SBarry Smith         for (j=0; j<ncols; j++) {
2880985db425SBarry Smith           if (aj[j] > j) {
2881985db425SBarry Smith             idx[i] = j;
2882985db425SBarry Smith             break;
2883985db425SBarry Smith           }
2884985db425SBarry Smith         }
2885985db425SBarry Smith       }
2886985db425SBarry Smith     }
2887985db425SBarry Smith     for (j=0; j<ncols; j++) {
2888985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2889985db425SBarry Smith       aa++; aj++;
2890e34fafa9SBarry Smith     }
2891e34fafa9SBarry Smith   }
2892e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2893e34fafa9SBarry Smith   PetscFunctionReturn(0);
2894e34fafa9SBarry Smith }
2895bbead8a2SBarry Smith 
2896bbead8a2SBarry Smith #include <petscblaslapack.h>
2897af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2898bbead8a2SBarry Smith 
2899713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2900bbead8a2SBarry Smith {
2901bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2902bbead8a2SBarry Smith   PetscErrorCode ierr;
290333d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2904bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2905bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29061a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2907bbead8a2SBarry Smith 
2908bbead8a2SBarry Smith   PetscFunctionBegin;
2909a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29104a0d0026SBarry Smith   if (a->ibdiagvalid) {
29114a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29124a0d0026SBarry Smith     PetscFunctionReturn(0);
29134a0d0026SBarry Smith   }
2914bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2915bbead8a2SBarry Smith   if (!a->ibdiag) {
2916785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29173bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2918bbead8a2SBarry Smith   }
2919bbead8a2SBarry Smith   diag = a->ibdiag;
2920bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2921bbead8a2SBarry Smith   /* factor and invert each block */
2922bbead8a2SBarry Smith   switch (bs) {
2923bbead8a2SBarry Smith   case 1:
2924bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2925bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2926ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2927ec1892c8SHong Zhang         if (allowzeropivot) {
29287b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29297b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29307b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29317b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29327b6c816cSBarry 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);
2933ec1892c8SHong Zhang       }
2934bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2935bbead8a2SBarry Smith     }
2936bbead8a2SBarry Smith     break;
2937bbead8a2SBarry Smith   case 2:
2938bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2939bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2940bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2941a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29427b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
294396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2944bbead8a2SBarry Smith       diag += 4;
2945bbead8a2SBarry Smith     }
2946bbead8a2SBarry Smith     break;
2947bbead8a2SBarry Smith   case 3:
2948bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2949bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2950bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2951a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29527b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
295396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2954bbead8a2SBarry Smith       diag += 9;
2955bbead8a2SBarry Smith     }
2956bbead8a2SBarry Smith     break;
2957bbead8a2SBarry Smith   case 4:
2958bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2959bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2960bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2961a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29627b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
296396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2964bbead8a2SBarry Smith       diag += 16;
2965bbead8a2SBarry Smith     }
2966bbead8a2SBarry Smith     break;
2967bbead8a2SBarry Smith   case 5:
2968bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2969bbead8a2SBarry 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;
2970bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2971a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29727b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2974bbead8a2SBarry Smith       diag += 25;
2975bbead8a2SBarry Smith     }
2976bbead8a2SBarry Smith     break;
2977bbead8a2SBarry Smith   case 6:
2978bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2979bbead8a2SBarry 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;
2980bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
2981a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29827b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2984bbead8a2SBarry Smith       diag += 36;
2985bbead8a2SBarry Smith     }
2986bbead8a2SBarry Smith     break;
2987bbead8a2SBarry Smith   case 7:
2988bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2989bbead8a2SBarry 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;
2990bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
2991a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29927b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
2994bbead8a2SBarry Smith       diag += 49;
2995bbead8a2SBarry Smith     }
2996bbead8a2SBarry Smith     break;
2997bbead8a2SBarry Smith   default:
2998dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
2999bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3000bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3001bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3002bbead8a2SBarry Smith       }
3003bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30045f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30057b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
300696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3007bbead8a2SBarry Smith       diag += bs2;
3008bbead8a2SBarry Smith     }
3009bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3010bbead8a2SBarry Smith   }
3011bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3012bbead8a2SBarry Smith   PetscFunctionReturn(0);
3013bbead8a2SBarry Smith }
3014bbead8a2SBarry Smith 
301573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
301673a71a0fSBarry Smith {
301773a71a0fSBarry Smith   PetscErrorCode ierr;
301873a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
301973a71a0fSBarry Smith   PetscScalar    a;
302073a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
302173a71a0fSBarry Smith 
302273a71a0fSBarry Smith   PetscFunctionBegin;
302373a71a0fSBarry Smith   if (!x->assembled) {
302473a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
302573a71a0fSBarry Smith     for (i=0; i<m; i++) {
302673a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
302773a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
302873a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
302973a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
303073a71a0fSBarry Smith       }
303173a71a0fSBarry Smith     }
303273a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
303373a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
303473a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
303573a71a0fSBarry Smith   PetscFunctionReturn(0);
303673a71a0fSBarry Smith }
303773a71a0fSBarry Smith 
30387d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30397d68702bSBarry Smith {
30407d68702bSBarry Smith   PetscErrorCode ierr;
30417d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30427d68702bSBarry Smith 
30437d68702bSBarry Smith   PetscFunctionBegin;
30446f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30457d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30467d68702bSBarry Smith   }
30477d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30487d68702bSBarry Smith   PetscFunctionReturn(0);
30497d68702bSBarry Smith }
30507d68702bSBarry Smith 
3051682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30520a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3053cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3054cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3055cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
305697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30577c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30587c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3059db4efbfdSBarry Smith                                         0,
3060db4efbfdSBarry Smith                                         0,
3061db4efbfdSBarry Smith                                         0,
3062db4efbfdSBarry Smith                                 /* 10*/ 0,
3063cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3064cb5b572fSBarry Smith                                         0,
306541f059aeSBarry Smith                                         MatSOR_SeqAIJ,
306617ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
306797304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3068cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3069cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3070cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3071cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
307297304618SKris Buschelman                                 /* 20*/ 0,
3073cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3074cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3075cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3076d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3077db4efbfdSBarry Smith                                         0,
3078db4efbfdSBarry Smith                                         0,
3079db4efbfdSBarry Smith                                         0,
3080db4efbfdSBarry Smith                                         0,
30814994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3082db4efbfdSBarry Smith                                         0,
3083db4efbfdSBarry Smith                                         0,
30848c778c55SBarry Smith                                         0,
30858c778c55SBarry Smith                                         0,
3086d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3087cb5b572fSBarry Smith                                         0,
3088cb5b572fSBarry Smith                                         0,
3089cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3090cb5b572fSBarry Smith                                         0,
3091d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
30927dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3093cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3094cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3095cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3096d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3097cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
30987d68702bSBarry Smith                                         MatShift_SeqAIJ,
309979299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31006e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
310173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31023b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31033b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31043b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3105a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
310693dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3107b9617806SBarry Smith                                         0,
31080513a670SBarry Smith                                         0,
3109cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3110cda55fadSBarry Smith                                         0,
3111d519adbfSMatthew Knepley                                 /* 59*/ 0,
3112b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3113b9b97703SBarry Smith                                         MatView_SeqAIJ,
3114357abbc8SBarry Smith                                         0,
3115321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3116321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3117321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3118ee4f033dSBarry Smith                                         0,
3119ee4f033dSBarry Smith                                         0,
3120ee4f033dSBarry Smith                                         0,
3121d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3122c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3123ee4f033dSBarry Smith                                         0,
3124dcf5cc72SBarry Smith                                         0,
31252c93a97aSBarry Smith                                         0,
31262c93a97aSBarry Smith                                 /* 74*/ 0,
31273acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
312897304618SKris Buschelman                                         0,
312997304618SKris Buschelman                                         0,
313097304618SKris Buschelman                                         0,
31316ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
313297304618SKris Buschelman                                         0,
313397304618SKris Buschelman                                         0,
313497304618SKris Buschelman                                         0,
3135bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3136d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31371cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31386284ec50SHong Zhang                                         0,
31396284ec50SHong Zhang                                         0,
3140bc011b1eSHong Zhang                                         0,
3141d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
314226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
314326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
314465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31454a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
314665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31476fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31486fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31496fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31502121bac1SHong Zhang                                         0,
31512121bac1SHong Zhang                                 /* 99*/ 0,
3152609c6c4dSKris Buschelman                                         0,
3153609c6c4dSKris Buschelman                                         0,
315487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
315587d4246cSBarry Smith                                         0,
3156d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
315799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3158f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3159f5edf698SHong Zhang                                         0,
31602bebee5dSHong Zhang                                         0,
3161cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3162985db425SBarry Smith                                         0,
31632af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31642af78befSBarry Smith                                         0,
3165599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3166d519adbfSMatthew Knepley                                 /*114*/ 0,
3167599ef60dSHong Zhang                                         0,
31683c2a7987SHong Zhang                                         0,
3169fe97e370SBarry Smith                                         0,
3170fbdbba38SShri Abhyankar                                         0,
3171fbdbba38SShri Abhyankar                                 /*119*/ 0,
3172fbdbba38SShri Abhyankar                                         0,
3173fbdbba38SShri Abhyankar                                         0,
317482d44351SHong Zhang                                         0,
3175b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
31760716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3177bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
317837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
317937868618SMatthew G Knepley                                         0,
318037868618SMatthew G Knepley                                         0,
31815df89d91SHong Zhang                                 /*129*/ 0,
318275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
318375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
318475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3185b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3186b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
31872b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
31882b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
31892b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
31903964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
31913964eb88SJed Brown                                  /*139*/0,
3192f9426fe0SMark Adams                                         0,
31931919a2e2SJed Brown                                         0,
31943a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
31959c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
31969c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
31979e29f15eSvictorle };
319817ab2063SBarry Smith 
31997087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3200bef8e0ddSBarry Smith {
3201bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
320297f1f81fSBarry Smith   PetscInt   i,nz,n;
3203bef8e0ddSBarry Smith 
3204bef8e0ddSBarry Smith   PetscFunctionBegin;
3205bef8e0ddSBarry Smith   nz = aij->maxnz;
3206d0f46423SBarry Smith   n  = mat->rmap->n;
3207bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3208bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3209bef8e0ddSBarry Smith   }
3210bef8e0ddSBarry Smith   aij->nz = nz;
3211bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3212bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3213bef8e0ddSBarry Smith   }
3214bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3215bef8e0ddSBarry Smith }
3216bef8e0ddSBarry Smith 
3217bef8e0ddSBarry Smith /*@
3218bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3219bef8e0ddSBarry Smith        in the matrix.
3220bef8e0ddSBarry Smith 
3221bef8e0ddSBarry Smith   Input Parameters:
3222bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3223bef8e0ddSBarry Smith -  indices - the column indices
3224bef8e0ddSBarry Smith 
322515091d37SBarry Smith   Level: advanced
322615091d37SBarry Smith 
3227bef8e0ddSBarry Smith   Notes:
3228bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3229bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3230bef8e0ddSBarry Smith   of the MatSetValues() operation.
3231bef8e0ddSBarry Smith 
3232bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3233d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3234bef8e0ddSBarry Smith 
3235bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3236bef8e0ddSBarry Smith 
3237b9617806SBarry Smith     The indices should start with zero, not one.
3238b9617806SBarry Smith 
3239bef8e0ddSBarry Smith @*/
32407087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3241bef8e0ddSBarry Smith {
32424ac538c5SBarry Smith   PetscErrorCode ierr;
3243bef8e0ddSBarry Smith 
3244bef8e0ddSBarry Smith   PetscFunctionBegin;
32450700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32464482741eSBarry Smith   PetscValidPointer(indices,2);
32474ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3248bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3249bef8e0ddSBarry Smith }
3250bef8e0ddSBarry Smith 
3251be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3252be6bf707SBarry Smith 
32537087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3254be6bf707SBarry Smith {
3255be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32566849ba73SBarry Smith   PetscErrorCode ierr;
3257d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3258be6bf707SBarry Smith 
3259be6bf707SBarry Smith   PetscFunctionBegin;
3260169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3261be6bf707SBarry Smith 
3262be6bf707SBarry Smith   /* allocate space for values if not already there */
3263be6bf707SBarry Smith   if (!aij->saved_values) {
3264854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32653bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3266be6bf707SBarry Smith   }
3267be6bf707SBarry Smith 
3268be6bf707SBarry Smith   /* copy values over */
326987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3270be6bf707SBarry Smith   PetscFunctionReturn(0);
3271be6bf707SBarry Smith }
3272be6bf707SBarry Smith 
3273be6bf707SBarry Smith /*@
3274be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3275be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3276be6bf707SBarry Smith        nonlinear portion.
3277be6bf707SBarry Smith 
3278be6bf707SBarry Smith    Collect on Mat
3279be6bf707SBarry Smith 
3280be6bf707SBarry Smith   Input Parameters:
32810e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3282be6bf707SBarry Smith 
328315091d37SBarry Smith   Level: advanced
328415091d37SBarry Smith 
3285be6bf707SBarry Smith   Common Usage, with SNESSolve():
3286be6bf707SBarry Smith $    Create Jacobian matrix
3287be6bf707SBarry Smith $    Set linear terms into matrix
3288be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3289be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3290be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3291512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3292be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3293be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3294be6bf707SBarry Smith $    In your Jacobian routine
3295be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3296be6bf707SBarry Smith $      Set nonlinear terms in matrix
3297be6bf707SBarry Smith 
3298be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3299be6bf707SBarry Smith $    // build linear portion of Jacobian
3300512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3301be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3302be6bf707SBarry Smith $    loop over nonlinear iterations
3303be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3304be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3305be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3306be6bf707SBarry Smith $       Solve linear system with Jacobian
3307be6bf707SBarry Smith $    endloop
3308be6bf707SBarry Smith 
3309be6bf707SBarry Smith   Notes:
3310be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3311512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3312be6bf707SBarry Smith     calling this routine.
3313be6bf707SBarry Smith 
33140c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33150c468ba9SBarry Smith     and does not allocated additional space.
33160c468ba9SBarry Smith 
3317be6bf707SBarry Smith .seealso: MatRetrieveValues()
3318be6bf707SBarry Smith 
3319be6bf707SBarry Smith @*/
33207087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3321be6bf707SBarry Smith {
33224ac538c5SBarry Smith   PetscErrorCode ierr;
3323be6bf707SBarry Smith 
3324be6bf707SBarry Smith   PetscFunctionBegin;
33250700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3326e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3327e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33284ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3329be6bf707SBarry Smith   PetscFunctionReturn(0);
3330be6bf707SBarry Smith }
3331be6bf707SBarry Smith 
33327087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3333be6bf707SBarry Smith {
3334be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33356849ba73SBarry Smith   PetscErrorCode ierr;
3336d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3337be6bf707SBarry Smith 
3338be6bf707SBarry Smith   PetscFunctionBegin;
3339169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3340f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3341be6bf707SBarry Smith   /* copy values over */
334287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3343be6bf707SBarry Smith   PetscFunctionReturn(0);
3344be6bf707SBarry Smith }
3345be6bf707SBarry Smith 
3346be6bf707SBarry Smith /*@
3347be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3348be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3349be6bf707SBarry Smith        nonlinear portion.
3350be6bf707SBarry Smith 
3351be6bf707SBarry Smith    Collect on Mat
3352be6bf707SBarry Smith 
3353be6bf707SBarry Smith   Input Parameters:
3354386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3355be6bf707SBarry Smith 
335615091d37SBarry Smith   Level: advanced
335715091d37SBarry Smith 
3358be6bf707SBarry Smith .seealso: MatStoreValues()
3359be6bf707SBarry Smith 
3360be6bf707SBarry Smith @*/
33617087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3362be6bf707SBarry Smith {
33634ac538c5SBarry Smith   PetscErrorCode ierr;
3364be6bf707SBarry Smith 
3365be6bf707SBarry Smith   PetscFunctionBegin;
33660700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3367e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3368e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33694ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3370be6bf707SBarry Smith   PetscFunctionReturn(0);
3371be6bf707SBarry Smith }
3372be6bf707SBarry Smith 
3373f83d6046SBarry Smith 
3374be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
337517ab2063SBarry Smith /*@C
3376682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33770d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33786e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
337951c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33802bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
338117ab2063SBarry Smith 
3382db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3383db81eaa0SLois Curfman McInnes 
338417ab2063SBarry Smith    Input Parameters:
3385db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
338617ab2063SBarry Smith .  m - number of rows
338717ab2063SBarry Smith .  n - number of columns
338817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
338951c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33900298fd71SBarry Smith          (possibly different for each row) or NULL
339117ab2063SBarry Smith 
339217ab2063SBarry Smith    Output Parameter:
3393416022c9SBarry Smith .  A - the matrix
339417ab2063SBarry Smith 
3395175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3396ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3397175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3398175b88e8SBarry Smith 
3399b259b22eSLois Curfman McInnes    Notes:
340049a6f317SBarry Smith    If nnz is given then nz is ignored
340149a6f317SBarry Smith 
340217ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
340317ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34040002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
340544cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
340617ab2063SBarry Smith 
340717ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34080298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34093d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34106da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
341117ab2063SBarry Smith 
3412682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34134fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3414682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34156c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34166c7ebb05SLois Curfman McInnes 
34176c7ebb05SLois Curfman McInnes    Options Database Keys:
3418698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34199db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
342017ab2063SBarry Smith 
3421027ccd11SLois Curfman McInnes    Level: intermediate
3422027ccd11SLois Curfman McInnes 
342369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
342436db0b34SBarry Smith 
342517ab2063SBarry Smith @*/
34267087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
342717ab2063SBarry Smith {
3428dfbe8321SBarry Smith   PetscErrorCode ierr;
34296945ee14SBarry Smith 
34303a40ed3dSBarry Smith   PetscFunctionBegin;
3431f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3432117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3433c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3434d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3435273d9f13SBarry Smith   PetscFunctionReturn(0);
3436273d9f13SBarry Smith }
3437273d9f13SBarry Smith 
3438273d9f13SBarry Smith /*@C
3439273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3440273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3441273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3442273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3443273d9f13SBarry Smith 
3444273d9f13SBarry Smith    Collective on MPI_Comm
3445273d9f13SBarry Smith 
3446273d9f13SBarry Smith    Input Parameters:
34471c4f3114SJed Brown +  B - The matrix
3448273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3449273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34500298fd71SBarry Smith          (possibly different for each row) or NULL
3451273d9f13SBarry Smith 
3452273d9f13SBarry Smith    Notes:
345349a6f317SBarry Smith      If nnz is given then nz is ignored
345449a6f317SBarry Smith 
3455273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3456273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3457273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3458273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3459273d9f13SBarry Smith 
3460273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34610298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3462273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3463273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3464273d9f13SBarry Smith 
3465aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3466aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3467aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3468aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3469aa95bbe8SBarry Smith 
3470a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3471a96a251dSBarry Smith    entries or columns indices
3472a96a251dSBarry Smith 
3473273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3474273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3475273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3476273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3477273d9f13SBarry Smith 
3478273d9f13SBarry Smith    Options Database Keys:
3479698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3480698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3481273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3482273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3483273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3484273d9f13SBarry Smith 
3485273d9f13SBarry Smith    Level: intermediate
3486273d9f13SBarry Smith 
348769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3488273d9f13SBarry Smith 
3489273d9f13SBarry Smith @*/
34907087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3491273d9f13SBarry Smith {
34924ac538c5SBarry Smith   PetscErrorCode ierr;
3493a23d5eceSKris Buschelman 
3494a23d5eceSKris Buschelman   PetscFunctionBegin;
34956ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
34966ba663aaSJed Brown   PetscValidType(B,1);
34974ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3498a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3499a23d5eceSKris Buschelman }
3500a23d5eceSKris Buschelman 
35017087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3502a23d5eceSKris Buschelman {
3503273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35042576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35056849ba73SBarry Smith   PetscErrorCode ierr;
350697f1f81fSBarry Smith   PetscInt       i;
3507273d9f13SBarry Smith 
3508273d9f13SBarry Smith   PetscFunctionBegin;
35092576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3510a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3511c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3512c461c341SBarry Smith     nz             = 0;
3513c461c341SBarry Smith   }
3514c461c341SBarry Smith 
351526283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
351626283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3517899cda47SBarry Smith 
3518435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
351960e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3520b73539f3SBarry Smith   if (nnz) {
3521d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
352260e0710aSBarry 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]);
352360e0710aSBarry 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);
3524b73539f3SBarry Smith     }
3525b73539f3SBarry Smith   }
3526b73539f3SBarry Smith 
3527273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35282205254eSKarl Rupp 
3529273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3530273d9f13SBarry Smith 
3531ab93d7beSBarry Smith   if (!skipallocation) {
35322ee49352SLisandro Dalcin     if (!b->imax) {
3533dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35343bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35352ee49352SLisandro Dalcin     }
3536273d9f13SBarry Smith     if (!nnz) {
3537435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3538c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3539d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3540d0f46423SBarry Smith       nz = nz*B->rmap->n;
3541273d9f13SBarry Smith     } else {
3542273d9f13SBarry Smith       nz = 0;
3543d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3544273d9f13SBarry Smith     }
3545ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35462205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3547ab93d7beSBarry Smith 
3548273d9f13SBarry Smith     /* allocate the matrix space */
354953dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35502ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3551dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35523bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3553bfeeae90SHong Zhang     b->i[0] = 0;
3554d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35555da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35565da197adSKris Buschelman     }
3557273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3558e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3559e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3560c461c341SBarry Smith   } else {
3561e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3562e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3563c461c341SBarry Smith   }
3564273d9f13SBarry Smith 
3565273d9f13SBarry Smith   b->nz               = 0;
3566273d9f13SBarry Smith   b->maxnz            = nz;
3567273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
35682205254eSKarl Rupp   if (realalloc) {
35692205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
35702205254eSKarl Rupp   }
3571cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3572cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3573273d9f13SBarry Smith   PetscFunctionReturn(0);
3574273d9f13SBarry Smith }
3575273d9f13SBarry Smith 
357658d36128SBarry Smith /*@
3577a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3578a1661176SMatthew Knepley 
3579a1661176SMatthew Knepley    Input Parameters:
3580a1661176SMatthew Knepley +  B - the matrix
3581a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3582a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3583a1661176SMatthew Knepley -  v - optional values in the matrix
3584a1661176SMatthew Knepley 
3585a1661176SMatthew Knepley    Level: developer
3586a1661176SMatthew Knepley 
358758d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
358858d36128SBarry Smith 
3589a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3590a1661176SMatthew Knepley 
3591a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3592a1661176SMatthew Knepley @*/
3593a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3594a1661176SMatthew Knepley {
3595a1661176SMatthew Knepley   PetscErrorCode ierr;
3596a1661176SMatthew Knepley 
3597a1661176SMatthew Knepley   PetscFunctionBegin;
35980700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35996ba663aaSJed Brown   PetscValidType(B,1);
36004ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3601a1661176SMatthew Knepley   PetscFunctionReturn(0);
3602a1661176SMatthew Knepley }
3603a1661176SMatthew Knepley 
36047087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3605a1661176SMatthew Knepley {
3606a1661176SMatthew Knepley   PetscInt       i;
3607a1661176SMatthew Knepley   PetscInt       m,n;
3608a1661176SMatthew Knepley   PetscInt       nz;
3609a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3610a1661176SMatthew Knepley   PetscScalar    *values;
3611a1661176SMatthew Knepley   PetscErrorCode ierr;
3612a1661176SMatthew Knepley 
3613a1661176SMatthew Knepley   PetscFunctionBegin;
361465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3615779a8d59SSatish Balay 
3616779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3617779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3618779a8d59SSatish Balay 
3619779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3620854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3621a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3622b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3623a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
362465e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3625a1661176SMatthew Knepley     nnz[i] = nz;
3626a1661176SMatthew Knepley   }
3627a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3628a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3629a1661176SMatthew Knepley 
3630a1661176SMatthew Knepley   if (v) {
3631a1661176SMatthew Knepley     values = (PetscScalar*) v;
3632a1661176SMatthew Knepley   } else {
36331795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3634a1661176SMatthew Knepley   }
3635a1661176SMatthew Knepley 
3636a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3637b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3638b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3639a1661176SMatthew Knepley   }
3640a1661176SMatthew Knepley 
3641a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3642a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3643a1661176SMatthew Knepley 
3644a1661176SMatthew Knepley   if (!v) {
3645a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3646a1661176SMatthew Knepley   }
36477827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3648a1661176SMatthew Knepley   PetscFunctionReturn(0);
3649a1661176SMatthew Knepley }
3650a1661176SMatthew Knepley 
3651c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3652af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3653170fe5c8SBarry Smith 
3654170fe5c8SBarry Smith /*
3655170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3656170fe5c8SBarry Smith 
3657170fe5c8SBarry Smith                n                       p                          p
3658170fe5c8SBarry Smith         (              )       (              )         (                  )
3659170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3660170fe5c8SBarry Smith         (              )       (              )         (                  )
3661170fe5c8SBarry Smith 
3662170fe5c8SBarry Smith */
3663170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3664170fe5c8SBarry Smith {
3665170fe5c8SBarry Smith   PetscErrorCode    ierr;
3666170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3667170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3668170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
36691de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3670170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3671170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3672170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3673170fe5c8SBarry Smith 
3674170fe5c8SBarry Smith   PetscFunctionBegin;
3675d0f46423SBarry Smith   m    = A->rmap->n;
3676d0f46423SBarry Smith   n    = A->cmap->n;
3677d0f46423SBarry Smith   p    = B->cmap->n;
3678170fe5c8SBarry Smith   a    = sub_a->v;
3679170fe5c8SBarry Smith   b    = sub_b->a;
3680170fe5c8SBarry Smith   c    = sub_c->v;
3681170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3682170fe5c8SBarry Smith 
3683170fe5c8SBarry Smith   ii  = sub_b->i;
3684170fe5c8SBarry Smith   idx = sub_b->j;
3685170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3686170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3687170fe5c8SBarry Smith     while (q-->0) {
3688170fe5c8SBarry Smith       c_q = c + m*(*idx);
3689170fe5c8SBarry Smith       a_q = a + m*i;
3690854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3691170fe5c8SBarry Smith       idx++;
3692170fe5c8SBarry Smith       b++;
3693170fe5c8SBarry Smith     }
3694170fe5c8SBarry Smith   }
3695170fe5c8SBarry Smith   PetscFunctionReturn(0);
3696170fe5c8SBarry Smith }
3697170fe5c8SBarry Smith 
3698170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3699170fe5c8SBarry Smith {
3700170fe5c8SBarry Smith   PetscErrorCode ierr;
3701d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3702170fe5c8SBarry Smith   Mat            Cmat;
3703170fe5c8SBarry Smith 
3704170fe5c8SBarry Smith   PetscFunctionBegin;
370560e0710aSBarry 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);
3706ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3707170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
370833d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3709170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37100298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3711d73949e8SHong Zhang 
3712d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37132205254eSKarl Rupp 
3714170fe5c8SBarry Smith   *C = Cmat;
3715170fe5c8SBarry Smith   PetscFunctionReturn(0);
3716170fe5c8SBarry Smith }
3717170fe5c8SBarry Smith 
3718170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3719150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3720170fe5c8SBarry Smith {
3721170fe5c8SBarry Smith   PetscErrorCode ierr;
3722170fe5c8SBarry Smith 
3723170fe5c8SBarry Smith   PetscFunctionBegin;
3724170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37253ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3726170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37273ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3728170fe5c8SBarry Smith   }
37293ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3730170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37313ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3732170fe5c8SBarry Smith   PetscFunctionReturn(0);
3733170fe5c8SBarry Smith }
3734170fe5c8SBarry Smith 
3735170fe5c8SBarry Smith 
37360bad9183SKris Buschelman /*MC
3737fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37380bad9183SKris Buschelman    based on compressed sparse row format.
37390bad9183SKris Buschelman 
37400bad9183SKris Buschelman    Options Database Keys:
37410bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37420bad9183SKris Buschelman 
37430bad9183SKris Buschelman   Level: beginner
37440bad9183SKris Buschelman 
3745f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37460bad9183SKris Buschelman M*/
37470bad9183SKris Buschelman 
3748ccd284c7SBarry Smith /*MC
3749ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3750ccd284c7SBarry Smith 
3751ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3752ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3753ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3754ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3755ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3756ccd284c7SBarry Smith 
3757ccd284c7SBarry Smith    Options Database Keys:
3758ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3759ccd284c7SBarry Smith 
3760ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3761ccd284c7SBarry Smith    enough exist.
3762ccd284c7SBarry Smith 
3763ccd284c7SBarry Smith   Level: beginner
3764ccd284c7SBarry Smith 
3765ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3766ccd284c7SBarry Smith M*/
3767ccd284c7SBarry Smith 
3768ccd284c7SBarry Smith /*MC
3769ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3770ccd284c7SBarry Smith 
3771ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3772ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3773ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3774ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3775ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3776ccd284c7SBarry Smith 
3777ccd284c7SBarry Smith    Options Database Keys:
3778ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3779ccd284c7SBarry Smith 
3780ccd284c7SBarry Smith   Level: beginner
3781ccd284c7SBarry Smith 
3782ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3783ccd284c7SBarry Smith M*/
3784ccd284c7SBarry Smith 
3785cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3786af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3787cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3788af8000cdSHong Zhang #endif
378963c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
379063c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
37913dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
379263c07aadSStefano Zampini #endif
3793cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
379442c9c57cSBarry Smith 
3795b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
379629b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
379729b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3798b3866ffcSBarry Smith #endif
379917667f90SBarry Smith 
3800c0c8ee5eSDmitry Karpeev 
38018c778c55SBarry Smith /*@C
38028397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38038c778c55SBarry Smith 
38048c778c55SBarry Smith    Not Collective
38058c778c55SBarry Smith 
38068c778c55SBarry Smith    Input Parameter:
3807579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38088c778c55SBarry Smith 
38098c778c55SBarry Smith    Output Parameter:
38108c778c55SBarry Smith .   array - pointer to the data
38118c778c55SBarry Smith 
38128c778c55SBarry Smith    Level: intermediate
38138c778c55SBarry Smith 
3814774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38158c778c55SBarry Smith @*/
38168c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38178c778c55SBarry Smith {
38188c778c55SBarry Smith   PetscErrorCode ierr;
38198c778c55SBarry Smith 
38208c778c55SBarry Smith   PetscFunctionBegin;
38218c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38228c778c55SBarry Smith   PetscFunctionReturn(0);
38238c778c55SBarry Smith }
38248c778c55SBarry Smith 
382521e72a00SBarry Smith /*@C
382621e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
382721e72a00SBarry Smith 
382821e72a00SBarry Smith    Not Collective
382921e72a00SBarry Smith 
383021e72a00SBarry Smith    Input Parameter:
3831579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
383221e72a00SBarry Smith 
383321e72a00SBarry Smith    Output Parameter:
383421e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
383521e72a00SBarry Smith 
383621e72a00SBarry Smith    Level: intermediate
383721e72a00SBarry Smith 
383821e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
383921e72a00SBarry Smith @*/
384021e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
384121e72a00SBarry Smith {
384221e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
384321e72a00SBarry Smith 
384421e72a00SBarry Smith   PetscFunctionBegin;
384521e72a00SBarry Smith   *nz = aij->rmax;
384621e72a00SBarry Smith   PetscFunctionReturn(0);
384721e72a00SBarry Smith }
384821e72a00SBarry Smith 
38498c778c55SBarry Smith /*@C
3850579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38518c778c55SBarry Smith 
38528c778c55SBarry Smith    Not Collective
38538c778c55SBarry Smith 
38548c778c55SBarry Smith    Input Parameters:
3855579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38568c778c55SBarry Smith .  array - pointer to the data
38578c778c55SBarry Smith 
38588c778c55SBarry Smith    Level: intermediate
38598c778c55SBarry Smith 
3860774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
38618c778c55SBarry Smith @*/
38628c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
38638c778c55SBarry Smith {
38648c778c55SBarry Smith   PetscErrorCode ierr;
38658c778c55SBarry Smith 
38668c778c55SBarry Smith   PetscFunctionBegin;
38678c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38688c778c55SBarry Smith   PetscFunctionReturn(0);
38698c778c55SBarry Smith }
38708c778c55SBarry Smith 
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3872273d9f13SBarry Smith {
3873273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3874dfbe8321SBarry Smith   PetscErrorCode ierr;
387538baddfdSBarry Smith   PetscMPIInt    size;
3876273d9f13SBarry Smith 
3877273d9f13SBarry Smith   PetscFunctionBegin;
3878ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3879e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3880273d9f13SBarry Smith 
3881b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
38822205254eSKarl Rupp 
3883b0a32e0cSBarry Smith   B->data = (void*)b;
38842205254eSKarl Rupp 
3885549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
38862205254eSKarl Rupp 
3887416022c9SBarry Smith   b->row                = 0;
3888416022c9SBarry Smith   b->col                = 0;
388982bf6240SBarry Smith   b->icol               = 0;
3890b810aeb4SBarry Smith   b->reallocs           = 0;
389136db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3892f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3893416022c9SBarry Smith   b->nonew              = 0;
3894416022c9SBarry Smith   b->diag               = 0;
3895416022c9SBarry Smith   b->solve_work         = 0;
38962a1b7f2aSHong Zhang   B->spptr              = 0;
3897be6bf707SBarry Smith   b->saved_values       = 0;
3898d7f994e1SBarry Smith   b->idiag              = 0;
389971f1c65dSBarry Smith   b->mdiag              = 0;
390071f1c65dSBarry Smith   b->ssor_work          = 0;
390171f1c65dSBarry Smith   b->omega              = 1.0;
390271f1c65dSBarry Smith   b->fshift             = 0.0;
390371f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3904bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3905a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
390617ab2063SBarry Smith 
390735d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3908bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3909bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39108c778c55SBarry Smith 
3911b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3912bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3913bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3914b3866ffcSBarry Smith #endif
391517f1a0eaSHong Zhang 
3916bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3917bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3918bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3919bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3920bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3921bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3922bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3923af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3924af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3925af8000cdSHong Zhang #endif
392663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
392763c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39283dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
392963c07aadSStefano Zampini #endif
3930b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3931bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3932bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3933bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3934bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3935bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3936bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3937bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3938bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39394108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
394017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39413a40ed3dSBarry Smith   PetscFunctionReturn(0);
394217ab2063SBarry Smith }
394317ab2063SBarry Smith 
3944b24902e0SBarry Smith /*
3945b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3946b24902e0SBarry Smith */
3947ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
394817ab2063SBarry Smith {
3949416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39506849ba73SBarry Smith   PetscErrorCode ierr;
3951d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
395217ab2063SBarry Smith 
39533a40ed3dSBarry Smith   PetscFunctionBegin;
3954273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3955273d9f13SBarry Smith 
3956d5f3da31SBarry Smith   C->factortype = A->factortype;
3957416022c9SBarry Smith   c->row        = 0;
3958416022c9SBarry Smith   c->col        = 0;
395982bf6240SBarry Smith   c->icol       = 0;
39606ad4291fSHong Zhang   c->reallocs   = 0;
396117ab2063SBarry Smith 
39626ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
396317ab2063SBarry Smith 
3964aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3965aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3966eec197d1SBarry Smith 
3967dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
39683bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
396917ab2063SBarry Smith   for (i=0; i<m; i++) {
3970416022c9SBarry Smith     c->imax[i] = a->imax[i];
3971416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
397217ab2063SBarry Smith   }
397317ab2063SBarry Smith 
397417ab2063SBarry Smith   /* allocate the matrix space */
3975f77e22a1SHong Zhang   if (mallocmatspace) {
3976dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
39773bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
39782205254eSKarl Rupp 
3979f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
39802205254eSKarl Rupp 
398197f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
398217ab2063SBarry Smith     if (m > 0) {
398397f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3984be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3985bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3986be6bf707SBarry Smith       } else {
3987bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
398817ab2063SBarry Smith       }
398908480c60SBarry Smith     }
3990f77e22a1SHong Zhang   }
399117ab2063SBarry Smith 
39926ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
3993416022c9SBarry Smith   c->roworiented       = a->roworiented;
3994416022c9SBarry Smith   c->nonew             = a->nonew;
3995416022c9SBarry Smith   if (a->diag) {
3996854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
39973bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
399817ab2063SBarry Smith     for (i=0; i<m; i++) {
3999416022c9SBarry Smith       c->diag[i] = a->diag[i];
400017ab2063SBarry Smith     }
40013a40ed3dSBarry Smith   } else c->diag = 0;
40022205254eSKarl Rupp 
40036ad4291fSHong Zhang   c->solve_work         = 0;
40046ad4291fSHong Zhang   c->saved_values       = 0;
40056ad4291fSHong Zhang   c->idiag              = 0;
400671f1c65dSBarry Smith   c->ssor_work          = 0;
4007a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4008e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4009e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40106ad4291fSHong Zhang 
4011893ad86cSHong Zhang   c->rmax         = a->rmax;
4012416022c9SBarry Smith   c->nz           = a->nz;
40138ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4014273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4015754ec7b1SSatish Balay 
40166ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40176ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4018cd6b891eSBarry Smith   if (a->compressedrow.use) {
40196ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4020dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40216ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40226ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
402327ea64f8SHong Zhang   } else {
402427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40250298fd71SBarry Smith     c->compressedrow.i      = NULL;
40260298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40276ad4291fSHong Zhang   }
4028ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4029e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40304846f1f5SKris Buschelman 
40312205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4032140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40333a40ed3dSBarry Smith   PetscFunctionReturn(0);
403417ab2063SBarry Smith }
403517ab2063SBarry Smith 
4036b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4037b24902e0SBarry Smith {
4038b24902e0SBarry Smith   PetscErrorCode ierr;
4039b24902e0SBarry Smith 
4040b24902e0SBarry Smith   PetscFunctionBegin;
4041ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40424b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4043cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
404433d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4045cfd3f464SBarry Smith   }
4046a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4047f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4048b24902e0SBarry Smith   PetscFunctionReturn(0);
4049b24902e0SBarry Smith }
4050b24902e0SBarry Smith 
4051112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4052fbdbba38SShri Abhyankar {
4053fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4054fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4055fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4056fbdbba38SShri Abhyankar   int            fd;
4057fbdbba38SShri Abhyankar   PetscMPIInt    size;
4058fbdbba38SShri Abhyankar   MPI_Comm       comm;
40593059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4060fbdbba38SShri Abhyankar 
4061fbdbba38SShri Abhyankar   PetscFunctionBegin;
4062c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4063c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4064fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4065fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4066fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4067bbead8a2SBarry Smith 
40680298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
40690298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4070bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40713059b6faSBarry Smith   if (bs < 0) bs = 1;
40723059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4073bbead8a2SBarry Smith 
4074fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4075fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4076fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4077fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4078fbdbba38SShri Abhyankar 
4079bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4080fbdbba38SShri Abhyankar 
4081fbdbba38SShri Abhyankar   /* read in row lengths */
4082785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4083fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4084fbdbba38SShri Abhyankar 
4085fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4086fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
408760e0710aSBarry 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);
4088fbdbba38SShri Abhyankar 
4089fbdbba38SShri Abhyankar   /* set global size if not set already*/
4090f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4091fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4092aabbc4fbSShri Abhyankar   } else {
40939d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4094fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
40954c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
40964c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
40974c5b953cSHong Zhang     }
409860e0710aSBarry 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);
4099aabbc4fbSShri Abhyankar   }
4100fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4101fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4102fbdbba38SShri Abhyankar 
4103fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4104fbdbba38SShri Abhyankar 
4105fbdbba38SShri Abhyankar   /* read in nonzero values */
4106fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4107fbdbba38SShri Abhyankar 
4108fbdbba38SShri Abhyankar   /* set matrix "i" values */
4109fbdbba38SShri Abhyankar   a->i[0] = 0;
4110fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4111fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4112fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4113fbdbba38SShri Abhyankar   }
4114fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4115fbdbba38SShri Abhyankar 
4116fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4117fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4118fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4119fbdbba38SShri Abhyankar }
4120fbdbba38SShri Abhyankar 
4121ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41227264ac53SSatish Balay {
41237264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4124dfbe8321SBarry Smith   PetscErrorCode ierr;
4125eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4126eeffb40dSHong Zhang   PetscInt k;
4127eeffb40dSHong Zhang #endif
41287264ac53SSatish Balay 
41293a40ed3dSBarry Smith   PetscFunctionBegin;
4130bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4131d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4132ca44d042SBarry Smith     *flg = PETSC_FALSE;
4133ca44d042SBarry Smith     PetscFunctionReturn(0);
4134bcd2baecSBarry Smith   }
41357264ac53SSatish Balay 
41367264ac53SSatish Balay   /* if the a->i are the same */
4137d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4138abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41397264ac53SSatish Balay 
41407264ac53SSatish Balay   /* if a->j are the same */
414197f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4142abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4143bcd2baecSBarry Smith 
4144bcd2baecSBarry Smith   /* if a->a are the same */
4145eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4146eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4147eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4148eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41493a40ed3dSBarry Smith       PetscFunctionReturn(0);
4150eeffb40dSHong Zhang     }
4151eeffb40dSHong Zhang   }
4152eeffb40dSHong Zhang #else
4153eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4154eeffb40dSHong Zhang #endif
4155eeffb40dSHong Zhang   PetscFunctionReturn(0);
41567264ac53SSatish Balay }
415736db0b34SBarry Smith 
415805869f15SSatish Balay /*@
415936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
416036db0b34SBarry Smith               provided by the user.
416136db0b34SBarry Smith 
4162c75a6043SHong Zhang       Collective on MPI_Comm
416336db0b34SBarry Smith 
416436db0b34SBarry Smith    Input Parameters:
416536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
416636db0b34SBarry Smith .   m - number of rows
416736db0b34SBarry Smith .   n - number of columns
416836db0b34SBarry Smith .   i - row indices
416936db0b34SBarry Smith .   j - column indices
417036db0b34SBarry Smith -   a - matrix values
417136db0b34SBarry Smith 
417236db0b34SBarry Smith    Output Parameter:
417336db0b34SBarry Smith .   mat - the matrix
417436db0b34SBarry Smith 
417536db0b34SBarry Smith    Level: intermediate
417636db0b34SBarry Smith 
417736db0b34SBarry Smith    Notes:
41780551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4179292fb18eSBarry Smith     once the matrix is destroyed and not before
418036db0b34SBarry Smith 
418136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
418236db0b34SBarry Smith 
4183bfeeae90SHong Zhang        The i and j indices are 0 based
418436db0b34SBarry Smith 
4185a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4186a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
41878eef79e4SBarry Smith     as shown
4188a4552177SSatish Balay 
41898eef79e4SBarry Smith $        1 0 0
41908eef79e4SBarry Smith $        2 0 3
41918eef79e4SBarry Smith $        4 5 6
41928eef79e4SBarry Smith $
41938eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
41948eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
41958eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4196a4552177SSatish Balay 
41979985e31cSBarry Smith 
419869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
419936db0b34SBarry Smith 
420036db0b34SBarry Smith @*/
4201c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
420236db0b34SBarry Smith {
4203dfbe8321SBarry Smith   PetscErrorCode ierr;
4204cbcfb4deSHong Zhang   PetscInt       ii;
420536db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4206cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4207cbcfb4deSHong Zhang   PetscInt jj;
4208cbcfb4deSHong Zhang #endif
420936db0b34SBarry Smith 
421036db0b34SBarry Smith   PetscFunctionBegin;
421141096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4212f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4213f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4214a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4215ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4216ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4217ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4218dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4219ab93d7beSBarry Smith 
422036db0b34SBarry Smith   aij->i            = i;
422136db0b34SBarry Smith   aij->j            = j;
422236db0b34SBarry Smith   aij->a            = a;
422336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
422436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4225e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4226e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
422736db0b34SBarry Smith 
422836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
422936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42302515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
423160e0710aSBarry 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]);
42329985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4233e32f2f54SBarry 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);
4234e32f2f54SBarry 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);
42359985e31cSBarry Smith     }
423636db0b34SBarry Smith #endif
423736db0b34SBarry Smith   }
42382515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
423936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
424060e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
424160e0710aSBarry 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]);
424236db0b34SBarry Smith   }
424336db0b34SBarry Smith #endif
424436db0b34SBarry Smith 
4245b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4246b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
424736db0b34SBarry Smith   PetscFunctionReturn(0);
424836db0b34SBarry Smith }
424980ef6e79SMatthew G Knepley /*@C
4250d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42518a0b0e6bSVictor Minden               provided by the user.
42528a0b0e6bSVictor Minden 
42538a0b0e6bSVictor Minden       Collective on MPI_Comm
42548a0b0e6bSVictor Minden 
42558a0b0e6bSVictor Minden    Input Parameters:
42568a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42578a0b0e6bSVictor Minden .   m   - number of rows
42588a0b0e6bSVictor Minden .   n   - number of columns
42598a0b0e6bSVictor Minden .   i   - row indices
42608a0b0e6bSVictor Minden .   j   - column indices
42611230e6d1SVictor Minden .   a   - matrix values
42621230e6d1SVictor Minden .   nz  - number of nonzeros
42631230e6d1SVictor Minden -   idx - 0 or 1 based
42648a0b0e6bSVictor Minden 
42658a0b0e6bSVictor Minden    Output Parameter:
42668a0b0e6bSVictor Minden .   mat - the matrix
42678a0b0e6bSVictor Minden 
42688a0b0e6bSVictor Minden    Level: intermediate
42698a0b0e6bSVictor Minden 
42708a0b0e6bSVictor Minden    Notes:
42718a0b0e6bSVictor Minden        The i and j indices are 0 based
42728a0b0e6bSVictor Minden 
42738a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
42748a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
42758a0b0e6bSVictor Minden     as shown:
42768a0b0e6bSVictor Minden 
42778a0b0e6bSVictor Minden         1 0 0
42788a0b0e6bSVictor Minden         2 0 3
42798a0b0e6bSVictor Minden         4 5 6
42808a0b0e6bSVictor Minden 
42818a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
42828a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
42838a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
42848a0b0e6bSVictor Minden 
42858a0b0e6bSVictor Minden 
428669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
42878a0b0e6bSVictor Minden 
42888a0b0e6bSVictor Minden @*/
4289c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
42908a0b0e6bSVictor Minden {
42918a0b0e6bSVictor Minden   PetscErrorCode ierr;
4292d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
42938a0b0e6bSVictor Minden 
42948a0b0e6bSVictor Minden 
42958a0b0e6bSVictor Minden   PetscFunctionBegin;
42961795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
42971230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4298c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
42991230e6d1SVictor Minden   }
43008a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43018a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43028a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43031230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43041230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43051230e6d1SVictor Minden     if (idx) {
43061230e6d1SVictor Minden       row = i[ii] - 1;
43071230e6d1SVictor Minden       col = j[ii] - 1;
43081230e6d1SVictor Minden     } else {
43091230e6d1SVictor Minden       row = i[ii];
43101230e6d1SVictor Minden       col = j[ii];
43118a0b0e6bSVictor Minden     }
43121230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43138a0b0e6bSVictor Minden   }
43148a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43158a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4316d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43178a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43188a0b0e6bSVictor Minden }
431936db0b34SBarry Smith 
4320acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4321acf2f550SJed Brown {
4322acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4323acf2f550SJed Brown   PetscErrorCode ierr;
4324acf2f550SJed Brown 
4325acf2f550SJed Brown   PetscFunctionBegin;
4326acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4327acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43282205254eSKarl Rupp 
4329acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4330acf2f550SJed Brown   PetscFunctionReturn(0);
4331acf2f550SJed Brown }
4332acf2f550SJed Brown 
43339c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43349c8f2541SHong Zhang {
43359c8f2541SHong Zhang   PetscErrorCode ierr;
43368761c3d6SHong Zhang   PetscMPIInt    size;
43379c8f2541SHong Zhang 
43389c8f2541SHong Zhang   PetscFunctionBegin;
43398761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43408761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43418761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43428761c3d6SHong Zhang   } else {
43439c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43448761c3d6SHong Zhang   }
43459c8f2541SHong Zhang   PetscFunctionReturn(0);
43469c8f2541SHong Zhang }
43479c8f2541SHong Zhang 
434881824310SBarry Smith /*
434953dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
435053dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
435153dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
435253dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
435353dd7562SDmitry Karpeev  */
435453dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
435553dd7562SDmitry Karpeev {
435653dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
435753dd7562SDmitry Karpeev   PetscErrorCode ierr;
435853dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
435953dd7562SDmitry Karpeev   PetscBool      seqaij;
436053dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
436153dd7562SDmitry Karpeev   PetscScalar    v;
436253dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
436353dd7562SDmitry Karpeev 
436453dd7562SDmitry Karpeev   PetscFunctionBegin;
436553dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
436653dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
436753dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
436853dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
436953dd7562SDmitry Karpeev   if (rowemb) {
437053dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
437153dd7562SDmitry 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);
437253dd7562SDmitry Karpeev   } else {
43736c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
437453dd7562SDmitry Karpeev   }
437553dd7562SDmitry Karpeev   if (colemb) {
437653dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
437753dd7562SDmitry 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);
437853dd7562SDmitry Karpeev   } else {
437953dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
438053dd7562SDmitry Karpeev   }
438153dd7562SDmitry Karpeev 
438253dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
438353dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
438453dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
438553dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
438653dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
438753dd7562SDmitry Karpeev     }
438853dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
438953dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
439053dd7562SDmitry Karpeev   }
439153dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
439253dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
439353dd7562SDmitry Karpeev   }
439453dd7562SDmitry Karpeev   count = 0;
439553dd7562SDmitry Karpeev   rowindices = NULL;
439653dd7562SDmitry Karpeev   colindices = NULL;
439753dd7562SDmitry Karpeev   if (rowemb) {
439853dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
439953dd7562SDmitry Karpeev   }
440053dd7562SDmitry Karpeev   if (colemb) {
440153dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
440253dd7562SDmitry Karpeev   }
440353dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
440453dd7562SDmitry Karpeev     PetscInt row;
440553dd7562SDmitry Karpeev     row = i;
440653dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
440753dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
440853dd7562SDmitry Karpeev       PetscInt col;
440953dd7562SDmitry Karpeev       col  = Baij->j[count];
441053dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
441153dd7562SDmitry Karpeev       v    = Baij->a[count];
441253dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
441353dd7562SDmitry Karpeev       ++count;
441453dd7562SDmitry Karpeev     }
441553dd7562SDmitry Karpeev   }
441653dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
441753dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
441853dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
441953dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
442053dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
442153dd7562SDmitry Karpeev   PetscFunctionReturn(0);
442253dd7562SDmitry Karpeev }
442353dd7562SDmitry Karpeev 
442453dd7562SDmitry Karpeev 
442553dd7562SDmitry Karpeev /*
442681824310SBarry Smith     Special version for direct calls from Fortran
442781824310SBarry Smith */
4428af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
442981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
443081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
443181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
443281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
443381824310SBarry Smith #endif
443481824310SBarry Smith 
443581824310SBarry Smith /* Change these macros so can be used in void function */
443681824310SBarry Smith #undef CHKERRQ
4437ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
443881824310SBarry Smith #undef SETERRQ2
4439e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44404994cf47SJed Brown #undef SETERRQ3
44414994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
444281824310SBarry Smith 
44438cc058d9SJed 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)
444481824310SBarry Smith {
444581824310SBarry Smith   Mat            A  = *AA;
444681824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
444781824310SBarry Smith   InsertMode     is = *isis;
444881824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444981824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
445081824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
445181824310SBarry Smith   PetscErrorCode ierr;
445281824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
445354f21887SBarry Smith   MatScalar      *ap,value,*aa;
4454ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4455ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
445681824310SBarry Smith 
445781824310SBarry Smith   PetscFunctionBegin;
44584994cf47SJed Brown   MatCheckPreallocated(A,1);
445981824310SBarry Smith   imax  = a->imax;
446081824310SBarry Smith   ai    = a->i;
446181824310SBarry Smith   ailen = a->ilen;
446281824310SBarry Smith   aj    = a->j;
446381824310SBarry Smith   aa    = a->a;
446481824310SBarry Smith 
446581824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
446681824310SBarry Smith     row = im[k];
446781824310SBarry Smith     if (row < 0) continue;
446881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4469ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
447081824310SBarry Smith #endif
447181824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
447281824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
447381824310SBarry Smith     low  = 0;
447481824310SBarry Smith     high = nrow;
447581824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
447681824310SBarry Smith       if (in[l] < 0) continue;
447781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4478ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
447981824310SBarry Smith #endif
448081824310SBarry Smith       col = in[l];
44812205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
44822205254eSKarl Rupp       else value = v[k + l*m];
44832205254eSKarl Rupp 
448481824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
448581824310SBarry Smith 
44862205254eSKarl Rupp       if (col <= lastcol) low = 0;
44872205254eSKarl Rupp       else high = nrow;
448881824310SBarry Smith       lastcol = col;
448981824310SBarry Smith       while (high-low > 5) {
449081824310SBarry Smith         t = (low+high)/2;
449181824310SBarry Smith         if (rp[t] > col) high = t;
449281824310SBarry Smith         else             low  = t;
449381824310SBarry Smith       }
449481824310SBarry Smith       for (i=low; i<high; i++) {
449581824310SBarry Smith         if (rp[i] > col) break;
449681824310SBarry Smith         if (rp[i] == col) {
449781824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
449881824310SBarry Smith           else                  ap[i] = value;
449981824310SBarry Smith           goto noinsert;
450081824310SBarry Smith         }
450181824310SBarry Smith       }
450281824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
450381824310SBarry Smith       if (nonew == 1) goto noinsert;
4504ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4505fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
450681824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
450781824310SBarry Smith       /* shift up all the later entries in this row */
450881824310SBarry Smith       for (ii=N; ii>=i; ii--) {
450981824310SBarry Smith         rp[ii+1] = rp[ii];
451081824310SBarry Smith         ap[ii+1] = ap[ii];
451181824310SBarry Smith       }
451281824310SBarry Smith       rp[i] = col;
451381824310SBarry Smith       ap[i] = value;
4514e56f5c9eSBarry Smith       A->nonzerostate++;
451581824310SBarry Smith noinsert:;
451681824310SBarry Smith       low = i + 1;
451781824310SBarry Smith     }
451881824310SBarry Smith     ailen[row] = nrow;
451981824310SBarry Smith   }
452081824310SBarry Smith   PetscFunctionReturnVoid();
452181824310SBarry Smith }
45229f7953f8SBarry Smith 
4523