xref: /petsc/src/mat/impls/aij/seq/aij.c (revision fff8e43f20a4eb7b6688edfb8395c542b46130d2)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h>
120716a85fSBarry Smith 
130716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
140716a85fSBarry Smith {
150716a85fSBarry Smith   PetscErrorCode ierr;
160716a85fSBarry Smith   PetscInt       i,m,n;
170716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
180716a85fSBarry Smith 
190716a85fSBarry Smith   PetscFunctionBegin;
200716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
210716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
220716a85fSBarry Smith   if (type == NORM_2) {
230716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
240716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
250716a85fSBarry Smith     }
260716a85fSBarry Smith   } else if (type == NORM_1) {
270716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
280716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
290716a85fSBarry Smith     }
300716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
310716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
320716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
330716a85fSBarry Smith     }
340716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
350716a85fSBarry Smith 
360716a85fSBarry Smith   if (type == NORM_2) {
378f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
380716a85fSBarry Smith   }
390716a85fSBarry Smith   PetscFunctionReturn(0);
400716a85fSBarry Smith }
410716a85fSBarry Smith 
423a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
433a062f41SBarry Smith {
443a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
453a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
463a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
473a062f41SBarry Smith   PetscInt        *rows;
483a062f41SBarry Smith   PetscErrorCode  ierr;
493a062f41SBarry Smith 
503a062f41SBarry Smith   PetscFunctionBegin;
513a062f41SBarry Smith   for (i=0; i<m; i++) {
523a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
533a062f41SBarry Smith       cnt++;
543a062f41SBarry Smith     }
553a062f41SBarry Smith   }
563a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
573a062f41SBarry Smith   cnt  = 0;
583a062f41SBarry Smith   for (i=0; i<m; i++) {
593a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
603a062f41SBarry Smith       rows[cnt] = i;
613a062f41SBarry Smith       cnt++;
623a062f41SBarry Smith     }
633a062f41SBarry Smith   }
643a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
653a062f41SBarry Smith   PetscFunctionReturn(0);
663a062f41SBarry Smith }
673a062f41SBarry Smith 
68f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
696ce1633cSBarry Smith {
706ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
716ce1633cSBarry Smith   const MatScalar *aa = a->a;
726ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
73b2db7409Sstefano_zampini   const PetscInt  *ii = a->i,*jj = a->j,*diag;
746ce1633cSBarry Smith   PetscInt        *rows;
756ce1633cSBarry Smith   PetscErrorCode  ierr;
766ce1633cSBarry Smith 
776ce1633cSBarry Smith   PetscFunctionBegin;
786ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
796ce1633cSBarry Smith   diag = a->diag;
806ce1633cSBarry Smith   for (i=0; i<m; i++) {
81b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
826ce1633cSBarry Smith       cnt++;
836ce1633cSBarry Smith     }
846ce1633cSBarry Smith   }
85785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
866ce1633cSBarry Smith   cnt  = 0;
876ce1633cSBarry Smith   for (i=0; i<m; i++) {
88b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
896ce1633cSBarry Smith       rows[cnt++] = i;
906ce1633cSBarry Smith     }
916ce1633cSBarry Smith   }
92f1f41ecbSJed Brown   *nrows = cnt;
93f1f41ecbSJed Brown   *zrows = rows;
94f1f41ecbSJed Brown   PetscFunctionReturn(0);
95f1f41ecbSJed Brown }
96f1f41ecbSJed Brown 
97f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
98f1f41ecbSJed Brown {
99f1f41ecbSJed Brown   PetscInt       nrows,*rows;
100f1f41ecbSJed Brown   PetscErrorCode ierr;
101f1f41ecbSJed Brown 
102f1f41ecbSJed Brown   PetscFunctionBegin;
1030298fd71SBarry Smith   *zrows = NULL;
104f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
105ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1066ce1633cSBarry Smith   PetscFunctionReturn(0);
1076ce1633cSBarry Smith }
1086ce1633cSBarry Smith 
109b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
110b3a44c85SBarry Smith {
111b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
112b3a44c85SBarry Smith   const MatScalar *aa;
113b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
114b3a44c85SBarry Smith   const PetscInt  *ii;
115b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
116b3a44c85SBarry Smith   PetscErrorCode  ierr;
117b3a44c85SBarry Smith 
118b3a44c85SBarry Smith   PetscFunctionBegin;
119b3a44c85SBarry Smith   *keptrows = 0;
120b3a44c85SBarry Smith   ii        = a->i;
121b3a44c85SBarry Smith   for (i=0; i<m; i++) {
122b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
123b3a44c85SBarry Smith     if (!n) {
124b3a44c85SBarry Smith       cnt++;
125b3a44c85SBarry Smith       goto ok1;
126b3a44c85SBarry Smith     }
127b3a44c85SBarry Smith     aa = a->a + ii[i];
128b3a44c85SBarry Smith     for (j=0; j<n; j++) {
129b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
130b3a44c85SBarry Smith     }
131b3a44c85SBarry Smith     cnt++;
132b3a44c85SBarry Smith ok1:;
133b3a44c85SBarry Smith   }
134b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
135854ce69bSBarry Smith   ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr);
136b3a44c85SBarry Smith   cnt  = 0;
137b3a44c85SBarry Smith   for (i=0; i<m; i++) {
138b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
139b3a44c85SBarry Smith     if (!n) continue;
140b3a44c85SBarry Smith     aa = a->a + ii[i];
141b3a44c85SBarry Smith     for (j=0; j<n; j++) {
142b3a44c85SBarry Smith       if (aa[j] != 0.0) {
143b3a44c85SBarry Smith         rows[cnt++] = i;
144b3a44c85SBarry Smith         break;
145b3a44c85SBarry Smith       }
146b3a44c85SBarry Smith     }
147b3a44c85SBarry Smith   }
148b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
149b3a44c85SBarry Smith   PetscFunctionReturn(0);
150b3a44c85SBarry Smith }
151b3a44c85SBarry Smith 
1527087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
15379299369SBarry Smith {
15479299369SBarry Smith   PetscErrorCode    ierr;
15579299369SBarry Smith   Mat_SeqAIJ        *aij = (Mat_SeqAIJ*) Y->data;
15699e65526SBarry Smith   PetscInt          i,m = Y->rmap->n;
15799e65526SBarry Smith   const PetscInt    *diag;
15854f21887SBarry Smith   MatScalar         *aa = aij->a;
15999e65526SBarry Smith   const PetscScalar *v;
160ace3abfcSBarry Smith   PetscBool         missing;
16179299369SBarry Smith 
16279299369SBarry Smith   PetscFunctionBegin;
16309f38230SBarry Smith   if (Y->assembled) {
1640298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
16509f38230SBarry Smith     if (!missing) {
16679299369SBarry Smith       diag = aij->diag;
16799e65526SBarry Smith       ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr);
16879299369SBarry Smith       if (is == INSERT_VALUES) {
16979299369SBarry Smith         for (i=0; i<m; i++) {
17079299369SBarry Smith           aa[diag[i]] = v[i];
17179299369SBarry Smith         }
17279299369SBarry Smith       } else {
17379299369SBarry Smith         for (i=0; i<m; i++) {
17479299369SBarry Smith           aa[diag[i]] += v[i];
17579299369SBarry Smith         }
17679299369SBarry Smith       }
17799e65526SBarry Smith       ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr);
17879299369SBarry Smith       PetscFunctionReturn(0);
17979299369SBarry Smith     }
180acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
18109f38230SBarry Smith   }
18209f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
18309f38230SBarry Smith   PetscFunctionReturn(0);
18409f38230SBarry Smith }
18579299369SBarry Smith 
1861a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
18717ab2063SBarry Smith {
188416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
189dfbe8321SBarry Smith   PetscErrorCode ierr;
19097f1f81fSBarry Smith   PetscInt       i,ishift;
19117ab2063SBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionBegin;
193d0f46423SBarry Smith   *m = A->rmap->n;
1943a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
195bfeeae90SHong Zhang   ishift = 0;
19653e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
1972462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
198bfeeae90SHong Zhang   } else if (oshift == 1) {
1991a83f524SJed Brown     PetscInt *tia;
200d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2013b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
202854ce69bSBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr);
2031a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2041a83f524SJed Brown     *ia = tia;
205ecc77c7aSBarry Smith     if (ja) {
2061a83f524SJed Brown       PetscInt *tja;
207854ce69bSBarry Smith       ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr);
2081a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2091a83f524SJed Brown       *ja = tja;
210ecc77c7aSBarry Smith     }
2116945ee14SBarry Smith   } else {
212ecc77c7aSBarry Smith     *ia = a->i;
213ecc77c7aSBarry Smith     if (ja) *ja = a->j;
214a2ce50c7SBarry Smith   }
2153a40ed3dSBarry Smith   PetscFunctionReturn(0);
216a2744918SBarry Smith }
217a2744918SBarry Smith 
2181a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2196945ee14SBarry Smith {
220dfbe8321SBarry Smith   PetscErrorCode ierr;
2216945ee14SBarry Smith 
2223a40ed3dSBarry Smith   PetscFunctionBegin;
2233a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
224bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
225606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
226ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
227bcd2baecSBarry Smith   }
2283a40ed3dSBarry Smith   PetscFunctionReturn(0);
22917ab2063SBarry Smith }
23017ab2063SBarry Smith 
2311a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2323b2fbd54SBarry Smith {
2333b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
234dfbe8321SBarry Smith   PetscErrorCode ierr;
235d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
23697f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2373b2fbd54SBarry Smith 
2383a40ed3dSBarry Smith   PetscFunctionBegin;
239899cda47SBarry Smith   *nn = n;
2403a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2413b2fbd54SBarry Smith   if (symmetric) {
2422462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2433b2fbd54SBarry Smith   } else {
2441795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
245854ce69bSBarry Smith     ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
246854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
2473b2fbd54SBarry Smith     jj   = a->j;
2483b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
249bfeeae90SHong Zhang       collengths[jj[i]]++;
2503b2fbd54SBarry Smith     }
2513b2fbd54SBarry Smith     cia[0] = oshift;
2523b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2533b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2543b2fbd54SBarry Smith     }
25597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2563b2fbd54SBarry Smith     jj   = a->j;
257a93ec695SBarry Smith     for (row=0; row<m; row++) {
258a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
259a93ec695SBarry Smith       for (i=0; i<mr; i++) {
260bfeeae90SHong Zhang         col = *jj++;
2612205254eSKarl Rupp 
2623b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2633b2fbd54SBarry Smith       }
2643b2fbd54SBarry Smith     }
265606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2663b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2673b2fbd54SBarry Smith   }
2683a40ed3dSBarry Smith   PetscFunctionReturn(0);
2693b2fbd54SBarry Smith }
2703b2fbd54SBarry Smith 
2711a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2723b2fbd54SBarry Smith {
273dfbe8321SBarry Smith   PetscErrorCode ierr;
274606d414cSSatish Balay 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2763a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2773b2fbd54SBarry Smith 
278606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
279606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2813b2fbd54SBarry Smith }
2823b2fbd54SBarry Smith 
2837cee066cSHong Zhang /*
2847cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2857cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
286040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2877cee066cSHong Zhang */
2887cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
2897cee066cSHong Zhang {
2907cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2917cee066cSHong Zhang   PetscErrorCode ierr;
2927cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2937cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2947cee066cSHong Zhang   PetscInt       *cspidx;
2957cee066cSHong Zhang 
2967cee066cSHong Zhang   PetscFunctionBegin;
2977cee066cSHong Zhang   *nn = n;
2987cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
299625f6d37SHong Zhang 
3001795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
301854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
302854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr);
303854ce69bSBarry Smith   ierr = PetscMalloc1(nz+1,&cspidx);CHKERRQ(ierr);
3047cee066cSHong Zhang   jj   = a->j;
3057cee066cSHong Zhang   for (i=0; i<nz; i++) {
3067cee066cSHong Zhang     collengths[jj[i]]++;
3077cee066cSHong Zhang   }
3087cee066cSHong Zhang   cia[0] = oshift;
3097cee066cSHong Zhang   for (i=0; i<n; i++) {
3107cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3117cee066cSHong Zhang   }
3127cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3137cee066cSHong Zhang   jj   = a->j;
3147cee066cSHong Zhang   for (row=0; row<m; row++) {
3157cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3167cee066cSHong Zhang     for (i=0; i<mr; i++) {
3177cee066cSHong Zhang       col = *jj++;
3187cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3197cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3207cee066cSHong Zhang     }
3217cee066cSHong Zhang   }
3227cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3237cee066cSHong Zhang   *ia    = cia; *ja = cja;
3247cee066cSHong Zhang   *spidx = cspidx;
3257cee066cSHong Zhang   PetscFunctionReturn(0);
3267cee066cSHong Zhang }
3277cee066cSHong Zhang 
3287cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3297cee066cSHong Zhang {
3307cee066cSHong Zhang   PetscErrorCode ierr;
3317cee066cSHong Zhang 
3327cee066cSHong Zhang   PetscFunctionBegin;
3335243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3347cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3357cee066cSHong Zhang   PetscFunctionReturn(0);
3367cee066cSHong Zhang }
3377cee066cSHong Zhang 
33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
33987d4246cSBarry Smith {
34087d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34187d4246cSBarry Smith   PetscInt       *ai = a->i;
34287d4246cSBarry Smith   PetscErrorCode ierr;
34387d4246cSBarry Smith 
34487d4246cSBarry Smith   PetscFunctionBegin;
34587d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
34687d4246cSBarry Smith   PetscFunctionReturn(0);
34787d4246cSBarry Smith }
34887d4246cSBarry Smith 
349bd04181cSBarry Smith /*
350bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
351bd04181cSBarry Smith 
352bd04181cSBarry Smith       -   a single row of values is set with each call
353bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
354bd04181cSBarry Smith       -   the values are always added to the matrix, not set
355bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
356bd04181cSBarry Smith 
3571f763a69SBarry Smith      This does NOT assume the global column indices are sorted
358bd04181cSBarry Smith 
3591f763a69SBarry Smith */
360bd04181cSBarry Smith 
361af0996ceSBarry Smith #include <petsc/private/isimpl.h>
362189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
363189e4007SBarry Smith {
364189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3651f763a69SBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
3661f763a69SBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j;
3671f763a69SBarry Smith   PetscInt       lastcol = -1;
368189e4007SBarry Smith   MatScalar      *ap,value,*aa = a->a;
369189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
370189e4007SBarry Smith 
371f38dd0b8SBarry Smith   row = ridx[im[0]];
3721f763a69SBarry Smith   rp   = aj + ai[row];
3731f763a69SBarry Smith   ap = aa + ai[row];
3741f763a69SBarry Smith   nrow = ailen[row];
375189e4007SBarry Smith   low  = 0;
376189e4007SBarry Smith   high = nrow;
377189e4007SBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
378189e4007SBarry Smith     col = cidx[in[l]];
379f38dd0b8SBarry Smith     value = v[l];
380189e4007SBarry Smith 
381189e4007SBarry Smith     if (col <= lastcol) low = 0;
382189e4007SBarry Smith     else high = nrow;
383189e4007SBarry Smith     lastcol = col;
384189e4007SBarry Smith     while (high-low > 5) {
385189e4007SBarry Smith       t = (low+high)/2;
386189e4007SBarry Smith       if (rp[t] > col) high = t;
387189e4007SBarry Smith       else low = t;
388189e4007SBarry Smith     }
389189e4007SBarry Smith     for (i=low; i<high; i++) {
390189e4007SBarry Smith       if (rp[i] == col) {
3911f763a69SBarry Smith         ap[i] += value;
392189e4007SBarry Smith         low = i + 1;
3931f763a69SBarry Smith         break;
394189e4007SBarry Smith       }
395189e4007SBarry Smith     }
396189e4007SBarry Smith   }
397f38dd0b8SBarry Smith   return 0;
398189e4007SBarry Smith }
399189e4007SBarry Smith 
40097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
40117ab2063SBarry Smith {
402416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
403e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
40497f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
4056849ba73SBarry Smith   PetscErrorCode ierr;
406e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
407d8cdefa3SHong Zhang   MatScalar      *ap=NULL,value=0.0,*aa = a->a;
408ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
409ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
41017ab2063SBarry Smith 
4113a40ed3dSBarry Smith   PetscFunctionBegin;
41217ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
413416022c9SBarry Smith     row = im[k];
4145ef9f2a5SBarry Smith     if (row < 0) continue;
4152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
416e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
4173b2fbd54SBarry Smith #endif
418720833daSHong Zhang     rp   = aj + ai[row];
419876c6284SHong Zhang     if (!A->structure_only) ap = aa + ai[row];
42017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
421416022c9SBarry Smith     low  = 0;
422c71e6ed7SBarry Smith     high = nrow;
42317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4245ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4252515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
426e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
4273b2fbd54SBarry Smith #endif
428bfeeae90SHong Zhang       col = in[l];
429720833daSHong Zhang       if (!A->structure_only) {
4304b0e389bSBarry Smith         if (roworiented) {
4315ef9f2a5SBarry Smith           value = v[l + k*n];
432bef8e0ddSBarry Smith         } else {
4334b0e389bSBarry Smith           value = v[k + l*m];
4344b0e389bSBarry Smith         }
435720833daSHong Zhang       } else { /* A->structure_only */
436720833daSHong Zhang         value = 1; /* avoid 'continue' below?  */
437720833daSHong Zhang       }
438dcd36c23SBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue;
43936db0b34SBarry Smith 
4402205254eSKarl Rupp       if (col <= lastcol) low = 0;
4412205254eSKarl Rupp       else high = nrow;
442e2ee6c50SBarry Smith       lastcol = col;
443416022c9SBarry Smith       while (high-low > 5) {
444416022c9SBarry Smith         t = (low+high)/2;
445416022c9SBarry Smith         if (rp[t] > col) high = t;
446416022c9SBarry Smith         else low = t;
44717ab2063SBarry Smith       }
448416022c9SBarry Smith       for (i=low; i<high; i++) {
44917ab2063SBarry Smith         if (rp[i] > col) break;
45017ab2063SBarry Smith         if (rp[i] == col) {
451876c6284SHong Zhang           if (!A->structure_only) {
452416022c9SBarry Smith             if (is == ADD_VALUES) ap[i] += value;
45317ab2063SBarry Smith             else ap[i] = value;
454720833daSHong Zhang           }
455e44c0bd4SBarry Smith           low = i + 1;
45617ab2063SBarry Smith           goto noinsert;
45717ab2063SBarry Smith         }
45817ab2063SBarry Smith       }
459dcd36c23SBarry Smith       if (value == 0.0 && ignorezeroentries && row != col) goto noinsert;
460c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
461e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
462720833daSHong Zhang       if (A->structure_only) {
463876c6284SHong Zhang         MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar);
464720833daSHong Zhang       } else {
465fef13f97SBarry Smith         MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
466720833daSHong Zhang       }
467c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
468416022c9SBarry Smith       /* shift up all the later entries in this row */
469416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
47017ab2063SBarry Smith         rp[ii+1] = rp[ii];
471876c6284SHong Zhang         if (!A->structure_only) ap[ii+1] = ap[ii];
472720833daSHong Zhang       }
47317ab2063SBarry Smith       rp[i] = col;
474876c6284SHong Zhang       if (!A->structure_only) ap[i] = value;
475416022c9SBarry Smith       low   = i + 1;
476e56f5c9eSBarry Smith       A->nonzerostate++;
477e44c0bd4SBarry Smith noinsert:;
47817ab2063SBarry Smith     }
47917ab2063SBarry Smith     ailen[row] = nrow;
48017ab2063SBarry Smith   }
4813a40ed3dSBarry Smith   PetscFunctionReturn(0);
48217ab2063SBarry Smith }
48317ab2063SBarry Smith 
48481824310SBarry Smith 
485a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4867eb43aa7SLois Curfman McInnes {
4877eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
48897f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
48997f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
49054f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4917eb43aa7SLois Curfman McInnes 
4923a40ed3dSBarry Smith   PetscFunctionBegin;
4937eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4947eb43aa7SLois Curfman McInnes     row = im[k];
495e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
496e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
497bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4987eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4997eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
500e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
501e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
502bfeeae90SHong Zhang       col  = in[l];
5037eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5047eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5057eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5067eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5077eb43aa7SLois Curfman McInnes         else low = t;
5087eb43aa7SLois Curfman McInnes       }
5097eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5107eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5117eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
512b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5137eb43aa7SLois Curfman McInnes           goto finished;
5147eb43aa7SLois Curfman McInnes         }
5157eb43aa7SLois Curfman McInnes       }
51697e567efSBarry Smith       *v++ = 0.0;
5177eb43aa7SLois Curfman McInnes finished:;
5187eb43aa7SLois Curfman McInnes     }
5197eb43aa7SLois Curfman McInnes   }
5203a40ed3dSBarry Smith   PetscFunctionReturn(0);
5217eb43aa7SLois Curfman McInnes }
5227eb43aa7SLois Curfman McInnes 
52317ab2063SBarry Smith 
524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
52517ab2063SBarry Smith {
526416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5276849ba73SBarry Smith   PetscErrorCode ierr;
5286f69ff64SBarry Smith   PetscInt       i,*col_lens;
5296f69ff64SBarry Smith   int            fd;
530b37d52dbSMark F. Adams   FILE           *file;
53117ab2063SBarry Smith 
5323a40ed3dSBarry Smith   PetscFunctionBegin;
533b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
534854ce69bSBarry Smith   ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr);
5352205254eSKarl Rupp 
5360700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
537d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
538d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
539416022c9SBarry Smith   col_lens[3] = a->nz;
540416022c9SBarry Smith 
541416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
542d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
543416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
54417ab2063SBarry Smith   }
545d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
546606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
547416022c9SBarry Smith 
548416022c9SBarry Smith   /* store column indices (zero start index) */
5496f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
550416022c9SBarry Smith 
551416022c9SBarry Smith   /* store nonzero values */
5526f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
553b37d52dbSMark F. Adams 
554b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
555b37d52dbSMark F. Adams   if (file) {
55633d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
557b37d52dbSMark F. Adams   }
5583a40ed3dSBarry Smith   PetscFunctionReturn(0);
55917ab2063SBarry Smith }
560416022c9SBarry Smith 
5617dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer)
5627dc0baabSHong Zhang {
5637dc0baabSHong Zhang   PetscErrorCode ierr;
5647dc0baabSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5657dc0baabSHong Zhang   PetscInt       i,k,m=A->rmap->N;
5667dc0baabSHong Zhang 
5677dc0baabSHong Zhang   PetscFunctionBegin;
5687dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
5697dc0baabSHong Zhang   for (i=0; i<m; i++) {
5707dc0baabSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
5717dc0baabSHong Zhang     for (k=a->i[i]; k<a->i[i+1]; k++) {
5727dc0baabSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr);
5737dc0baabSHong Zhang     }
5747dc0baabSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
5757dc0baabSHong Zhang   }
5767dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
5777dc0baabSHong Zhang   PetscFunctionReturn(0);
5787dc0baabSHong Zhang }
5797dc0baabSHong Zhang 
58009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
581cd155464SBarry Smith 
582dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
583416022c9SBarry Smith {
584416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
585dfbe8321SBarry Smith   PetscErrorCode    ierr;
58660e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
587e060cb09SBarry Smith   const char        *name;
588f3ef73ceSBarry Smith   PetscViewerFormat format;
58917ab2063SBarry Smith 
5903a40ed3dSBarry Smith   PetscFunctionBegin;
5917dc0baabSHong Zhang   if (A->structure_only) {
5927dc0baabSHong Zhang     ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr);
5937dc0baabSHong Zhang     PetscFunctionReturn(0);
5947dc0baabSHong Zhang   }
59543e49210SHong Zhang 
596b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
59771c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
59897f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
59960e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
600c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
601d00d2cf4SBarry Smith       nofinalvalue = 1;
602d00d2cf4SBarry Smith     }
603d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
604d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
60577431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
606fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
607fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
608fbfe6fa7SJed Brown #else
60977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
610fbfe6fa7SJed Brown #endif
611b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
61217ab2063SBarry Smith 
61317ab2063SBarry Smith     for (i=0; i<m; i++) {
61460e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
615aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
616a9bf72d8SJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
61717ab2063SBarry Smith #else
61860e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
61917ab2063SBarry Smith #endif
62017ab2063SBarry Smith       }
62117ab2063SBarry Smith     }
622d00d2cf4SBarry Smith     if (nofinalvalue) {
623c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
624c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
625c337ccceSJed Brown #else
626d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
627c337ccceSJed Brown #endif
628d00d2cf4SBarry Smith     }
629317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
630fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
631d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
63268369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
633cd155464SBarry Smith     PetscFunctionReturn(0);
634fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
635d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
63644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
63777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
63860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
639aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
64160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
64360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
64560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6466831982aSBarry Smith         }
64744cd7ae7SLois Curfman McInnes #else
64860e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
64944cd7ae7SLois Curfman McInnes #endif
65044cd7ae7SLois Curfman McInnes       }
651b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65244cd7ae7SLois Curfman McInnes     }
653d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
654fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
65597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
656d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
657854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
658496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
659496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
66060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
661496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
662aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
664496be53dSLois Curfman McInnes #else
665496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
666496be53dSLois Curfman McInnes #endif
667496be53dSLois Curfman McInnes         }
668496be53dSLois Curfman McInnes       }
669496be53dSLois Curfman McInnes     }
6702e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
67177431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6722e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6732205254eSKarl Rupp       if (i+4<m) {
6742205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);
6752205254eSKarl Rupp       } else if (i+3<m) {
6762205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);
6772205254eSKarl Rupp       } else if (i+2<m) {
6782205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6792205254eSKarl Rupp       } else if (i+1<m) {
6802205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6812205254eSKarl Rupp       } else if (i<m) {
6822205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6832205254eSKarl Rupp       } else {
6842205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6852205254eSKarl Rupp       }
686496be53dSLois Curfman McInnes     }
687b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
688606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
689496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
69060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
69177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
692496be53dSLois Curfman McInnes       }
693b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
694496be53dSLois Curfman McInnes     }
695b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
696496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
69760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
698496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
699aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
70160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7026831982aSBarry Smith           }
703496be53dSLois Curfman McInnes #else
70460e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
705496be53dSLois Curfman McInnes #endif
706496be53dSLois Curfman McInnes         }
707496be53dSLois Curfman McInnes       }
708b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
709496be53dSLois Curfman McInnes     }
710d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
711fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
71297f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
71387828ca2SBarry Smith     PetscScalar value;
71468f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
71568f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
71668f1ed48SBarry Smith 
71768f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
71868f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
71968f1ed48SBarry Smith         realonly = PETSC_FALSE;
72068f1ed48SBarry Smith         break;
72168f1ed48SBarry Smith       }
72268f1ed48SBarry Smith     }
72368f1ed48SBarry Smith #endif
72402594712SBarry Smith 
725d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
72602594712SBarry Smith     for (i=0; i<m; i++) {
72702594712SBarry Smith       jcnt = 0;
728d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
729e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
73002594712SBarry Smith           value = a->a[cnt++];
731e24b481bSBarry Smith           jcnt++;
73202594712SBarry Smith         } else {
73302594712SBarry Smith           value = 0.0;
73402594712SBarry Smith         }
735aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73668f1ed48SBarry Smith         if (realonly) {
73760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
73868f1ed48SBarry Smith         } else {
73960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
74068f1ed48SBarry Smith         }
74102594712SBarry Smith #else
74260e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
74302594712SBarry Smith #endif
74402594712SBarry Smith       }
745b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74602594712SBarry Smith     }
747d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7483c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
749150b93efSMatthew G. Knepley     PetscInt fshift=1;
750d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7513c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
75219303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
7533c215bfdSMatthew Knepley #else
75419303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
7553c215bfdSMatthew Knepley #endif
756d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7573c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
75860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
7593c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
760a9a0e077SKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7613c215bfdSMatthew Knepley #else
762150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7633c215bfdSMatthew Knepley #endif
7643c215bfdSMatthew Knepley       }
7653c215bfdSMatthew Knepley     }
766d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7673a40ed3dSBarry Smith   } else {
768d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
769d5f3da31SBarry Smith     if (A->factortype) {
77016cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
77116cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
77216cd7e1dSShri Abhyankar         /* L part */
77360e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
77416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
77516cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
77660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
77716cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7786712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
77916cd7e1dSShri Abhyankar           } else {
78060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
78116cd7e1dSShri Abhyankar           }
78216cd7e1dSShri Abhyankar #else
78360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
78416cd7e1dSShri Abhyankar #endif
78516cd7e1dSShri Abhyankar         }
78616cd7e1dSShri Abhyankar         /* diagonal */
78716cd7e1dSShri Abhyankar         j = a->diag[i];
78816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78916cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
79060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
79116cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7926712e2f1SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr);
79316cd7e1dSShri Abhyankar         } else {
79460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
79516cd7e1dSShri Abhyankar         }
79616cd7e1dSShri Abhyankar #else
79760e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
79816cd7e1dSShri Abhyankar #endif
79916cd7e1dSShri Abhyankar 
80016cd7e1dSShri Abhyankar         /* U part */
80160e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
80216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
80316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
80460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
80516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
80622ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
80716cd7e1dSShri Abhyankar           } else {
80860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
80916cd7e1dSShri Abhyankar           }
81016cd7e1dSShri Abhyankar #else
81160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
81216cd7e1dSShri Abhyankar #endif
81316cd7e1dSShri Abhyankar         }
81416cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
81516cd7e1dSShri Abhyankar       }
81616cd7e1dSShri Abhyankar     } else {
81717ab2063SBarry Smith       for (i=0; i<m; i++) {
81877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
81960e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
820aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
82136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
82260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
82336db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
82460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8253a40ed3dSBarry Smith           } else {
82660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
82717ab2063SBarry Smith           }
82817ab2063SBarry Smith #else
82960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
83017ab2063SBarry Smith #endif
83117ab2063SBarry Smith         }
832b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
83317ab2063SBarry Smith       }
83416cd7e1dSShri Abhyankar     }
835d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
83617ab2063SBarry Smith   }
837b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8383a40ed3dSBarry Smith   PetscFunctionReturn(0);
839416022c9SBarry Smith }
840416022c9SBarry Smith 
8419804daf3SBarry Smith #include <petscdraw.h>
842dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
843416022c9SBarry Smith {
844480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
845416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
846dfbe8321SBarry Smith   PetscErrorCode    ierr;
847383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
848383922c3SLisandro Dalcin   int               color;
849b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
850b0a32e0cSBarry Smith   PetscViewer       viewer;
851f3ef73ceSBarry Smith   PetscViewerFormat format;
852cddf8d76SBarry Smith 
8533a40ed3dSBarry Smith   PetscFunctionBegin;
854480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
855b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
856b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
857383922c3SLisandro Dalcin 
858416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8590513a670SBarry Smith 
860fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
861383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
8620513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
863b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
864416022c9SBarry Smith     for (i=0; i<m; i++) {
865cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
866bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
867bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
86836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
869b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
870cddf8d76SBarry Smith       }
871cddf8d76SBarry Smith     }
872b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
873cddf8d76SBarry Smith     for (i=0; i<m; i++) {
874cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
875bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
876bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
877cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
878b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
879cddf8d76SBarry Smith       }
880cddf8d76SBarry Smith     }
881b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
882cddf8d76SBarry Smith     for (i=0; i<m; i++) {
883cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
884bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
885bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
88636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
887b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
888416022c9SBarry Smith       }
889416022c9SBarry Smith     }
890383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
8910513a670SBarry Smith   } else {
8920513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8930513a670SBarry Smith     /* first determine max of all nonzero values */
894b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
895383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
896b0a32e0cSBarry Smith     PetscDraw popup;
8970513a670SBarry Smith 
8980513a670SBarry Smith     for (i=0; i<nz; i++) {
8990513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
9000513a670SBarry Smith     }
901383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
902b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
90345f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
904383922c3SLisandro Dalcin 
905383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
9060513a670SBarry Smith     for (i=0; i<m; i++) {
907383922c3SLisandro Dalcin       y_l = m - i - 1.0;
908383922c3SLisandro Dalcin       y_r = y_l + 1.0;
909bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
910383922c3SLisandro Dalcin         x_l = a->j[j];
911383922c3SLisandro Dalcin         x_r = x_l + 1.0;
912b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv);
913b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
9140513a670SBarry Smith         count++;
9150513a670SBarry Smith       }
9160513a670SBarry Smith     }
917383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
9180513a670SBarry Smith   }
919480ef9eaSBarry Smith   PetscFunctionReturn(0);
920480ef9eaSBarry Smith }
921cddf8d76SBarry Smith 
9229804daf3SBarry Smith #include <petscdraw.h>
923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
924480ef9eaSBarry Smith {
925dfbe8321SBarry Smith   PetscErrorCode ierr;
926b0a32e0cSBarry Smith   PetscDraw      draw;
92736db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
928ace3abfcSBarry Smith   PetscBool      isnull;
929480ef9eaSBarry Smith 
930480ef9eaSBarry Smith   PetscFunctionBegin;
931b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
932b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
933480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
934480ef9eaSBarry Smith 
935d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
936480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
937b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
938832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
939b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9400298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
941832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
9423a40ed3dSBarry Smith   PetscFunctionReturn(0);
943416022c9SBarry Smith }
944416022c9SBarry Smith 
945dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
946416022c9SBarry Smith {
947dfbe8321SBarry Smith   PetscErrorCode ierr;
948ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
949416022c9SBarry Smith 
9503a40ed3dSBarry Smith   PetscFunctionBegin;
951251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
952251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
953251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
954c45a1595SBarry Smith   if (iascii) {
9553a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9560f5bd95cSBarry Smith   } else if (isbinary) {
9573a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9580f5bd95cSBarry Smith   } else if (isdraw) {
9593a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
96011aeaf0aSBarry Smith   }
9614108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9623a40ed3dSBarry Smith   PetscFunctionReturn(0);
96317ab2063SBarry Smith }
96419bcc07fSBarry Smith 
965dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
96617ab2063SBarry Smith {
967416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9686849ba73SBarry Smith   PetscErrorCode ierr;
96997f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
970d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
97154f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9723447b6efSHong Zhang   PetscReal      ratio  = 0.6;
97317ab2063SBarry Smith 
9743a40ed3dSBarry Smith   PetscFunctionBegin;
9753a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
97617ab2063SBarry Smith 
97743ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
97817ab2063SBarry Smith   for (i=1; i<m; i++) {
979416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
98017ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
98194a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
98217ab2063SBarry Smith     if (fshift) {
983bfeeae90SHong Zhang       ip = aj + ai[i];
984bfeeae90SHong Zhang       ap = aa + ai[i];
98517ab2063SBarry Smith       N  = ailen[i];
98617ab2063SBarry Smith       for (j=0; j<N; j++) {
98717ab2063SBarry Smith         ip[j-fshift] = ip[j];
988876c6284SHong Zhang         if (!A->structure_only) ap[j-fshift] = ap[j];
98917ab2063SBarry Smith       }
99017ab2063SBarry Smith     }
99117ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
99217ab2063SBarry Smith   }
99317ab2063SBarry Smith   if (m) {
99417ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
99517ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
99617ab2063SBarry Smith   }
9977b083b7cSBarry Smith 
99817ab2063SBarry Smith   /* reset ilen and imax for each row */
9997b083b7cSBarry Smith   a->nonzerorowcnt = 0;
1000396832f4SHong Zhang   if (A->structure_only) {
1001396832f4SHong Zhang     ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
1002396832f4SHong Zhang   } else { /* !A->structure_only */
100317ab2063SBarry Smith     for (i=0; i<m; i++) {
100417ab2063SBarry Smith       ailen[i] = imax[i] = ai[i+1] - ai[i];
10057b083b7cSBarry Smith       a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
100617ab2063SBarry Smith     }
1007396832f4SHong Zhang   }
1008bfeeae90SHong Zhang   a->nz = ai[m];
100965e19b50SBarry Smith   if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift);
101017ab2063SBarry Smith 
101109f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1012d0f46423SBarry Smith   ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr);
1013ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
1014ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
10152205254eSKarl Rupp 
10168e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1017dd5f02e7SSatish Balay   a->reallocs         = 0;
10186712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
101936db0b34SBarry Smith   a->rmax             = rmax;
10204e220ebcSLois Curfman McInnes 
1021396832f4SHong Zhang   if (!A->structure_only) {
102211e456e1SBarry Smith     ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
1023396832f4SHong Zhang   }
10244108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
1025acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10263a40ed3dSBarry Smith   PetscFunctionReturn(0);
102717ab2063SBarry Smith }
102817ab2063SBarry Smith 
102999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
103099cafbc1SBarry Smith {
103199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
103299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
103354f21887SBarry Smith   MatScalar      *aa = a->a;
1034acf2f550SJed Brown   PetscErrorCode ierr;
103599cafbc1SBarry Smith 
103699cafbc1SBarry Smith   PetscFunctionBegin;
103799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1038acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
103999cafbc1SBarry Smith   PetscFunctionReturn(0);
104099cafbc1SBarry Smith }
104199cafbc1SBarry Smith 
104299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
104399cafbc1SBarry Smith {
104499cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
104599cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
104654f21887SBarry Smith   MatScalar      *aa = a->a;
1047acf2f550SJed Brown   PetscErrorCode ierr;
104899cafbc1SBarry Smith 
104999cafbc1SBarry Smith   PetscFunctionBegin;
105099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1051acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
105299cafbc1SBarry Smith   PetscFunctionReturn(0);
105399cafbc1SBarry Smith }
105499cafbc1SBarry Smith 
1055dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
105617ab2063SBarry Smith {
1057416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1058dfbe8321SBarry Smith   PetscErrorCode ierr;
10593a40ed3dSBarry Smith 
10603a40ed3dSBarry Smith   PetscFunctionBegin;
1061d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1062acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10633a40ed3dSBarry Smith   PetscFunctionReturn(0);
106417ab2063SBarry Smith }
1065416022c9SBarry Smith 
1066dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
106717ab2063SBarry Smith {
1068416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1069dfbe8321SBarry Smith   PetscErrorCode ierr;
1070d5d45c9bSBarry Smith 
10713a40ed3dSBarry Smith   PetscFunctionBegin;
1072aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1073d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
107417ab2063SBarry Smith #endif
1075e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10766bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10776bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
107805b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1079d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
108005b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
108171f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
108205b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10836bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
108405b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10856bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
1086cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10870b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1088a30b2313SHong Zhang 
10894108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1090bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1091901853e0SKris Buschelman 
1092dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1093bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1094bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1095bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1096bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1097bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1098bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1099af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1100af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1101af8000cdSHong Zhang #endif
110263c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
110363c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
11043dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
110563c07aadSStefano Zampini #endif
1106b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1107bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1108bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1109bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1110bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
11113a40ed3dSBarry Smith   PetscFunctionReturn(0);
111217ab2063SBarry Smith }
111317ab2063SBarry Smith 
1114ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
111517ab2063SBarry Smith {
1116416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11174846f1f5SKris Buschelman   PetscErrorCode ierr;
11183a40ed3dSBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
1120a65d3064SKris Buschelman   switch (op) {
1121a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11224e0d8c25SBarry Smith     a->roworiented = flg;
1123a65d3064SKris Buschelman     break;
1124a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1125a9817697SBarry Smith     a->keepnonzeropattern = flg;
1126a65d3064SKris Buschelman     break;
1127512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1128512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1129a65d3064SKris Buschelman     break;
1130a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11314e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1132a65d3064SKris Buschelman     break;
1133a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11344e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1135a65d3064SKris Buschelman     break;
113628b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
113728b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
113828b2fa4aSMatthew Knepley     break;
1139a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11404e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11410df259c2SBarry Smith     break;
11423d472b54SHong Zhang   case MAT_SPD:
1143b1646e73SJed Brown   case MAT_SYMMETRIC:
1144b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1145b1646e73SJed Brown   case MAT_HERMITIAN:
1146b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1147957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
11485021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11495021d80fSJed Brown     break;
11504e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1151a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1152a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1153290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1154a65d3064SKris Buschelman     break;
1155b87ac2d8SJed Brown   case MAT_USE_INODES:
1156b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1157b87ac2d8SJed Brown     break;
1158c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1159c10200c1SHong Zhang     A->submat_singleis = flg;
1160c10200c1SHong Zhang     break;
1161a65d3064SKris Buschelman   default:
1162e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1163a65d3064SKris Buschelman   }
11644108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11653a40ed3dSBarry Smith   PetscFunctionReturn(0);
116617ab2063SBarry Smith }
116717ab2063SBarry Smith 
1168dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
116917ab2063SBarry Smith {
1170416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11716849ba73SBarry Smith   PetscErrorCode ierr;
1172d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
117335e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
117417ab2063SBarry Smith 
11753a40ed3dSBarry Smith   PetscFunctionBegin;
1176d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1177e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
117835e7444dSHong Zhang 
1179d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1180d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
118135e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11822c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
118335e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
118435e7444dSHong Zhang     PetscFunctionReturn(0);
118535e7444dSHong Zhang   }
118635e7444dSHong Zhang 
11872dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11881ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
118935e7444dSHong Zhang   for (i=0; i<n; i++) {
119035e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11912f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
119235e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
119335e7444dSHong Zhang       if (aj[j] == i) {
119435e7444dSHong Zhang         x[i] = aa[j];
119517ab2063SBarry Smith         break;
119617ab2063SBarry Smith       }
119717ab2063SBarry Smith     }
119817ab2063SBarry Smith   }
11991ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
120117ab2063SBarry Smith }
120217ab2063SBarry Smith 
1203c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1204dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
120517ab2063SBarry Smith {
1206416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1207d9ca1df4SBarry Smith   PetscScalar       *y;
1208d9ca1df4SBarry Smith   const PetscScalar *x;
1209dfbe8321SBarry Smith   PetscErrorCode    ierr;
1210d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
12115c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1212d9ca1df4SBarry Smith   const MatScalar   *v;
1213a77337e4SBarry Smith   PetscScalar       alpha;
1214d9ca1df4SBarry Smith   PetscInt          n,i,j;
1215d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
12163447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1217ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
12185c897100SBarry Smith #endif
121917ab2063SBarry Smith 
12203a40ed3dSBarry Smith   PetscFunctionBegin;
12212e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1222d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12245c897100SBarry Smith 
12255c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1226bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12275c897100SBarry Smith #else
12283447b6efSHong Zhang   if (usecprow) {
12293447b6efSHong Zhang     m    = cprow.nrows;
12303447b6efSHong Zhang     ii   = cprow.i;
12317b2bb3b9SHong Zhang     ridx = cprow.rindex;
12323447b6efSHong Zhang   } else {
12333447b6efSHong Zhang     ii = a->i;
12343447b6efSHong Zhang   }
123517ab2063SBarry Smith   for (i=0; i<m; i++) {
12363447b6efSHong Zhang     idx = a->j + ii[i];
12373447b6efSHong Zhang     v   = a->a + ii[i];
12383447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12393447b6efSHong Zhang     if (usecprow) {
12407b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12413447b6efSHong Zhang     } else {
124217ab2063SBarry Smith       alpha = x[i];
12433447b6efSHong Zhang     }
124404fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
124517ab2063SBarry Smith   }
12465c897100SBarry Smith #endif
1247dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1248d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12491ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
125117ab2063SBarry Smith }
125217ab2063SBarry Smith 
1253dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12545c897100SBarry Smith {
1255dfbe8321SBarry Smith   PetscErrorCode ierr;
12565c897100SBarry Smith 
12575c897100SBarry Smith   PetscFunctionBegin;
1258170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12595c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12605c897100SBarry Smith   PetscFunctionReturn(0);
12615c897100SBarry Smith }
12625c897100SBarry Smith 
1263c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
126478b84d54SShri Abhyankar 
1265dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
126617ab2063SBarry Smith {
1267416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1268d9fead3dSBarry Smith   PetscScalar       *y;
126954f21887SBarry Smith   const PetscScalar *x;
127054f21887SBarry Smith   const MatScalar   *aa;
1271dfbe8321SBarry Smith   PetscErrorCode    ierr;
1272003131ecSBarry Smith   PetscInt          m=A->rmap->n;
12730298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12747b083b7cSBarry Smith   PetscInt          n,i;
1275362ced78SSatish Balay   PetscScalar       sum;
1276ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
127717ab2063SBarry Smith 
1278b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
127997952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1280fee21e36SBarry Smith #endif
1281fee21e36SBarry Smith 
12823a40ed3dSBarry Smith   PetscFunctionBegin;
12833649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1285416022c9SBarry Smith   ii   = a->i;
12864eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
12874f390cb1SBarry Smith     ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr);
128897952fefSHong Zhang     m    = a->compressedrow.nrows;
128997952fefSHong Zhang     ii   = a->compressedrow.i;
129097952fefSHong Zhang     ridx = a->compressedrow.rindex;
129197952fefSHong Zhang     for (i=0; i<m; i++) {
129297952fefSHong Zhang       n           = ii[i+1] - ii[i];
129397952fefSHong Zhang       aj          = a->j + ii[i];
129497952fefSHong Zhang       aa          = a->a + ii[i];
129597952fefSHong Zhang       sum         = 0.0;
1296003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1297003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
129897952fefSHong Zhang       y[*ridx++] = sum;
129997952fefSHong Zhang     }
130097952fefSHong Zhang   } else { /* do not use compressed row format */
1301b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
13023d3eaba7SBarry Smith     aj   = a->j;
13033d3eaba7SBarry Smith     aa   = a->a;
1304b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1305b05257ddSBarry Smith #else
130617ab2063SBarry Smith     for (i=0; i<m; i++) {
1307003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1308003131ecSBarry Smith       aj          = a->j + ii[i];
1309003131ecSBarry Smith       aa          = a->a + ii[i];
131017ab2063SBarry Smith       sum         = 0.0;
1311003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
131217ab2063SBarry Smith       y[i] = sum;
131317ab2063SBarry Smith     }
13148d195f9aSBarry Smith #endif
1315b05257ddSBarry Smith   }
13167b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13173649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13181ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13193a40ed3dSBarry Smith   PetscFunctionReturn(0);
132017ab2063SBarry Smith }
132117ab2063SBarry Smith 
1322b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1323b434eb95SMatthew G. Knepley {
1324b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1325b434eb95SMatthew G. Knepley   PetscScalar       *y;
1326b434eb95SMatthew G. Knepley   const PetscScalar *x;
1327b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1328b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1329b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1330b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1331b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1332b434eb95SMatthew G. Knepley   PetscScalar       sum;
1333b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1334b434eb95SMatthew G. Knepley 
1335b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1336b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1337b434eb95SMatthew G. Knepley #endif
1338b434eb95SMatthew G. Knepley 
1339b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1340b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1341b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1342b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1343b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1344b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1345b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1346b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1347b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1348b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1349b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1350b434eb95SMatthew G. Knepley       sum         = 0.0;
1351b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1352b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1353b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1354b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1355b434eb95SMatthew G. Knepley     }
1356b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
13573d3eaba7SBarry Smith     ii = a->i;
1358b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1359b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1360b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1361b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1362b434eb95SMatthew G. Knepley       sum         = 0.0;
1363b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1364b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1365b434eb95SMatthew G. Knepley       y[i] = sum;
1366b434eb95SMatthew G. Knepley     }
1367b434eb95SMatthew G. Knepley   }
1368b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1369b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1370b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1371b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1372b434eb95SMatthew G. Knepley }
1373b434eb95SMatthew G. Knepley 
1374b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1375b434eb95SMatthew G. Knepley {
1376b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1377b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1378b434eb95SMatthew G. Knepley   const PetscScalar *x;
1379b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1380b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1381b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1382b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1383b434eb95SMatthew G. Knepley   PetscScalar       sum;
1384b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1385b434eb95SMatthew G. Knepley 
1386b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1387b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1388d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1389b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1390b434eb95SMatthew G. Knepley     if (zz != yy) {
1391b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1392b434eb95SMatthew G. Knepley     }
1393b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1394b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1395b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1396b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1397b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1398b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1399b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1400b434eb95SMatthew G. Knepley       sum = y[*ridx];
1401b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1402b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1403b434eb95SMatthew G. Knepley     }
1404b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
14053d3eaba7SBarry Smith     ii = a->i;
1406b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1407b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1408b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1409b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1410b434eb95SMatthew G. Knepley       sum = y[i];
1411b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1412b434eb95SMatthew G. Knepley       z[i] = sum;
1413b434eb95SMatthew G. Knepley     }
1414b434eb95SMatthew G. Knepley   }
1415b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1416b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1417d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1418b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1419b434eb95SMatthew G. Knepley }
1420b434eb95SMatthew G. Knepley 
1421c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1422dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
142317ab2063SBarry Smith {
1424416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1425f15663dcSBarry Smith   PetscScalar       *y,*z;
1426f15663dcSBarry Smith   const PetscScalar *x;
142754f21887SBarry Smith   const MatScalar   *aa;
1428dfbe8321SBarry Smith   PetscErrorCode    ierr;
1429d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1430d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1431362ced78SSatish Balay   PetscScalar       sum;
1432ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14339ea0dfa2SSatish Balay 
14343a40ed3dSBarry Smith   PetscFunctionBegin;
1435f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1436d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14374eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
14384eb6d288SHong Zhang     if (zz != yy) {
14394eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
14404eb6d288SHong Zhang     }
144197952fefSHong Zhang     m    = a->compressedrow.nrows;
144297952fefSHong Zhang     ii   = a->compressedrow.i;
144397952fefSHong Zhang     ridx = a->compressedrow.rindex;
144497952fefSHong Zhang     for (i=0; i<m; i++) {
144597952fefSHong Zhang       n   = ii[i+1] - ii[i];
144697952fefSHong Zhang       aj  = a->j + ii[i];
144797952fefSHong Zhang       aa  = a->a + ii[i];
144897952fefSHong Zhang       sum = y[*ridx];
1449f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
145097952fefSHong Zhang       z[*ridx++] = sum;
145197952fefSHong Zhang     }
145297952fefSHong Zhang   } else { /* do not use compressed row format */
14533d3eaba7SBarry Smith     ii = a->i;
1454f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
14553d3eaba7SBarry Smith     aj = a->j;
14563d3eaba7SBarry Smith     aa = a->a;
1457f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1458f15663dcSBarry Smith #else
145917ab2063SBarry Smith     for (i=0; i<m; i++) {
1460f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1461f15663dcSBarry Smith       aj  = a->j + ii[i];
1462f15663dcSBarry Smith       aa  = a->a + ii[i];
146317ab2063SBarry Smith       sum = y[i];
1464f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
146517ab2063SBarry Smith       z[i] = sum;
146617ab2063SBarry Smith     }
146702ab625aSSatish Balay #endif
1468f15663dcSBarry Smith   }
1469dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1470f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1471d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
14728154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
14736b375ea7SVictor Minden   /*
1474918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1475918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1476918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
14776b375ea7SVictor Minden   */
1478918e98c3SVictor Minden #endif
14793a40ed3dSBarry Smith   PetscFunctionReturn(0);
148017ab2063SBarry Smith }
148117ab2063SBarry Smith 
148217ab2063SBarry Smith /*
148317ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
148417ab2063SBarry Smith */
1485dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
148617ab2063SBarry Smith {
1487416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
14886849ba73SBarry Smith   PetscErrorCode ierr;
1489d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
149017ab2063SBarry Smith 
14913a40ed3dSBarry Smith   PetscFunctionBegin;
149209f38230SBarry Smith   if (!a->diag) {
1493785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
14943bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
149509f38230SBarry Smith   }
1496d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
149709f38230SBarry Smith     a->diag[i] = a->i[i+1];
1498bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1499bfeeae90SHong Zhang       if (a->j[j] == i) {
150009f38230SBarry Smith         a->diag[i] = j;
150117ab2063SBarry Smith         break;
150217ab2063SBarry Smith       }
150317ab2063SBarry Smith     }
150417ab2063SBarry Smith   }
15053a40ed3dSBarry Smith   PetscFunctionReturn(0);
150617ab2063SBarry Smith }
150717ab2063SBarry Smith 
1508be5855fcSBarry Smith /*
1509be5855fcSBarry Smith      Checks for missing diagonals
1510be5855fcSBarry Smith */
1511ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1512be5855fcSBarry Smith {
1513be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
15147734d3b5SMatthew G. Knepley   PetscInt   *diag,*ii = a->i,i;
1515be5855fcSBarry Smith 
1516be5855fcSBarry Smith   PetscFunctionBegin;
151709f38230SBarry Smith   *missing = PETSC_FALSE;
15187734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
151909f38230SBarry Smith     *missing = PETSC_TRUE;
152009f38230SBarry Smith     if (d) *d = 0;
1521955c1f14SBarry Smith     PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");
152209f38230SBarry Smith   } else {
1523f1e2ffcdSBarry Smith     diag = a->diag;
1524d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
15257734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
152609f38230SBarry Smith         *missing = PETSC_TRUE;
152709f38230SBarry Smith         if (d) *d = i;
1528955c1f14SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);
1529358d2f5dSShri Abhyankar         break;
153009f38230SBarry Smith       }
1531be5855fcSBarry Smith     }
1532be5855fcSBarry Smith   }
1533be5855fcSBarry Smith   PetscFunctionReturn(0);
1534be5855fcSBarry Smith }
1535be5855fcSBarry Smith 
1536422a814eSBarry Smith /*
1537422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1538422a814eSBarry Smith */
15397087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
154071f1c65dSBarry Smith {
154171f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
154271f1c65dSBarry Smith   PetscErrorCode ierr;
1543d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
154454f21887SBarry Smith   MatScalar      *v = a->a;
154554f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
154671f1c65dSBarry Smith 
154771f1c65dSBarry Smith   PetscFunctionBegin;
154871f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
154971f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
155071f1c65dSBarry Smith   diag = a->diag;
155171f1c65dSBarry Smith   if (!a->idiag) {
1552dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
15533bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
155471f1c65dSBarry Smith     v    = a->a;
155571f1c65dSBarry Smith   }
155671f1c65dSBarry Smith   mdiag = a->mdiag;
155771f1c65dSBarry Smith   idiag = a->idiag;
155871f1c65dSBarry Smith 
1559422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
156071f1c65dSBarry Smith     for (i=0; i<m; i++) {
156171f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1562899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1563899639b0SHong Zhang         if (PetscRealPart(fshift)) {
1564899639b0SHong Zhang           ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr);
15657b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
15667b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
15677b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
15687b6c816cSBarry Smith         } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
1569899639b0SHong Zhang       }
157071f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
157171f1c65dSBarry Smith     }
157271f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
157371f1c65dSBarry Smith   } else {
157471f1c65dSBarry Smith     for (i=0; i<m; i++) {
157571f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
157671f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
157771f1c65dSBarry Smith     }
1578dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
157971f1c65dSBarry Smith   }
158071f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
158171f1c65dSBarry Smith   PetscFunctionReturn(0);
158271f1c65dSBarry Smith }
158371f1c65dSBarry Smith 
1584c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
158541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
158617ab2063SBarry Smith {
1587416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1588e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
15893d3eaba7SBarry Smith   const MatScalar   *v,*idiag=0,*mdiag;
159054f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1591dfbe8321SBarry Smith   PetscErrorCode    ierr;
15923d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
159397f1f81fSBarry Smith   const PetscInt    *idx,*diag;
159417ab2063SBarry Smith 
15953a40ed3dSBarry Smith   PetscFunctionBegin;
1596b965ef7fSBarry Smith   its = its*lits;
159791723122SBarry Smith 
159871f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
159971f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
160071f1c65dSBarry Smith   a->fshift = fshift;
160171f1c65dSBarry Smith   a->omega  = omega;
1602ed480e8bSBarry Smith 
160371f1c65dSBarry Smith   diag  = a->diag;
160471f1c65dSBarry Smith   t     = a->ssor_work;
1605ed480e8bSBarry Smith   idiag = a->idiag;
160671f1c65dSBarry Smith   mdiag = a->mdiag;
1607ed480e8bSBarry Smith 
16081ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16093649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1610ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
161117ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
161217ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1613ed480e8bSBarry Smith     bs = b;
161417ab2063SBarry Smith     for (i=0; i<m; i++) {
161571f1c65dSBarry Smith       d   = fshift + mdiag[i];
1616416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1617ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1618ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
161917ab2063SBarry Smith       sum = b[i]*d/omega;
1620003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
162117ab2063SBarry Smith       x[i] = sum;
162217ab2063SBarry Smith     }
16231ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16243649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1625efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16263a40ed3dSBarry Smith     PetscFunctionReturn(0);
162717ab2063SBarry Smith   }
1628c783ea89SBarry Smith 
16292205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16302205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
163117ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1632887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
163317ab2063SBarry Smith 
163417ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
163517ab2063SBarry Smith 
1636887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
163717ab2063SBarry Smith     */
163817ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
163917ab2063SBarry Smith 
164017ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
164117ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1642416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1643ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1644ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
164517ab2063SBarry Smith       sum = b[i];
1646e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1647ed480e8bSBarry Smith       x[i] = sum*idiag[i];
164817ab2063SBarry Smith     }
164917ab2063SBarry Smith 
165017ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1651416022c9SBarry Smith     v = a->a;
16522205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
165317ab2063SBarry Smith 
165417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1655ed480e8bSBarry Smith     ts   = t;
1656416022c9SBarry Smith     diag = a->diag;
165717ab2063SBarry Smith     for (i=0; i<m; i++) {
1658416022c9SBarry Smith       n   = diag[i] - a->i[i];
1659ed480e8bSBarry Smith       idx = a->j + a->i[i];
1660ed480e8bSBarry Smith       v   = a->a + a->i[i];
166117ab2063SBarry Smith       sum = t[i];
1662003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1663ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1664733d66baSBarry Smith       /*  x = x + t */
1665733d66baSBarry Smith       x[i] += t[i];
166617ab2063SBarry Smith     }
166717ab2063SBarry Smith 
1668dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
16691ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16703649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
16713a40ed3dSBarry Smith     PetscFunctionReturn(0);
167217ab2063SBarry Smith   }
167317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
167417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
167517ab2063SBarry Smith       for (i=0; i<m; i++) {
1676416022c9SBarry Smith         n   = diag[i] - a->i[i];
1677ed480e8bSBarry Smith         idx = a->j + a->i[i];
1678ed480e8bSBarry Smith         v   = a->a + a->i[i];
167917ab2063SBarry Smith         sum = b[i];
1680e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16815c99c7daSBarry Smith         t[i] = sum;
1682ed480e8bSBarry Smith         x[i] = sum*idiag[i];
168317ab2063SBarry Smith       }
16845c99c7daSBarry Smith       xb   = t;
1685efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16863a40ed3dSBarry Smith     } else xb = b;
168717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
168817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1689416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1690ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1691ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
169217ab2063SBarry Smith         sum = xb[i];
1693e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
16945c99c7daSBarry Smith         if (xb == b) {
1695ed480e8bSBarry Smith           x[i] = sum*idiag[i];
16965c99c7daSBarry Smith         } else {
1697b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
169817ab2063SBarry Smith         }
16995c99c7daSBarry Smith       }
1700b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
170117ab2063SBarry Smith     }
170217ab2063SBarry Smith     its--;
170317ab2063SBarry Smith   }
170417ab2063SBarry Smith   while (its--) {
170517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
170617ab2063SBarry Smith       for (i=0; i<m; i++) {
1707b19a5dc2SMark Adams         /* lower */
1708b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1709ed480e8bSBarry Smith         idx = a->j + a->i[i];
1710ed480e8bSBarry Smith         v   = a->a + a->i[i];
171117ab2063SBarry Smith         sum = b[i];
1712e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1713b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1714b19a5dc2SMark Adams         /* upper */
1715b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1716b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1717b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1718b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1719b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
172017ab2063SBarry Smith       }
1721b19a5dc2SMark Adams       xb   = t;
17229f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1723b19a5dc2SMark Adams     } else xb = b;
172417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
172517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1726b19a5dc2SMark Adams         sum = xb[i];
1727b19a5dc2SMark Adams         if (xb == b) {
1728b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1729416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1730ed480e8bSBarry Smith           idx = a->j + a->i[i];
1731ed480e8bSBarry Smith           v   = a->a + a->i[i];
1732e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1733ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1734b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1735b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1736b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1737b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1738b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1739b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
174017ab2063SBarry Smith         }
1741b19a5dc2SMark Adams       }
1742b19a5dc2SMark Adams       if (xb == b) {
17439f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1744b19a5dc2SMark Adams       } else {
1745b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1746b19a5dc2SMark Adams       }
174717ab2063SBarry Smith     }
174817ab2063SBarry Smith   }
17491ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17503649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1751365a8a9eSBarry Smith   PetscFunctionReturn(0);
175217ab2063SBarry Smith }
175317ab2063SBarry Smith 
17542af78befSBarry Smith 
1755dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
175617ab2063SBarry Smith {
1757416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
17584e220ebcSLois Curfman McInnes 
17593a40ed3dSBarry Smith   PetscFunctionBegin;
17604e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
17614e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
17624e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
17634e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
17644e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
17658e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
17667adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1767d5f3da31SBarry Smith   if (A->factortype) {
17684e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
17694e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
17704e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
17714e220ebcSLois Curfman McInnes   } else {
17724e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
17734e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
17744e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
17754e220ebcSLois Curfman McInnes   }
17763a40ed3dSBarry Smith   PetscFunctionReturn(0);
177717ab2063SBarry Smith }
177817ab2063SBarry Smith 
17792b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
178017ab2063SBarry Smith {
1781416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1782c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
17836849ba73SBarry Smith   PetscErrorCode    ierr;
178497b48c8fSBarry Smith   const PetscScalar *xx;
178597b48c8fSBarry Smith   PetscScalar       *bb;
1786c7da8527SEric Chamberland   PetscInt          d = 0;
178717ab2063SBarry Smith 
17883a40ed3dSBarry Smith   PetscFunctionBegin;
178997b48c8fSBarry Smith   if (x && b) {
179097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
179197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
179297b48c8fSBarry Smith     for (i=0; i<N; i++) {
179397b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
179497b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
179597b48c8fSBarry Smith     }
179697b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
179797b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
179897b48c8fSBarry Smith   }
179997b48c8fSBarry Smith 
1800a9817697SBarry Smith   if (a->keepnonzeropattern) {
1801f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1802e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1803bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1804f1e2ffcdSBarry Smith     }
1805f4df32b1SMatthew Knepley     if (diag != 0.0) {
1806c7da8527SEric Chamberland       for (i=0; i<N; i++) {
1807c7da8527SEric Chamberland         d = rows[i];
1808c7da8527SEric Chamberland         if (a->diag[d] >= a->i[d+1]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %D",d);
1809c7da8527SEric Chamberland       }
1810f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1811f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1812f1e2ffcdSBarry Smith       }
1813f1e2ffcdSBarry Smith     }
1814f1e2ffcdSBarry Smith   } else {
1815f4df32b1SMatthew Knepley     if (diag != 0.0) {
181617ab2063SBarry Smith       for (i=0; i<N; i++) {
1817e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18187ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1819416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1820f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1821bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18227ae801bdSBarry Smith         } else { /* in case row was completely empty */
1823f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
182417ab2063SBarry Smith         }
182517ab2063SBarry Smith       }
18263a40ed3dSBarry Smith     } else {
182717ab2063SBarry Smith       for (i=0; i<N; i++) {
1828e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1829416022c9SBarry Smith         a->ilen[rows[i]] = 0;
183017ab2063SBarry Smith       }
183117ab2063SBarry Smith     }
1832e56f5c9eSBarry Smith     A->nonzerostate++;
1833f1e2ffcdSBarry Smith   }
183443a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18353a40ed3dSBarry Smith   PetscFunctionReturn(0);
183617ab2063SBarry Smith }
183717ab2063SBarry Smith 
18386e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18396e169961SBarry Smith {
18406e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18416e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
18426e169961SBarry Smith   PetscErrorCode    ierr;
18432b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
18446e169961SBarry Smith   const PetscScalar *xx;
18456e169961SBarry Smith   PetscScalar       *bb;
18466e169961SBarry Smith 
18476e169961SBarry Smith   PetscFunctionBegin;
18486e169961SBarry Smith   if (x && b) {
18496e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
18506e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
18512b40b63fSBarry Smith     vecs = PETSC_TRUE;
18526e169961SBarry Smith   }
18531795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
18546e169961SBarry Smith   for (i=0; i<N; i++) {
18556e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18566e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
18572205254eSKarl Rupp 
18586e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
18596e169961SBarry Smith   }
18606e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
18616e169961SBarry Smith     if (!zeroed[i]) {
18626e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
18636e169961SBarry Smith         if (zeroed[a->j[j]]) {
18642b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
18656e169961SBarry Smith           a->a[j] = 0.0;
18666e169961SBarry Smith         }
18676e169961SBarry Smith       }
18682b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
18696e169961SBarry Smith   }
18706e169961SBarry Smith   if (x && b) {
18716e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
18726e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
18736e169961SBarry Smith   }
18746e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
18756e169961SBarry Smith   if (diag != 0.0) {
18766e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
18771d5a398dSstefano_zampini     if (missing) {
18781d5a398dSstefano_zampini       if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
18791d5a398dSstefano_zampini       else {
18801d5a398dSstefano_zampini         for (i=0; i<N; i++) {
18811d5a398dSstefano_zampini           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
18821d5a398dSstefano_zampini         }
18831d5a398dSstefano_zampini       }
18841d5a398dSstefano_zampini     } else {
18856e169961SBarry Smith       for (i=0; i<N; i++) {
18866e169961SBarry Smith         a->a[a->diag[rows[i]]] = diag;
18876e169961SBarry Smith       }
18886e169961SBarry Smith     }
18891d5a398dSstefano_zampini   }
18906e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18916e169961SBarry Smith   PetscFunctionReturn(0);
18926e169961SBarry Smith }
18936e169961SBarry Smith 
1894a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
189517ab2063SBarry Smith {
1896416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
189797f1f81fSBarry Smith   PetscInt   *itmp;
189817ab2063SBarry Smith 
18993a40ed3dSBarry Smith   PetscFunctionBegin;
1900e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
190117ab2063SBarry Smith 
1902416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1903bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
190417ab2063SBarry Smith   if (idx) {
1905bfeeae90SHong Zhang     itmp = a->j + a->i[row];
190626fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
190717ab2063SBarry Smith     else *idx = 0;
190817ab2063SBarry Smith   }
19093a40ed3dSBarry Smith   PetscFunctionReturn(0);
191017ab2063SBarry Smith }
191117ab2063SBarry Smith 
1912bfeeae90SHong Zhang /* remove this function? */
1913a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
191417ab2063SBarry Smith {
19153a40ed3dSBarry Smith   PetscFunctionBegin;
19163a40ed3dSBarry Smith   PetscFunctionReturn(0);
191717ab2063SBarry Smith }
191817ab2063SBarry Smith 
1919dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
192017ab2063SBarry Smith {
1921416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
192254f21887SBarry Smith   MatScalar      *v  = a->a;
192336db0b34SBarry Smith   PetscReal      sum = 0.0;
19246849ba73SBarry Smith   PetscErrorCode ierr;
192597f1f81fSBarry Smith   PetscInt       i,j;
192617ab2063SBarry Smith 
19273a40ed3dSBarry Smith   PetscFunctionBegin;
192817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1929570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1930570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
1931570b7f6dSBarry Smith     *nrm = BLASnrm2_(&nz,v,&one);
1932570b7f6dSBarry Smith #else
1933416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
193436db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
193517ab2063SBarry Smith     }
19368f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1937570b7f6dSBarry Smith #endif
193851f70360SJed Brown     ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr);
19393a40ed3dSBarry Smith   } else if (type == NORM_1) {
194036db0b34SBarry Smith     PetscReal *tmp;
194197f1f81fSBarry Smith     PetscInt  *jj = a->j;
19421795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
1943064f8208SBarry Smith     *nrm = 0.0;
1944416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1945bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
194617ab2063SBarry Smith     }
1947d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1948064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
194917ab2063SBarry Smith     }
1950606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
195151f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
19523a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1953064f8208SBarry Smith     *nrm = 0.0;
1954d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1955bfeeae90SHong Zhang       v   = a->a + a->i[j];
195617ab2063SBarry Smith       sum = 0.0;
1957416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1958cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
195917ab2063SBarry Smith       }
1960064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
196117ab2063SBarry Smith     }
196251f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
1963f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
19643a40ed3dSBarry Smith   PetscFunctionReturn(0);
196517ab2063SBarry Smith }
196617ab2063SBarry Smith 
19674e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
19684e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
19694e938277SHong Zhang {
19704e938277SHong Zhang   PetscErrorCode ierr;
19714e938277SHong Zhang   PetscInt       i,j,anzj;
19724e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
19734e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
19744e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
19754e938277SHong Zhang 
19764e938277SHong Zhang   PetscFunctionBegin;
19774e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
1978854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
1979785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
1980785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
19814e938277SHong Zhang 
19824e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
19834e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
198426fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
19854e938277SHong Zhang   /* Form ati for csr format of A^T. */
198626fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
19874e938277SHong Zhang 
19884e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
19894e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
19904e938277SHong Zhang 
19914e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
19924e938277SHong Zhang   for (i=0;i<am;i++) {
19934e938277SHong Zhang     anzj = ai[i+1] - ai[i];
19944e938277SHong Zhang     for (j=0;j<anzj;j++) {
19954e938277SHong Zhang       atj[atfill[*aj]] = i;
19964e938277SHong Zhang       atfill[*aj++]   += 1;
19974e938277SHong Zhang     }
19984e938277SHong Zhang   }
19994e938277SHong Zhang 
20004e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20014e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2002ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
200333d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
2004a2f3521dSMark F. Adams 
20054e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20064e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20074e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20084e938277SHong Zhang   b->nonew   = 0;
20094e938277SHong Zhang   PetscFunctionReturn(0);
20104e938277SHong Zhang }
20114e938277SHong Zhang 
2012fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
201317ab2063SBarry Smith {
2014416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2015416022c9SBarry Smith   Mat            C;
20166849ba73SBarry Smith   PetscErrorCode ierr;
2017d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
201854f21887SBarry Smith   MatScalar      *array = a->a;
201917ab2063SBarry Smith 
20203a40ed3dSBarry Smith   PetscFunctionBegin;
2021cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2022fc4dec0aSBarry Smith 
2023cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) {
2024854ce69bSBarry Smith     ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr);
2025bfeeae90SHong Zhang 
2026bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2027ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2028d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
202933d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
20307adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2031ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2032606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2033a541d17aSBarry Smith   } else {
2034a541d17aSBarry Smith     C = *B;
2035a541d17aSBarry Smith   }
2036a541d17aSBarry Smith 
203717ab2063SBarry Smith   for (i=0; i<m; i++) {
203817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
203987d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2040b9b97703SBarry Smith     array += len;
2041b9b97703SBarry Smith     aj    += len;
204217ab2063SBarry Smith   }
20436d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20446d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
204517ab2063SBarry Smith 
2046cf37664fSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) {
2047416022c9SBarry Smith     *B = C;
204817ab2063SBarry Smith   } else {
204928be2f97SBarry Smith     ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr);
205017ab2063SBarry Smith   }
20513a40ed3dSBarry Smith   PetscFunctionReturn(0);
205217ab2063SBarry Smith }
205317ab2063SBarry Smith 
20547087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2055cd0d46ebSvictorle {
20563d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
205754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
205854f21887SBarry Smith   MatScalar      *va,*vb;
20596849ba73SBarry Smith   PetscErrorCode ierr;
206097f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2061cd0d46ebSvictorle 
2062cd0d46ebSvictorle   PetscFunctionBegin;
2063cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2064cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
20655485867bSBarry Smith   if (ma!=nb || na!=mb) {
20665485867bSBarry Smith     *f = PETSC_FALSE;
20675485867bSBarry Smith     PetscFunctionReturn(0);
20685485867bSBarry Smith   }
2069cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2070cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2071cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2072785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2073785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2074cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2075cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2076cd0d46ebSvictorle 
2077cd0d46ebSvictorle   *f = PETSC_TRUE;
2078cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2079cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
208097f1f81fSBarry Smith       PetscInt    idc,idr;
20815485867bSBarry Smith       PetscScalar vc,vr;
2082cd0d46ebSvictorle       /* column/row index/value */
20835485867bSBarry Smith       idc = adx[aptr[i]];
20845485867bSBarry Smith       idr = bdx[bptr[idc]];
20855485867bSBarry Smith       vc  = va[aptr[i]];
20865485867bSBarry Smith       vr  = vb[bptr[idc]];
20875485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
20885485867bSBarry Smith         *f = PETSC_FALSE;
20895485867bSBarry Smith         goto done;
2090cd0d46ebSvictorle       } else {
20915485867bSBarry Smith         aptr[i]++;
20925485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2093cd0d46ebSvictorle       }
2094cd0d46ebSvictorle     }
2095cd0d46ebSvictorle   }
2096cd0d46ebSvictorle done:
2097cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
20983aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2099cd0d46ebSvictorle   PetscFunctionReturn(0);
2100cd0d46ebSvictorle }
2101cd0d46ebSvictorle 
21027087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21031cbb95d3SBarry Smith {
21043d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
210554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
210654f21887SBarry Smith   MatScalar      *va,*vb;
21071cbb95d3SBarry Smith   PetscErrorCode ierr;
21081cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21091cbb95d3SBarry Smith 
21101cbb95d3SBarry Smith   PetscFunctionBegin;
21111cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21121cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21131cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21141cbb95d3SBarry Smith     *f = PETSC_FALSE;
21151cbb95d3SBarry Smith     PetscFunctionReturn(0);
21161cbb95d3SBarry Smith   }
21171cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
21181cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
21191cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2120785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2121785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
21221cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
21231cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
21241cbb95d3SBarry Smith 
21251cbb95d3SBarry Smith   *f = PETSC_TRUE;
21261cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
21271cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21281cbb95d3SBarry Smith       PetscInt    idc,idr;
21291cbb95d3SBarry Smith       PetscScalar vc,vr;
21301cbb95d3SBarry Smith       /* column/row index/value */
21311cbb95d3SBarry Smith       idc = adx[aptr[i]];
21321cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
21331cbb95d3SBarry Smith       vc  = va[aptr[i]];
21341cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
21351cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
21361cbb95d3SBarry Smith         *f = PETSC_FALSE;
21371cbb95d3SBarry Smith         goto done;
21381cbb95d3SBarry Smith       } else {
21391cbb95d3SBarry Smith         aptr[i]++;
21401cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
21411cbb95d3SBarry Smith       }
21421cbb95d3SBarry Smith     }
21431cbb95d3SBarry Smith   }
21441cbb95d3SBarry Smith done:
21451cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
21461cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
21471cbb95d3SBarry Smith   PetscFunctionReturn(0);
21481cbb95d3SBarry Smith }
21491cbb95d3SBarry Smith 
2150ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21519e29f15eSvictorle {
2152dfbe8321SBarry Smith   PetscErrorCode ierr;
21536e111a19SKarl Rupp 
21549e29f15eSvictorle   PetscFunctionBegin;
21555485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21569e29f15eSvictorle   PetscFunctionReturn(0);
21579e29f15eSvictorle }
21589e29f15eSvictorle 
2159ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
21601cbb95d3SBarry Smith {
21611cbb95d3SBarry Smith   PetscErrorCode ierr;
21626e111a19SKarl Rupp 
21631cbb95d3SBarry Smith   PetscFunctionBegin;
21641cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
21651cbb95d3SBarry Smith   PetscFunctionReturn(0);
21661cbb95d3SBarry Smith }
21671cbb95d3SBarry Smith 
2168dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
216917ab2063SBarry Smith {
2170416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
2171*fff8e43fSBarry Smith   const PetscScalar *l,*r;
2172*fff8e43fSBarry Smith   PetscScalar       x;
217354f21887SBarry Smith   MatScalar         *v;
2174dfbe8321SBarry Smith   PetscErrorCode    ierr;
2175*fff8e43fSBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz;
2176*fff8e43fSBarry Smith   const PetscInt    *jj;
217717ab2063SBarry Smith 
21783a40ed3dSBarry Smith   PetscFunctionBegin;
217917ab2063SBarry Smith   if (ll) {
21803ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
21813ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2182e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2183e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
2184*fff8e43fSBarry Smith     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
2185416022c9SBarry Smith     v    = a->a;
218617ab2063SBarry Smith     for (i=0; i<m; i++) {
218717ab2063SBarry Smith       x = l[i];
2188416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
21892205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
219017ab2063SBarry Smith     }
2191*fff8e43fSBarry Smith     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
2192efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
219317ab2063SBarry Smith   }
219417ab2063SBarry Smith   if (rr) {
2195e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2196e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
2197*fff8e43fSBarry Smith     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
2198416022c9SBarry Smith     v    = a->a; jj = a->j;
21992205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
2200*fff8e43fSBarry Smith     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
2201efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
220217ab2063SBarry Smith   }
2203acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22043a40ed3dSBarry Smith   PetscFunctionReturn(0);
220517ab2063SBarry Smith }
220617ab2063SBarry Smith 
22077dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
220817ab2063SBarry Smith {
2209db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
22106849ba73SBarry Smith   PetscErrorCode ierr;
2211d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
221297f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
22135d0c19d7SBarry Smith   const PetscInt *irow,*icol;
22145d0c19d7SBarry Smith   PetscInt       nrows,ncols;
221597f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
221654f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2217416022c9SBarry Smith   Mat            C;
2218cdc6f3adSToby Isaac   PetscBool      stride;
221917ab2063SBarry Smith 
22203a40ed3dSBarry Smith   PetscFunctionBegin;
222199141d43SSatish Balay 
222217ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2223b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2224b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
222517ab2063SBarry Smith 
2226251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2227ff718158SBarry Smith   if (stride) {
2228ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2229ff718158SBarry Smith   } else {
2230ff718158SBarry Smith     first = 0;
2231ff718158SBarry Smith     step  = 0;
2232ff718158SBarry Smith   }
2233fee21e36SBarry Smith   if (stride && step == 1) {
223402834360SBarry Smith     /* special case of contiguous rows */
2235dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
223602834360SBarry Smith     /* loop over new rows determining lens and starting points */
223702834360SBarry Smith     for (i=0; i<nrows; i++) {
2238bfeeae90SHong Zhang       kstart = ai[irow[i]];
2239a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2240a91a9bebSLisandro Dalcin       starts[i] = kstart;
224102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2242bfeeae90SHong Zhang         if (aj[k] >= first) {
224302834360SBarry Smith           starts[i] = k;
224402834360SBarry Smith           break;
224502834360SBarry Smith         }
224602834360SBarry Smith       }
2247a2744918SBarry Smith       sum = 0;
224802834360SBarry Smith       while (k < kend) {
2249bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2250a2744918SBarry Smith         sum++;
225102834360SBarry Smith       }
2252a2744918SBarry Smith       lens[i] = sum;
225302834360SBarry Smith     }
225402834360SBarry Smith     /* create submatrix */
2255cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
225697f1f81fSBarry Smith       PetscInt n_cols,n_rows;
225708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2258e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2259d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
226008480c60SBarry Smith       C    = *B;
22613a40ed3dSBarry Smith     } else {
22623bef6203SJed Brown       PetscInt rbs,cbs;
2263ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2264f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
22653bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
22663bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
22673bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
22687adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2269ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
227008480c60SBarry Smith     }
2271db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2272db02288aSLois Curfman McInnes 
227302834360SBarry Smith     /* loop over rows inserting into submatrix */
2274db02288aSLois Curfman McInnes     a_new = c->a;
2275db02288aSLois Curfman McInnes     j_new = c->j;
2276db02288aSLois Curfman McInnes     i_new = c->i;
2277bfeeae90SHong Zhang 
227802834360SBarry Smith     for (i=0; i<nrows; i++) {
2279a2744918SBarry Smith       ii    = starts[i];
2280a2744918SBarry Smith       lensi = lens[i];
2281a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2282a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
228302834360SBarry Smith       }
228487828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2285a2744918SBarry Smith       a_new     += lensi;
2286a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2287a2744918SBarry Smith       c->ilen[i] = lensi;
228802834360SBarry Smith     }
22890e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
22903a40ed3dSBarry Smith   } else {
229102834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
22921795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2293854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
22944dcab191SBarry Smith     for (i=0; i<ncols; i++) {
22954dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
22964dcab191SBarry 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);
22974dcab191SBarry Smith #endif
22984dcab191SBarry Smith       smap[icol[i]] = i+1;
22994dcab191SBarry Smith     }
23004dcab191SBarry Smith 
230102834360SBarry Smith     /* determine lens of each row */
230202834360SBarry Smith     for (i=0; i<nrows; i++) {
2303bfeeae90SHong Zhang       kstart  = ai[irow[i]];
230402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
230502834360SBarry Smith       lens[i] = 0;
230602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2307bfeeae90SHong Zhang         if (smap[aj[k]]) {
230802834360SBarry Smith           lens[i]++;
230902834360SBarry Smith         }
231002834360SBarry Smith       }
231102834360SBarry Smith     }
231217ab2063SBarry Smith     /* Create and fill new matrix */
2313a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2314ace3abfcSBarry Smith       PetscBool equal;
23150f5bd95cSBarry Smith 
231699141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2317e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2318d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2319f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2320d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
232108480c60SBarry Smith       C    = *B;
23223a40ed3dSBarry Smith     } else {
23233bef6203SJed Brown       PetscInt rbs,cbs;
2324ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2325f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23263bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23273bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23283bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23297adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2330ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
233108480c60SBarry Smith     }
233299141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
233317ab2063SBarry Smith     for (i=0; i<nrows; i++) {
233499141d43SSatish Balay       row      = irow[i];
2335bfeeae90SHong Zhang       kstart   = ai[row];
233699141d43SSatish Balay       kend     = kstart + a->ilen[row];
2337bfeeae90SHong Zhang       mat_i    = c->i[i];
233899141d43SSatish Balay       mat_j    = c->j + mat_i;
233999141d43SSatish Balay       mat_a    = c->a + mat_i;
234099141d43SSatish Balay       mat_ilen = c->ilen + i;
234117ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2342bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2343ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
234499141d43SSatish Balay           *mat_a++ = a->a[k];
234599141d43SSatish Balay           (*mat_ilen)++;
234699141d43SSatish Balay 
234717ab2063SBarry Smith         }
234817ab2063SBarry Smith       }
234917ab2063SBarry Smith     }
235002834360SBarry Smith     /* Free work space */
235102834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2352606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2353606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2354cdc6f3adSToby Isaac     /* sort */
2355cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2356cdc6f3adSToby Isaac       PetscInt ilen;
2357cdc6f3adSToby Isaac 
2358cdc6f3adSToby Isaac       mat_i = c->i[i];
2359cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2360cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2361cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2362390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2363cdc6f3adSToby Isaac     }
236402834360SBarry Smith   }
23656d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23666d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
236717ab2063SBarry Smith 
236817ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2369416022c9SBarry Smith   *B   = C;
23703a40ed3dSBarry Smith   PetscFunctionReturn(0);
237117ab2063SBarry Smith }
237217ab2063SBarry Smith 
2373fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
237482d44351SHong Zhang {
237582d44351SHong Zhang   PetscErrorCode ierr;
237682d44351SHong Zhang   Mat            B;
237782d44351SHong Zhang 
237882d44351SHong Zhang   PetscFunctionBegin;
2379c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
238082d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
238182d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
238233d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
238382d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
238482d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
238582d44351SHong Zhang     *subMat = B;
2386c2d650bdSHong Zhang   } else {
2387c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2388c2d650bdSHong Zhang   }
238982d44351SHong Zhang   PetscFunctionReturn(0);
239082d44351SHong Zhang }
239182d44351SHong Zhang 
23929a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2393a871dcd8SBarry Smith {
239463b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2395dfbe8321SBarry Smith   PetscErrorCode ierr;
239663b91edcSBarry Smith   Mat            outA;
2397ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
239863b91edcSBarry Smith 
23993a40ed3dSBarry Smith   PetscFunctionBegin;
2400e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24011df811f5SHong Zhang 
2402b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2403b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2404a871dcd8SBarry Smith 
240563b91edcSBarry Smith   outA             = inA;
2406d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2407f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2408f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
24092205254eSKarl Rupp 
2410c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24116bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24122205254eSKarl Rupp 
2413c3122656SLisandro Dalcin   a->row = row;
24142205254eSKarl Rupp 
2415c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24166bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24172205254eSKarl Rupp 
2418c3122656SLisandro Dalcin   a->col = col;
241963b91edcSBarry Smith 
242036db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
24216bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
24224c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
24233bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2424f0ec6fceSSatish Balay 
242594a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2426854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
24273bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
242894a9d846SBarry Smith   }
242963b91edcSBarry Smith 
2430f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2431137fb511SHong Zhang   if (row_identity && col_identity) {
2432ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2433137fb511SHong Zhang   } else {
2434719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2435137fb511SHong Zhang   }
24363a40ed3dSBarry Smith   PetscFunctionReturn(0);
2437a871dcd8SBarry Smith }
2438a871dcd8SBarry Smith 
2439f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2440f0b747eeSBarry Smith {
2441f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2442f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2443efee365bSSatish Balay   PetscErrorCode ierr;
2444c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
24453a40ed3dSBarry Smith 
24463a40ed3dSBarry Smith   PetscFunctionBegin;
2447c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
24488b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2449efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2450acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
24513a40ed3dSBarry Smith   PetscFunctionReturn(0);
2452f0b747eeSBarry Smith }
2453f0b747eeSBarry Smith 
24545c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj)
245516b64355SHong Zhang {
245616b64355SHong Zhang   PetscErrorCode ierr;
245716b64355SHong Zhang   PetscInt       i;
245816b64355SHong Zhang 
245916b64355SHong Zhang   PetscFunctionBegin;
246016b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
246116b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
246216b64355SHong Zhang 
246316b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
246416b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
246516b64355SHong Zhang     }
246616b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
246716b64355SHong Zhang 
246816b64355SHong Zhang     if (submatj->rbuf1) {
246916b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
247016b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
247116b64355SHong Zhang     }
247216b64355SHong Zhang 
247316b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
247416b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
247516b64355SHong Zhang     }
247616b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
247716b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
247816b64355SHong Zhang   }
247916b64355SHong Zhang 
248016b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
248116b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
248216b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
248316b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
248416b64355SHong Zhang #else
248516b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
248616b64355SHong Zhang #endif
248716b64355SHong Zhang 
248816b64355SHong Zhang   if (!submatj->allcolumns) {
248916b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
249016b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
249116b64355SHong Zhang #else
249216b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
249316b64355SHong Zhang #endif
249416b64355SHong Zhang   }
249516b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
249616b64355SHong Zhang 
249716b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
249816b64355SHong Zhang   PetscFunctionReturn(0);
249916b64355SHong Zhang }
250016b64355SHong Zhang 
250116b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C)
250216b64355SHong Zhang {
250316b64355SHong Zhang   PetscErrorCode ierr;
250416b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
25055c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
250616b64355SHong Zhang 
250716b64355SHong Zhang   PetscFunctionBegin;
250816b64355SHong Zhang   ierr = submatj->destroy(C);CHKERRQ(ierr);
2509e69d178cSHong Zhang   ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr);
251016b64355SHong Zhang   PetscFunctionReturn(0);
251116b64355SHong Zhang }
251216b64355SHong Zhang 
25137dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2514cddf8d76SBarry Smith {
2515dfbe8321SBarry Smith   PetscErrorCode ierr;
251697f1f81fSBarry Smith   PetscInt       i;
2517cddf8d76SBarry Smith 
25183a40ed3dSBarry Smith   PetscFunctionBegin;
2519cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2520df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2521cddf8d76SBarry Smith   }
2522cddf8d76SBarry Smith 
2523cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25247dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2525cddf8d76SBarry Smith   }
25263a40ed3dSBarry Smith   PetscFunctionReturn(0);
2527cddf8d76SBarry Smith }
2528cddf8d76SBarry Smith 
252997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25304dcbc457SBarry Smith {
2531e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25326849ba73SBarry Smith   PetscErrorCode ierr;
25335d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25345d0c19d7SBarry Smith   const PetscInt *idx;
253597f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2536f1af5d2fSBarry Smith   PetscBT        table;
2537bbd702dbSSatish Balay 
25383a40ed3dSBarry Smith   PetscFunctionBegin;
2539d0f46423SBarry Smith   m  = A->rmap->n;
2540e4d965acSSatish Balay   ai = a->i;
2541bfeeae90SHong Zhang   aj = a->j;
25428a047759SSatish Balay 
2543e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
254406763907SSatish Balay 
2545854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
254653b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
254706763907SSatish Balay 
2548e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2549b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2550e4d965acSSatish Balay     isz  = 0;
25516831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2552e4d965acSSatish Balay 
2553e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25544dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2555b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2556e4d965acSSatish Balay 
2557dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2558e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25592205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25604dcbc457SBarry Smith     }
256106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25626bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2563e4d965acSSatish Balay 
256404a348a9SBarry Smith     k = 0;
256504a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
256604a348a9SBarry Smith       n = isz;
256706763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2568e4d965acSSatish Balay         row   = nidx[k];
2569e4d965acSSatish Balay         start = ai[row];
2570e4d965acSSatish Balay         end   = ai[row+1];
257104a348a9SBarry Smith         for (l = start; l<end; l++) {
2572efb16452SHong Zhang           val = aj[l];
25732205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2574e4d965acSSatish Balay         }
2575e4d965acSSatish Balay       }
2576e4d965acSSatish Balay     }
257770b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2578e4d965acSSatish Balay   }
257994bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2580606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25813a40ed3dSBarry Smith   PetscFunctionReturn(0);
25824dcbc457SBarry Smith }
258317ab2063SBarry Smith 
25840513a670SBarry Smith /* -------------------------------------------------------------- */
2585dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
25860513a670SBarry Smith {
25870513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25886849ba73SBarry Smith   PetscErrorCode ierr;
25893b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
25905d0c19d7SBarry Smith   const PetscInt *row,*col;
25915d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
259256cd22aeSBarry Smith   IS             icolp,irowp;
25930298fd71SBarry Smith   PetscInt       *cwork = NULL;
25940298fd71SBarry Smith   PetscScalar    *vwork = NULL;
25950513a670SBarry Smith 
25963a40ed3dSBarry Smith   PetscFunctionBegin;
25974c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
259856cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
25994c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
260056cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26010513a670SBarry Smith 
26020513a670SBarry Smith   /* determine lengths of permuted rows */
2603854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
26042205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2605ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2606f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
260733d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
26087adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2609ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2610606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26110513a670SBarry Smith 
2612785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26130513a670SBarry Smith   for (i=0; i<m; i++) {
261432ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26152205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2616cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
261732ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26180513a670SBarry Smith   }
2619606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26202205254eSKarl Rupp 
26213c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26222205254eSKarl Rupp 
26230513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26240513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
262556cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
262656cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26276bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26286bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26293a40ed3dSBarry Smith   PetscFunctionReturn(0);
26300513a670SBarry Smith }
26310513a670SBarry Smith 
2632dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2633cb5b572fSBarry Smith {
2634dfbe8321SBarry Smith   PetscErrorCode ierr;
2635cb5b572fSBarry Smith 
2636cb5b572fSBarry Smith   PetscFunctionBegin;
263733f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
263833f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2639be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2640be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2641be6bf707SBarry Smith 
2642700c5bfcSBarry 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");
2643d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2644cb5b572fSBarry Smith   } else {
2645cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2646cb5b572fSBarry Smith   }
2647cb5b572fSBarry Smith   PetscFunctionReturn(0);
2648cb5b572fSBarry Smith }
2649cb5b572fSBarry Smith 
26504994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2651273d9f13SBarry Smith {
2652dfbe8321SBarry Smith   PetscErrorCode ierr;
2653273d9f13SBarry Smith 
2654273d9f13SBarry Smith   PetscFunctionBegin;
2655ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2656273d9f13SBarry Smith   PetscFunctionReturn(0);
2657273d9f13SBarry Smith }
2658273d9f13SBarry Smith 
26598c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26606c0721eeSBarry Smith {
26616c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26626e111a19SKarl Rupp 
26636c0721eeSBarry Smith   PetscFunctionBegin;
26646c0721eeSBarry Smith   *array = a->a;
26656c0721eeSBarry Smith   PetscFunctionReturn(0);
26666c0721eeSBarry Smith }
26676c0721eeSBarry Smith 
26688c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26696c0721eeSBarry Smith {
26706c0721eeSBarry Smith   PetscFunctionBegin;
26716c0721eeSBarry Smith   PetscFunctionReturn(0);
26726c0721eeSBarry Smith }
2673273d9f13SBarry Smith 
26748229c054SShri Abhyankar /*
26758229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
26768229c054SShri Abhyankar    have different nonzero structure.
26778229c054SShri Abhyankar */
2678b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
2679ec7775f6SShri Abhyankar {
2680b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
2681ec7775f6SShri Abhyankar 
2682ec7775f6SShri Abhyankar   PetscFunctionBegin;
2683ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2684ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
2685b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
2686b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
2687b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
26888af7cee1SJed Brown     nnz[i] = 0;
26898af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
2690b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
2691b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
26928af7cee1SJed Brown       nnz[i]++;
26938af7cee1SJed Brown     }
26948af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2695ec7775f6SShri Abhyankar   }
2696ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2697ec7775f6SShri Abhyankar }
2698ec7775f6SShri Abhyankar 
2699b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2700b264fe52SHong Zhang {
2701b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
2702b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
2703b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
2704b264fe52SHong Zhang   PetscErrorCode ierr;
2705b264fe52SHong Zhang 
2706b264fe52SHong Zhang   PetscFunctionBegin;
2707b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
2708b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
2709b264fe52SHong Zhang   PetscFunctionReturn(0);
2710b264fe52SHong Zhang }
2711b264fe52SHong Zhang 
2712f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2713ac90fabeSBarry Smith {
2714dfbe8321SBarry Smith   PetscErrorCode ierr;
2715ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2716c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2717ac90fabeSBarry Smith 
2718ac90fabeSBarry Smith   PetscFunctionBegin;
2719c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2720ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2721f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27228b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2723acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2724a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2725ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2726ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
2727ac90fabeSBarry Smith   } else {
27288229c054SShri Abhyankar     Mat      B;
27298229c054SShri Abhyankar     PetscInt *nnz;
2730785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2731ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2732bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27334aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
273433d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2735176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27368229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2737ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2738ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
273928be2f97SBarry Smith     ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr);
27408229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2741ac90fabeSBarry Smith   }
2742ac90fabeSBarry Smith   PetscFunctionReturn(0);
2743ac90fabeSBarry Smith }
2744ac90fabeSBarry Smith 
27457087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2746354c94deSBarry Smith {
2747354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2748354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2749354c94deSBarry Smith   PetscInt    i,nz;
2750354c94deSBarry Smith   PetscScalar *a;
2751354c94deSBarry Smith 
2752354c94deSBarry Smith   PetscFunctionBegin;
2753354c94deSBarry Smith   nz = aij->nz;
2754354c94deSBarry Smith   a  = aij->a;
27552205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2756354c94deSBarry Smith #else
2757354c94deSBarry Smith   PetscFunctionBegin;
2758354c94deSBarry Smith #endif
2759354c94deSBarry Smith   PetscFunctionReturn(0);
2760354c94deSBarry Smith }
2761354c94deSBarry Smith 
2762985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2763e34fafa9SBarry Smith {
2764e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2765e34fafa9SBarry Smith   PetscErrorCode ierr;
2766d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2767e34fafa9SBarry Smith   PetscReal      atmp;
2768985db425SBarry Smith   PetscScalar    *x;
2769e34fafa9SBarry Smith   MatScalar      *aa;
2770e34fafa9SBarry Smith 
2771e34fafa9SBarry Smith   PetscFunctionBegin;
2772e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2773e34fafa9SBarry Smith   aa = a->a;
2774e34fafa9SBarry Smith   ai = a->i;
2775e34fafa9SBarry Smith   aj = a->j;
2776e34fafa9SBarry Smith 
2777985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2778e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2779e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2780e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2781e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2782e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
27839189402eSHong Zhang     x[i]  = 0.0;
2784e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2785985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2786985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2787985db425SBarry Smith       aa++; aj++;
2788985db425SBarry Smith     }
2789985db425SBarry Smith   }
2790985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2791985db425SBarry Smith   PetscFunctionReturn(0);
2792985db425SBarry Smith }
2793985db425SBarry Smith 
2794985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2795985db425SBarry Smith {
2796985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2797985db425SBarry Smith   PetscErrorCode ierr;
2798d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2799985db425SBarry Smith   PetscScalar    *x;
2800985db425SBarry Smith   MatScalar      *aa;
2801985db425SBarry Smith 
2802985db425SBarry Smith   PetscFunctionBegin;
2803e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2804985db425SBarry Smith   aa = a->a;
2805985db425SBarry Smith   ai = a->i;
2806985db425SBarry Smith   aj = a->j;
2807985db425SBarry Smith 
2808985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2809985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2810985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2811e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2812985db425SBarry Smith   for (i=0; i<m; i++) {
2813985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2814d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2815985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2816985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2817985db425SBarry Smith       x[i] = 0.0;
2818985db425SBarry Smith       if (idx) {
2819985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2820985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2821985db425SBarry Smith           if (aj[j] > j) {
2822985db425SBarry Smith             idx[i] = j;
2823985db425SBarry Smith             break;
2824985db425SBarry Smith           }
2825985db425SBarry Smith         }
2826985db425SBarry Smith       }
2827985db425SBarry Smith     }
2828985db425SBarry Smith     for (j=0; j<ncols; j++) {
2829985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2830985db425SBarry Smith       aa++; aj++;
2831985db425SBarry Smith     }
2832985db425SBarry Smith   }
2833985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2834985db425SBarry Smith   PetscFunctionReturn(0);
2835985db425SBarry Smith }
2836985db425SBarry Smith 
2837c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2838c87e5d42SMatthew Knepley {
2839c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2840c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2841c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2842c87e5d42SMatthew Knepley   PetscReal      atmp;
2843c87e5d42SMatthew Knepley   PetscScalar    *x;
2844c87e5d42SMatthew Knepley   MatScalar      *aa;
2845c87e5d42SMatthew Knepley 
2846c87e5d42SMatthew Knepley   PetscFunctionBegin;
2847e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2848c87e5d42SMatthew Knepley   aa = a->a;
2849c87e5d42SMatthew Knepley   ai = a->i;
2850c87e5d42SMatthew Knepley   aj = a->j;
2851c87e5d42SMatthew Knepley 
2852c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2853c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2854c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
285560e0710aSBarry 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);
2856c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2857c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2858289a08f5SMatthew Knepley     if (ncols) {
2859289a08f5SMatthew Knepley       /* Get first nonzero */
2860289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2861289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28622205254eSKarl Rupp         if (atmp > 1.0e-12) {
28632205254eSKarl Rupp           x[i] = atmp;
28642205254eSKarl Rupp           if (idx) idx[i] = aj[j];
28652205254eSKarl Rupp           break;
28662205254eSKarl Rupp         }
2867289a08f5SMatthew Knepley       }
286812431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2869289a08f5SMatthew Knepley     } else {
2870289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2871289a08f5SMatthew Knepley     }
2872c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2873c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2874289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2875c87e5d42SMatthew Knepley       aa++; aj++;
2876c87e5d42SMatthew Knepley     }
2877c87e5d42SMatthew Knepley   }
2878c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2879c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2880c87e5d42SMatthew Knepley }
2881c87e5d42SMatthew Knepley 
2882985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2883985db425SBarry Smith {
2884985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
2885985db425SBarry Smith   PetscErrorCode  ierr;
2886d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
2887d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
2888985db425SBarry Smith   PetscScalar     *x;
2889d9ca1df4SBarry Smith   const MatScalar *aa;
2890985db425SBarry Smith 
2891985db425SBarry Smith   PetscFunctionBegin;
2892e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2893985db425SBarry Smith   aa = a->a;
2894985db425SBarry Smith   ai = a->i;
2895985db425SBarry Smith   aj = a->j;
2896985db425SBarry Smith 
2897985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2898985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2899985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2900e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2901985db425SBarry Smith   for (i=0; i<m; i++) {
2902985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2903d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2904985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2905985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2906985db425SBarry Smith       x[i] = 0.0;
2907985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2908985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2909985db425SBarry Smith         for (j=0; j<ncols; j++) {
2910985db425SBarry Smith           if (aj[j] > j) {
2911985db425SBarry Smith             idx[i] = j;
2912985db425SBarry Smith             break;
2913985db425SBarry Smith           }
2914985db425SBarry Smith         }
2915985db425SBarry Smith       }
2916985db425SBarry Smith     }
2917985db425SBarry Smith     for (j=0; j<ncols; j++) {
2918985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2919985db425SBarry Smith       aa++; aj++;
2920e34fafa9SBarry Smith     }
2921e34fafa9SBarry Smith   }
2922e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2923e34fafa9SBarry Smith   PetscFunctionReturn(0);
2924e34fafa9SBarry Smith }
2925bbead8a2SBarry Smith 
2926bbead8a2SBarry Smith #include <petscblaslapack.h>
2927af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h>
2928bbead8a2SBarry Smith 
2929713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2930bbead8a2SBarry Smith {
2931bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2932bbead8a2SBarry Smith   PetscErrorCode ierr;
293333d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2934bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2935bbead8a2SBarry Smith   PetscReal      shift = 0.0;
29361a9391e3SHong Zhang   PetscBool      allowzeropivot,zeropivotdetected=PETSC_FALSE;
2937bbead8a2SBarry Smith 
2938bbead8a2SBarry Smith   PetscFunctionBegin;
2939a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
29404a0d0026SBarry Smith   if (a->ibdiagvalid) {
29414a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29424a0d0026SBarry Smith     PetscFunctionReturn(0);
29434a0d0026SBarry Smith   }
2944bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2945bbead8a2SBarry Smith   if (!a->ibdiag) {
2946785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29473bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2948bbead8a2SBarry Smith   }
2949bbead8a2SBarry Smith   diag = a->ibdiag;
2950bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2951bbead8a2SBarry Smith   /* factor and invert each block */
2952bbead8a2SBarry Smith   switch (bs) {
2953bbead8a2SBarry Smith   case 1:
2954bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2955bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2956ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
2957ec1892c8SHong Zhang         if (allowzeropivot) {
29587b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
29597b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
29607b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
29617b6c816cSBarry Smith           ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
29627b6c816cSBarry 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);
2963ec1892c8SHong Zhang       }
2964bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2965bbead8a2SBarry Smith     }
2966bbead8a2SBarry Smith     break;
2967bbead8a2SBarry Smith   case 2:
2968bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2969bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2970bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
2971a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29727b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
297396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
2974bbead8a2SBarry Smith       diag += 4;
2975bbead8a2SBarry Smith     }
2976bbead8a2SBarry Smith     break;
2977bbead8a2SBarry Smith   case 3:
2978bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2979bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
2980bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
2981a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29827b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
298396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
2984bbead8a2SBarry Smith       diag += 9;
2985bbead8a2SBarry Smith     }
2986bbead8a2SBarry Smith     break;
2987bbead8a2SBarry Smith   case 4:
2988bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2989bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
2990bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
2991a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
29927b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
299396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
2994bbead8a2SBarry Smith       diag += 16;
2995bbead8a2SBarry Smith     }
2996bbead8a2SBarry Smith     break;
2997bbead8a2SBarry Smith   case 5:
2998bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2999bbead8a2SBarry 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;
3000bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
3001a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30027b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
300396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3004bbead8a2SBarry Smith       diag += 25;
3005bbead8a2SBarry Smith     }
3006bbead8a2SBarry Smith     break;
3007bbead8a2SBarry Smith   case 6:
3008bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3009bbead8a2SBarry 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;
3010bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
3011a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30127b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
301396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3014bbead8a2SBarry Smith       diag += 36;
3015bbead8a2SBarry Smith     }
3016bbead8a2SBarry Smith     break;
3017bbead8a2SBarry Smith   case 7:
3018bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3019bbead8a2SBarry 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;
3020bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
3021a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30227b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
302396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3024bbead8a2SBarry Smith       diag += 49;
3025bbead8a2SBarry Smith     }
3026bbead8a2SBarry Smith     break;
3027bbead8a2SBarry Smith   default:
3028dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3029bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3030bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3031bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3032bbead8a2SBarry Smith       }
3033bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
30345f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
30357b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
303696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3037bbead8a2SBarry Smith       diag += bs2;
3038bbead8a2SBarry Smith     }
3039bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3040bbead8a2SBarry Smith   }
3041bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3042bbead8a2SBarry Smith   PetscFunctionReturn(0);
3043bbead8a2SBarry Smith }
3044bbead8a2SBarry Smith 
304573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
304673a71a0fSBarry Smith {
304773a71a0fSBarry Smith   PetscErrorCode ierr;
304873a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
304973a71a0fSBarry Smith   PetscScalar    a;
305073a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
305173a71a0fSBarry Smith 
305273a71a0fSBarry Smith   PetscFunctionBegin;
305373a71a0fSBarry Smith   if (!x->assembled) {
305473a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
305573a71a0fSBarry Smith     for (i=0; i<m; i++) {
305673a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
305773a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
305873a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
305973a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
306073a71a0fSBarry Smith       }
306173a71a0fSBarry Smith     }
306273a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
306373a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306473a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
306573a71a0fSBarry Smith   PetscFunctionReturn(0);
306673a71a0fSBarry Smith }
306773a71a0fSBarry Smith 
30687d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a)
30697d68702bSBarry Smith {
30707d68702bSBarry Smith   PetscErrorCode ierr;
30717d68702bSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)Y->data;
30727d68702bSBarry Smith 
30737d68702bSBarry Smith   PetscFunctionBegin;
30746f33a894SBarry Smith   if (!Y->preallocated || !aij->nz) {
30757d68702bSBarry Smith     ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr);
30767d68702bSBarry Smith   }
30777d68702bSBarry Smith   ierr = MatShift_Basic(Y,a);CHKERRQ(ierr);
30787d68702bSBarry Smith   PetscFunctionReturn(0);
30797d68702bSBarry Smith }
30807d68702bSBarry Smith 
3081682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30820a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3083cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3084cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3085cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
308697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30877c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30887c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3089db4efbfdSBarry Smith                                         0,
3090db4efbfdSBarry Smith                                         0,
3091db4efbfdSBarry Smith                                         0,
3092db4efbfdSBarry Smith                                 /* 10*/ 0,
3093cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3094cb5b572fSBarry Smith                                         0,
309541f059aeSBarry Smith                                         MatSOR_SeqAIJ,
309617ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
309797304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3098cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3099cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3100cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3101cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
310297304618SKris Buschelman                                 /* 20*/ 0,
3103cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3104cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3105cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3106d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3107db4efbfdSBarry Smith                                         0,
3108db4efbfdSBarry Smith                                         0,
3109db4efbfdSBarry Smith                                         0,
3110db4efbfdSBarry Smith                                         0,
31114994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3112db4efbfdSBarry Smith                                         0,
3113db4efbfdSBarry Smith                                         0,
31148c778c55SBarry Smith                                         0,
31158c778c55SBarry Smith                                         0,
3116d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3117cb5b572fSBarry Smith                                         0,
3118cb5b572fSBarry Smith                                         0,
3119cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3120cb5b572fSBarry Smith                                         0,
3121d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
31227dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3123cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3124cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3125cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3126d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3127cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
31287d68702bSBarry Smith                                         MatShift_SeqAIJ,
312979299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31306e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
313173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31323b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31333b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31343b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3135a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
313693dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3137b9617806SBarry Smith                                         0,
31380513a670SBarry Smith                                         0,
3139cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3140cda55fadSBarry Smith                                         0,
3141d519adbfSMatthew Knepley                                 /* 59*/ 0,
3142b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3143b9b97703SBarry Smith                                         MatView_SeqAIJ,
3144357abbc8SBarry Smith                                         0,
3145321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3146321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3147321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3148ee4f033dSBarry Smith                                         0,
3149ee4f033dSBarry Smith                                         0,
3150ee4f033dSBarry Smith                                         0,
3151d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3152c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3153ee4f033dSBarry Smith                                         0,
3154dcf5cc72SBarry Smith                                         0,
31552c93a97aSBarry Smith                                         0,
31562c93a97aSBarry Smith                                 /* 74*/ 0,
31573acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
315897304618SKris Buschelman                                         0,
315997304618SKris Buschelman                                         0,
316097304618SKris Buschelman                                         0,
31616ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
316297304618SKris Buschelman                                         0,
316397304618SKris Buschelman                                         0,
316497304618SKris Buschelman                                         0,
3165bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3166d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31671cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31686284ec50SHong Zhang                                         0,
31696284ec50SHong Zhang                                         0,
3170bc011b1eSHong Zhang                                         0,
3171d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
317226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
317326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
317465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31754a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
317665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31776fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31786fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31796fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31802121bac1SHong Zhang                                         0,
31812121bac1SHong Zhang                                 /* 99*/ 0,
3182609c6c4dSKris Buschelman                                         0,
3183609c6c4dSKris Buschelman                                         0,
318487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
318587d4246cSBarry Smith                                         0,
3186d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
318799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3188f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3189f5edf698SHong Zhang                                         0,
31902bebee5dSHong Zhang                                         0,
3191cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3192985db425SBarry Smith                                         0,
31932af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
31942af78befSBarry Smith                                         0,
3195599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3196d519adbfSMatthew Knepley                                 /*114*/ 0,
3197599ef60dSHong Zhang                                         0,
31983c2a7987SHong Zhang                                         0,
3199fe97e370SBarry Smith                                         0,
3200fbdbba38SShri Abhyankar                                         0,
3201fbdbba38SShri Abhyankar                                 /*119*/ 0,
3202fbdbba38SShri Abhyankar                                         0,
3203fbdbba38SShri Abhyankar                                         0,
320482d44351SHong Zhang                                         0,
3205b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32060716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3207bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
320837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
320937868618SMatthew G Knepley                                         0,
321037868618SMatthew G Knepley                                         0,
32115df89d91SHong Zhang                                 /*129*/ 0,
321275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
321375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
321475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3215b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3216b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32172b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32182b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32192b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32203964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32213964eb88SJed Brown                                  /*139*/0,
3222f9426fe0SMark Adams                                         0,
32231919a2e2SJed Brown                                         0,
32243a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
32259c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
32269c8f2541SHong Zhang                                  /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ
32279e29f15eSvictorle };
322817ab2063SBarry Smith 
32297087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3230bef8e0ddSBarry Smith {
3231bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
323297f1f81fSBarry Smith   PetscInt   i,nz,n;
3233bef8e0ddSBarry Smith 
3234bef8e0ddSBarry Smith   PetscFunctionBegin;
3235bef8e0ddSBarry Smith   nz = aij->maxnz;
3236d0f46423SBarry Smith   n  = mat->rmap->n;
3237bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3238bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3239bef8e0ddSBarry Smith   }
3240bef8e0ddSBarry Smith   aij->nz = nz;
3241bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3242bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3243bef8e0ddSBarry Smith   }
3244bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3245bef8e0ddSBarry Smith }
3246bef8e0ddSBarry Smith 
3247bef8e0ddSBarry Smith /*@
3248bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3249bef8e0ddSBarry Smith        in the matrix.
3250bef8e0ddSBarry Smith 
3251bef8e0ddSBarry Smith   Input Parameters:
3252bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3253bef8e0ddSBarry Smith -  indices - the column indices
3254bef8e0ddSBarry Smith 
325515091d37SBarry Smith   Level: advanced
325615091d37SBarry Smith 
3257bef8e0ddSBarry Smith   Notes:
3258bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3259bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3260bef8e0ddSBarry Smith   of the MatSetValues() operation.
3261bef8e0ddSBarry Smith 
3262bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3263d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3264bef8e0ddSBarry Smith 
3265bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3266bef8e0ddSBarry Smith 
3267b9617806SBarry Smith     The indices should start with zero, not one.
3268b9617806SBarry Smith 
3269bef8e0ddSBarry Smith @*/
32707087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3271bef8e0ddSBarry Smith {
32724ac538c5SBarry Smith   PetscErrorCode ierr;
3273bef8e0ddSBarry Smith 
3274bef8e0ddSBarry Smith   PetscFunctionBegin;
32750700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32764482741eSBarry Smith   PetscValidPointer(indices,2);
32774ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3278bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3279bef8e0ddSBarry Smith }
3280bef8e0ddSBarry Smith 
3281be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3282be6bf707SBarry Smith 
32837087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3284be6bf707SBarry Smith {
3285be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
32866849ba73SBarry Smith   PetscErrorCode ierr;
3287d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3288be6bf707SBarry Smith 
3289be6bf707SBarry Smith   PetscFunctionBegin;
3290169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3291be6bf707SBarry Smith 
3292be6bf707SBarry Smith   /* allocate space for values if not already there */
3293be6bf707SBarry Smith   if (!aij->saved_values) {
3294854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
32953bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3296be6bf707SBarry Smith   }
3297be6bf707SBarry Smith 
3298be6bf707SBarry Smith   /* copy values over */
329987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3300be6bf707SBarry Smith   PetscFunctionReturn(0);
3301be6bf707SBarry Smith }
3302be6bf707SBarry Smith 
3303be6bf707SBarry Smith /*@
3304be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3305be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3306be6bf707SBarry Smith        nonlinear portion.
3307be6bf707SBarry Smith 
3308be6bf707SBarry Smith    Collect on Mat
3309be6bf707SBarry Smith 
3310be6bf707SBarry Smith   Input Parameters:
33110e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3312be6bf707SBarry Smith 
331315091d37SBarry Smith   Level: advanced
331415091d37SBarry Smith 
3315be6bf707SBarry Smith   Common Usage, with SNESSolve():
3316be6bf707SBarry Smith $    Create Jacobian matrix
3317be6bf707SBarry Smith $    Set linear terms into matrix
3318be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3319be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3320be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3321512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3322be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3323be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3324be6bf707SBarry Smith $    In your Jacobian routine
3325be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3326be6bf707SBarry Smith $      Set nonlinear terms in matrix
3327be6bf707SBarry Smith 
3328be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3329be6bf707SBarry Smith $    // build linear portion of Jacobian
3330512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3331be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3332be6bf707SBarry Smith $    loop over nonlinear iterations
3333be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3334be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3335be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3336be6bf707SBarry Smith $       Solve linear system with Jacobian
3337be6bf707SBarry Smith $    endloop
3338be6bf707SBarry Smith 
3339be6bf707SBarry Smith   Notes:
3340be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3341512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3342be6bf707SBarry Smith     calling this routine.
3343be6bf707SBarry Smith 
33440c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33450c468ba9SBarry Smith     and does not allocated additional space.
33460c468ba9SBarry Smith 
3347be6bf707SBarry Smith .seealso: MatRetrieveValues()
3348be6bf707SBarry Smith 
3349be6bf707SBarry Smith @*/
33507087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3351be6bf707SBarry Smith {
33524ac538c5SBarry Smith   PetscErrorCode ierr;
3353be6bf707SBarry Smith 
3354be6bf707SBarry Smith   PetscFunctionBegin;
33550700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3356e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3357e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33584ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3359be6bf707SBarry Smith   PetscFunctionReturn(0);
3360be6bf707SBarry Smith }
3361be6bf707SBarry Smith 
33627087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3363be6bf707SBarry Smith {
3364be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33656849ba73SBarry Smith   PetscErrorCode ierr;
3366d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3367be6bf707SBarry Smith 
3368be6bf707SBarry Smith   PetscFunctionBegin;
3369169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3370f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3371be6bf707SBarry Smith   /* copy values over */
337287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3373be6bf707SBarry Smith   PetscFunctionReturn(0);
3374be6bf707SBarry Smith }
3375be6bf707SBarry Smith 
3376be6bf707SBarry Smith /*@
3377be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3378be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3379be6bf707SBarry Smith        nonlinear portion.
3380be6bf707SBarry Smith 
3381be6bf707SBarry Smith    Collect on Mat
3382be6bf707SBarry Smith 
3383be6bf707SBarry Smith   Input Parameters:
3384386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3385be6bf707SBarry Smith 
338615091d37SBarry Smith   Level: advanced
338715091d37SBarry Smith 
3388be6bf707SBarry Smith .seealso: MatStoreValues()
3389be6bf707SBarry Smith 
3390be6bf707SBarry Smith @*/
33917087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3392be6bf707SBarry Smith {
33934ac538c5SBarry Smith   PetscErrorCode ierr;
3394be6bf707SBarry Smith 
3395be6bf707SBarry Smith   PetscFunctionBegin;
33960700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3397e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3398e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33994ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3400be6bf707SBarry Smith   PetscFunctionReturn(0);
3401be6bf707SBarry Smith }
3402be6bf707SBarry Smith 
3403f83d6046SBarry Smith 
3404be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
340517ab2063SBarry Smith /*@C
3406682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34070d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34086e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
340951c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34102bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
341117ab2063SBarry Smith 
3412db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3413db81eaa0SLois Curfman McInnes 
341417ab2063SBarry Smith    Input Parameters:
3415db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
341617ab2063SBarry Smith .  m - number of rows
341717ab2063SBarry Smith .  n - number of columns
341817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
341951c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34200298fd71SBarry Smith          (possibly different for each row) or NULL
342117ab2063SBarry Smith 
342217ab2063SBarry Smith    Output Parameter:
3423416022c9SBarry Smith .  A - the matrix
342417ab2063SBarry Smith 
3425175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3426ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3427175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3428175b88e8SBarry Smith 
3429b259b22eSLois Curfman McInnes    Notes:
343049a6f317SBarry Smith    If nnz is given then nz is ignored
343149a6f317SBarry Smith 
343217ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
343317ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34340002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
343544cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
343617ab2063SBarry Smith 
343717ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34380298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34393d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34406da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
344117ab2063SBarry Smith 
3442682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34434fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3444682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34456c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34466c7ebb05SLois Curfman McInnes 
34476c7ebb05SLois Curfman McInnes    Options Database Keys:
3448698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34499db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
345017ab2063SBarry Smith 
3451027ccd11SLois Curfman McInnes    Level: intermediate
3452027ccd11SLois Curfman McInnes 
345369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
345436db0b34SBarry Smith 
345517ab2063SBarry Smith @*/
34567087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
345717ab2063SBarry Smith {
3458dfbe8321SBarry Smith   PetscErrorCode ierr;
34596945ee14SBarry Smith 
34603a40ed3dSBarry Smith   PetscFunctionBegin;
3461f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3462117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3463c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3464d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3465273d9f13SBarry Smith   PetscFunctionReturn(0);
3466273d9f13SBarry Smith }
3467273d9f13SBarry Smith 
3468273d9f13SBarry Smith /*@C
3469273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3470273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3471273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3472273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3473273d9f13SBarry Smith 
3474273d9f13SBarry Smith    Collective on MPI_Comm
3475273d9f13SBarry Smith 
3476273d9f13SBarry Smith    Input Parameters:
34771c4f3114SJed Brown +  B - The matrix
3478273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3479273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34800298fd71SBarry Smith          (possibly different for each row) or NULL
3481273d9f13SBarry Smith 
3482273d9f13SBarry Smith    Notes:
348349a6f317SBarry Smith      If nnz is given then nz is ignored
348449a6f317SBarry Smith 
3485273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3486273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3487273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3488273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3489273d9f13SBarry Smith 
3490273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34910298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3492273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3493273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3494273d9f13SBarry Smith 
3495aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3496aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3497aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3498aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3499aa95bbe8SBarry Smith 
3500a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3501a96a251dSBarry Smith    entries or columns indices
3502a96a251dSBarry Smith 
3503273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3504273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3505273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3506273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3507273d9f13SBarry Smith 
3508273d9f13SBarry Smith    Options Database Keys:
3509698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3510698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3511273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3512273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3513273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3514273d9f13SBarry Smith 
3515273d9f13SBarry Smith    Level: intermediate
3516273d9f13SBarry Smith 
351769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3518273d9f13SBarry Smith 
3519273d9f13SBarry Smith @*/
35207087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3521273d9f13SBarry Smith {
35224ac538c5SBarry Smith   PetscErrorCode ierr;
3523a23d5eceSKris Buschelman 
3524a23d5eceSKris Buschelman   PetscFunctionBegin;
35256ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35266ba663aaSJed Brown   PetscValidType(B,1);
35274ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3528a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3529a23d5eceSKris Buschelman }
3530a23d5eceSKris Buschelman 
35317087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3532a23d5eceSKris Buschelman {
3533273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35342576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35356849ba73SBarry Smith   PetscErrorCode ierr;
353697f1f81fSBarry Smith   PetscInt       i;
3537273d9f13SBarry Smith 
3538273d9f13SBarry Smith   PetscFunctionBegin;
35392576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3540a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3541c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3542c461c341SBarry Smith     nz             = 0;
3543c461c341SBarry Smith   }
354426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
354526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3546899cda47SBarry Smith 
3547435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
354860e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3549b73539f3SBarry Smith   if (nnz) {
3550d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
355160e0710aSBarry 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]);
355260e0710aSBarry 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);
3553b73539f3SBarry Smith     }
3554b73539f3SBarry Smith   }
3555b73539f3SBarry Smith 
3556273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35572205254eSKarl Rupp 
3558273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3559273d9f13SBarry Smith 
3560ab93d7beSBarry Smith   if (!skipallocation) {
35612ee49352SLisandro Dalcin     if (!b->imax) {
3562dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35633bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35642ee49352SLisandro Dalcin     }
3565273d9f13SBarry Smith     if (!nnz) {
3566435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3567c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3568d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3569d0f46423SBarry Smith       nz = nz*B->rmap->n;
3570273d9f13SBarry Smith     } else {
3571273d9f13SBarry Smith       nz = 0;
3572d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3573273d9f13SBarry Smith     }
3574ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
35752205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3576ab93d7beSBarry Smith 
3577273d9f13SBarry Smith     /* allocate the matrix space */
357853dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
35792ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3580396832f4SHong Zhang     if (B->structure_only) {
35815848002fSHong Zhang       ierr    = PetscMalloc1(nz,&b->j);CHKERRQ(ierr);
35825848002fSHong Zhang       ierr    = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr);
3583396832f4SHong Zhang       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr);
3584396832f4SHong Zhang     } else {
3585dcca6d9dSJed Brown       ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
35863bb1ff40SBarry Smith       ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3587396832f4SHong Zhang     }
3588bfeeae90SHong Zhang     b->i[0] = 0;
3589d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
35905da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
35915da197adSKris Buschelman     }
3592396832f4SHong Zhang     if (B->structure_only) {
3593396832f4SHong Zhang       b->singlemalloc = PETSC_FALSE;
3594396832f4SHong Zhang       b->free_a       = PETSC_FALSE;
3595396832f4SHong Zhang     } else {
3596273d9f13SBarry Smith       b->singlemalloc = PETSC_TRUE;
3597e6b907acSBarry Smith       b->free_a       = PETSC_TRUE;
3598396832f4SHong Zhang     }
3599e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3600c461c341SBarry Smith   } else {
3601e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3602e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3603c461c341SBarry Smith   }
3604273d9f13SBarry Smith 
3605273d9f13SBarry Smith   b->nz               = 0;
3606273d9f13SBarry Smith   b->maxnz            = nz;
3607273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36082205254eSKarl Rupp   if (realalloc) {
36092205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36102205254eSKarl Rupp   }
3611cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
3612cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
3613273d9f13SBarry Smith   PetscFunctionReturn(0);
3614273d9f13SBarry Smith }
3615273d9f13SBarry Smith 
361658d36128SBarry Smith /*@
3617a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3618a1661176SMatthew Knepley 
3619a1661176SMatthew Knepley    Input Parameters:
3620a1661176SMatthew Knepley +  B - the matrix
3621a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3622a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3623a1661176SMatthew Knepley -  v - optional values in the matrix
3624a1661176SMatthew Knepley 
3625a1661176SMatthew Knepley    Level: developer
3626a1661176SMatthew Knepley 
362758d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
362858d36128SBarry Smith 
3629a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3630a1661176SMatthew Knepley 
3631a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3632a1661176SMatthew Knepley @*/
3633a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3634a1661176SMatthew Knepley {
3635a1661176SMatthew Knepley   PetscErrorCode ierr;
3636a1661176SMatthew Knepley 
3637a1661176SMatthew Knepley   PetscFunctionBegin;
36380700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36396ba663aaSJed Brown   PetscValidType(B,1);
36404ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3641a1661176SMatthew Knepley   PetscFunctionReturn(0);
3642a1661176SMatthew Knepley }
3643a1661176SMatthew Knepley 
36447087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3645a1661176SMatthew Knepley {
3646a1661176SMatthew Knepley   PetscInt       i;
3647a1661176SMatthew Knepley   PetscInt       m,n;
3648a1661176SMatthew Knepley   PetscInt       nz;
3649a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3650a1661176SMatthew Knepley   PetscScalar    *values;
3651a1661176SMatthew Knepley   PetscErrorCode ierr;
3652a1661176SMatthew Knepley 
3653a1661176SMatthew Knepley   PetscFunctionBegin;
365465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3655779a8d59SSatish Balay 
3656779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3657779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3658779a8d59SSatish Balay 
3659779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3660854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
3661a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3662b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3663a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
366465e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3665a1661176SMatthew Knepley     nnz[i] = nz;
3666a1661176SMatthew Knepley   }
3667a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3668a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3669a1661176SMatthew Knepley 
3670a1661176SMatthew Knepley   if (v) {
3671a1661176SMatthew Knepley     values = (PetscScalar*) v;
3672a1661176SMatthew Knepley   } else {
36731795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3674a1661176SMatthew Knepley   }
3675a1661176SMatthew Knepley 
3676a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3677b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3678b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3679a1661176SMatthew Knepley   }
3680a1661176SMatthew Knepley 
3681a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3682a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3683a1661176SMatthew Knepley 
3684a1661176SMatthew Knepley   if (!v) {
3685a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3686a1661176SMatthew Knepley   }
36877827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3688a1661176SMatthew Knepley   PetscFunctionReturn(0);
3689a1661176SMatthew Knepley }
3690a1661176SMatthew Knepley 
3691c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
3692af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
3693170fe5c8SBarry Smith 
3694170fe5c8SBarry Smith /*
3695170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3696170fe5c8SBarry Smith 
3697170fe5c8SBarry Smith                n                       p                          p
3698170fe5c8SBarry Smith         (              )       (              )         (                  )
3699170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3700170fe5c8SBarry Smith         (              )       (              )         (                  )
3701170fe5c8SBarry Smith 
3702170fe5c8SBarry Smith */
3703170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3704170fe5c8SBarry Smith {
3705170fe5c8SBarry Smith   PetscErrorCode    ierr;
3706170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3707170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3708170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37091de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3710170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3711170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3712170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3713170fe5c8SBarry Smith 
3714170fe5c8SBarry Smith   PetscFunctionBegin;
3715d0f46423SBarry Smith   m    = A->rmap->n;
3716d0f46423SBarry Smith   n    = A->cmap->n;
3717d0f46423SBarry Smith   p    = B->cmap->n;
3718170fe5c8SBarry Smith   a    = sub_a->v;
3719170fe5c8SBarry Smith   b    = sub_b->a;
3720170fe5c8SBarry Smith   c    = sub_c->v;
3721170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3722170fe5c8SBarry Smith 
3723170fe5c8SBarry Smith   ii  = sub_b->i;
3724170fe5c8SBarry Smith   idx = sub_b->j;
3725170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3726170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3727170fe5c8SBarry Smith     while (q-->0) {
3728170fe5c8SBarry Smith       c_q = c + m*(*idx);
3729170fe5c8SBarry Smith       a_q = a + m*i;
3730854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3731170fe5c8SBarry Smith       idx++;
3732170fe5c8SBarry Smith       b++;
3733170fe5c8SBarry Smith     }
3734170fe5c8SBarry Smith   }
3735170fe5c8SBarry Smith   PetscFunctionReturn(0);
3736170fe5c8SBarry Smith }
3737170fe5c8SBarry Smith 
3738170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3739170fe5c8SBarry Smith {
3740170fe5c8SBarry Smith   PetscErrorCode ierr;
3741d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3742170fe5c8SBarry Smith   Mat            Cmat;
3743170fe5c8SBarry Smith 
3744170fe5c8SBarry Smith   PetscFunctionBegin;
374560e0710aSBarry 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);
3746ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3747170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
374833d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3749170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37500298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3751d73949e8SHong Zhang 
3752d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37532205254eSKarl Rupp 
3754170fe5c8SBarry Smith   *C = Cmat;
3755170fe5c8SBarry Smith   PetscFunctionReturn(0);
3756170fe5c8SBarry Smith }
3757170fe5c8SBarry Smith 
3758170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3759150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3760170fe5c8SBarry Smith {
3761170fe5c8SBarry Smith   PetscErrorCode ierr;
3762170fe5c8SBarry Smith 
3763170fe5c8SBarry Smith   PetscFunctionBegin;
3764170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37653ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3766170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37673ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3768170fe5c8SBarry Smith   }
37693ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3770170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37713ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3772170fe5c8SBarry Smith   PetscFunctionReturn(0);
3773170fe5c8SBarry Smith }
3774170fe5c8SBarry Smith 
3775170fe5c8SBarry Smith 
37760bad9183SKris Buschelman /*MC
3777fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
37780bad9183SKris Buschelman    based on compressed sparse row format.
37790bad9183SKris Buschelman 
37800bad9183SKris Buschelman    Options Database Keys:
37810bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
37820bad9183SKris Buschelman 
37830bad9183SKris Buschelman   Level: beginner
37840bad9183SKris Buschelman 
3785f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
37860bad9183SKris Buschelman M*/
37870bad9183SKris Buschelman 
3788ccd284c7SBarry Smith /*MC
3789ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3790ccd284c7SBarry Smith 
3791ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3792ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3793ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3794ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3795ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3796ccd284c7SBarry Smith 
3797ccd284c7SBarry Smith    Options Database Keys:
3798ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3799ccd284c7SBarry Smith 
3800ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3801ccd284c7SBarry Smith    enough exist.
3802ccd284c7SBarry Smith 
3803ccd284c7SBarry Smith   Level: beginner
3804ccd284c7SBarry Smith 
3805ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3806ccd284c7SBarry Smith M*/
3807ccd284c7SBarry Smith 
3808ccd284c7SBarry Smith /*MC
3809ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3810ccd284c7SBarry Smith 
3811ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3812ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3813ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3814ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3815ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3816ccd284c7SBarry Smith 
3817ccd284c7SBarry Smith    Options Database Keys:
3818ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3819ccd284c7SBarry Smith 
3820ccd284c7SBarry Smith   Level: beginner
3821ccd284c7SBarry Smith 
3822ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3823ccd284c7SBarry Smith M*/
3824ccd284c7SBarry Smith 
3825cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
3826af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3827cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
3828af8000cdSHong Zhang #endif
382963c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
383063c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
38313dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
383263c07aadSStefano Zampini #endif
3833cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*);
383442c9c57cSBarry Smith 
3835b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
383629b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
383729b38603SBarry Smith PETSC_EXTERN PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3838b3866ffcSBarry Smith #endif
383917667f90SBarry Smith 
3840c0c8ee5eSDmitry Karpeev 
38418c778c55SBarry Smith /*@C
38428397e458SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored
38438c778c55SBarry Smith 
38448c778c55SBarry Smith    Not Collective
38458c778c55SBarry Smith 
38468c778c55SBarry Smith    Input Parameter:
3847579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38488c778c55SBarry Smith 
38498c778c55SBarry Smith    Output Parameter:
38508c778c55SBarry Smith .   array - pointer to the data
38518c778c55SBarry Smith 
38528c778c55SBarry Smith    Level: intermediate
38538c778c55SBarry Smith 
3854774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
38558c778c55SBarry Smith @*/
38568c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
38578c778c55SBarry Smith {
38588c778c55SBarry Smith   PetscErrorCode ierr;
38598c778c55SBarry Smith 
38608c778c55SBarry Smith   PetscFunctionBegin;
38618c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
38628c778c55SBarry Smith   PetscFunctionReturn(0);
38638c778c55SBarry Smith }
38648c778c55SBarry Smith 
386521e72a00SBarry Smith /*@C
386621e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
386721e72a00SBarry Smith 
386821e72a00SBarry Smith    Not Collective
386921e72a00SBarry Smith 
387021e72a00SBarry Smith    Input Parameter:
3871579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
387221e72a00SBarry Smith 
387321e72a00SBarry Smith    Output Parameter:
387421e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
387521e72a00SBarry Smith 
387621e72a00SBarry Smith    Level: intermediate
387721e72a00SBarry Smith 
387821e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
387921e72a00SBarry Smith @*/
388021e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
388121e72a00SBarry Smith {
388221e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
388321e72a00SBarry Smith 
388421e72a00SBarry Smith   PetscFunctionBegin;
388521e72a00SBarry Smith   *nz = aij->rmax;
388621e72a00SBarry Smith   PetscFunctionReturn(0);
388721e72a00SBarry Smith }
388821e72a00SBarry Smith 
38898c778c55SBarry Smith /*@C
3890579dbff0SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
38918c778c55SBarry Smith 
38928c778c55SBarry Smith    Not Collective
38938c778c55SBarry Smith 
38948c778c55SBarry Smith    Input Parameters:
3895579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
38968c778c55SBarry Smith .  array - pointer to the data
38978c778c55SBarry Smith 
38988c778c55SBarry Smith    Level: intermediate
38998c778c55SBarry Smith 
3900774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39018c778c55SBarry Smith @*/
39028c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39038c778c55SBarry Smith {
39048c778c55SBarry Smith   PetscErrorCode ierr;
39058c778c55SBarry Smith 
39068c778c55SBarry Smith   PetscFunctionBegin;
39078c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39088c778c55SBarry Smith   PetscFunctionReturn(0);
39098c778c55SBarry Smith }
39108c778c55SBarry Smith 
39118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3912273d9f13SBarry Smith {
3913273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3914dfbe8321SBarry Smith   PetscErrorCode ierr;
391538baddfdSBarry Smith   PetscMPIInt    size;
3916273d9f13SBarry Smith 
3917273d9f13SBarry Smith   PetscFunctionBegin;
3918ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3919e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3920273d9f13SBarry Smith 
3921b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39222205254eSKarl Rupp 
3923b0a32e0cSBarry Smith   B->data = (void*)b;
39242205254eSKarl Rupp 
3925549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39262205254eSKarl Rupp 
3927416022c9SBarry Smith   b->row                = 0;
3928416022c9SBarry Smith   b->col                = 0;
392982bf6240SBarry Smith   b->icol               = 0;
3930b810aeb4SBarry Smith   b->reallocs           = 0;
393136db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3932f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3933416022c9SBarry Smith   b->nonew              = 0;
3934416022c9SBarry Smith   b->diag               = 0;
3935416022c9SBarry Smith   b->solve_work         = 0;
39362a1b7f2aSHong Zhang   B->spptr              = 0;
3937be6bf707SBarry Smith   b->saved_values       = 0;
3938d7f994e1SBarry Smith   b->idiag              = 0;
393971f1c65dSBarry Smith   b->mdiag              = 0;
394071f1c65dSBarry Smith   b->ssor_work          = 0;
394171f1c65dSBarry Smith   b->omega              = 1.0;
394271f1c65dSBarry Smith   b->fshift             = 0.0;
394371f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3944bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3945a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
394617ab2063SBarry Smith 
394735d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3948bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3949bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39508c778c55SBarry Smith 
3951b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3952bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3953bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3954b3866ffcSBarry Smith #endif
395517f1a0eaSHong Zhang 
3956bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
3957bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
3958bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
3959bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
3960bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
3961bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
3962bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
3963af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3964af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
3965af8000cdSHong Zhang #endif
396663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
396763c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
39683dad0653Sstefano_zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr);
396963c07aadSStefano Zampini #endif
3970b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
3971bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3972bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
3973bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
3974bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
3975bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
3976bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
3977bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
3978bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
39794108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
398017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
39813a40ed3dSBarry Smith   PetscFunctionReturn(0);
398217ab2063SBarry Smith }
398317ab2063SBarry Smith 
3984b24902e0SBarry Smith /*
3985b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
3986b24902e0SBarry Smith */
3987ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
398817ab2063SBarry Smith {
3989416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
39906849ba73SBarry Smith   PetscErrorCode ierr;
3991d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
399217ab2063SBarry Smith 
39933a40ed3dSBarry Smith   PetscFunctionBegin;
3994273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
3995273d9f13SBarry Smith 
3996d5f3da31SBarry Smith   C->factortype = A->factortype;
3997416022c9SBarry Smith   c->row        = 0;
3998416022c9SBarry Smith   c->col        = 0;
399982bf6240SBarry Smith   c->icol       = 0;
40006ad4291fSHong Zhang   c->reallocs   = 0;
400117ab2063SBarry Smith 
40026ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
400317ab2063SBarry Smith 
4004aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4005aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4006eec197d1SBarry Smith 
4007dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40083bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
400917ab2063SBarry Smith   for (i=0; i<m; i++) {
4010416022c9SBarry Smith     c->imax[i] = a->imax[i];
4011416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
401217ab2063SBarry Smith   }
401317ab2063SBarry Smith 
401417ab2063SBarry Smith   /* allocate the matrix space */
4015f77e22a1SHong Zhang   if (mallocmatspace) {
4016dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40173bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40182205254eSKarl Rupp 
4019f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40202205254eSKarl Rupp 
402197f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
402217ab2063SBarry Smith     if (m > 0) {
402397f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4024be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4025bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4026be6bf707SBarry Smith       } else {
4027bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
402817ab2063SBarry Smith       }
402908480c60SBarry Smith     }
4030f77e22a1SHong Zhang   }
403117ab2063SBarry Smith 
40326ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4033416022c9SBarry Smith   c->roworiented       = a->roworiented;
4034416022c9SBarry Smith   c->nonew             = a->nonew;
4035416022c9SBarry Smith   if (a->diag) {
4036854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
40373bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
403817ab2063SBarry Smith     for (i=0; i<m; i++) {
4039416022c9SBarry Smith       c->diag[i] = a->diag[i];
404017ab2063SBarry Smith     }
40413a40ed3dSBarry Smith   } else c->diag = 0;
40422205254eSKarl Rupp 
40436ad4291fSHong Zhang   c->solve_work         = 0;
40446ad4291fSHong Zhang   c->saved_values       = 0;
40456ad4291fSHong Zhang   c->idiag              = 0;
404671f1c65dSBarry Smith   c->ssor_work          = 0;
4047a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4048e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4049e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
40506ad4291fSHong Zhang 
4051893ad86cSHong Zhang   c->rmax         = a->rmax;
4052416022c9SBarry Smith   c->nz           = a->nz;
40538ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4054273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4055754ec7b1SSatish Balay 
40566ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
40576ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4058cd6b891eSBarry Smith   if (a->compressedrow.use) {
40596ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4060dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
40616ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
40626ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
406327ea64f8SHong Zhang   } else {
406427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
40650298fd71SBarry Smith     c->compressedrow.i      = NULL;
40660298fd71SBarry Smith     c->compressedrow.rindex = NULL;
40676ad4291fSHong Zhang   }
4068ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4069e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
40704846f1f5SKris Buschelman 
40712205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4072140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
40733a40ed3dSBarry Smith   PetscFunctionReturn(0);
407417ab2063SBarry Smith }
407517ab2063SBarry Smith 
4076b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4077b24902e0SBarry Smith {
4078b24902e0SBarry Smith   PetscErrorCode ierr;
4079b24902e0SBarry Smith 
4080b24902e0SBarry Smith   PetscFunctionBegin;
4081ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
40824b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4083cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
408433d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4085cfd3f464SBarry Smith   }
4086a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4087f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4088b24902e0SBarry Smith   PetscFunctionReturn(0);
4089b24902e0SBarry Smith }
4090b24902e0SBarry Smith 
4091112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4092fbdbba38SShri Abhyankar {
4093fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4094fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4095fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4096fbdbba38SShri Abhyankar   int            fd;
4097fbdbba38SShri Abhyankar   PetscMPIInt    size;
4098fbdbba38SShri Abhyankar   MPI_Comm       comm;
40993059b6faSBarry Smith   PetscInt       bs = newMat->rmap->bs;
4100fbdbba38SShri Abhyankar 
4101fbdbba38SShri Abhyankar   PetscFunctionBegin;
4102c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
4103c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4104fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4105fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4106fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4107bbead8a2SBarry Smith 
41080298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41090298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4110bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41113059b6faSBarry Smith   if (bs < 0) bs = 1;
41123059b6faSBarry Smith   ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);
4113bbead8a2SBarry Smith 
4114fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4115fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4116fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4117fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4118fbdbba38SShri Abhyankar 
4119bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4120fbdbba38SShri Abhyankar 
4121fbdbba38SShri Abhyankar   /* read in row lengths */
4122785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4123fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4124fbdbba38SShri Abhyankar 
4125fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4126fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
412760e0710aSBarry 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);
4128fbdbba38SShri Abhyankar 
4129fbdbba38SShri Abhyankar   /* set global size if not set already*/
4130f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4131fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4132aabbc4fbSShri Abhyankar   } else {
41339d36ed5fSBarry Smith     /* if sizes and type are already set, check if the matrix  global sizes are correct */
4134fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41354c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41364c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41374c5b953cSHong Zhang     }
413860e0710aSBarry 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);
4139aabbc4fbSShri Abhyankar   }
4140fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4141fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4142fbdbba38SShri Abhyankar 
4143fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4144fbdbba38SShri Abhyankar 
4145fbdbba38SShri Abhyankar   /* read in nonzero values */
4146fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4147fbdbba38SShri Abhyankar 
4148fbdbba38SShri Abhyankar   /* set matrix "i" values */
4149fbdbba38SShri Abhyankar   a->i[0] = 0;
4150fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4151fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4152fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4153fbdbba38SShri Abhyankar   }
4154fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4155fbdbba38SShri Abhyankar 
4156fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4157fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4158fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4159fbdbba38SShri Abhyankar }
4160fbdbba38SShri Abhyankar 
4161ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
41627264ac53SSatish Balay {
41637264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4164dfbe8321SBarry Smith   PetscErrorCode ierr;
4165eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4166eeffb40dSHong Zhang   PetscInt k;
4167eeffb40dSHong Zhang #endif
41687264ac53SSatish Balay 
41693a40ed3dSBarry Smith   PetscFunctionBegin;
4170bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4171d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4172ca44d042SBarry Smith     *flg = PETSC_FALSE;
4173ca44d042SBarry Smith     PetscFunctionReturn(0);
4174bcd2baecSBarry Smith   }
41757264ac53SSatish Balay 
41767264ac53SSatish Balay   /* if the a->i are the same */
4177d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4178abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
41797264ac53SSatish Balay 
41807264ac53SSatish Balay   /* if a->j are the same */
418197f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4182abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4183bcd2baecSBarry Smith 
4184bcd2baecSBarry Smith   /* if a->a are the same */
4185eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4186eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4187eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4188eeffb40dSHong Zhang       *flg = PETSC_FALSE;
41893a40ed3dSBarry Smith       PetscFunctionReturn(0);
4190eeffb40dSHong Zhang     }
4191eeffb40dSHong Zhang   }
4192eeffb40dSHong Zhang #else
4193eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4194eeffb40dSHong Zhang #endif
4195eeffb40dSHong Zhang   PetscFunctionReturn(0);
41967264ac53SSatish Balay }
419736db0b34SBarry Smith 
419805869f15SSatish Balay /*@
419936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
420036db0b34SBarry Smith               provided by the user.
420136db0b34SBarry Smith 
4202c75a6043SHong Zhang       Collective on MPI_Comm
420336db0b34SBarry Smith 
420436db0b34SBarry Smith    Input Parameters:
420536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
420636db0b34SBarry Smith .   m - number of rows
420736db0b34SBarry Smith .   n - number of columns
420836db0b34SBarry Smith .   i - row indices
420936db0b34SBarry Smith .   j - column indices
421036db0b34SBarry Smith -   a - matrix values
421136db0b34SBarry Smith 
421236db0b34SBarry Smith    Output Parameter:
421336db0b34SBarry Smith .   mat - the matrix
421436db0b34SBarry Smith 
421536db0b34SBarry Smith    Level: intermediate
421636db0b34SBarry Smith 
421736db0b34SBarry Smith    Notes:
42180551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4219292fb18eSBarry Smith     once the matrix is destroyed and not before
422036db0b34SBarry Smith 
422136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
422236db0b34SBarry Smith 
4223bfeeae90SHong Zhang        The i and j indices are 0 based
422436db0b34SBarry Smith 
4225a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4226a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
42278eef79e4SBarry Smith     as shown
4228a4552177SSatish Balay 
42298eef79e4SBarry Smith $        1 0 0
42308eef79e4SBarry Smith $        2 0 3
42318eef79e4SBarry Smith $        4 5 6
42328eef79e4SBarry Smith $
42338eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42348eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
42358eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
4236a4552177SSatish Balay 
42379985e31cSBarry Smith 
423869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
423936db0b34SBarry Smith 
424036db0b34SBarry Smith @*/
4241c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
424236db0b34SBarry Smith {
4243dfbe8321SBarry Smith   PetscErrorCode ierr;
4244cbcfb4deSHong Zhang   PetscInt       ii;
424536db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4246cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4247cbcfb4deSHong Zhang   PetscInt jj;
4248cbcfb4deSHong Zhang #endif
424936db0b34SBarry Smith 
425036db0b34SBarry Smith   PetscFunctionBegin;
425141096f02SStefano Zampini   if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4252f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4253f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4254a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4255ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4256ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4257ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4258dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4259ab93d7beSBarry Smith 
426036db0b34SBarry Smith   aij->i            = i;
426136db0b34SBarry Smith   aij->j            = j;
426236db0b34SBarry Smith   aij->a            = a;
426336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
426436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4265e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4266e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
426736db0b34SBarry Smith 
426836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
426936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
42702515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
427160e0710aSBarry 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]);
42729985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4273e32f2f54SBarry Smith       if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii);
4274e32f2f54SBarry 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);
42759985e31cSBarry Smith     }
427636db0b34SBarry Smith #endif
427736db0b34SBarry Smith   }
42782515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
427936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
428060e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
428160e0710aSBarry 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]);
428236db0b34SBarry Smith   }
428336db0b34SBarry Smith #endif
428436db0b34SBarry Smith 
4285b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4286b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
428736db0b34SBarry Smith   PetscFunctionReturn(0);
428836db0b34SBarry Smith }
428980ef6e79SMatthew G Knepley /*@C
4290d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
42918a0b0e6bSVictor Minden               provided by the user.
42928a0b0e6bSVictor Minden 
42938a0b0e6bSVictor Minden       Collective on MPI_Comm
42948a0b0e6bSVictor Minden 
42958a0b0e6bSVictor Minden    Input Parameters:
42968a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
42978a0b0e6bSVictor Minden .   m   - number of rows
42988a0b0e6bSVictor Minden .   n   - number of columns
42998a0b0e6bSVictor Minden .   i   - row indices
43008a0b0e6bSVictor Minden .   j   - column indices
43011230e6d1SVictor Minden .   a   - matrix values
43021230e6d1SVictor Minden .   nz  - number of nonzeros
43031230e6d1SVictor Minden -   idx - 0 or 1 based
43048a0b0e6bSVictor Minden 
43058a0b0e6bSVictor Minden    Output Parameter:
43068a0b0e6bSVictor Minden .   mat - the matrix
43078a0b0e6bSVictor Minden 
43088a0b0e6bSVictor Minden    Level: intermediate
43098a0b0e6bSVictor Minden 
43108a0b0e6bSVictor Minden    Notes:
43118a0b0e6bSVictor Minden        The i and j indices are 0 based
43128a0b0e6bSVictor Minden 
43138a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43148a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43158a0b0e6bSVictor Minden     as shown:
43168a0b0e6bSVictor Minden 
43178a0b0e6bSVictor Minden         1 0 0
43188a0b0e6bSVictor Minden         2 0 3
43198a0b0e6bSVictor Minden         4 5 6
43208a0b0e6bSVictor Minden 
43218a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43228a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43238a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43248a0b0e6bSVictor Minden 
43258a0b0e6bSVictor Minden 
432669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43278a0b0e6bSVictor Minden 
43288a0b0e6bSVictor Minden @*/
4329c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
43308a0b0e6bSVictor Minden {
43318a0b0e6bSVictor Minden   PetscErrorCode ierr;
4332d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43338a0b0e6bSVictor Minden 
43348a0b0e6bSVictor Minden 
43358a0b0e6bSVictor Minden   PetscFunctionBegin;
43361795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
43371230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4338c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
43391230e6d1SVictor Minden   }
43408a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
43418a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
43428a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
43431230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
43441230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
43451230e6d1SVictor Minden     if (idx) {
43461230e6d1SVictor Minden       row = i[ii] - 1;
43471230e6d1SVictor Minden       col = j[ii] - 1;
43481230e6d1SVictor Minden     } else {
43491230e6d1SVictor Minden       row = i[ii];
43501230e6d1SVictor Minden       col = j[ii];
43518a0b0e6bSVictor Minden     }
43521230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
43538a0b0e6bSVictor Minden   }
43548a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
43558a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4356d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
43578a0b0e6bSVictor Minden   PetscFunctionReturn(0);
43588a0b0e6bSVictor Minden }
435936db0b34SBarry Smith 
4360acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4361acf2f550SJed Brown {
4362acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4363acf2f550SJed Brown   PetscErrorCode ierr;
4364acf2f550SJed Brown 
4365acf2f550SJed Brown   PetscFunctionBegin;
4366acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4367acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
43682205254eSKarl Rupp 
4369acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4370acf2f550SJed Brown   PetscFunctionReturn(0);
4371acf2f550SJed Brown }
4372acf2f550SJed Brown 
43739c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
43749c8f2541SHong Zhang {
43759c8f2541SHong Zhang   PetscErrorCode ierr;
43768761c3d6SHong Zhang   PetscMPIInt    size;
43779c8f2541SHong Zhang 
43789c8f2541SHong Zhang   PetscFunctionBegin;
43798761c3d6SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
43808761c3d6SHong Zhang   if (size == 1 && scall == MAT_REUSE_MATRIX) {
43818761c3d6SHong Zhang     ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43828761c3d6SHong Zhang   } else {
43839c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
43848761c3d6SHong Zhang   }
43859c8f2541SHong Zhang   PetscFunctionReturn(0);
43869c8f2541SHong Zhang }
43879c8f2541SHong Zhang 
438881824310SBarry Smith /*
438953dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
439053dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
439153dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
439253dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
439353dd7562SDmitry Karpeev  */
439453dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
439553dd7562SDmitry Karpeev {
439653dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
439753dd7562SDmitry Karpeev   PetscErrorCode ierr;
439853dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
439953dd7562SDmitry Karpeev   PetscBool      seqaij;
440053dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
440153dd7562SDmitry Karpeev   PetscScalar    v;
440253dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
440353dd7562SDmitry Karpeev 
440453dd7562SDmitry Karpeev   PetscFunctionBegin;
440553dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
440653dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
440753dd7562SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
440853dd7562SDmitry Karpeev   if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
440953dd7562SDmitry Karpeev   if (rowemb) {
441053dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
441153dd7562SDmitry 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);
441253dd7562SDmitry Karpeev   } else {
44136c4ed002SBarry Smith     if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
441453dd7562SDmitry Karpeev   }
441553dd7562SDmitry Karpeev   if (colemb) {
441653dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
441753dd7562SDmitry 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);
441853dd7562SDmitry Karpeev   } else {
441953dd7562SDmitry Karpeev     if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
442053dd7562SDmitry Karpeev   }
442153dd7562SDmitry Karpeev 
442253dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
442353dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
442453dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
442553dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
442653dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
442753dd7562SDmitry Karpeev     }
442853dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
442953dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
443053dd7562SDmitry Karpeev   }
443153dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
443253dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
443353dd7562SDmitry Karpeev   }
443453dd7562SDmitry Karpeev   count = 0;
443553dd7562SDmitry Karpeev   rowindices = NULL;
443653dd7562SDmitry Karpeev   colindices = NULL;
443753dd7562SDmitry Karpeev   if (rowemb) {
443853dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
443953dd7562SDmitry Karpeev   }
444053dd7562SDmitry Karpeev   if (colemb) {
444153dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
444253dd7562SDmitry Karpeev   }
444353dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
444453dd7562SDmitry Karpeev     PetscInt row;
444553dd7562SDmitry Karpeev     row = i;
444653dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
444753dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
444853dd7562SDmitry Karpeev       PetscInt col;
444953dd7562SDmitry Karpeev       col  = Baij->j[count];
445053dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
445153dd7562SDmitry Karpeev       v    = Baij->a[count];
445253dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
445353dd7562SDmitry Karpeev       ++count;
445453dd7562SDmitry Karpeev     }
445553dd7562SDmitry Karpeev   }
445653dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
445753dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
445853dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
445953dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
446053dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
446153dd7562SDmitry Karpeev   PetscFunctionReturn(0);
446253dd7562SDmitry Karpeev }
446353dd7562SDmitry Karpeev 
446453dd7562SDmitry Karpeev 
446553dd7562SDmitry Karpeev /*
446681824310SBarry Smith     Special version for direct calls from Fortran
446781824310SBarry Smith */
4468af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
446981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
447081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
447181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
447281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
447381824310SBarry Smith #endif
447481824310SBarry Smith 
447581824310SBarry Smith /* Change these macros so can be used in void function */
447681824310SBarry Smith #undef CHKERRQ
4477ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
447881824310SBarry Smith #undef SETERRQ2
4479e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
44804994cf47SJed Brown #undef SETERRQ3
44814994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
448281824310SBarry Smith 
44838cc058d9SJed 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)
448481824310SBarry Smith {
448581824310SBarry Smith   Mat            A  = *AA;
448681824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
448781824310SBarry Smith   InsertMode     is = *isis;
448881824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
448981824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
449081824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
449181824310SBarry Smith   PetscErrorCode ierr;
449281824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
449354f21887SBarry Smith   MatScalar      *ap,value,*aa;
4494ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4495ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
449681824310SBarry Smith 
449781824310SBarry Smith   PetscFunctionBegin;
44984994cf47SJed Brown   MatCheckPreallocated(A,1);
449981824310SBarry Smith   imax  = a->imax;
450081824310SBarry Smith   ai    = a->i;
450181824310SBarry Smith   ailen = a->ilen;
450281824310SBarry Smith   aj    = a->j;
450381824310SBarry Smith   aa    = a->a;
450481824310SBarry Smith 
450581824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
450681824310SBarry Smith     row = im[k];
450781824310SBarry Smith     if (row < 0) continue;
450881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4509ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
451081824310SBarry Smith #endif
451181824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
451281824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
451381824310SBarry Smith     low  = 0;
451481824310SBarry Smith     high = nrow;
451581824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
451681824310SBarry Smith       if (in[l] < 0) continue;
451781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4518ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
451981824310SBarry Smith #endif
452081824310SBarry Smith       col = in[l];
45212205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45222205254eSKarl Rupp       else value = v[k + l*m];
45232205254eSKarl Rupp 
452481824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
452581824310SBarry Smith 
45262205254eSKarl Rupp       if (col <= lastcol) low = 0;
45272205254eSKarl Rupp       else high = nrow;
452881824310SBarry Smith       lastcol = col;
452981824310SBarry Smith       while (high-low > 5) {
453081824310SBarry Smith         t = (low+high)/2;
453181824310SBarry Smith         if (rp[t] > col) high = t;
453281824310SBarry Smith         else             low  = t;
453381824310SBarry Smith       }
453481824310SBarry Smith       for (i=low; i<high; i++) {
453581824310SBarry Smith         if (rp[i] > col) break;
453681824310SBarry Smith         if (rp[i] == col) {
453781824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
453881824310SBarry Smith           else                  ap[i] = value;
453981824310SBarry Smith           goto noinsert;
454081824310SBarry Smith         }
454181824310SBarry Smith       }
454281824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
454381824310SBarry Smith       if (nonew == 1) goto noinsert;
4544ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4545fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
454681824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
454781824310SBarry Smith       /* shift up all the later entries in this row */
454881824310SBarry Smith       for (ii=N; ii>=i; ii--) {
454981824310SBarry Smith         rp[ii+1] = rp[ii];
455081824310SBarry Smith         ap[ii+1] = ap[ii];
455181824310SBarry Smith       }
455281824310SBarry Smith       rp[i] = col;
455381824310SBarry Smith       ap[i] = value;
4554e56f5c9eSBarry Smith       A->nonzerostate++;
455581824310SBarry Smith noinsert:;
455681824310SBarry Smith       low = i + 1;
455781824310SBarry Smith     }
455881824310SBarry Smith     ailen[row] = nrow;
455981824310SBarry Smith   }
456081824310SBarry Smith   PetscFunctionReturnVoid();
456181824310SBarry Smith }
45629f7953f8SBarry Smith 
4563