xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 720833dad2477b699db6e03e085046968cda09c2)
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;
412*720833daSHong Zhang   //printf("A->structure_only %d\n",A->structure_only);
41317ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
414416022c9SBarry Smith     row = im[k];
4155ef9f2a5SBarry Smith     if (row < 0) continue;
4162515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
417e32f2f54SBarry 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);
4183b2fbd54SBarry Smith #endif
419*720833daSHong Zhang     rp   = aj + ai[row];
420*720833daSHong Zhang     if (A->structure_only) {
421*720833daSHong Zhang       ap = aa + ai[row];
422*720833daSHong Zhang     }
42317ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
424416022c9SBarry Smith     low  = 0;
425c71e6ed7SBarry Smith     high = nrow;
42617ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4275ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4282515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
429e32f2f54SBarry 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);
4303b2fbd54SBarry Smith #endif
431bfeeae90SHong Zhang       col = in[l];
432*720833daSHong Zhang       if (!A->structure_only) {
4334b0e389bSBarry Smith         if (roworiented) {
4345ef9f2a5SBarry Smith           value = v[l + k*n];
435bef8e0ddSBarry Smith         } else {
4364b0e389bSBarry Smith           value = v[k + l*m];
4374b0e389bSBarry Smith         }
438*720833daSHong Zhang       } else { /* A->structure_only */
439*720833daSHong Zhang         value = 1; /* avoid 'continue' below?  */
440*720833daSHong Zhang       }
441dcd36c23SBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue;
44236db0b34SBarry Smith 
4432205254eSKarl Rupp       if (col <= lastcol) low = 0;
4442205254eSKarl Rupp       else high = nrow;
445e2ee6c50SBarry Smith       lastcol = col;
446416022c9SBarry Smith       while (high-low > 5) {
447416022c9SBarry Smith         t = (low+high)/2;
448416022c9SBarry Smith         if (rp[t] > col) high = t;
449416022c9SBarry Smith         else low = t;
45017ab2063SBarry Smith       }
451416022c9SBarry Smith       for (i=low; i<high; i++) {
45217ab2063SBarry Smith         if (rp[i] > col) break;
45317ab2063SBarry Smith         if (rp[i] == col) {
454*720833daSHong Zhang           if (A->structure_only) {
455416022c9SBarry Smith             if (is == ADD_VALUES) ap[i] += value;
45617ab2063SBarry Smith             else ap[i] = value;
457*720833daSHong Zhang           }
458e44c0bd4SBarry Smith           low = i + 1;
45917ab2063SBarry Smith           goto noinsert;
46017ab2063SBarry Smith         }
46117ab2063SBarry Smith       }
462dcd36c23SBarry Smith       if (value == 0.0 && ignorezeroentries && row != col) goto noinsert;
463c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
464e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
465*720833daSHong Zhang       if (A->structure_only) {
466*720833daSHong Zhang         MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,imax,nonew,MatScalar);
467*720833daSHong Zhang       } else {
468fef13f97SBarry Smith         MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
469*720833daSHong Zhang       }
470c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
471416022c9SBarry Smith       /* shift up all the later entries in this row */
472416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
47317ab2063SBarry Smith         rp[ii+1] = rp[ii];
474*720833daSHong Zhang         if (A->structure_only) {
47517ab2063SBarry Smith           ap[ii+1] = ap[ii];
47617ab2063SBarry Smith         }
477*720833daSHong Zhang       }
47817ab2063SBarry Smith       rp[i] = col;
479*720833daSHong Zhang       if (A->structure_only) {
48017ab2063SBarry Smith         ap[i] = value;
481*720833daSHong Zhang       }
482416022c9SBarry Smith       low   = i + 1;
483e56f5c9eSBarry Smith       A->nonzerostate++;
484e44c0bd4SBarry Smith noinsert:;
48517ab2063SBarry Smith     }
48617ab2063SBarry Smith     ailen[row] = nrow;
48717ab2063SBarry Smith   }
4883a40ed3dSBarry Smith   PetscFunctionReturn(0);
48917ab2063SBarry Smith }
49017ab2063SBarry Smith 
49181824310SBarry Smith 
492a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4937eb43aa7SLois Curfman McInnes {
4947eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
49597f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
49697f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
49754f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4987eb43aa7SLois Curfman McInnes 
4993a40ed3dSBarry Smith   PetscFunctionBegin;
5007eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
5017eb43aa7SLois Curfman McInnes     row = im[k];
502e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
503e32f2f54SBarry 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);
504bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
5057eb43aa7SLois Curfman McInnes     nrow = ailen[row];
5067eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
507e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
508e32f2f54SBarry 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);
509bfeeae90SHong Zhang       col  = in[l];
5107eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5117eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5127eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5137eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5147eb43aa7SLois Curfman McInnes         else low = t;
5157eb43aa7SLois Curfman McInnes       }
5167eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5177eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5187eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
519b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5207eb43aa7SLois Curfman McInnes           goto finished;
5217eb43aa7SLois Curfman McInnes         }
5227eb43aa7SLois Curfman McInnes       }
52397e567efSBarry Smith       *v++ = 0.0;
5247eb43aa7SLois Curfman McInnes finished:;
5257eb43aa7SLois Curfman McInnes     }
5267eb43aa7SLois Curfman McInnes   }
5273a40ed3dSBarry Smith   PetscFunctionReturn(0);
5287eb43aa7SLois Curfman McInnes }
5297eb43aa7SLois Curfman McInnes 
53017ab2063SBarry Smith 
531dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
53217ab2063SBarry Smith {
533416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5346849ba73SBarry Smith   PetscErrorCode ierr;
5356f69ff64SBarry Smith   PetscInt       i,*col_lens;
5366f69ff64SBarry Smith   int            fd;
537b37d52dbSMark F. Adams   FILE           *file;
53817ab2063SBarry Smith 
5393a40ed3dSBarry Smith   PetscFunctionBegin;
540b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
541854ce69bSBarry Smith   ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr);
5422205254eSKarl Rupp 
5430700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
544d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
545d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
546416022c9SBarry Smith   col_lens[3] = a->nz;
547416022c9SBarry Smith 
548416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
549d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
550416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
55117ab2063SBarry Smith   }
552d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
553606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
554416022c9SBarry Smith 
555416022c9SBarry Smith   /* store column indices (zero start index) */
5566f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
557416022c9SBarry Smith 
558416022c9SBarry Smith   /* store nonzero values */
5596f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
560b37d52dbSMark F. Adams 
561b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
562b37d52dbSMark F. Adams   if (file) {
56333d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
564b37d52dbSMark F. Adams   }
5653a40ed3dSBarry Smith   PetscFunctionReturn(0);
56617ab2063SBarry Smith }
567416022c9SBarry Smith 
56809573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
569cd155464SBarry Smith 
570dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
571416022c9SBarry Smith {
572416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
573dfbe8321SBarry Smith   PetscErrorCode    ierr;
57460e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
575e060cb09SBarry Smith   const char        *name;
576f3ef73ceSBarry Smith   PetscViewerFormat format;
57717ab2063SBarry Smith 
5783a40ed3dSBarry Smith   PetscFunctionBegin;
57943e49210SHong Zhang   if (!a->a) PetscFunctionReturn(0);
58043e49210SHong Zhang 
581b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
58271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
58397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
58460e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
585c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
586d00d2cf4SBarry Smith       nofinalvalue = 1;
587d00d2cf4SBarry Smith     }
588d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
589d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
59077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
591fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
592fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
593fbfe6fa7SJed Brown #else
59477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
595fbfe6fa7SJed Brown #endif
596b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
59717ab2063SBarry Smith 
59817ab2063SBarry Smith     for (i=0; i<m; i++) {
59960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
600aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
601a9bf72d8SJed 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);
60217ab2063SBarry Smith #else
60360e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
60417ab2063SBarry Smith #endif
60517ab2063SBarry Smith       }
60617ab2063SBarry Smith     }
607d00d2cf4SBarry Smith     if (nofinalvalue) {
608c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
609c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
610c337ccceSJed Brown #else
611d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
612c337ccceSJed Brown #endif
613d00d2cf4SBarry Smith     }
614317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
615fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
616d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
61768369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
618cd155464SBarry Smith     PetscFunctionReturn(0);
619fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
620d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
62144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
62277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
62360e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
624aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
62660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
62860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
62936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
63060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6316831982aSBarry Smith         }
63244cd7ae7SLois Curfman McInnes #else
63360e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
63444cd7ae7SLois Curfman McInnes #endif
63544cd7ae7SLois Curfman McInnes       }
636b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
63744cd7ae7SLois Curfman McInnes     }
638d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
639fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
64097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
641d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
642854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
643496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
644496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
64560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
646496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
647aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
649496be53dSLois Curfman McInnes #else
650496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
651496be53dSLois Curfman McInnes #endif
652496be53dSLois Curfman McInnes         }
653496be53dSLois Curfman McInnes       }
654496be53dSLois Curfman McInnes     }
6552e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
65677431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6572e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6582205254eSKarl Rupp       if (i+4<m) {
6592205254eSKarl 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);
6602205254eSKarl Rupp       } else if (i+3<m) {
6612205254eSKarl 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);
6622205254eSKarl Rupp       } else if (i+2<m) {
6632205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6642205254eSKarl Rupp       } else if (i+1<m) {
6652205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6662205254eSKarl Rupp       } else if (i<m) {
6672205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6682205254eSKarl Rupp       } else {
6692205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6702205254eSKarl Rupp       }
671496be53dSLois Curfman McInnes     }
672b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
673606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
674496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
67560e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
67677431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
677496be53dSLois Curfman McInnes       }
678b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
679496be53dSLois Curfman McInnes     }
680b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
681496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
68260e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
683496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
684aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
68536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
68660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6876831982aSBarry Smith           }
688496be53dSLois Curfman McInnes #else
68960e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
690496be53dSLois Curfman McInnes #endif
691496be53dSLois Curfman McInnes         }
692496be53dSLois Curfman McInnes       }
693b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
694496be53dSLois Curfman McInnes     }
695d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
696fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
69797f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
69887828ca2SBarry Smith     PetscScalar value;
69968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
70068f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
70168f1ed48SBarry Smith 
70268f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
70368f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
70468f1ed48SBarry Smith         realonly = PETSC_FALSE;
70568f1ed48SBarry Smith         break;
70668f1ed48SBarry Smith       }
70768f1ed48SBarry Smith     }
70868f1ed48SBarry Smith #endif
70902594712SBarry Smith 
710d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
71102594712SBarry Smith     for (i=0; i<m; i++) {
71202594712SBarry Smith       jcnt = 0;
713d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
714e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
71502594712SBarry Smith           value = a->a[cnt++];
716e24b481bSBarry Smith           jcnt++;
71702594712SBarry Smith         } else {
71802594712SBarry Smith           value = 0.0;
71902594712SBarry Smith         }
720aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
72168f1ed48SBarry Smith         if (realonly) {
72260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
72368f1ed48SBarry Smith         } else {
72460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
72568f1ed48SBarry Smith         }
72602594712SBarry Smith #else
72760e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
72802594712SBarry Smith #endif
72902594712SBarry Smith       }
730b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
73102594712SBarry Smith     }
732d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7333c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
734150b93efSMatthew G. Knepley     PetscInt fshift=1;
735d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7363c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
73719303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7383c215bfdSMatthew Knepley #else
73919303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7403c215bfdSMatthew Knepley #endif
741d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7423c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
74360e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7443c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
745a9a0e077SKarl 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);
7463c215bfdSMatthew Knepley #else
747150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7483c215bfdSMatthew Knepley #endif
7493c215bfdSMatthew Knepley       }
7503c215bfdSMatthew Knepley     }
751d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7523a40ed3dSBarry Smith   } else {
753d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
754d5f3da31SBarry Smith     if (A->factortype) {
75516cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
75616cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
75716cd7e1dSShri Abhyankar         /* L part */
75860e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
75916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
76016cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
76160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
76216cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7636712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
76416cd7e1dSShri Abhyankar           } else {
76560e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
76616cd7e1dSShri Abhyankar           }
76716cd7e1dSShri Abhyankar #else
76860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
76916cd7e1dSShri Abhyankar #endif
77016cd7e1dSShri Abhyankar         }
77116cd7e1dSShri Abhyankar         /* diagonal */
77216cd7e1dSShri Abhyankar         j = a->diag[i];
77316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
77416cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
77560e0710aSBarry 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);
77616cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7776712e2f1SBarry 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);
77816cd7e1dSShri Abhyankar         } else {
77960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
78016cd7e1dSShri Abhyankar         }
78116cd7e1dSShri Abhyankar #else
78260e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
78316cd7e1dSShri Abhyankar #endif
78416cd7e1dSShri Abhyankar 
78516cd7e1dSShri Abhyankar         /* U part */
78660e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
78716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78816cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
78960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
79016cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
79122ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
79216cd7e1dSShri Abhyankar           } else {
79360e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
79416cd7e1dSShri Abhyankar           }
79516cd7e1dSShri Abhyankar #else
79660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
79716cd7e1dSShri Abhyankar #endif
79816cd7e1dSShri Abhyankar         }
79916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
80016cd7e1dSShri Abhyankar       }
80116cd7e1dSShri Abhyankar     } else {
80217ab2063SBarry Smith       for (i=0; i<m; i++) {
80377431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
80460e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
805aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
80636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
80760e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
80836db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
80960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8103a40ed3dSBarry Smith           } else {
81160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
81217ab2063SBarry Smith           }
81317ab2063SBarry Smith #else
81460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
81517ab2063SBarry Smith #endif
81617ab2063SBarry Smith         }
817b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
81817ab2063SBarry Smith       }
81916cd7e1dSShri Abhyankar     }
820d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
82117ab2063SBarry Smith   }
822b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8233a40ed3dSBarry Smith   PetscFunctionReturn(0);
824416022c9SBarry Smith }
825416022c9SBarry Smith 
8269804daf3SBarry Smith #include <petscdraw.h>
827dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
828416022c9SBarry Smith {
829480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
830416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
831dfbe8321SBarry Smith   PetscErrorCode    ierr;
832383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
833383922c3SLisandro Dalcin   int               color;
834b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
835b0a32e0cSBarry Smith   PetscViewer       viewer;
836f3ef73ceSBarry Smith   PetscViewerFormat format;
837cddf8d76SBarry Smith 
8383a40ed3dSBarry Smith   PetscFunctionBegin;
839480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
840b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
841b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
842383922c3SLisandro Dalcin 
843416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8440513a670SBarry Smith 
845fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
846383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8470513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
848b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
849416022c9SBarry Smith     for (i=0; i<m; i++) {
850cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
851bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
852bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
85336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
854b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
855cddf8d76SBarry Smith       }
856cddf8d76SBarry Smith     }
857b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
858cddf8d76SBarry Smith     for (i=0; i<m; i++) {
859cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
860bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
861bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
862cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
863b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
864cddf8d76SBarry Smith       }
865cddf8d76SBarry Smith     }
866b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
867cddf8d76SBarry Smith     for (i=0; i<m; i++) {
868cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
869bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
870bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
87136db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
872b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
873416022c9SBarry Smith       }
874416022c9SBarry Smith     }
875383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8760513a670SBarry Smith   } else {
8770513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8780513a670SBarry Smith     /* first determine max of all nonzero values */
879b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
880383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
881b0a32e0cSBarry Smith     PetscDraw popup;
8820513a670SBarry Smith 
8830513a670SBarry Smith     for (i=0; i<nz; i++) {
8840513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8850513a670SBarry Smith     }
886383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
887b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
88845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
889383922c3SLisandro Dalcin 
890383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8910513a670SBarry Smith     for (i=0; i<m; i++) {
892383922c3SLisandro Dalcin       y_l = m - i - 1.0;
893383922c3SLisandro Dalcin       y_r = y_l + 1.0;
894bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
895383922c3SLisandro Dalcin         x_l = a->j[j];
896383922c3SLisandro Dalcin         x_r = x_l + 1.0;
897b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
898b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8990513a670SBarry Smith         count++;
9000513a670SBarry Smith       }
9010513a670SBarry Smith     }
902383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
9030513a670SBarry Smith   }
904480ef9eaSBarry Smith   PetscFunctionReturn(0);
905480ef9eaSBarry Smith }
906cddf8d76SBarry Smith 
9079804daf3SBarry Smith #include <petscdraw.h>
908dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
909480ef9eaSBarry Smith {
910dfbe8321SBarry Smith   PetscErrorCode ierr;
911b0a32e0cSBarry Smith   PetscDraw      draw;
91236db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
913ace3abfcSBarry Smith   PetscBool      isnull;
914480ef9eaSBarry Smith 
915480ef9eaSBarry Smith   PetscFunctionBegin;
916b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
917b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
918480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
919480ef9eaSBarry Smith 
920d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
921480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
922b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
923832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
924b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9250298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
926832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9273a40ed3dSBarry Smith   PetscFunctionReturn(0);
928416022c9SBarry Smith }
929416022c9SBarry Smith 
930dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
931416022c9SBarry Smith {
932dfbe8321SBarry Smith   PetscErrorCode ierr;
933ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
934416022c9SBarry Smith 
9353a40ed3dSBarry Smith   PetscFunctionBegin;
936251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
937251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
938251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
939c45a1595SBarry Smith   if (iascii) {
9403a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9410f5bd95cSBarry Smith   } else if (isbinary) {
9423a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9430f5bd95cSBarry Smith   } else if (isdraw) {
9443a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
94511aeaf0aSBarry Smith   }
9464108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9473a40ed3dSBarry Smith   PetscFunctionReturn(0);
94817ab2063SBarry Smith }
94919bcc07fSBarry Smith 
950dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
95117ab2063SBarry Smith {
952416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9536849ba73SBarry Smith   PetscErrorCode ierr;
95497f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
955d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
95654f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9573447b6efSHong Zhang   PetscReal      ratio  = 0.6;
95817ab2063SBarry Smith 
9593a40ed3dSBarry Smith   PetscFunctionBegin;
9603a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
96117ab2063SBarry Smith 
96243ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
96317ab2063SBarry Smith   for (i=1; i<m; i++) {
964416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
96517ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
96694a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
96717ab2063SBarry Smith     if (fshift) {
968bfeeae90SHong Zhang       ip = aj + ai[i];
969bfeeae90SHong Zhang       ap = aa + ai[i];
97017ab2063SBarry Smith       N  = ailen[i];
97117ab2063SBarry Smith       for (j=0; j<N; j++) {
97217ab2063SBarry Smith         ip[j-fshift] = ip[j];
97317ab2063SBarry Smith         ap[j-fshift] = ap[j];
97417ab2063SBarry Smith       }
97517ab2063SBarry Smith     }
97617ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
97717ab2063SBarry Smith   }
97817ab2063SBarry Smith   if (m) {
97917ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
98017ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
98117ab2063SBarry Smith   }
9827b083b7cSBarry Smith 
98317ab2063SBarry Smith   /* reset ilen and imax for each row */
9847b083b7cSBarry Smith   a->nonzerorowcnt = 0;
98517ab2063SBarry Smith   for (i=0; i<m; i++) {
98617ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9877b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
98817ab2063SBarry Smith   }
989bfeeae90SHong Zhang   a->nz = ai[m];
99065e19b50SBarry 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);
99117ab2063SBarry Smith 
99209f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
993d0f46423SBarry 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);
994ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
995ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9962205254eSKarl Rupp 
9978e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
998dd5f02e7SSatish Balay   a->reallocs         = 0;
9996712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
100036db0b34SBarry Smith   a->rmax             = rmax;
10014e220ebcSLois Curfman McInnes 
100211e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
10034108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
1004acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10053a40ed3dSBarry Smith   PetscFunctionReturn(0);
100617ab2063SBarry Smith }
100717ab2063SBarry Smith 
100899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
100999cafbc1SBarry Smith {
101099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
101199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
101254f21887SBarry Smith   MatScalar      *aa = a->a;
1013acf2f550SJed Brown   PetscErrorCode ierr;
101499cafbc1SBarry Smith 
101599cafbc1SBarry Smith   PetscFunctionBegin;
101699cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1017acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101899cafbc1SBarry Smith   PetscFunctionReturn(0);
101999cafbc1SBarry Smith }
102099cafbc1SBarry Smith 
102199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
102299cafbc1SBarry Smith {
102399cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
102499cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
102554f21887SBarry Smith   MatScalar      *aa = a->a;
1026acf2f550SJed Brown   PetscErrorCode ierr;
102799cafbc1SBarry Smith 
102899cafbc1SBarry Smith   PetscFunctionBegin;
102999cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1030acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
103199cafbc1SBarry Smith   PetscFunctionReturn(0);
103299cafbc1SBarry Smith }
103399cafbc1SBarry Smith 
1034dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
103517ab2063SBarry Smith {
1036416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1037dfbe8321SBarry Smith   PetscErrorCode ierr;
10383a40ed3dSBarry Smith 
10393a40ed3dSBarry Smith   PetscFunctionBegin;
1040d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1041acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10423a40ed3dSBarry Smith   PetscFunctionReturn(0);
104317ab2063SBarry Smith }
1044416022c9SBarry Smith 
1045dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
104617ab2063SBarry Smith {
1047416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1048dfbe8321SBarry Smith   PetscErrorCode ierr;
1049d5d45c9bSBarry Smith 
10503a40ed3dSBarry Smith   PetscFunctionBegin;
1051aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1052d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
105317ab2063SBarry Smith #endif
1054e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10556bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10566bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
105705b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1058d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
105905b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
106071f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
106105b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10626bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
106305b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10646bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1065cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10660b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1067a30b2313SHong Zhang 
10684108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1069bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1070901853e0SKris Buschelman 
1071dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1072bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1073bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1074bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1075bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1076bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1077bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1078af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1079af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1080af8000cdSHong Zhang #endif
108163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
108263c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
10833dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
108463c07aadSStefano Zampini #endif
1085b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1086bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1087bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1088bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1089bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10903a40ed3dSBarry Smith   PetscFunctionReturn(0);
109117ab2063SBarry Smith }
109217ab2063SBarry Smith 
1093ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
109417ab2063SBarry Smith {
1095416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10964846f1f5SKris Buschelman   PetscErrorCode ierr;
10973a40ed3dSBarry Smith 
10983a40ed3dSBarry Smith   PetscFunctionBegin;
1099a65d3064SKris Buschelman   switch (op) {
1100a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11014e0d8c25SBarry Smith     a->roworiented = flg;
1102a65d3064SKris Buschelman     break;
1103a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1104a9817697SBarry Smith     a->keepnonzeropattern = flg;
1105a65d3064SKris Buschelman     break;
1106512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1107512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1108a65d3064SKris Buschelman     break;
1109a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11104e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1111a65d3064SKris Buschelman     break;
1112a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11134e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1114a65d3064SKris Buschelman     break;
111528b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
111628b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
111728b2fa4aSMatthew Knepley     break;
1118a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11194e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11200df259c2SBarry Smith     break;
11213d472b54SHong Zhang   case MAT_SPD:
1122b1646e73SJed Brown   case MAT_SYMMETRIC:
1123b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1124b1646e73SJed Brown   case MAT_HERMITIAN:
1125b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1126957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11275021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11285021d80fSJed Brown     break;
11294e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1130a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1131a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1132290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1133a65d3064SKris Buschelman     break;
1134b87ac2d8SJed Brown   case MAT_USE_INODES:
1135b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1136b87ac2d8SJed Brown     break;
1137c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1138c10200c1SHong Zhang     A->submat_singleis = flg;
1139c10200c1SHong Zhang     break;
1140a65d3064SKris Buschelman   default:
1141e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1142a65d3064SKris Buschelman   }
11434108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11443a40ed3dSBarry Smith   PetscFunctionReturn(0);
114517ab2063SBarry Smith }
114617ab2063SBarry Smith 
1147dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
114817ab2063SBarry Smith {
1149416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11506849ba73SBarry Smith   PetscErrorCode ierr;
1151d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
115235e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
115317ab2063SBarry Smith 
11543a40ed3dSBarry Smith   PetscFunctionBegin;
1155d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1156e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
115735e7444dSHong Zhang 
1158d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1159d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
116035e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11612c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
116235e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
116335e7444dSHong Zhang     PetscFunctionReturn(0);
116435e7444dSHong Zhang   }
116535e7444dSHong Zhang 
11662dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11671ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
116835e7444dSHong Zhang   for (i=0; i<n; i++) {
116935e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11702f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
117135e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
117235e7444dSHong Zhang       if (aj[j] == i) {
117335e7444dSHong Zhang         x[i] = aa[j];
117417ab2063SBarry Smith         break;
117517ab2063SBarry Smith       }
117617ab2063SBarry Smith     }
117717ab2063SBarry Smith   }
11781ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11793a40ed3dSBarry Smith   PetscFunctionReturn(0);
118017ab2063SBarry Smith }
118117ab2063SBarry Smith 
1182c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1183dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
118417ab2063SBarry Smith {
1185416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1186d9ca1df4SBarry Smith   PetscScalar       *y;
1187d9ca1df4SBarry Smith   const PetscScalar *x;
1188dfbe8321SBarry Smith   PetscErrorCode    ierr;
1189d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
11905c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1191d9ca1df4SBarry Smith   const MatScalar   *v;
1192a77337e4SBarry Smith   PetscScalar       alpha;
1193d9ca1df4SBarry Smith   PetscInt          n,i,j;
1194d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
11953447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1196ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11975c897100SBarry Smith #endif
119817ab2063SBarry Smith 
11993a40ed3dSBarry Smith   PetscFunctionBegin;
12002e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1201d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12035c897100SBarry Smith 
12045c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1205bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12065c897100SBarry Smith #else
12073447b6efSHong Zhang   if (usecprow) {
12083447b6efSHong Zhang     m    = cprow.nrows;
12093447b6efSHong Zhang     ii   = cprow.i;
12107b2bb3b9SHong Zhang     ridx = cprow.rindex;
12113447b6efSHong Zhang   } else {
12123447b6efSHong Zhang     ii = a->i;
12133447b6efSHong Zhang   }
121417ab2063SBarry Smith   for (i=0; i<m; i++) {
12153447b6efSHong Zhang     idx = a->j + ii[i];
12163447b6efSHong Zhang     v   = a->a + ii[i];
12173447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12183447b6efSHong Zhang     if (usecprow) {
12197b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12203447b6efSHong Zhang     } else {
122117ab2063SBarry Smith       alpha = x[i];
12223447b6efSHong Zhang     }
122304fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
122417ab2063SBarry Smith   }
12255c897100SBarry Smith #endif
1226dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1227d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12281ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12293a40ed3dSBarry Smith   PetscFunctionReturn(0);
123017ab2063SBarry Smith }
123117ab2063SBarry Smith 
1232dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12335c897100SBarry Smith {
1234dfbe8321SBarry Smith   PetscErrorCode ierr;
12355c897100SBarry Smith 
12365c897100SBarry Smith   PetscFunctionBegin;
1237170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12385c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12395c897100SBarry Smith   PetscFunctionReturn(0);
12405c897100SBarry Smith }
12415c897100SBarry Smith 
1242c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
124378b84d54SShri Abhyankar 
1244dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
124517ab2063SBarry Smith {
1246416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1247d9fead3dSBarry Smith   PetscScalar       *y;
124854f21887SBarry Smith   const PetscScalar *x;
124954f21887SBarry Smith   const MatScalar   *aa;
1250dfbe8321SBarry Smith   PetscErrorCode    ierr;
1251003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12520298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12537b083b7cSBarry Smith   PetscInt          n,i;
1254362ced78SSatish Balay   PetscScalar       sum;
1255ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
125617ab2063SBarry Smith 
1257b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
125897952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1259fee21e36SBarry Smith #endif
1260fee21e36SBarry Smith 
12613a40ed3dSBarry Smith   PetscFunctionBegin;
12623649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12631ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1264416022c9SBarry Smith   ii   = a->i;
12654eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12664f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
126797952fefSHong Zhang     m    = a->compressedrow.nrows;
126897952fefSHong Zhang     ii   = a->compressedrow.i;
126997952fefSHong Zhang     ridx = a->compressedrow.rindex;
127097952fefSHong Zhang     for (i=0; i<m; i++) {
127197952fefSHong Zhang       n           = ii[i+1] - ii[i];
127297952fefSHong Zhang       aj          = a->j + ii[i];
127397952fefSHong Zhang       aa          = a->a + ii[i];
127497952fefSHong Zhang       sum         = 0.0;
1275003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1276003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
127797952fefSHong Zhang       y[*ridx++] = sum;
127897952fefSHong Zhang     }
127997952fefSHong Zhang   } else { /* do not use compressed row format */
1280b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
12813d3eaba7SBarry Smith     aj   = a->j;
12823d3eaba7SBarry Smith     aa   = a->a;
1283b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1284b05257ddSBarry Smith #else
128517ab2063SBarry Smith     for (i=0; i<m; i++) {
1286003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1287003131ecSBarry Smith       aj          = a->j + ii[i];
1288003131ecSBarry Smith       aa          = a->a + ii[i];
128917ab2063SBarry Smith       sum         = 0.0;
1290003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
129117ab2063SBarry Smith       y[i] = sum;
129217ab2063SBarry Smith     }
12938d195f9aSBarry Smith #endif
1294b05257ddSBarry Smith   }
12957b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
12963649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12971ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12983a40ed3dSBarry Smith   PetscFunctionReturn(0);
129917ab2063SBarry Smith }
130017ab2063SBarry Smith 
1301b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1302b434eb95SMatthew G. Knepley {
1303b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1304b434eb95SMatthew G. Knepley   PetscScalar       *y;
1305b434eb95SMatthew G. Knepley   const PetscScalar *x;
1306b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1307b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1308b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1309b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1310b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1311b434eb95SMatthew G. Knepley   PetscScalar       sum;
1312b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1313b434eb95SMatthew G. Knepley 
1314b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1315b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1316b434eb95SMatthew G. Knepley #endif
1317b434eb95SMatthew G. Knepley 
1318b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1319b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1320b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1321b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1322b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1323b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1324b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1325b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1326b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1327b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1328b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1329b434eb95SMatthew G. Knepley       sum         = 0.0;
1330b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1331b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1332b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1333b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1334b434eb95SMatthew G. Knepley     }
1335b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13363d3eaba7SBarry Smith     ii = a->i;
1337b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1338b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1339b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1340b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1341b434eb95SMatthew G. Knepley       sum         = 0.0;
1342b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1343b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1344b434eb95SMatthew G. Knepley       y[i] = sum;
1345b434eb95SMatthew G. Knepley     }
1346b434eb95SMatthew G. Knepley   }
1347b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1348b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1349b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1350b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1351b434eb95SMatthew G. Knepley }
1352b434eb95SMatthew G. Knepley 
1353b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1354b434eb95SMatthew G. Knepley {
1355b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1356b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1357b434eb95SMatthew G. Knepley   const PetscScalar *x;
1358b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1359b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1360b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1361b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1362b434eb95SMatthew G. Knepley   PetscScalar       sum;
1363b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1364b434eb95SMatthew G. Knepley 
1365b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1366b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1367d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1368b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1369b434eb95SMatthew G. Knepley     if (zz != yy) {
1370b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1371b434eb95SMatthew G. Knepley     }
1372b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1373b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1374b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1375b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1376b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1377b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1378b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1379b434eb95SMatthew G. Knepley       sum = y[*ridx];
1380b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1381b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1382b434eb95SMatthew G. Knepley     }
1383b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13843d3eaba7SBarry Smith     ii = a->i;
1385b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1386b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1387b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1388b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1389b434eb95SMatthew G. Knepley       sum = y[i];
1390b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1391b434eb95SMatthew G. Knepley       z[i] = sum;
1392b434eb95SMatthew G. Knepley     }
1393b434eb95SMatthew G. Knepley   }
1394b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1395b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1396d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1397b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1398b434eb95SMatthew G. Knepley }
1399b434eb95SMatthew G. Knepley 
1400c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1401dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
140217ab2063SBarry Smith {
1403416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1404f15663dcSBarry Smith   PetscScalar       *y,*z;
1405f15663dcSBarry Smith   const PetscScalar *x;
140654f21887SBarry Smith   const MatScalar   *aa;
1407dfbe8321SBarry Smith   PetscErrorCode    ierr;
1408d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1409d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1410362ced78SSatish Balay   PetscScalar       sum;
1411ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14129ea0dfa2SSatish Balay 
14133a40ed3dSBarry Smith   PetscFunctionBegin;
1414f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1415d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14164eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
14174eb6d288SHong Zhang     if (zz != yy) {
14184eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14194eb6d288SHong Zhang     }
142097952fefSHong Zhang     m    = a->compressedrow.nrows;
142197952fefSHong Zhang     ii   = a->compressedrow.i;
142297952fefSHong Zhang     ridx = a->compressedrow.rindex;
142397952fefSHong Zhang     for (i=0; i<m; i++) {
142497952fefSHong Zhang       n   = ii[i+1] - ii[i];
142597952fefSHong Zhang       aj  = a->j + ii[i];
142697952fefSHong Zhang       aa  = a->a + ii[i];
142797952fefSHong Zhang       sum = y[*ridx];
1428f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
142997952fefSHong Zhang       z[*ridx++] = sum;
143097952fefSHong Zhang     }
143197952fefSHong Zhang   } else { /* do not use compressed row format */
14323d3eaba7SBarry Smith     ii = a->i;
1433f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14343d3eaba7SBarry Smith     aj = a->j;
14353d3eaba7SBarry Smith     aa = a->a;
1436f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1437f15663dcSBarry Smith #else
143817ab2063SBarry Smith     for (i=0; i<m; i++) {
1439f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1440f15663dcSBarry Smith       aj  = a->j + ii[i];
1441f15663dcSBarry Smith       aa  = a->a + ii[i];
144217ab2063SBarry Smith       sum = y[i];
1443f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
144417ab2063SBarry Smith       z[i] = sum;
144517ab2063SBarry Smith     }
144602ab625aSSatish Balay #endif
1447f15663dcSBarry Smith   }
1448dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1449f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1450d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14518154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14526b375ea7SVictor Minden   /*
1453918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1454918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1455918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14566b375ea7SVictor Minden   */
1457918e98c3SVictor Minden #endif
14583a40ed3dSBarry Smith   PetscFunctionReturn(0);
145917ab2063SBarry Smith }
146017ab2063SBarry Smith 
146117ab2063SBarry Smith /*
146217ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
146317ab2063SBarry Smith */
1464dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
146517ab2063SBarry Smith {
1466416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14676849ba73SBarry Smith   PetscErrorCode ierr;
1468d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
146917ab2063SBarry Smith 
14703a40ed3dSBarry Smith   PetscFunctionBegin;
147109f38230SBarry Smith   if (!a->diag) {
1472785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14733bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
147409f38230SBarry Smith   }
1475d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
147609f38230SBarry Smith     a->diag[i] = a->i[i+1];
1477bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1478bfeeae90SHong Zhang       if (a->j[j] == i) {
147909f38230SBarry Smith         a->diag[i] = j;
148017ab2063SBarry Smith         break;
148117ab2063SBarry Smith       }
148217ab2063SBarry Smith     }
148317ab2063SBarry Smith   }
14843a40ed3dSBarry Smith   PetscFunctionReturn(0);
148517ab2063SBarry Smith }
148617ab2063SBarry Smith 
1487be5855fcSBarry Smith /*
1488be5855fcSBarry Smith      Checks for missing diagonals
1489be5855fcSBarry Smith */
1490ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1491be5855fcSBarry Smith {
1492be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
14937734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1494be5855fcSBarry Smith 
1495be5855fcSBarry Smith   PetscFunctionBegin;
149609f38230SBarry Smith   *missing = PETSC_FALSE;
14977734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
149809f38230SBarry Smith     *missing = PETSC_TRUE;
149909f38230SBarry Smith     if (d) *d = 0;
1500955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
150109f38230SBarry Smith   } else {
1502f1e2ffcdSBarry Smith     diag = a->diag;
1503d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
15047734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
150509f38230SBarry Smith         *missing = PETSC_TRUE;
150609f38230SBarry Smith         if (d) *d = i;
1507955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1508358d2f5dSShri Abhyankar         break;
150909f38230SBarry Smith       }
1510be5855fcSBarry Smith     }
1511be5855fcSBarry Smith   }
1512be5855fcSBarry Smith   PetscFunctionReturn(0);
1513be5855fcSBarry Smith }
1514be5855fcSBarry Smith 
1515422a814eSBarry Smith /*
1516422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1517422a814eSBarry Smith */
15187087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
151971f1c65dSBarry Smith {
152071f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
152171f1c65dSBarry Smith   PetscErrorCode ierr;
1522d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
152354f21887SBarry Smith   MatScalar      *v = a->a;
152454f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
152571f1c65dSBarry Smith 
152671f1c65dSBarry Smith   PetscFunctionBegin;
152771f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
152871f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
152971f1c65dSBarry Smith   diag = a->diag;
153071f1c65dSBarry Smith   if (!a->idiag) {
1531dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15323bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
153371f1c65dSBarry Smith     v    = a->a;
153471f1c65dSBarry Smith   }
153571f1c65dSBarry Smith   mdiag = a->mdiag;
153671f1c65dSBarry Smith   idiag = a->idiag;
153771f1c65dSBarry Smith 
1538422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
153971f1c65dSBarry Smith     for (i=0; i<m; i++) {
154071f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1541899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1542899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1543899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15447b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15457b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15467b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15477b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1548899639b0SHong Zhang       }
154971f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
155071f1c65dSBarry Smith     }
155171f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
155271f1c65dSBarry Smith   } else {
155371f1c65dSBarry Smith     for (i=0; i<m; i++) {
155471f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
155571f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
155671f1c65dSBarry Smith     }
1557dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
155871f1c65dSBarry Smith   }
155971f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
156071f1c65dSBarry Smith   PetscFunctionReturn(0);
156171f1c65dSBarry Smith }
156271f1c65dSBarry Smith 
1563c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
156441f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
156517ab2063SBarry Smith {
1566416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1567e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15683d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
156954f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1570dfbe8321SBarry Smith   PetscErrorCode    ierr;
15713d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
157297f1f81fSBarry Smith   const PetscInt    *idx,*diag;
157317ab2063SBarry Smith 
15743a40ed3dSBarry Smith   PetscFunctionBegin;
1575b965ef7fSBarry Smith   its = its*lits;
157691723122SBarry Smith 
157771f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
157871f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
157971f1c65dSBarry Smith   a->fshift = fshift;
158071f1c65dSBarry Smith   a->omega  = omega;
1581ed480e8bSBarry Smith 
158271f1c65dSBarry Smith   diag  = a->diag;
158371f1c65dSBarry Smith   t     = a->ssor_work;
1584ed480e8bSBarry Smith   idiag = a->idiag;
158571f1c65dSBarry Smith   mdiag = a->mdiag;
1586ed480e8bSBarry Smith 
15871ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
15883649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1589ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
159017ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
159117ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1592ed480e8bSBarry Smith     bs = b;
159317ab2063SBarry Smith     for (i=0; i<m; i++) {
159471f1c65dSBarry Smith       d   = fshift + mdiag[i];
1595416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1596ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1597ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
159817ab2063SBarry Smith       sum = b[i]*d/omega;
1599003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
160017ab2063SBarry Smith       x[i] = sum;
160117ab2063SBarry Smith     }
16021ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16033649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1604efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16053a40ed3dSBarry Smith     PetscFunctionReturn(0);
160617ab2063SBarry Smith   }
1607c783ea89SBarry Smith 
16082205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16092205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
161017ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1611887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
161217ab2063SBarry Smith 
161317ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
161417ab2063SBarry Smith 
1615887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
161617ab2063SBarry Smith     */
161717ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
161817ab2063SBarry Smith 
161917ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
162017ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1621416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1622ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1623ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
162417ab2063SBarry Smith       sum = b[i];
1625e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1626ed480e8bSBarry Smith       x[i] = sum*idiag[i];
162717ab2063SBarry Smith     }
162817ab2063SBarry Smith 
162917ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1630416022c9SBarry Smith     v = a->a;
16312205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
163217ab2063SBarry Smith 
163317ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1634ed480e8bSBarry Smith     ts   = t;
1635416022c9SBarry Smith     diag = a->diag;
163617ab2063SBarry Smith     for (i=0; i<m; i++) {
1637416022c9SBarry Smith       n   = diag[i] - a->i[i];
1638ed480e8bSBarry Smith       idx = a->j + a->i[i];
1639ed480e8bSBarry Smith       v   = a->a + a->i[i];
164017ab2063SBarry Smith       sum = t[i];
1641003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1642ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1643733d66baSBarry Smith       /*  x = x + t */
1644733d66baSBarry Smith       x[i] += t[i];
164517ab2063SBarry Smith     }
164617ab2063SBarry Smith 
1647dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16481ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16493649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16503a40ed3dSBarry Smith     PetscFunctionReturn(0);
165117ab2063SBarry Smith   }
165217ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
165317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
165417ab2063SBarry Smith       for (i=0; i<m; i++) {
1655416022c9SBarry Smith         n   = diag[i] - a->i[i];
1656ed480e8bSBarry Smith         idx = a->j + a->i[i];
1657ed480e8bSBarry Smith         v   = a->a + a->i[i];
165817ab2063SBarry Smith         sum = b[i];
1659e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16605c99c7daSBarry Smith         t[i] = sum;
1661ed480e8bSBarry Smith         x[i] = sum*idiag[i];
166217ab2063SBarry Smith       }
16635c99c7daSBarry Smith       xb   = t;
1664efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16653a40ed3dSBarry Smith     } else xb = b;
166617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
166717ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1668416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1669ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1670ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
167117ab2063SBarry Smith         sum = xb[i];
1672e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16735c99c7daSBarry Smith         if (xb == b) {
1674ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16755c99c7daSBarry Smith         } else {
1676b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
167717ab2063SBarry Smith         }
16785c99c7daSBarry Smith       }
1679b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
168017ab2063SBarry Smith     }
168117ab2063SBarry Smith     its--;
168217ab2063SBarry Smith   }
168317ab2063SBarry Smith   while (its--) {
168417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
168517ab2063SBarry Smith       for (i=0; i<m; i++) {
1686b19a5dc2SMark Adams         /* lower */
1687b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1688ed480e8bSBarry Smith         idx = a->j + a->i[i];
1689ed480e8bSBarry Smith         v   = a->a + a->i[i];
169017ab2063SBarry Smith         sum = b[i];
1691e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1692b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1693b19a5dc2SMark Adams         /* upper */
1694b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1695b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1696b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1697b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1698b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
169917ab2063SBarry Smith       }
1700b19a5dc2SMark Adams       xb   = t;
17019f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1702b19a5dc2SMark Adams     } else xb = b;
170317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
170417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1705b19a5dc2SMark Adams         sum = xb[i];
1706b19a5dc2SMark Adams         if (xb == b) {
1707b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1708416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1709ed480e8bSBarry Smith           idx = a->j + a->i[i];
1710ed480e8bSBarry Smith           v   = a->a + a->i[i];
1711e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1712ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1713b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1714b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1715b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1716b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1717b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1718b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
171917ab2063SBarry Smith         }
1720b19a5dc2SMark Adams       }
1721b19a5dc2SMark Adams       if (xb == b) {
17229f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1723b19a5dc2SMark Adams       } else {
1724b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1725b19a5dc2SMark Adams       }
172617ab2063SBarry Smith     }
172717ab2063SBarry Smith   }
17281ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17293649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1730365a8a9eSBarry Smith   PetscFunctionReturn(0);
173117ab2063SBarry Smith }
173217ab2063SBarry Smith 
17332af78befSBarry Smith 
1734dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
173517ab2063SBarry Smith {
1736416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17374e220ebcSLois Curfman McInnes 
17383a40ed3dSBarry Smith   PetscFunctionBegin;
17394e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17404e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17414e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17424e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17434e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17448e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17457adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1746d5f3da31SBarry Smith   if (A->factortype) {
17474e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17484e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17494e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17504e220ebcSLois Curfman McInnes   } else {
17514e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17524e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17534e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17544e220ebcSLois Curfman McInnes   }
17553a40ed3dSBarry Smith   PetscFunctionReturn(0);
175617ab2063SBarry Smith }
175717ab2063SBarry Smith 
17582b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
175917ab2063SBarry Smith {
1760416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1761c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17626849ba73SBarry Smith   PetscErrorCode    ierr;
176397b48c8fSBarry Smith   const PetscScalar *xx;
176497b48c8fSBarry Smith   PetscScalar       *bb;
1765c7da8527SEric Chamberland   PetscInt          d = 0;
176617ab2063SBarry Smith 
17673a40ed3dSBarry Smith   PetscFunctionBegin;
176897b48c8fSBarry Smith   if (x && b) {
176997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
177097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
177197b48c8fSBarry Smith     for (i=0; i<N; i++) {
177297b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
177397b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
177497b48c8fSBarry Smith     }
177597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
177697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
177797b48c8fSBarry Smith   }
177897b48c8fSBarry Smith 
1779a9817697SBarry Smith   if (a->keepnonzeropattern) {
1780f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1781e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1782bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1783f1e2ffcdSBarry Smith     }
1784f4df32b1SMatthew Knepley     if (diag != 0.0) {
1785c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1786c7da8527SEric Chamberland         d = rows[i];
1787c7da8527SEric 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);
1788c7da8527SEric Chamberland       }
1789f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1790f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1791f1e2ffcdSBarry Smith       }
1792f1e2ffcdSBarry Smith     }
1793f1e2ffcdSBarry Smith   } else {
1794f4df32b1SMatthew Knepley     if (diag != 0.0) {
179517ab2063SBarry Smith       for (i=0; i<N; i++) {
1796e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
17977ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1798416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1799f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1800bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18017ae801bdSBarry Smith         } else { /* in case row was completely empty */
1802f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
180317ab2063SBarry Smith         }
180417ab2063SBarry Smith       }
18053a40ed3dSBarry Smith     } else {
180617ab2063SBarry Smith       for (i=0; i<N; i++) {
1807e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1808416022c9SBarry Smith         a->ilen[rows[i]] = 0;
180917ab2063SBarry Smith       }
181017ab2063SBarry Smith     }
1811e56f5c9eSBarry Smith     A->nonzerostate++;
1812f1e2ffcdSBarry Smith   }
181343a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18143a40ed3dSBarry Smith   PetscFunctionReturn(0);
181517ab2063SBarry Smith }
181617ab2063SBarry Smith 
18176e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18186e169961SBarry Smith {
18196e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18206e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18216e169961SBarry Smith   PetscErrorCode    ierr;
18222b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18236e169961SBarry Smith   const PetscScalar *xx;
18246e169961SBarry Smith   PetscScalar       *bb;
18256e169961SBarry Smith 
18266e169961SBarry Smith   PetscFunctionBegin;
18276e169961SBarry Smith   if (x && b) {
18286e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18296e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18302b40b63fSBarry Smith     vecs = PETSC_TRUE;
18316e169961SBarry Smith   }
18321795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18336e169961SBarry Smith   for (i=0; i<N; i++) {
18346e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18356e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18362205254eSKarl Rupp 
18376e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18386e169961SBarry Smith   }
18396e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18406e169961SBarry Smith     if (!zeroed[i]) {
18416e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18426e169961SBarry Smith         if (zeroed[a->j[j]]) {
18432b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18446e169961SBarry Smith           a->a[j] = 0.0;
18456e169961SBarry Smith         }
18466e169961SBarry Smith       }
18472b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18486e169961SBarry Smith   }
18496e169961SBarry Smith   if (x && b) {
18506e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18516e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18526e169961SBarry Smith   }
18536e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18546e169961SBarry Smith   if (diag != 0.0) {
18556e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18561d5a398dSstefano_zampini     if (missing) {
18571d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18581d5a398dSstefano_zampini       else {
18591d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18601d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18611d5a398dSstefano_zampini         }
18621d5a398dSstefano_zampini       }
18631d5a398dSstefano_zampini     } else {
18646e169961SBarry Smith       for (i=0; i<N; i++) {
18656e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18666e169961SBarry Smith       }
18676e169961SBarry Smith     }
18681d5a398dSstefano_zampini   }
18696e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18706e169961SBarry Smith   PetscFunctionReturn(0);
18716e169961SBarry Smith }
18726e169961SBarry Smith 
1873a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
187417ab2063SBarry Smith {
1875416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
187697f1f81fSBarry Smith   PetscInt   *itmp;
187717ab2063SBarry Smith 
18783a40ed3dSBarry Smith   PetscFunctionBegin;
1879e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
188017ab2063SBarry Smith 
1881416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1882bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
188317ab2063SBarry Smith   if (idx) {
1884bfeeae90SHong Zhang     itmp = a->j + a->i[row];
188526fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
188617ab2063SBarry Smith     else *idx = 0;
188717ab2063SBarry Smith   }
18883a40ed3dSBarry Smith   PetscFunctionReturn(0);
188917ab2063SBarry Smith }
189017ab2063SBarry Smith 
1891bfeeae90SHong Zhang /* remove this function? */
1892a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
189317ab2063SBarry Smith {
18943a40ed3dSBarry Smith   PetscFunctionBegin;
18953a40ed3dSBarry Smith   PetscFunctionReturn(0);
189617ab2063SBarry Smith }
189717ab2063SBarry Smith 
1898dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
189917ab2063SBarry Smith {
1900416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
190154f21887SBarry Smith   MatScalar      *v  = a->a;
190236db0b34SBarry Smith   PetscReal      sum = 0.0;
19036849ba73SBarry Smith   PetscErrorCode ierr;
190497f1f81fSBarry Smith   PetscInt       i,j;
190517ab2063SBarry Smith 
19063a40ed3dSBarry Smith   PetscFunctionBegin;
190717ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1908570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1909570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1910570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1911570b7f6dSBarry Smith #else
1912416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
191336db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
191417ab2063SBarry Smith     }
19158f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1916570b7f6dSBarry Smith #endif
191751f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19183a40ed3dSBarry Smith   } else if (type == NORM_1) {
191936db0b34SBarry Smith     PetscReal *tmp;
192097f1f81fSBarry Smith     PetscInt  *jj = a->j;
19211795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1922064f8208SBarry Smith     *nrm = 0.0;
1923416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1924bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
192517ab2063SBarry Smith     }
1926d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1927064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
192817ab2063SBarry Smith     }
1929606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
193051f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19313a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1932064f8208SBarry Smith     *nrm = 0.0;
1933d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1934bfeeae90SHong Zhang       v   = a->a + a->i[j];
193517ab2063SBarry Smith       sum = 0.0;
1936416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1937cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
193817ab2063SBarry Smith       }
1939064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
194017ab2063SBarry Smith     }
194151f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1942f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19433a40ed3dSBarry Smith   PetscFunctionReturn(0);
194417ab2063SBarry Smith }
194517ab2063SBarry Smith 
19464e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19474e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19484e938277SHong Zhang {
19494e938277SHong Zhang   PetscErrorCode ierr;
19504e938277SHong Zhang   PetscInt       i,j,anzj;
19514e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19524e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19534e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19544e938277SHong Zhang 
19554e938277SHong Zhang   PetscFunctionBegin;
19564e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1957854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1958785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1959785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19604e938277SHong Zhang 
19614e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19624e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
196326fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19644e938277SHong Zhang   /* Form ati for csr format of A^T. */
196526fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19664e938277SHong Zhang 
19674e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19684e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19694e938277SHong Zhang 
19704e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19714e938277SHong Zhang   for (i=0;i<am;i++) {
19724e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19734e938277SHong Zhang     for (j=0;j<anzj;j++) {
19744e938277SHong Zhang       atj[atfill[*aj]] = i;
19754e938277SHong Zhang       atfill[*aj++]   += 1;
19764e938277SHong Zhang     }
19774e938277SHong Zhang   }
19784e938277SHong Zhang 
19794e938277SHong Zhang   /* Clean up temporary space and complete requests. */
19804e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
1981ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
198233d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
1983a2f3521dSMark F. Adams 
19844e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
19854e938277SHong Zhang   b->free_a  = PETSC_FALSE;
19864e938277SHong Zhang   b->free_ij = PETSC_TRUE;
19874e938277SHong Zhang   b->nonew   = 0;
19884e938277SHong Zhang   PetscFunctionReturn(0);
19894e938277SHong Zhang }
19904e938277SHong Zhang 
1991fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
199217ab2063SBarry Smith {
1993416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1994416022c9SBarry Smith   Mat            C;
19956849ba73SBarry Smith   PetscErrorCode ierr;
1996d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
199754f21887SBarry Smith   MatScalar      *array = a->a;
199817ab2063SBarry Smith 
19993a40ed3dSBarry Smith   PetscFunctionBegin;
2000cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2001fc4dec0aSBarry Smith 
2002cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
2003854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
2004bfeeae90SHong Zhang 
2005bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2006ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2007d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
200833d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
20097adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2010ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2011606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2012a541d17aSBarry Smith   } else {
2013a541d17aSBarry Smith     C = *B;
2014a541d17aSBarry Smith   }
2015a541d17aSBarry Smith 
201617ab2063SBarry Smith   for (i=0; i<m; i++) {
201717ab2063SBarry Smith     len    = ai[i+1]-ai[i];
201887d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2019b9b97703SBarry Smith     array += len;
2020b9b97703SBarry Smith     aj    += len;
202117ab2063SBarry Smith   }
20226d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20236d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
202417ab2063SBarry Smith 
2025cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2026416022c9SBarry Smith     *B = C;
202717ab2063SBarry Smith   } else {
202828be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
202917ab2063SBarry Smith   }
20303a40ed3dSBarry Smith   PetscFunctionReturn(0);
203117ab2063SBarry Smith }
203217ab2063SBarry Smith 
20337087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2034cd0d46ebSvictorle {
20353d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
203654f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
203754f21887SBarry Smith   MatScalar      *va,*vb;
20386849ba73SBarry Smith   PetscErrorCode ierr;
203997f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2040cd0d46ebSvictorle 
2041cd0d46ebSvictorle   PetscFunctionBegin;
2042cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2043cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20445485867bSBarry Smith   if (ma!=nb || na!=mb) {
20455485867bSBarry Smith     *f = PETSC_FALSE;
20465485867bSBarry Smith     PetscFunctionReturn(0);
20475485867bSBarry Smith   }
2048cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2049cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2050cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2051785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2052785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2053cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2054cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2055cd0d46ebSvictorle 
2056cd0d46ebSvictorle   *f = PETSC_TRUE;
2057cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2058cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
205997f1f81fSBarry Smith       PetscInt    idc,idr;
20605485867bSBarry Smith       PetscScalar vc,vr;
2061cd0d46ebSvictorle       /* column/row index/value */
20625485867bSBarry Smith       idc = adx[aptr[i]];
20635485867bSBarry Smith       idr = bdx[bptr[idc]];
20645485867bSBarry Smith       vc  = va[aptr[i]];
20655485867bSBarry Smith       vr  = vb[bptr[idc]];
20665485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20675485867bSBarry Smith         *f = PETSC_FALSE;
20685485867bSBarry Smith         goto done;
2069cd0d46ebSvictorle       } else {
20705485867bSBarry Smith         aptr[i]++;
20715485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2072cd0d46ebSvictorle       }
2073cd0d46ebSvictorle     }
2074cd0d46ebSvictorle   }
2075cd0d46ebSvictorle done:
2076cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20773aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2078cd0d46ebSvictorle   PetscFunctionReturn(0);
2079cd0d46ebSvictorle }
2080cd0d46ebSvictorle 
20817087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
20821cbb95d3SBarry Smith {
20833d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
208454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
208554f21887SBarry Smith   MatScalar      *va,*vb;
20861cbb95d3SBarry Smith   PetscErrorCode ierr;
20871cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
20881cbb95d3SBarry Smith 
20891cbb95d3SBarry Smith   PetscFunctionBegin;
20901cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
20911cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20921cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
20931cbb95d3SBarry Smith     *f = PETSC_FALSE;
20941cbb95d3SBarry Smith     PetscFunctionReturn(0);
20951cbb95d3SBarry Smith   }
20961cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
20971cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
20981cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2099785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2100785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
21011cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
21021cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
21031cbb95d3SBarry Smith 
21041cbb95d3SBarry Smith   *f = PETSC_TRUE;
21051cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
21061cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21071cbb95d3SBarry Smith       PetscInt    idc,idr;
21081cbb95d3SBarry Smith       PetscScalar vc,vr;
21091cbb95d3SBarry Smith       /* column/row index/value */
21101cbb95d3SBarry Smith       idc = adx[aptr[i]];
21111cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
21121cbb95d3SBarry Smith       vc  = va[aptr[i]];
21131cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
21141cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
21151cbb95d3SBarry Smith         *f = PETSC_FALSE;
21161cbb95d3SBarry Smith         goto done;
21171cbb95d3SBarry Smith       } else {
21181cbb95d3SBarry Smith         aptr[i]++;
21191cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21201cbb95d3SBarry Smith       }
21211cbb95d3SBarry Smith     }
21221cbb95d3SBarry Smith   }
21231cbb95d3SBarry Smith done:
21241cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21251cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21261cbb95d3SBarry Smith   PetscFunctionReturn(0);
21271cbb95d3SBarry Smith }
21281cbb95d3SBarry Smith 
2129ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21309e29f15eSvictorle {
2131dfbe8321SBarry Smith   PetscErrorCode ierr;
21326e111a19SKarl Rupp 
21339e29f15eSvictorle   PetscFunctionBegin;
21345485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21359e29f15eSvictorle   PetscFunctionReturn(0);
21369e29f15eSvictorle }
21379e29f15eSvictorle 
2138ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21391cbb95d3SBarry Smith {
21401cbb95d3SBarry Smith   PetscErrorCode ierr;
21416e111a19SKarl Rupp 
21421cbb95d3SBarry Smith   PetscFunctionBegin;
21431cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21441cbb95d3SBarry Smith   PetscFunctionReturn(0);
21451cbb95d3SBarry Smith }
21461cbb95d3SBarry Smith 
2147dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
214817ab2063SBarry Smith {
2149416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
215054f21887SBarry Smith   PetscScalar    *l,*r,x;
215154f21887SBarry Smith   MatScalar      *v;
2152dfbe8321SBarry Smith   PetscErrorCode ierr;
2153d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
215417ab2063SBarry Smith 
21553a40ed3dSBarry Smith   PetscFunctionBegin;
215617ab2063SBarry Smith   if (ll) {
21573ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21583ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2159e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2160e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
21611ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2162416022c9SBarry Smith     v    = a->a;
216317ab2063SBarry Smith     for (i=0; i<m; i++) {
216417ab2063SBarry Smith       x = l[i];
2165416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21662205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
216717ab2063SBarry Smith     }
21681ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2169efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
217017ab2063SBarry Smith   }
217117ab2063SBarry Smith   if (rr) {
2172e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2173e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
21741ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2175416022c9SBarry Smith     v    = a->a; jj = a->j;
21762205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
21771ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2178efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
217917ab2063SBarry Smith   }
2180acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
21813a40ed3dSBarry Smith   PetscFunctionReturn(0);
218217ab2063SBarry Smith }
218317ab2063SBarry Smith 
21847dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
218517ab2063SBarry Smith {
2186db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
21876849ba73SBarry Smith   PetscErrorCode ierr;
2188d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
218997f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
21905d0c19d7SBarry Smith   const PetscInt *irow,*icol;
21915d0c19d7SBarry Smith   PetscInt       nrows,ncols;
219297f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
219354f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2194416022c9SBarry Smith   Mat            C;
2195cdc6f3adSToby Isaac   PetscBool      stride;
219617ab2063SBarry Smith 
21973a40ed3dSBarry Smith   PetscFunctionBegin;
219899141d43SSatish Balay 
219917ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2200b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2201b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
220217ab2063SBarry Smith 
2203251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2204ff718158SBarry Smith   if (stride) {
2205ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2206ff718158SBarry Smith   } else {
2207ff718158SBarry Smith     first = 0;
2208ff718158SBarry Smith     step  = 0;
2209ff718158SBarry Smith   }
2210fee21e36SBarry Smith   if (stride && step == 1) {
221102834360SBarry Smith     /* special case of contiguous rows */
2212dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
221302834360SBarry Smith     /* loop over new rows determining lens and starting points */
221402834360SBarry Smith     for (i=0; i<nrows; i++) {
2215bfeeae90SHong Zhang       kstart = ai[irow[i]];
2216a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2217a91a9bebSLisandro Dalcin       starts[i] = kstart;
221802834360SBarry Smith       for (k=kstart; k<kend; k++) {
2219bfeeae90SHong Zhang         if (aj[k] >= first) {
222002834360SBarry Smith           starts[i] = k;
222102834360SBarry Smith           break;
222202834360SBarry Smith         }
222302834360SBarry Smith       }
2224a2744918SBarry Smith       sum = 0;
222502834360SBarry Smith       while (k < kend) {
2226bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2227a2744918SBarry Smith         sum++;
222802834360SBarry Smith       }
2229a2744918SBarry Smith       lens[i] = sum;
223002834360SBarry Smith     }
223102834360SBarry Smith     /* create submatrix */
2232cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
223397f1f81fSBarry Smith       PetscInt n_cols,n_rows;
223408480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2235e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2236d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
223708480c60SBarry Smith       C    = *B;
22383a40ed3dSBarry Smith     } else {
22393bef6203SJed Brown       PetscInt rbs,cbs;
2240ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2241f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22423bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22433bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22443bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22457adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2246ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
224708480c60SBarry Smith     }
2248db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2249db02288aSLois Curfman McInnes 
225002834360SBarry Smith     /* loop over rows inserting into submatrix */
2251db02288aSLois Curfman McInnes     a_new = c->a;
2252db02288aSLois Curfman McInnes     j_new = c->j;
2253db02288aSLois Curfman McInnes     i_new = c->i;
2254bfeeae90SHong Zhang 
225502834360SBarry Smith     for (i=0; i<nrows; i++) {
2256a2744918SBarry Smith       ii    = starts[i];
2257a2744918SBarry Smith       lensi = lens[i];
2258a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2259a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
226002834360SBarry Smith       }
226187828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2262a2744918SBarry Smith       a_new     += lensi;
2263a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2264a2744918SBarry Smith       c->ilen[i] = lensi;
226502834360SBarry Smith     }
22660e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22673a40ed3dSBarry Smith   } else {
226802834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22691795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2270854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22714dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22724dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22734dcab191SBarry 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);
22744dcab191SBarry Smith #endif
22754dcab191SBarry Smith       smap[icol[i]] = i+1;
22764dcab191SBarry Smith     }
22774dcab191SBarry Smith 
227802834360SBarry Smith     /* determine lens of each row */
227902834360SBarry Smith     for (i=0; i<nrows; i++) {
2280bfeeae90SHong Zhang       kstart  = ai[irow[i]];
228102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
228202834360SBarry Smith       lens[i] = 0;
228302834360SBarry Smith       for (k=kstart; k<kend; k++) {
2284bfeeae90SHong Zhang         if (smap[aj[k]]) {
228502834360SBarry Smith           lens[i]++;
228602834360SBarry Smith         }
228702834360SBarry Smith       }
228802834360SBarry Smith     }
228917ab2063SBarry Smith     /* Create and fill new matrix */
2290a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2291ace3abfcSBarry Smith       PetscBool equal;
22920f5bd95cSBarry Smith 
229399141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2294e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2295d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2296f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2297d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
229808480c60SBarry Smith       C    = *B;
22993a40ed3dSBarry Smith     } else {
23003bef6203SJed Brown       PetscInt rbs,cbs;
2301ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2302f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23033bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23043bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23053bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23067adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2307ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
230808480c60SBarry Smith     }
230999141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
231017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
231199141d43SSatish Balay       row      = irow[i];
2312bfeeae90SHong Zhang       kstart   = ai[row];
231399141d43SSatish Balay       kend     = kstart + a->ilen[row];
2314bfeeae90SHong Zhang       mat_i    = c->i[i];
231599141d43SSatish Balay       mat_j    = c->j + mat_i;
231699141d43SSatish Balay       mat_a    = c->a + mat_i;
231799141d43SSatish Balay       mat_ilen = c->ilen + i;
231817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2319bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2320ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
232199141d43SSatish Balay           *mat_a++ = a->a[k];
232299141d43SSatish Balay           (*mat_ilen)++;
232399141d43SSatish Balay 
232417ab2063SBarry Smith         }
232517ab2063SBarry Smith       }
232617ab2063SBarry Smith     }
232702834360SBarry Smith     /* Free work space */
232802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2329606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2330606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2331cdc6f3adSToby Isaac     /* sort */
2332cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2333cdc6f3adSToby Isaac       PetscInt ilen;
2334cdc6f3adSToby Isaac 
2335cdc6f3adSToby Isaac       mat_i = c->i[i];
2336cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2337cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2338cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2339390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2340cdc6f3adSToby Isaac     }
234102834360SBarry Smith   }
23426d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23436d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
234417ab2063SBarry Smith 
234517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2346416022c9SBarry Smith   *B   = C;
23473a40ed3dSBarry Smith   PetscFunctionReturn(0);
234817ab2063SBarry Smith }
234917ab2063SBarry Smith 
2350fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
235182d44351SHong Zhang {
235282d44351SHong Zhang   PetscErrorCode ierr;
235382d44351SHong Zhang   Mat            B;
235482d44351SHong Zhang 
235582d44351SHong Zhang   PetscFunctionBegin;
2356c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
235782d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
235882d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
235933d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
236082d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
236182d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
236282d44351SHong Zhang     *subMat = B;
2363c2d650bdSHong Zhang   } else {
2364c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2365c2d650bdSHong Zhang   }
236682d44351SHong Zhang   PetscFunctionReturn(0);
236782d44351SHong Zhang }
236882d44351SHong Zhang 
23699a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2370a871dcd8SBarry Smith {
237163b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2372dfbe8321SBarry Smith   PetscErrorCode ierr;
237363b91edcSBarry Smith   Mat            outA;
2374ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
237563b91edcSBarry Smith 
23763a40ed3dSBarry Smith   PetscFunctionBegin;
2377e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
23781df811f5SHong Zhang 
2379b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2380b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2381a871dcd8SBarry Smith 
238263b91edcSBarry Smith   outA             = inA;
2383d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2384f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2385f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
23862205254eSKarl Rupp 
2387c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
23886bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
23892205254eSKarl Rupp 
2390c3122656SLisandro Dalcin   a->row = row;
23912205254eSKarl Rupp 
2392c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
23936bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
23942205254eSKarl Rupp 
2395c3122656SLisandro Dalcin   a->col = col;
239663b91edcSBarry Smith 
239736db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
23986bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
23994c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
24003bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2401f0ec6fceSSatish Balay 
240294a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2403854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
24043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
240594a9d846SBarry Smith   }
240663b91edcSBarry Smith 
2407f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2408137fb511SHong Zhang   if (row_identity && col_identity) {
2409ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2410137fb511SHong Zhang   } else {
2411719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2412137fb511SHong Zhang   }
24133a40ed3dSBarry Smith   PetscFunctionReturn(0);
2414a871dcd8SBarry Smith }
2415a871dcd8SBarry Smith 
2416f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2417f0b747eeSBarry Smith {
2418f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2419f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2420efee365bSSatish Balay   PetscErrorCode ierr;
2421c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24223a40ed3dSBarry Smith 
24233a40ed3dSBarry Smith   PetscFunctionBegin;
2424c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24258b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2426efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2427acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24283a40ed3dSBarry Smith   PetscFunctionReturn(0);
2429f0b747eeSBarry Smith }
2430f0b747eeSBarry Smith 
24315c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
243216b64355SHong Zhang {
243316b64355SHong Zhang   PetscErrorCode ierr;
243416b64355SHong Zhang   PetscInt       i;
243516b64355SHong Zhang 
243616b64355SHong Zhang   PetscFunctionBegin;
243716b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
243816b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
243916b64355SHong Zhang 
244016b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
244116b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
244216b64355SHong Zhang     }
244316b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
244416b64355SHong Zhang 
244516b64355SHong Zhang     if (submatj->rbuf1) {
244616b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
244716b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
244816b64355SHong Zhang     }
244916b64355SHong Zhang 
245016b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
245116b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
245216b64355SHong Zhang     }
245316b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
245416b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
245516b64355SHong Zhang   }
245616b64355SHong Zhang 
245716b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
245816b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
245916b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
246016b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
246116b64355SHong Zhang #else
246216b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
246316b64355SHong Zhang #endif
246416b64355SHong Zhang 
246516b64355SHong Zhang   if (!submatj->allcolumns) {
246616b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
246716b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
246816b64355SHong Zhang #else
246916b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
247016b64355SHong Zhang #endif
247116b64355SHong Zhang   }
247216b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
247316b64355SHong Zhang 
247416b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
247516b64355SHong Zhang   PetscFunctionReturn(0);
247616b64355SHong Zhang }
247716b64355SHong Zhang 
247816b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
247916b64355SHong Zhang {
248016b64355SHong Zhang   PetscErrorCode ierr;
248116b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
24825c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
248316b64355SHong Zhang 
248416b64355SHong Zhang   PetscFunctionBegin;
248516b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2486e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
248716b64355SHong Zhang   PetscFunctionReturn(0);
248816b64355SHong Zhang }
248916b64355SHong Zhang 
24907dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2491cddf8d76SBarry Smith {
2492dfbe8321SBarry Smith   PetscErrorCode ierr;
249397f1f81fSBarry Smith   PetscInt       i;
2494cddf8d76SBarry Smith 
24953a40ed3dSBarry Smith   PetscFunctionBegin;
2496cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2497df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2498cddf8d76SBarry Smith   }
2499cddf8d76SBarry Smith 
2500cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25017dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2502cddf8d76SBarry Smith   }
25033a40ed3dSBarry Smith   PetscFunctionReturn(0);
2504cddf8d76SBarry Smith }
2505cddf8d76SBarry Smith 
250697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25074dcbc457SBarry Smith {
2508e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25096849ba73SBarry Smith   PetscErrorCode ierr;
25105d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25115d0c19d7SBarry Smith   const PetscInt *idx;
251297f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2513f1af5d2fSBarry Smith   PetscBT        table;
2514bbd702dbSSatish Balay 
25153a40ed3dSBarry Smith   PetscFunctionBegin;
2516d0f46423SBarry Smith   m  = A->rmap->n;
2517e4d965acSSatish Balay   ai = a->i;
2518bfeeae90SHong Zhang   aj = a->j;
25198a047759SSatish Balay 
2520e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
252106763907SSatish Balay 
2522854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
252353b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
252406763907SSatish Balay 
2525e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2526b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2527e4d965acSSatish Balay     isz  = 0;
25286831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2529e4d965acSSatish Balay 
2530e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25314dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2532b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2533e4d965acSSatish Balay 
2534dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2535e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25362205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25374dcbc457SBarry Smith     }
253806763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25396bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2540e4d965acSSatish Balay 
254104a348a9SBarry Smith     k = 0;
254204a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
254304a348a9SBarry Smith       n = isz;
254406763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2545e4d965acSSatish Balay         row   = nidx[k];
2546e4d965acSSatish Balay         start = ai[row];
2547e4d965acSSatish Balay         end   = ai[row+1];
254804a348a9SBarry Smith         for (l = start; l<end; l++) {
2549efb16452SHong Zhang           val = aj[l];
25502205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2551e4d965acSSatish Balay         }
2552e4d965acSSatish Balay       }
2553e4d965acSSatish Balay     }
255470b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2555e4d965acSSatish Balay   }
255694bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2557606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25583a40ed3dSBarry Smith   PetscFunctionReturn(0);
25594dcbc457SBarry Smith }
256017ab2063SBarry Smith 
25610513a670SBarry Smith /* -------------------------------------------------------------- */
2562dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25630513a670SBarry Smith {
25640513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25656849ba73SBarry Smith   PetscErrorCode ierr;
25663b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25675d0c19d7SBarry Smith   const PetscInt *row,*col;
25685d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
256956cd22aeSBarry Smith   IS             icolp,irowp;
25700298fd71SBarry Smith   PetscInt       *cwork = NULL;
25710298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25720513a670SBarry Smith 
25733a40ed3dSBarry Smith   PetscFunctionBegin;
25744c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
257556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25764c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
257756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
25780513a670SBarry Smith 
25790513a670SBarry Smith   /* determine lengths of permuted rows */
2580854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
25812205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2582ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2583f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
258433d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
25857adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2586ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2587606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
25880513a670SBarry Smith 
2589785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
25900513a670SBarry Smith   for (i=0; i<m; i++) {
259132ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25922205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2593cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
259432ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
25950513a670SBarry Smith   }
2596606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
25972205254eSKarl Rupp 
25983c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
25992205254eSKarl Rupp 
26000513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26010513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
260256cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
260356cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26046bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26056bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26063a40ed3dSBarry Smith   PetscFunctionReturn(0);
26070513a670SBarry Smith }
26080513a670SBarry Smith 
2609dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2610cb5b572fSBarry Smith {
2611dfbe8321SBarry Smith   PetscErrorCode ierr;
2612cb5b572fSBarry Smith 
2613cb5b572fSBarry Smith   PetscFunctionBegin;
261433f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
261533f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2616be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2617be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2618be6bf707SBarry Smith 
2619700c5bfcSBarry 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");
2620d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2621cb5b572fSBarry Smith   } else {
2622cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2623cb5b572fSBarry Smith   }
2624cb5b572fSBarry Smith   PetscFunctionReturn(0);
2625cb5b572fSBarry Smith }
2626cb5b572fSBarry Smith 
26274994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2628273d9f13SBarry Smith {
2629dfbe8321SBarry Smith   PetscErrorCode ierr;
2630273d9f13SBarry Smith 
2631273d9f13SBarry Smith   PetscFunctionBegin;
2632ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2633273d9f13SBarry Smith   PetscFunctionReturn(0);
2634273d9f13SBarry Smith }
2635273d9f13SBarry Smith 
26368c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26376c0721eeSBarry Smith {
26386c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26396e111a19SKarl Rupp 
26406c0721eeSBarry Smith   PetscFunctionBegin;
26416c0721eeSBarry Smith   *array = a->a;
26426c0721eeSBarry Smith   PetscFunctionReturn(0);
26436c0721eeSBarry Smith }
26446c0721eeSBarry Smith 
26458c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26466c0721eeSBarry Smith {
26476c0721eeSBarry Smith   PetscFunctionBegin;
26486c0721eeSBarry Smith   PetscFunctionReturn(0);
26496c0721eeSBarry Smith }
2650273d9f13SBarry Smith 
26518229c054SShri Abhyankar /*
26528229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26538229c054SShri Abhyankar    have different nonzero structure.
26548229c054SShri Abhyankar */
2655b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2656ec7775f6SShri Abhyankar {
2657b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2658ec7775f6SShri Abhyankar 
2659ec7775f6SShri Abhyankar   PetscFunctionBegin;
2660ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2661ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2662b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2663b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2664b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26658af7cee1SJed Brown     nnz[i] = 0;
26668af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2667b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2668b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26698af7cee1SJed Brown       nnz[i]++;
26708af7cee1SJed Brown     }
26718af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2672ec7775f6SShri Abhyankar   }
2673ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2674ec7775f6SShri Abhyankar }
2675ec7775f6SShri Abhyankar 
2676b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2677b264fe52SHong Zhang {
2678b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2679b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2680b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2681b264fe52SHong Zhang   PetscErrorCode ierr;
2682b264fe52SHong Zhang 
2683b264fe52SHong Zhang   PetscFunctionBegin;
2684b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2685b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2686b264fe52SHong Zhang   PetscFunctionReturn(0);
2687b264fe52SHong Zhang }
2688b264fe52SHong Zhang 
2689f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2690ac90fabeSBarry Smith {
2691dfbe8321SBarry Smith   PetscErrorCode ierr;
2692ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2693c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2694ac90fabeSBarry Smith 
2695ac90fabeSBarry Smith   PetscFunctionBegin;
2696c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2697ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2698f4df32b1SMatthew Knepley     PetscScalar alpha = a;
26998b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2700acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2701a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2702ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2703ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2704ac90fabeSBarry Smith   } else {
27058229c054SShri Abhyankar     Mat      B;
27068229c054SShri Abhyankar     PetscInt *nnz;
2707785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2708ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2709bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27104aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
271133d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2712176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27138229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2714ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2715ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
271628be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27178229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2718ac90fabeSBarry Smith   }
2719ac90fabeSBarry Smith   PetscFunctionReturn(0);
2720ac90fabeSBarry Smith }
2721ac90fabeSBarry Smith 
27227087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2723354c94deSBarry Smith {
2724354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2725354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2726354c94deSBarry Smith   PetscInt    i,nz;
2727354c94deSBarry Smith   PetscScalar *a;
2728354c94deSBarry Smith 
2729354c94deSBarry Smith   PetscFunctionBegin;
2730354c94deSBarry Smith   nz = aij->nz;
2731354c94deSBarry Smith   a  = aij->a;
27322205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2733354c94deSBarry Smith #else
2734354c94deSBarry Smith   PetscFunctionBegin;
2735354c94deSBarry Smith #endif
2736354c94deSBarry Smith   PetscFunctionReturn(0);
2737354c94deSBarry Smith }
2738354c94deSBarry Smith 
2739985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2740e34fafa9SBarry Smith {
2741e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2742e34fafa9SBarry Smith   PetscErrorCode ierr;
2743d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2744e34fafa9SBarry Smith   PetscReal      atmp;
2745985db425SBarry Smith   PetscScalar    *x;
2746e34fafa9SBarry Smith   MatScalar      *aa;
2747e34fafa9SBarry Smith 
2748e34fafa9SBarry Smith   PetscFunctionBegin;
2749e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2750e34fafa9SBarry Smith   aa = a->a;
2751e34fafa9SBarry Smith   ai = a->i;
2752e34fafa9SBarry Smith   aj = a->j;
2753e34fafa9SBarry Smith 
2754985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2755e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2756e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2757e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2758e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2759e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27609189402eSHong Zhang     x[i]  = 0.0;
2761e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2762985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2763985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2764985db425SBarry Smith       aa++; aj++;
2765985db425SBarry Smith     }
2766985db425SBarry Smith   }
2767985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2768985db425SBarry Smith   PetscFunctionReturn(0);
2769985db425SBarry Smith }
2770985db425SBarry Smith 
2771985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2772985db425SBarry Smith {
2773985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2774985db425SBarry Smith   PetscErrorCode ierr;
2775d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2776985db425SBarry Smith   PetscScalar    *x;
2777985db425SBarry Smith   MatScalar      *aa;
2778985db425SBarry Smith 
2779985db425SBarry Smith   PetscFunctionBegin;
2780e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2781985db425SBarry Smith   aa = a->a;
2782985db425SBarry Smith   ai = a->i;
2783985db425SBarry Smith   aj = a->j;
2784985db425SBarry Smith 
2785985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2786985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2787985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2788e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2789985db425SBarry Smith   for (i=0; i<m; i++) {
2790985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2791d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2792985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2793985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2794985db425SBarry Smith       x[i] = 0.0;
2795985db425SBarry Smith       if (idx) {
2796985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2797985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2798985db425SBarry Smith           if (aj[j] > j) {
2799985db425SBarry Smith             idx[i] = j;
2800985db425SBarry Smith             break;
2801985db425SBarry Smith           }
2802985db425SBarry Smith         }
2803985db425SBarry Smith       }
2804985db425SBarry Smith     }
2805985db425SBarry Smith     for (j=0; j<ncols; j++) {
2806985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2807985db425SBarry Smith       aa++; aj++;
2808985db425SBarry Smith     }
2809985db425SBarry Smith   }
2810985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2811985db425SBarry Smith   PetscFunctionReturn(0);
2812985db425SBarry Smith }
2813985db425SBarry Smith 
2814c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2815c87e5d42SMatthew Knepley {
2816c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2817c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2818c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2819c87e5d42SMatthew Knepley   PetscReal      atmp;
2820c87e5d42SMatthew Knepley   PetscScalar    *x;
2821c87e5d42SMatthew Knepley   MatScalar      *aa;
2822c87e5d42SMatthew Knepley 
2823c87e5d42SMatthew Knepley   PetscFunctionBegin;
2824e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2825c87e5d42SMatthew Knepley   aa = a->a;
2826c87e5d42SMatthew Knepley   ai = a->i;
2827c87e5d42SMatthew Knepley   aj = a->j;
2828c87e5d42SMatthew Knepley 
2829c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2830c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2831c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
283260e0710aSBarry 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);
2833c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2834c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2835289a08f5SMatthew Knepley     if (ncols) {
2836289a08f5SMatthew Knepley       /* Get first nonzero */
2837289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2838289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28392205254eSKarl Rupp         if (atmp > 1.0e-12) {
28402205254eSKarl Rupp           x[i] = atmp;
28412205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28422205254eSKarl Rupp           break;
28432205254eSKarl Rupp         }
2844289a08f5SMatthew Knepley       }
284512431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2846289a08f5SMatthew Knepley     } else {
2847289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2848289a08f5SMatthew Knepley     }
2849c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2850c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2851289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2852c87e5d42SMatthew Knepley       aa++; aj++;
2853c87e5d42SMatthew Knepley     }
2854c87e5d42SMatthew Knepley   }
2855c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2856c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2857c87e5d42SMatthew Knepley }
2858c87e5d42SMatthew Knepley 
2859985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2860985db425SBarry Smith {
2861985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2862985db425SBarry Smith   PetscErrorCode  ierr;
2863d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2864d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2865985db425SBarry Smith   PetscScalar     *x;
2866d9ca1df4SBarry Smith   const MatScalar *aa;
2867985db425SBarry Smith 
2868985db425SBarry Smith   PetscFunctionBegin;
2869e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2870985db425SBarry Smith   aa = a->a;
2871985db425SBarry Smith   ai = a->i;
2872985db425SBarry Smith   aj = a->j;
2873985db425SBarry Smith 
2874985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2875985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2876985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2877e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2878985db425SBarry Smith   for (i=0; i<m; i++) {
2879985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2880d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2881985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2882985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2883985db425SBarry Smith       x[i] = 0.0;
2884985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2885985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2886985db425SBarry Smith         for (j=0; j<ncols; j++) {
2887985db425SBarry Smith           if (aj[j] > j) {
2888985db425SBarry Smith             idx[i] = j;
2889985db425SBarry Smith             break;
2890985db425SBarry Smith           }
2891985db425SBarry Smith         }
2892985db425SBarry Smith       }
2893985db425SBarry Smith     }
2894985db425SBarry Smith     for (j=0; j<ncols; j++) {
2895985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2896985db425SBarry Smith       aa++; aj++;
2897e34fafa9SBarry Smith     }
2898e34fafa9SBarry Smith   }
2899e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2900e34fafa9SBarry Smith   PetscFunctionReturn(0);
2901e34fafa9SBarry Smith }
2902bbead8a2SBarry Smith 
2903bbead8a2SBarry Smith #include <petscblaslapack.h>
2904af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2905bbead8a2SBarry Smith 
2906713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2907bbead8a2SBarry Smith {
2908bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2909bbead8a2SBarry Smith   PetscErrorCode ierr;
291033d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2911bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2912bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29131a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2914bbead8a2SBarry Smith 
2915bbead8a2SBarry Smith   PetscFunctionBegin;
2916a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29174a0d0026SBarry Smith   if (a->ibdiagvalid) {
29184a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29194a0d0026SBarry Smith     PetscFunctionReturn(0);
29204a0d0026SBarry Smith   }
2921bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2922bbead8a2SBarry Smith   if (!a->ibdiag) {
2923785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29243bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2925bbead8a2SBarry Smith   }
2926bbead8a2SBarry Smith   diag = a->ibdiag;
2927bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2928bbead8a2SBarry Smith   /* factor and invert each block */
2929bbead8a2SBarry Smith   switch (bs) {
2930bbead8a2SBarry Smith   case 1:
2931bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2932bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2933ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2934ec1892c8SHong Zhang         if (allowzeropivot) {
29357b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29367b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29377b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29387b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29397b6c816cSBarry 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);
2940ec1892c8SHong Zhang       }
2941bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2942bbead8a2SBarry Smith     }
2943bbead8a2SBarry Smith     break;
2944bbead8a2SBarry Smith   case 2:
2945bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2946bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2947bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2948a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29497b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
295096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2951bbead8a2SBarry Smith       diag += 4;
2952bbead8a2SBarry Smith     }
2953bbead8a2SBarry Smith     break;
2954bbead8a2SBarry Smith   case 3:
2955bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2956bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2957bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2958a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29597b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
296096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2961bbead8a2SBarry Smith       diag += 9;
2962bbead8a2SBarry Smith     }
2963bbead8a2SBarry Smith     break;
2964bbead8a2SBarry Smith   case 4:
2965bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2966bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2967bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2968a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29697b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2971bbead8a2SBarry Smith       diag += 16;
2972bbead8a2SBarry Smith     }
2973bbead8a2SBarry Smith     break;
2974bbead8a2SBarry Smith   case 5:
2975bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2976bbead8a2SBarry 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;
2977bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
2978a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29797b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
2981bbead8a2SBarry Smith       diag += 25;
2982bbead8a2SBarry Smith     }
2983bbead8a2SBarry Smith     break;
2984bbead8a2SBarry Smith   case 6:
2985bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2986bbead8a2SBarry 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;
2987bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
2988a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29897b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
2991bbead8a2SBarry Smith       diag += 36;
2992bbead8a2SBarry Smith     }
2993bbead8a2SBarry Smith     break;
2994bbead8a2SBarry Smith   case 7:
2995bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2996bbead8a2SBarry 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;
2997bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
2998a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29997b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
300096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3001bbead8a2SBarry Smith       diag += 49;
3002bbead8a2SBarry Smith     }
3003bbead8a2SBarry Smith     break;
3004bbead8a2SBarry Smith   default:
3005dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3006bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3007bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3008bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3009bbead8a2SBarry Smith       }
3010bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30115f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30127b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
301396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3014bbead8a2SBarry Smith       diag += bs2;
3015bbead8a2SBarry Smith     }
3016bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3017bbead8a2SBarry Smith   }
3018bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3019bbead8a2SBarry Smith   PetscFunctionReturn(0);
3020bbead8a2SBarry Smith }
3021bbead8a2SBarry Smith 
302273a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
302373a71a0fSBarry Smith {
302473a71a0fSBarry Smith   PetscErrorCode ierr;
302573a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
302673a71a0fSBarry Smith   PetscScalar    a;
302773a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
302873a71a0fSBarry Smith 
302973a71a0fSBarry Smith   PetscFunctionBegin;
303073a71a0fSBarry Smith   if (!x->assembled) {
303173a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
303273a71a0fSBarry Smith     for (i=0; i<m; i++) {
303373a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
303473a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
303573a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
303673a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
303773a71a0fSBarry Smith       }
303873a71a0fSBarry Smith     }
303973a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
304073a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304173a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
304273a71a0fSBarry Smith   PetscFunctionReturn(0);
304373a71a0fSBarry Smith }
304473a71a0fSBarry Smith 
30457d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30467d68702bSBarry Smith {
30477d68702bSBarry Smith   PetscErrorCode ierr;
30487d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30497d68702bSBarry Smith 
30507d68702bSBarry Smith   PetscFunctionBegin;
30516f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30527d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30537d68702bSBarry Smith   }
30547d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30557d68702bSBarry Smith   PetscFunctionReturn(0);
30567d68702bSBarry Smith }
30577d68702bSBarry Smith 
3058682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30590a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3060cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3061cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3062cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
306397304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30647c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30657c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3066db4efbfdSBarry Smith                                         0,
3067db4efbfdSBarry Smith                                         0,
3068db4efbfdSBarry Smith                                         0,
3069db4efbfdSBarry Smith                                 /* 10*/ 0,
3070cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3071cb5b572fSBarry Smith                                         0,
307241f059aeSBarry Smith                                         MatSOR_SeqAIJ,
307317ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
307497304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3075cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3076cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3077cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3078cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
307997304618SKris Buschelman                                 /* 20*/ 0,
3080cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3081cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3082cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3083d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3084db4efbfdSBarry Smith                                         0,
3085db4efbfdSBarry Smith                                         0,
3086db4efbfdSBarry Smith                                         0,
3087db4efbfdSBarry Smith                                         0,
30884994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3089db4efbfdSBarry Smith                                         0,
3090db4efbfdSBarry Smith                                         0,
30918c778c55SBarry Smith                                         0,
30928c778c55SBarry Smith                                         0,
3093d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3094cb5b572fSBarry Smith                                         0,
3095cb5b572fSBarry Smith                                         0,
3096cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3097cb5b572fSBarry Smith                                         0,
3098d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
30997dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3100cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3101cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3102cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3103d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3104cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
31057d68702bSBarry Smith                                         MatShift_SeqAIJ,
310679299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31076e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
310873a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31093b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31103b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31113b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3112a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
311393dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3114b9617806SBarry Smith                                         0,
31150513a670SBarry Smith                                         0,
3116cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3117cda55fadSBarry Smith                                         0,
3118d519adbfSMatthew Knepley                                 /* 59*/ 0,
3119b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3120b9b97703SBarry Smith                                         MatView_SeqAIJ,
3121357abbc8SBarry Smith                                         0,
3122321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3123321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3124321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3125ee4f033dSBarry Smith                                         0,
3126ee4f033dSBarry Smith                                         0,
3127ee4f033dSBarry Smith                                         0,
3128d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3129c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3130ee4f033dSBarry Smith                                         0,
3131dcf5cc72SBarry Smith                                         0,
31322c93a97aSBarry Smith                                         0,
31332c93a97aSBarry Smith                                 /* 74*/ 0,
31343acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
313597304618SKris Buschelman                                         0,
313697304618SKris Buschelman                                         0,
313797304618SKris Buschelman                                         0,
31386ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
313997304618SKris Buschelman                                         0,
314097304618SKris Buschelman                                         0,
314197304618SKris Buschelman                                         0,
3142bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3143d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31441cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31456284ec50SHong Zhang                                         0,
31466284ec50SHong Zhang                                         0,
3147bc011b1eSHong Zhang                                         0,
3148d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
314926be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
315026be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
315165e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31524a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
315365e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31546fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31556fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31566fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31572121bac1SHong Zhang                                         0,
31582121bac1SHong Zhang                                 /* 99*/ 0,
3159609c6c4dSKris Buschelman                                         0,
3160609c6c4dSKris Buschelman                                         0,
316187d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
316287d4246cSBarry Smith                                         0,
3163d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
316499cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3165f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3166f5edf698SHong Zhang                                         0,
31672bebee5dSHong Zhang                                         0,
3168cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3169985db425SBarry Smith                                         0,
31702af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31712af78befSBarry Smith                                         0,
3172599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3173d519adbfSMatthew Knepley                                 /*114*/ 0,
3174599ef60dSHong Zhang                                         0,
31753c2a7987SHong Zhang                                         0,
3176fe97e370SBarry Smith                                         0,
3177fbdbba38SShri Abhyankar                                         0,
3178fbdbba38SShri Abhyankar                                 /*119*/ 0,
3179fbdbba38SShri Abhyankar                                         0,
3180fbdbba38SShri Abhyankar                                         0,
318182d44351SHong Zhang                                         0,
3182b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
31830716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3184bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
318537868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
318637868618SMatthew G Knepley                                         0,
318737868618SMatthew G Knepley                                         0,
31885df89d91SHong Zhang                                 /*129*/ 0,
318975648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
319075648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
319175648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3192b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3193b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
31942b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
31952b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
31962b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
31973964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
31983964eb88SJed Brown                                  /*139*/0,
3199f9426fe0SMark Adams                                         0,
32001919a2e2SJed Brown                                         0,
32013a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
32029c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
32039c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
32049e29f15eSvictorle };
320517ab2063SBarry Smith 
32067087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3207bef8e0ddSBarry Smith {
3208bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
320997f1f81fSBarry Smith   PetscInt   i,nz,n;
3210bef8e0ddSBarry Smith 
3211bef8e0ddSBarry Smith   PetscFunctionBegin;
3212bef8e0ddSBarry Smith   nz = aij->maxnz;
3213d0f46423SBarry Smith   n  = mat->rmap->n;
3214bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3215bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3216bef8e0ddSBarry Smith   }
3217bef8e0ddSBarry Smith   aij->nz = nz;
3218bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3219bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3220bef8e0ddSBarry Smith   }
3221bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3222bef8e0ddSBarry Smith }
3223bef8e0ddSBarry Smith 
3224bef8e0ddSBarry Smith /*@
3225bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3226bef8e0ddSBarry Smith        in the matrix.
3227bef8e0ddSBarry Smith 
3228bef8e0ddSBarry Smith   Input Parameters:
3229bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3230bef8e0ddSBarry Smith -  indices - the column indices
3231bef8e0ddSBarry Smith 
323215091d37SBarry Smith   Level: advanced
323315091d37SBarry Smith 
3234bef8e0ddSBarry Smith   Notes:
3235bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3236bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3237bef8e0ddSBarry Smith   of the MatSetValues() operation.
3238bef8e0ddSBarry Smith 
3239bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3240d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3241bef8e0ddSBarry Smith 
3242bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3243bef8e0ddSBarry Smith 
3244b9617806SBarry Smith     The indices should start with zero, not one.
3245b9617806SBarry Smith 
3246bef8e0ddSBarry Smith @*/
32477087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3248bef8e0ddSBarry Smith {
32494ac538c5SBarry Smith   PetscErrorCode ierr;
3250bef8e0ddSBarry Smith 
3251bef8e0ddSBarry Smith   PetscFunctionBegin;
32520700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32534482741eSBarry Smith   PetscValidPointer(indices,2);
32544ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3255bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3256bef8e0ddSBarry Smith }
3257bef8e0ddSBarry Smith 
3258be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3259be6bf707SBarry Smith 
32607087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3261be6bf707SBarry Smith {
3262be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32636849ba73SBarry Smith   PetscErrorCode ierr;
3264d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3265be6bf707SBarry Smith 
3266be6bf707SBarry Smith   PetscFunctionBegin;
3267169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3268be6bf707SBarry Smith 
3269be6bf707SBarry Smith   /* allocate space for values if not already there */
3270be6bf707SBarry Smith   if (!aij->saved_values) {
3271854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32723bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3273be6bf707SBarry Smith   }
3274be6bf707SBarry Smith 
3275be6bf707SBarry Smith   /* copy values over */
327687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3277be6bf707SBarry Smith   PetscFunctionReturn(0);
3278be6bf707SBarry Smith }
3279be6bf707SBarry Smith 
3280be6bf707SBarry Smith /*@
3281be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3282be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3283be6bf707SBarry Smith        nonlinear portion.
3284be6bf707SBarry Smith 
3285be6bf707SBarry Smith    Collect on Mat
3286be6bf707SBarry Smith 
3287be6bf707SBarry Smith   Input Parameters:
32880e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3289be6bf707SBarry Smith 
329015091d37SBarry Smith   Level: advanced
329115091d37SBarry Smith 
3292be6bf707SBarry Smith   Common Usage, with SNESSolve():
3293be6bf707SBarry Smith $    Create Jacobian matrix
3294be6bf707SBarry Smith $    Set linear terms into matrix
3295be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3296be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3297be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3298512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3299be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3300be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3301be6bf707SBarry Smith $    In your Jacobian routine
3302be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3303be6bf707SBarry Smith $      Set nonlinear terms in matrix
3304be6bf707SBarry Smith 
3305be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3306be6bf707SBarry Smith $    // build linear portion of Jacobian
3307512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3308be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3309be6bf707SBarry Smith $    loop over nonlinear iterations
3310be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3311be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3312be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3313be6bf707SBarry Smith $       Solve linear system with Jacobian
3314be6bf707SBarry Smith $    endloop
3315be6bf707SBarry Smith 
3316be6bf707SBarry Smith   Notes:
3317be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3318512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3319be6bf707SBarry Smith     calling this routine.
3320be6bf707SBarry Smith 
33210c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33220c468ba9SBarry Smith     and does not allocated additional space.
33230c468ba9SBarry Smith 
3324be6bf707SBarry Smith .seealso: MatRetrieveValues()
3325be6bf707SBarry Smith 
3326be6bf707SBarry Smith @*/
33277087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3328be6bf707SBarry Smith {
33294ac538c5SBarry Smith   PetscErrorCode ierr;
3330be6bf707SBarry Smith 
3331be6bf707SBarry Smith   PetscFunctionBegin;
33320700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3333e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3334e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33354ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3336be6bf707SBarry Smith   PetscFunctionReturn(0);
3337be6bf707SBarry Smith }
3338be6bf707SBarry Smith 
33397087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3340be6bf707SBarry Smith {
3341be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33426849ba73SBarry Smith   PetscErrorCode ierr;
3343d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3344be6bf707SBarry Smith 
3345be6bf707SBarry Smith   PetscFunctionBegin;
3346169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3347f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3348be6bf707SBarry Smith   /* copy values over */
334987828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3350be6bf707SBarry Smith   PetscFunctionReturn(0);
3351be6bf707SBarry Smith }
3352be6bf707SBarry Smith 
3353be6bf707SBarry Smith /*@
3354be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3355be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3356be6bf707SBarry Smith        nonlinear portion.
3357be6bf707SBarry Smith 
3358be6bf707SBarry Smith    Collect on Mat
3359be6bf707SBarry Smith 
3360be6bf707SBarry Smith   Input Parameters:
3361386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3362be6bf707SBarry Smith 
336315091d37SBarry Smith   Level: advanced
336415091d37SBarry Smith 
3365be6bf707SBarry Smith .seealso: MatStoreValues()
3366be6bf707SBarry Smith 
3367be6bf707SBarry Smith @*/
33687087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3369be6bf707SBarry Smith {
33704ac538c5SBarry Smith   PetscErrorCode ierr;
3371be6bf707SBarry Smith 
3372be6bf707SBarry Smith   PetscFunctionBegin;
33730700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3374e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3375e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33764ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3377be6bf707SBarry Smith   PetscFunctionReturn(0);
3378be6bf707SBarry Smith }
3379be6bf707SBarry Smith 
3380f83d6046SBarry Smith 
3381be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
338217ab2063SBarry Smith /*@C
3383682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
33840d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
33856e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
338651c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
33872bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
338817ab2063SBarry Smith 
3389db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3390db81eaa0SLois Curfman McInnes 
339117ab2063SBarry Smith    Input Parameters:
3392db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
339317ab2063SBarry Smith .  m - number of rows
339417ab2063SBarry Smith .  n - number of columns
339517ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
339651c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
33970298fd71SBarry Smith          (possibly different for each row) or NULL
339817ab2063SBarry Smith 
339917ab2063SBarry Smith    Output Parameter:
3400416022c9SBarry Smith .  A - the matrix
340117ab2063SBarry Smith 
3402175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3403ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3404175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3405175b88e8SBarry Smith 
3406b259b22eSLois Curfman McInnes    Notes:
340749a6f317SBarry Smith    If nnz is given then nz is ignored
340849a6f317SBarry Smith 
340917ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
341017ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34110002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
341244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
341317ab2063SBarry Smith 
341417ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34150298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34163d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34176da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
341817ab2063SBarry Smith 
3419682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34204fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3421682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34226c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34236c7ebb05SLois Curfman McInnes 
34246c7ebb05SLois Curfman McInnes    Options Database Keys:
3425698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34269db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
342717ab2063SBarry Smith 
3428027ccd11SLois Curfman McInnes    Level: intermediate
3429027ccd11SLois Curfman McInnes 
343069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
343136db0b34SBarry Smith 
343217ab2063SBarry Smith @*/
34337087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
343417ab2063SBarry Smith {
3435dfbe8321SBarry Smith   PetscErrorCode ierr;
34366945ee14SBarry Smith 
34373a40ed3dSBarry Smith   PetscFunctionBegin;
3438f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3439117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3440c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3441d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3442273d9f13SBarry Smith   PetscFunctionReturn(0);
3443273d9f13SBarry Smith }
3444273d9f13SBarry Smith 
3445273d9f13SBarry Smith /*@C
3446273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3447273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3448273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3449273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3450273d9f13SBarry Smith 
3451273d9f13SBarry Smith    Collective on MPI_Comm
3452273d9f13SBarry Smith 
3453273d9f13SBarry Smith    Input Parameters:
34541c4f3114SJed Brown +  B - The matrix
3455273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3456273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34570298fd71SBarry Smith          (possibly different for each row) or NULL
3458273d9f13SBarry Smith 
3459273d9f13SBarry Smith    Notes:
346049a6f317SBarry Smith      If nnz is given then nz is ignored
346149a6f317SBarry Smith 
3462273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3463273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3464273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3465273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3466273d9f13SBarry Smith 
3467273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34680298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3469273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3470273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3471273d9f13SBarry Smith 
3472aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3473aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3474aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3475aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3476aa95bbe8SBarry Smith 
3477a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3478a96a251dSBarry Smith    entries or columns indices
3479a96a251dSBarry Smith 
3480273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3481273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3482273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3483273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3484273d9f13SBarry Smith 
3485273d9f13SBarry Smith    Options Database Keys:
3486698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3487698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3488273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3489273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3490273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3491273d9f13SBarry Smith 
3492273d9f13SBarry Smith    Level: intermediate
3493273d9f13SBarry Smith 
349469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3495273d9f13SBarry Smith 
3496273d9f13SBarry Smith @*/
34977087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3498273d9f13SBarry Smith {
34994ac538c5SBarry Smith   PetscErrorCode ierr;
3500a23d5eceSKris Buschelman 
3501a23d5eceSKris Buschelman   PetscFunctionBegin;
35026ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35036ba663aaSJed Brown   PetscValidType(B,1);
35044ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3505a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3506a23d5eceSKris Buschelman }
3507a23d5eceSKris Buschelman 
35087087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3509a23d5eceSKris Buschelman {
3510273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35112576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35126849ba73SBarry Smith   PetscErrorCode ierr;
351397f1f81fSBarry Smith   PetscInt       i;
3514273d9f13SBarry Smith 
3515273d9f13SBarry Smith   PetscFunctionBegin;
35162576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3517a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3518c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3519c461c341SBarry Smith     nz             = 0;
3520c461c341SBarry Smith   }
3521c461c341SBarry Smith 
352226283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
352326283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3524899cda47SBarry Smith 
3525435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
352660e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3527b73539f3SBarry Smith   if (nnz) {
3528d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
352960e0710aSBarry 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]);
353060e0710aSBarry 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);
3531b73539f3SBarry Smith     }
3532b73539f3SBarry Smith   }
3533b73539f3SBarry Smith 
3534273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35352205254eSKarl Rupp 
3536273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3537273d9f13SBarry Smith 
3538ab93d7beSBarry Smith   if (!skipallocation) {
35392ee49352SLisandro Dalcin     if (!b->imax) {
3540dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35413bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35422ee49352SLisandro Dalcin     }
3543273d9f13SBarry Smith     if (!nnz) {
3544435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3545c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3546d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3547d0f46423SBarry Smith       nz = nz*B->rmap->n;
3548273d9f13SBarry Smith     } else {
3549273d9f13SBarry Smith       nz = 0;
3550d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3551273d9f13SBarry Smith     }
3552ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35532205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3554ab93d7beSBarry Smith 
3555273d9f13SBarry Smith     /* allocate the matrix space */
355653dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35572ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3558dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35593bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3560bfeeae90SHong Zhang     b->i[0] = 0;
3561d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35625da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35635da197adSKris Buschelman     }
3564273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3565e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3566e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3567c461c341SBarry Smith   } else {
3568e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3569e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3570c461c341SBarry Smith   }
3571273d9f13SBarry Smith 
3572273d9f13SBarry Smith   b->nz               = 0;
3573273d9f13SBarry Smith   b->maxnz            = nz;
3574273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
35752205254eSKarl Rupp   if (realalloc) {
35762205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
35772205254eSKarl Rupp   }
3578cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3579cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3580273d9f13SBarry Smith   PetscFunctionReturn(0);
3581273d9f13SBarry Smith }
3582273d9f13SBarry Smith 
358358d36128SBarry Smith /*@
3584a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3585a1661176SMatthew Knepley 
3586a1661176SMatthew Knepley    Input Parameters:
3587a1661176SMatthew Knepley +  B - the matrix
3588a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3589a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3590a1661176SMatthew Knepley -  v - optional values in the matrix
3591a1661176SMatthew Knepley 
3592a1661176SMatthew Knepley    Level: developer
3593a1661176SMatthew Knepley 
359458d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
359558d36128SBarry Smith 
3596a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3597a1661176SMatthew Knepley 
3598a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3599a1661176SMatthew Knepley @*/
3600a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3601a1661176SMatthew Knepley {
3602a1661176SMatthew Knepley   PetscErrorCode ierr;
3603a1661176SMatthew Knepley 
3604a1661176SMatthew Knepley   PetscFunctionBegin;
36050700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36066ba663aaSJed Brown   PetscValidType(B,1);
36074ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3608a1661176SMatthew Knepley   PetscFunctionReturn(0);
3609a1661176SMatthew Knepley }
3610a1661176SMatthew Knepley 
36117087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3612a1661176SMatthew Knepley {
3613a1661176SMatthew Knepley   PetscInt       i;
3614a1661176SMatthew Knepley   PetscInt       m,n;
3615a1661176SMatthew Knepley   PetscInt       nz;
3616a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3617a1661176SMatthew Knepley   PetscScalar    *values;
3618a1661176SMatthew Knepley   PetscErrorCode ierr;
3619a1661176SMatthew Knepley 
3620a1661176SMatthew Knepley   PetscFunctionBegin;
362165e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3622779a8d59SSatish Balay 
3623779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3624779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3625779a8d59SSatish Balay 
3626779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3627854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3628a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3629b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3630a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
363165e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3632a1661176SMatthew Knepley     nnz[i] = nz;
3633a1661176SMatthew Knepley   }
3634a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3635a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3636a1661176SMatthew Knepley 
3637a1661176SMatthew Knepley   if (v) {
3638a1661176SMatthew Knepley     values = (PetscScalar*) v;
3639a1661176SMatthew Knepley   } else {
36401795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3641a1661176SMatthew Knepley   }
3642a1661176SMatthew Knepley 
3643a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3644b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3645b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3646a1661176SMatthew Knepley   }
3647a1661176SMatthew Knepley 
3648a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3649a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3650a1661176SMatthew Knepley 
3651a1661176SMatthew Knepley   if (!v) {
3652a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3653a1661176SMatthew Knepley   }
36547827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3655a1661176SMatthew Knepley   PetscFunctionReturn(0);
3656a1661176SMatthew Knepley }
3657a1661176SMatthew Knepley 
3658c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3659af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3660170fe5c8SBarry Smith 
3661170fe5c8SBarry Smith /*
3662170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3663170fe5c8SBarry Smith 
3664170fe5c8SBarry Smith                n                       p                          p
3665170fe5c8SBarry Smith         (              )       (              )         (                  )
3666170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3667170fe5c8SBarry Smith         (              )       (              )         (                  )
3668170fe5c8SBarry Smith 
3669170fe5c8SBarry Smith */
3670170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3671170fe5c8SBarry Smith {
3672170fe5c8SBarry Smith   PetscErrorCode    ierr;
3673170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3674170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3675170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
36761de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3677170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3678170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3679170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3680170fe5c8SBarry Smith 
3681170fe5c8SBarry Smith   PetscFunctionBegin;
3682d0f46423SBarry Smith   m    = A->rmap->n;
3683d0f46423SBarry Smith   n    = A->cmap->n;
3684d0f46423SBarry Smith   p    = B->cmap->n;
3685170fe5c8SBarry Smith   a    = sub_a->v;
3686170fe5c8SBarry Smith   b    = sub_b->a;
3687170fe5c8SBarry Smith   c    = sub_c->v;
3688170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3689170fe5c8SBarry Smith 
3690170fe5c8SBarry Smith   ii  = sub_b->i;
3691170fe5c8SBarry Smith   idx = sub_b->j;
3692170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3693170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3694170fe5c8SBarry Smith     while (q-->0) {
3695170fe5c8SBarry Smith       c_q = c + m*(*idx);
3696170fe5c8SBarry Smith       a_q = a + m*i;
3697854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3698170fe5c8SBarry Smith       idx++;
3699170fe5c8SBarry Smith       b++;
3700170fe5c8SBarry Smith     }
3701170fe5c8SBarry Smith   }
3702170fe5c8SBarry Smith   PetscFunctionReturn(0);
3703170fe5c8SBarry Smith }
3704170fe5c8SBarry Smith 
3705170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3706170fe5c8SBarry Smith {
3707170fe5c8SBarry Smith   PetscErrorCode ierr;
3708d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3709170fe5c8SBarry Smith   Mat            Cmat;
3710170fe5c8SBarry Smith 
3711170fe5c8SBarry Smith   PetscFunctionBegin;
371260e0710aSBarry 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);
3713ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3714170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
371533d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3716170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37170298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3718d73949e8SHong Zhang 
3719d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37202205254eSKarl Rupp 
3721170fe5c8SBarry Smith   *C = Cmat;
3722170fe5c8SBarry Smith   PetscFunctionReturn(0);
3723170fe5c8SBarry Smith }
3724170fe5c8SBarry Smith 
3725170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3726150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3727170fe5c8SBarry Smith {
3728170fe5c8SBarry Smith   PetscErrorCode ierr;
3729170fe5c8SBarry Smith 
3730170fe5c8SBarry Smith   PetscFunctionBegin;
3731170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37323ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3733170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37343ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3735170fe5c8SBarry Smith   }
37363ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3737170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37383ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3739170fe5c8SBarry Smith   PetscFunctionReturn(0);
3740170fe5c8SBarry Smith }
3741170fe5c8SBarry Smith 
3742170fe5c8SBarry Smith 
37430bad9183SKris Buschelman /*MC
3744fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37450bad9183SKris Buschelman    based on compressed sparse row format.
37460bad9183SKris Buschelman 
37470bad9183SKris Buschelman    Options Database Keys:
37480bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37490bad9183SKris Buschelman 
37500bad9183SKris Buschelman   Level: beginner
37510bad9183SKris Buschelman 
3752f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37530bad9183SKris Buschelman M*/
37540bad9183SKris Buschelman 
3755ccd284c7SBarry Smith /*MC
3756ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3757ccd284c7SBarry Smith 
3758ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3759ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3760ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3761ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3762ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3763ccd284c7SBarry Smith 
3764ccd284c7SBarry Smith    Options Database Keys:
3765ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3766ccd284c7SBarry Smith 
3767ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3768ccd284c7SBarry Smith    enough exist.
3769ccd284c7SBarry Smith 
3770ccd284c7SBarry Smith   Level: beginner
3771ccd284c7SBarry Smith 
3772ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3773ccd284c7SBarry Smith M*/
3774ccd284c7SBarry Smith 
3775ccd284c7SBarry Smith /*MC
3776ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3777ccd284c7SBarry Smith 
3778ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3779ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3780ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3781ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3782ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3783ccd284c7SBarry Smith 
3784ccd284c7SBarry Smith    Options Database Keys:
3785ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3786ccd284c7SBarry Smith 
3787ccd284c7SBarry Smith   Level: beginner
3788ccd284c7SBarry Smith 
3789ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3790ccd284c7SBarry Smith M*/
3791ccd284c7SBarry Smith 
3792cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3793af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3794cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3795af8000cdSHong Zhang #endif
379663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
379763c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
37983dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
379963c07aadSStefano Zampini #endif
3800cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
380142c9c57cSBarry Smith 
3802b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
380329b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
380429b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3805b3866ffcSBarry Smith #endif
380617667f90SBarry Smith 
3807c0c8ee5eSDmitry Karpeev 
38088c778c55SBarry Smith /*@C
38098397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38108c778c55SBarry Smith 
38118c778c55SBarry Smith    Not Collective
38128c778c55SBarry Smith 
38138c778c55SBarry Smith    Input Parameter:
3814579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38158c778c55SBarry Smith 
38168c778c55SBarry Smith    Output Parameter:
38178c778c55SBarry Smith .   array - pointer to the data
38188c778c55SBarry Smith 
38198c778c55SBarry Smith    Level: intermediate
38208c778c55SBarry Smith 
3821774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38228c778c55SBarry Smith @*/
38238c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38248c778c55SBarry Smith {
38258c778c55SBarry Smith   PetscErrorCode ierr;
38268c778c55SBarry Smith 
38278c778c55SBarry Smith   PetscFunctionBegin;
38288c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38298c778c55SBarry Smith   PetscFunctionReturn(0);
38308c778c55SBarry Smith }
38318c778c55SBarry Smith 
383221e72a00SBarry Smith /*@C
383321e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
383421e72a00SBarry Smith 
383521e72a00SBarry Smith    Not Collective
383621e72a00SBarry Smith 
383721e72a00SBarry Smith    Input Parameter:
3838579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
383921e72a00SBarry Smith 
384021e72a00SBarry Smith    Output Parameter:
384121e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
384221e72a00SBarry Smith 
384321e72a00SBarry Smith    Level: intermediate
384421e72a00SBarry Smith 
384521e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
384621e72a00SBarry Smith @*/
384721e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
384821e72a00SBarry Smith {
384921e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
385021e72a00SBarry Smith 
385121e72a00SBarry Smith   PetscFunctionBegin;
385221e72a00SBarry Smith   *nz = aij->rmax;
385321e72a00SBarry Smith   PetscFunctionReturn(0);
385421e72a00SBarry Smith }
385521e72a00SBarry Smith 
38568c778c55SBarry Smith /*@C
3857579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38588c778c55SBarry Smith 
38598c778c55SBarry Smith    Not Collective
38608c778c55SBarry Smith 
38618c778c55SBarry Smith    Input Parameters:
3862579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38638c778c55SBarry Smith .  array - pointer to the data
38648c778c55SBarry Smith 
38658c778c55SBarry Smith    Level: intermediate
38668c778c55SBarry Smith 
3867774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
38688c778c55SBarry Smith @*/
38698c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
38708c778c55SBarry Smith {
38718c778c55SBarry Smith   PetscErrorCode ierr;
38728c778c55SBarry Smith 
38738c778c55SBarry Smith   PetscFunctionBegin;
38748c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38758c778c55SBarry Smith   PetscFunctionReturn(0);
38768c778c55SBarry Smith }
38778c778c55SBarry Smith 
38788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3879273d9f13SBarry Smith {
3880273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3881dfbe8321SBarry Smith   PetscErrorCode ierr;
388238baddfdSBarry Smith   PetscMPIInt    size;
3883273d9f13SBarry Smith 
3884273d9f13SBarry Smith   PetscFunctionBegin;
3885ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3886e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3887273d9f13SBarry Smith 
3888b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
38892205254eSKarl Rupp 
3890b0a32e0cSBarry Smith   B->data = (void*)b;
38912205254eSKarl Rupp 
3892549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
38932205254eSKarl Rupp 
3894416022c9SBarry Smith   b->row                = 0;
3895416022c9SBarry Smith   b->col                = 0;
389682bf6240SBarry Smith   b->icol               = 0;
3897b810aeb4SBarry Smith   b->reallocs           = 0;
389836db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3899f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3900416022c9SBarry Smith   b->nonew              = 0;
3901416022c9SBarry Smith   b->diag               = 0;
3902416022c9SBarry Smith   b->solve_work         = 0;
39032a1b7f2aSHong Zhang   B->spptr              = 0;
3904be6bf707SBarry Smith   b->saved_values       = 0;
3905d7f994e1SBarry Smith   b->idiag              = 0;
390671f1c65dSBarry Smith   b->mdiag              = 0;
390771f1c65dSBarry Smith   b->ssor_work          = 0;
390871f1c65dSBarry Smith   b->omega              = 1.0;
390971f1c65dSBarry Smith   b->fshift             = 0.0;
391071f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3911bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3912a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
391317ab2063SBarry Smith 
391435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3915bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3916bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39178c778c55SBarry Smith 
3918b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3919bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3920bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3921b3866ffcSBarry Smith #endif
392217f1a0eaSHong Zhang 
3923bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3924bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3925bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3926bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3927bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3928bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3929bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3930af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3931af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3932af8000cdSHong Zhang #endif
393363c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
393463c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39353dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
393663c07aadSStefano Zampini #endif
3937b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3938bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3939bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3940bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3941bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3942bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3943bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3944bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3945bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39464108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
394717667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39483a40ed3dSBarry Smith   PetscFunctionReturn(0);
394917ab2063SBarry Smith }
395017ab2063SBarry Smith 
3951b24902e0SBarry Smith /*
3952b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3953b24902e0SBarry Smith */
3954ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
395517ab2063SBarry Smith {
3956416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39576849ba73SBarry Smith   PetscErrorCode ierr;
3958d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
395917ab2063SBarry Smith 
39603a40ed3dSBarry Smith   PetscFunctionBegin;
3961273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3962273d9f13SBarry Smith 
3963d5f3da31SBarry Smith   C->factortype = A->factortype;
3964416022c9SBarry Smith   c->row        = 0;
3965416022c9SBarry Smith   c->col        = 0;
396682bf6240SBarry Smith   c->icol       = 0;
39676ad4291fSHong Zhang   c->reallocs   = 0;
396817ab2063SBarry Smith 
39696ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
397017ab2063SBarry Smith 
3971aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
3972aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
3973eec197d1SBarry Smith 
3974dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
39753bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
397617ab2063SBarry Smith   for (i=0; i<m; i++) {
3977416022c9SBarry Smith     c->imax[i] = a->imax[i];
3978416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
397917ab2063SBarry Smith   }
398017ab2063SBarry Smith 
398117ab2063SBarry Smith   /* allocate the matrix space */
3982f77e22a1SHong Zhang   if (mallocmatspace) {
3983dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
39843bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
39852205254eSKarl Rupp 
3986f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
39872205254eSKarl Rupp 
398897f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
398917ab2063SBarry Smith     if (m > 0) {
399097f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
3991be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
3992bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
3993be6bf707SBarry Smith       } else {
3994bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
399517ab2063SBarry Smith       }
399608480c60SBarry Smith     }
3997f77e22a1SHong Zhang   }
399817ab2063SBarry Smith 
39996ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4000416022c9SBarry Smith   c->roworiented       = a->roworiented;
4001416022c9SBarry Smith   c->nonew             = a->nonew;
4002416022c9SBarry Smith   if (a->diag) {
4003854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
40043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
400517ab2063SBarry Smith     for (i=0; i<m; i++) {
4006416022c9SBarry Smith       c->diag[i] = a->diag[i];
400717ab2063SBarry Smith     }
40083a40ed3dSBarry Smith   } else c->diag = 0;
40092205254eSKarl Rupp 
40106ad4291fSHong Zhang   c->solve_work         = 0;
40116ad4291fSHong Zhang   c->saved_values       = 0;
40126ad4291fSHong Zhang   c->idiag              = 0;
401371f1c65dSBarry Smith   c->ssor_work          = 0;
4014a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4015e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4016e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40176ad4291fSHong Zhang 
4018893ad86cSHong Zhang   c->rmax         = a->rmax;
4019416022c9SBarry Smith   c->nz           = a->nz;
40208ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4021273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4022754ec7b1SSatish Balay 
40236ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40246ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4025cd6b891eSBarry Smith   if (a->compressedrow.use) {
40266ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4027dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40286ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40296ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
403027ea64f8SHong Zhang   } else {
403127ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40320298fd71SBarry Smith     c->compressedrow.i      = NULL;
40330298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40346ad4291fSHong Zhang   }
4035ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4036e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40374846f1f5SKris Buschelman 
40382205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4039140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40403a40ed3dSBarry Smith   PetscFunctionReturn(0);
404117ab2063SBarry Smith }
404217ab2063SBarry Smith 
4043b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4044b24902e0SBarry Smith {
4045b24902e0SBarry Smith   PetscErrorCode ierr;
4046b24902e0SBarry Smith 
4047b24902e0SBarry Smith   PetscFunctionBegin;
4048ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40494b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4050cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
405133d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4052cfd3f464SBarry Smith   }
4053a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4054f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4055b24902e0SBarry Smith   PetscFunctionReturn(0);
4056b24902e0SBarry Smith }
4057b24902e0SBarry Smith 
4058112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4059fbdbba38SShri Abhyankar {
4060fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4061fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4062fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4063fbdbba38SShri Abhyankar   int            fd;
4064fbdbba38SShri Abhyankar   PetscMPIInt    size;
4065fbdbba38SShri Abhyankar   MPI_Comm       comm;
40663059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4067fbdbba38SShri Abhyankar 
4068fbdbba38SShri Abhyankar   PetscFunctionBegin;
4069c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4070c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4071fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4072fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4073fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4074bbead8a2SBarry Smith 
40750298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
40760298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4077bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40783059b6faSBarry Smith   if (bs < 0) bs = 1;
40793059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4080bbead8a2SBarry Smith 
4081fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4082fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4083fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4084fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4085fbdbba38SShri Abhyankar 
4086bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4087fbdbba38SShri Abhyankar 
4088fbdbba38SShri Abhyankar   /* read in row lengths */
4089785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4090fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4091fbdbba38SShri Abhyankar 
4092fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4093fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
409460e0710aSBarry 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);
4095fbdbba38SShri Abhyankar 
4096fbdbba38SShri Abhyankar   /* set global size if not set already*/
4097f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4098fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4099aabbc4fbSShri Abhyankar   } else {
41009d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4101fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41024c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41034c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41044c5b953cSHong Zhang     }
410560e0710aSBarry 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);
4106aabbc4fbSShri Abhyankar   }
4107fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4108fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4109fbdbba38SShri Abhyankar 
4110fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4111fbdbba38SShri Abhyankar 
4112fbdbba38SShri Abhyankar   /* read in nonzero values */
4113fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4114fbdbba38SShri Abhyankar 
4115fbdbba38SShri Abhyankar   /* set matrix "i" values */
4116fbdbba38SShri Abhyankar   a->i[0] = 0;
4117fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4118fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4119fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4120fbdbba38SShri Abhyankar   }
4121fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4122fbdbba38SShri Abhyankar 
4123fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4124fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4125fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4126fbdbba38SShri Abhyankar }
4127fbdbba38SShri Abhyankar 
4128ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41297264ac53SSatish Balay {
41307264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4131dfbe8321SBarry Smith   PetscErrorCode ierr;
4132eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4133eeffb40dSHong Zhang   PetscInt k;
4134eeffb40dSHong Zhang #endif
41357264ac53SSatish Balay 
41363a40ed3dSBarry Smith   PetscFunctionBegin;
4137bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4138d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4139ca44d042SBarry Smith     *flg = PETSC_FALSE;
4140ca44d042SBarry Smith     PetscFunctionReturn(0);
4141bcd2baecSBarry Smith   }
41427264ac53SSatish Balay 
41437264ac53SSatish Balay   /* if the a->i are the same */
4144d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4145abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41467264ac53SSatish Balay 
41477264ac53SSatish Balay   /* if a->j are the same */
414897f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4149abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4150bcd2baecSBarry Smith 
4151bcd2baecSBarry Smith   /* if a->a are the same */
4152eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4153eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4154eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4155eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41563a40ed3dSBarry Smith       PetscFunctionReturn(0);
4157eeffb40dSHong Zhang     }
4158eeffb40dSHong Zhang   }
4159eeffb40dSHong Zhang #else
4160eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4161eeffb40dSHong Zhang #endif
4162eeffb40dSHong Zhang   PetscFunctionReturn(0);
41637264ac53SSatish Balay }
416436db0b34SBarry Smith 
416505869f15SSatish Balay /*@
416636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
416736db0b34SBarry Smith               provided by the user.
416836db0b34SBarry Smith 
4169c75a6043SHong Zhang       Collective on MPI_Comm
417036db0b34SBarry Smith 
417136db0b34SBarry Smith    Input Parameters:
417236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
417336db0b34SBarry Smith .   m - number of rows
417436db0b34SBarry Smith .   n - number of columns
417536db0b34SBarry Smith .   i - row indices
417636db0b34SBarry Smith .   j - column indices
417736db0b34SBarry Smith -   a - matrix values
417836db0b34SBarry Smith 
417936db0b34SBarry Smith    Output Parameter:
418036db0b34SBarry Smith .   mat - the matrix
418136db0b34SBarry Smith 
418236db0b34SBarry Smith    Level: intermediate
418336db0b34SBarry Smith 
418436db0b34SBarry Smith    Notes:
41850551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4186292fb18eSBarry Smith     once the matrix is destroyed and not before
418736db0b34SBarry Smith 
418836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
418936db0b34SBarry Smith 
4190bfeeae90SHong Zhang        The i and j indices are 0 based
419136db0b34SBarry Smith 
4192a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4193a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
41948eef79e4SBarry Smith     as shown
4195a4552177SSatish Balay 
41968eef79e4SBarry Smith $        1 0 0
41978eef79e4SBarry Smith $        2 0 3
41988eef79e4SBarry Smith $        4 5 6
41998eef79e4SBarry Smith $
42008eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42018eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
42028eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4203a4552177SSatish Balay 
42049985e31cSBarry Smith 
420569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
420636db0b34SBarry Smith 
420736db0b34SBarry Smith @*/
4208c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
420936db0b34SBarry Smith {
4210dfbe8321SBarry Smith   PetscErrorCode ierr;
4211cbcfb4deSHong Zhang   PetscInt       ii;
421236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4213cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4214cbcfb4deSHong Zhang   PetscInt jj;
4215cbcfb4deSHong Zhang #endif
421636db0b34SBarry Smith 
421736db0b34SBarry Smith   PetscFunctionBegin;
421841096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4219f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4220f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4221a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4222ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4223ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4224ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4225dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4226ab93d7beSBarry Smith 
422736db0b34SBarry Smith   aij->i            = i;
422836db0b34SBarry Smith   aij->j            = j;
422936db0b34SBarry Smith   aij->a            = a;
423036db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
423136db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4232e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4233e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
423436db0b34SBarry Smith 
423536db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
423636db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42372515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
423860e0710aSBarry 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]);
42399985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4240e32f2f54SBarry 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);
4241e32f2f54SBarry 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);
42429985e31cSBarry Smith     }
424336db0b34SBarry Smith #endif
424436db0b34SBarry Smith   }
42452515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
424636db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
424760e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
424860e0710aSBarry 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]);
424936db0b34SBarry Smith   }
425036db0b34SBarry Smith #endif
425136db0b34SBarry Smith 
4252b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4253b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
425436db0b34SBarry Smith   PetscFunctionReturn(0);
425536db0b34SBarry Smith }
425680ef6e79SMatthew G Knepley /*@C
4257d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42588a0b0e6bSVictor Minden               provided by the user.
42598a0b0e6bSVictor Minden 
42608a0b0e6bSVictor Minden       Collective on MPI_Comm
42618a0b0e6bSVictor Minden 
42628a0b0e6bSVictor Minden    Input Parameters:
42638a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42648a0b0e6bSVictor Minden .   m   - number of rows
42658a0b0e6bSVictor Minden .   n   - number of columns
42668a0b0e6bSVictor Minden .   i   - row indices
42678a0b0e6bSVictor Minden .   j   - column indices
42681230e6d1SVictor Minden .   a   - matrix values
42691230e6d1SVictor Minden .   nz  - number of nonzeros
42701230e6d1SVictor Minden -   idx - 0 or 1 based
42718a0b0e6bSVictor Minden 
42728a0b0e6bSVictor Minden    Output Parameter:
42738a0b0e6bSVictor Minden .   mat - the matrix
42748a0b0e6bSVictor Minden 
42758a0b0e6bSVictor Minden    Level: intermediate
42768a0b0e6bSVictor Minden 
42778a0b0e6bSVictor Minden    Notes:
42788a0b0e6bSVictor Minden        The i and j indices are 0 based
42798a0b0e6bSVictor Minden 
42808a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
42818a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
42828a0b0e6bSVictor Minden     as shown:
42838a0b0e6bSVictor Minden 
42848a0b0e6bSVictor Minden         1 0 0
42858a0b0e6bSVictor Minden         2 0 3
42868a0b0e6bSVictor Minden         4 5 6
42878a0b0e6bSVictor Minden 
42888a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
42898a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
42908a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
42918a0b0e6bSVictor Minden 
42928a0b0e6bSVictor Minden 
429369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
42948a0b0e6bSVictor Minden 
42958a0b0e6bSVictor Minden @*/
4296c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
42978a0b0e6bSVictor Minden {
42988a0b0e6bSVictor Minden   PetscErrorCode ierr;
4299d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43008a0b0e6bSVictor Minden 
43018a0b0e6bSVictor Minden 
43028a0b0e6bSVictor Minden   PetscFunctionBegin;
43031795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
43041230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4305c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
43061230e6d1SVictor Minden   }
43078a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43088a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43098a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43101230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43111230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43121230e6d1SVictor Minden     if (idx) {
43131230e6d1SVictor Minden       row = i[ii] - 1;
43141230e6d1SVictor Minden       col = j[ii] - 1;
43151230e6d1SVictor Minden     } else {
43161230e6d1SVictor Minden       row = i[ii];
43171230e6d1SVictor Minden       col = j[ii];
43188a0b0e6bSVictor Minden     }
43191230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43208a0b0e6bSVictor Minden   }
43218a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43228a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4323d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43248a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43258a0b0e6bSVictor Minden }
432636db0b34SBarry Smith 
4327acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4328acf2f550SJed Brown {
4329acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4330acf2f550SJed Brown   PetscErrorCode ierr;
4331acf2f550SJed Brown 
4332acf2f550SJed Brown   PetscFunctionBegin;
4333acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4334acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43352205254eSKarl Rupp 
4336acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4337acf2f550SJed Brown   PetscFunctionReturn(0);
4338acf2f550SJed Brown }
4339acf2f550SJed Brown 
43409c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43419c8f2541SHong Zhang {
43429c8f2541SHong Zhang   PetscErrorCode ierr;
43438761c3d6SHong Zhang   PetscMPIInt    size;
43449c8f2541SHong Zhang 
43459c8f2541SHong Zhang   PetscFunctionBegin;
43468761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43478761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43488761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43498761c3d6SHong Zhang   } else {
43509c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43518761c3d6SHong Zhang   }
43529c8f2541SHong Zhang   PetscFunctionReturn(0);
43539c8f2541SHong Zhang }
43549c8f2541SHong Zhang 
435581824310SBarry Smith /*
435653dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
435753dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
435853dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
435953dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
436053dd7562SDmitry Karpeev  */
436153dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
436253dd7562SDmitry Karpeev {
436353dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
436453dd7562SDmitry Karpeev   PetscErrorCode ierr;
436553dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
436653dd7562SDmitry Karpeev   PetscBool      seqaij;
436753dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
436853dd7562SDmitry Karpeev   PetscScalar    v;
436953dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
437053dd7562SDmitry Karpeev 
437153dd7562SDmitry Karpeev   PetscFunctionBegin;
437253dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
437353dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
437453dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
437553dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
437653dd7562SDmitry Karpeev   if (rowemb) {
437753dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
437853dd7562SDmitry 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);
437953dd7562SDmitry Karpeev   } else {
43806c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
438153dd7562SDmitry Karpeev   }
438253dd7562SDmitry Karpeev   if (colemb) {
438353dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
438453dd7562SDmitry 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);
438553dd7562SDmitry Karpeev   } else {
438653dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
438753dd7562SDmitry Karpeev   }
438853dd7562SDmitry Karpeev 
438953dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
439053dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
439153dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
439253dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
439353dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
439453dd7562SDmitry Karpeev     }
439553dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
439653dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
439753dd7562SDmitry Karpeev   }
439853dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
439953dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
440053dd7562SDmitry Karpeev   }
440153dd7562SDmitry Karpeev   count = 0;
440253dd7562SDmitry Karpeev   rowindices = NULL;
440353dd7562SDmitry Karpeev   colindices = NULL;
440453dd7562SDmitry Karpeev   if (rowemb) {
440553dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
440653dd7562SDmitry Karpeev   }
440753dd7562SDmitry Karpeev   if (colemb) {
440853dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
440953dd7562SDmitry Karpeev   }
441053dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
441153dd7562SDmitry Karpeev     PetscInt row;
441253dd7562SDmitry Karpeev     row = i;
441353dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
441453dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
441553dd7562SDmitry Karpeev       PetscInt col;
441653dd7562SDmitry Karpeev       col  = Baij->j[count];
441753dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
441853dd7562SDmitry Karpeev       v    = Baij->a[count];
441953dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
442053dd7562SDmitry Karpeev       ++count;
442153dd7562SDmitry Karpeev     }
442253dd7562SDmitry Karpeev   }
442353dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
442453dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
442553dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
442653dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
442753dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
442853dd7562SDmitry Karpeev   PetscFunctionReturn(0);
442953dd7562SDmitry Karpeev }
443053dd7562SDmitry Karpeev 
443153dd7562SDmitry Karpeev 
443253dd7562SDmitry Karpeev /*
443381824310SBarry Smith     Special version for direct calls from Fortran
443481824310SBarry Smith */
4435af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
443681824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
443781824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
443881824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
443981824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
444081824310SBarry Smith #endif
444181824310SBarry Smith 
444281824310SBarry Smith /* Change these macros so can be used in void function */
444381824310SBarry Smith #undef CHKERRQ
4444ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
444581824310SBarry Smith #undef SETERRQ2
4446e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44474994cf47SJed Brown #undef SETERRQ3
44484994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
444981824310SBarry Smith 
44508cc058d9SJed 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)
445181824310SBarry Smith {
445281824310SBarry Smith   Mat            A  = *AA;
445381824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
445481824310SBarry Smith   InsertMode     is = *isis;
445581824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
445681824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
445781824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
445881824310SBarry Smith   PetscErrorCode ierr;
445981824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
446054f21887SBarry Smith   MatScalar      *ap,value,*aa;
4461ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4462ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
446381824310SBarry Smith 
446481824310SBarry Smith   PetscFunctionBegin;
44654994cf47SJed Brown   MatCheckPreallocated(A,1);
446681824310SBarry Smith   imax  = a->imax;
446781824310SBarry Smith   ai    = a->i;
446881824310SBarry Smith   ailen = a->ilen;
446981824310SBarry Smith   aj    = a->j;
447081824310SBarry Smith   aa    = a->a;
447181824310SBarry Smith 
447281824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
447381824310SBarry Smith     row = im[k];
447481824310SBarry Smith     if (row < 0) continue;
447581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4476ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
447781824310SBarry Smith #endif
447881824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
447981824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
448081824310SBarry Smith     low  = 0;
448181824310SBarry Smith     high = nrow;
448281824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
448381824310SBarry Smith       if (in[l] < 0) continue;
448481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4485ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
448681824310SBarry Smith #endif
448781824310SBarry Smith       col = in[l];
44882205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
44892205254eSKarl Rupp       else value = v[k + l*m];
44902205254eSKarl Rupp 
449181824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
449281824310SBarry Smith 
44932205254eSKarl Rupp       if (col <= lastcol) low = 0;
44942205254eSKarl Rupp       else high = nrow;
449581824310SBarry Smith       lastcol = col;
449681824310SBarry Smith       while (high-low > 5) {
449781824310SBarry Smith         t = (low+high)/2;
449881824310SBarry Smith         if (rp[t] > col) high = t;
449981824310SBarry Smith         else             low  = t;
450081824310SBarry Smith       }
450181824310SBarry Smith       for (i=low; i<high; i++) {
450281824310SBarry Smith         if (rp[i] > col) break;
450381824310SBarry Smith         if (rp[i] == col) {
450481824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
450581824310SBarry Smith           else                  ap[i] = value;
450681824310SBarry Smith           goto noinsert;
450781824310SBarry Smith         }
450881824310SBarry Smith       }
450981824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
451081824310SBarry Smith       if (nonew == 1) goto noinsert;
4511ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4512fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
451381824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
451481824310SBarry Smith       /* shift up all the later entries in this row */
451581824310SBarry Smith       for (ii=N; ii>=i; ii--) {
451681824310SBarry Smith         rp[ii+1] = rp[ii];
451781824310SBarry Smith         ap[ii+1] = ap[ii];
451881824310SBarry Smith       }
451981824310SBarry Smith       rp[i] = col;
452081824310SBarry Smith       ap[i] = value;
4521e56f5c9eSBarry Smith       A->nonzerostate++;
452281824310SBarry Smith noinsert:;
452381824310SBarry Smith       low = i + 1;
452481824310SBarry Smith     }
452581824310SBarry Smith     ailen[row] = nrow;
452681824310SBarry Smith   }
452781824310SBarry Smith   PetscFunctionReturnVoid();
452881824310SBarry Smith }
45299f7953f8SBarry Smith 
4530