xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 6712e2f1ace79231a3dc52d650f8fe8f207c217c)
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>
1106873bf2SBarry Smith #include <petsc-private/kernels/blocktranspose.h>
1278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1378b84d54SShri Abhyankar #include <petscthreadcomm.h>
1478b84d54SShri Abhyankar #endif
150716a85fSBarry Smith 
160716a85fSBarry Smith #undef __FUNCT__
170716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
180716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
190716a85fSBarry Smith {
200716a85fSBarry Smith   PetscErrorCode ierr;
210716a85fSBarry Smith   PetscInt       i,m,n;
220716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
230716a85fSBarry Smith 
240716a85fSBarry Smith   PetscFunctionBegin;
250716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
260716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
270716a85fSBarry Smith   if (type == NORM_2) {
280716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
290716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
300716a85fSBarry Smith     }
310716a85fSBarry Smith   } else if (type == NORM_1) {
320716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
330716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
340716a85fSBarry Smith     }
350716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
360716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
370716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
380716a85fSBarry Smith     }
390716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
400716a85fSBarry Smith 
410716a85fSBarry Smith   if (type == NORM_2) {
428f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
430716a85fSBarry Smith   }
440716a85fSBarry Smith   PetscFunctionReturn(0);
450716a85fSBarry Smith }
460716a85fSBarry Smith 
474a2ae208SSatish Balay #undef __FUNCT__
48f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
49f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
506ce1633cSBarry Smith {
516ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
526ce1633cSBarry Smith   const MatScalar *aa = a->a;
536ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
546ce1633cSBarry Smith   const PetscInt  *jj = a->j,*diag;
556ce1633cSBarry Smith   PetscInt        *rows;
566ce1633cSBarry Smith   PetscErrorCode  ierr;
576ce1633cSBarry Smith 
586ce1633cSBarry Smith   PetscFunctionBegin;
596ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
606ce1633cSBarry Smith   diag = a->diag;
616ce1633cSBarry Smith   for (i=0; i<m; i++) {
626ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
636ce1633cSBarry Smith       cnt++;
646ce1633cSBarry Smith     }
656ce1633cSBarry Smith   }
66785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
676ce1633cSBarry Smith   cnt  = 0;
686ce1633cSBarry Smith   for (i=0; i<m; i++) {
696ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
706ce1633cSBarry Smith       rows[cnt++] = i;
716ce1633cSBarry Smith     }
726ce1633cSBarry Smith   }
73f1f41ecbSJed Brown   *nrows = cnt;
74f1f41ecbSJed Brown   *zrows = rows;
75f1f41ecbSJed Brown   PetscFunctionReturn(0);
76f1f41ecbSJed Brown }
77f1f41ecbSJed Brown 
78f1f41ecbSJed Brown #undef __FUNCT__
79f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
80f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
81f1f41ecbSJed Brown {
82f1f41ecbSJed Brown   PetscInt       nrows,*rows;
83f1f41ecbSJed Brown   PetscErrorCode ierr;
84f1f41ecbSJed Brown 
85f1f41ecbSJed Brown   PetscFunctionBegin;
860298fd71SBarry Smith   *zrows = NULL;
87f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
88ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
896ce1633cSBarry Smith   PetscFunctionReturn(0);
906ce1633cSBarry Smith }
916ce1633cSBarry Smith 
926ce1633cSBarry Smith #undef __FUNCT__
93b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
94b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
95b3a44c85SBarry Smith {
96b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
97b3a44c85SBarry Smith   const MatScalar *aa;
98b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
99b3a44c85SBarry Smith   const PetscInt  *ii;
100b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
101b3a44c85SBarry Smith   PetscErrorCode  ierr;
102b3a44c85SBarry Smith 
103b3a44c85SBarry Smith   PetscFunctionBegin;
104b3a44c85SBarry Smith   *keptrows = 0;
105b3a44c85SBarry Smith   ii        = a->i;
106b3a44c85SBarry Smith   for (i=0; i<m; i++) {
107b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
108b3a44c85SBarry Smith     if (!n) {
109b3a44c85SBarry Smith       cnt++;
110b3a44c85SBarry Smith       goto ok1;
111b3a44c85SBarry Smith     }
112b3a44c85SBarry Smith     aa = a->a + ii[i];
113b3a44c85SBarry Smith     for (j=0; j<n; j++) {
114b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
115b3a44c85SBarry Smith     }
116b3a44c85SBarry Smith     cnt++;
117b3a44c85SBarry Smith ok1:;
118b3a44c85SBarry Smith   }
119b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
120785e854fSJed Brown   ierr = PetscMalloc1((A->rmap->n-cnt),&rows);CHKERRQ(ierr);
121b3a44c85SBarry Smith   cnt  = 0;
122b3a44c85SBarry Smith   for (i=0; i<m; i++) {
123b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
124b3a44c85SBarry Smith     if (!n) continue;
125b3a44c85SBarry Smith     aa = a->a + ii[i];
126b3a44c85SBarry Smith     for (j=0; j<n; j++) {
127b3a44c85SBarry Smith       if (aa[j] != 0.0) {
128b3a44c85SBarry Smith         rows[cnt++] = i;
129b3a44c85SBarry Smith         break;
130b3a44c85SBarry Smith       }
131b3a44c85SBarry Smith     }
132b3a44c85SBarry Smith   }
133b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
134b3a44c85SBarry Smith   PetscFunctionReturn(0);
135b3a44c85SBarry Smith }
136b3a44c85SBarry Smith 
137b3a44c85SBarry Smith #undef __FUNCT__
13879299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1397087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
14079299369SBarry Smith {
14179299369SBarry Smith   PetscErrorCode ierr;
14279299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
143d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
14454f21887SBarry Smith   MatScalar      *aa = aij->a;
14554f21887SBarry Smith   PetscScalar    *v;
146ace3abfcSBarry Smith   PetscBool      missing;
14779299369SBarry Smith 
14879299369SBarry Smith   PetscFunctionBegin;
14909f38230SBarry Smith   if (Y->assembled) {
1500298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
15109f38230SBarry Smith     if (!missing) {
15279299369SBarry Smith       diag = aij->diag;
15379299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
15479299369SBarry Smith       if (is == INSERT_VALUES) {
15579299369SBarry Smith         for (i=0; i<m; i++) {
15679299369SBarry Smith           aa[diag[i]] = v[i];
15779299369SBarry Smith         }
15879299369SBarry Smith       } else {
15979299369SBarry Smith         for (i=0; i<m; i++) {
16079299369SBarry Smith           aa[diag[i]] += v[i];
16179299369SBarry Smith         }
16279299369SBarry Smith       }
16379299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
16479299369SBarry Smith       PetscFunctionReturn(0);
16579299369SBarry Smith     }
166acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
16709f38230SBarry Smith   }
16809f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
16909f38230SBarry Smith   PetscFunctionReturn(0);
17009f38230SBarry Smith }
17179299369SBarry Smith 
17279299369SBarry Smith #undef __FUNCT__
1734a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
1741a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
17517ab2063SBarry Smith {
176416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
177dfbe8321SBarry Smith   PetscErrorCode ierr;
17897f1f81fSBarry Smith   PetscInt       i,ishift;
17917ab2063SBarry Smith 
1803a40ed3dSBarry Smith   PetscFunctionBegin;
181d0f46423SBarry Smith   *m = A->rmap->n;
1823a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
183bfeeae90SHong Zhang   ishift = 0;
18453e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
1851a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
186bfeeae90SHong Zhang   } else if (oshift == 1) {
1871a83f524SJed Brown     PetscInt *tia;
188d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1893b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
190785e854fSJed Brown     ierr = PetscMalloc1((A->rmap->n+1),&tia);CHKERRQ(ierr);
1911a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
1921a83f524SJed Brown     *ia = tia;
193ecc77c7aSBarry Smith     if (ja) {
1941a83f524SJed Brown       PetscInt *tja;
195785e854fSJed Brown       ierr = PetscMalloc1((nz+1),&tja);CHKERRQ(ierr);
1961a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
1971a83f524SJed Brown       *ja = tja;
198ecc77c7aSBarry Smith     }
1996945ee14SBarry Smith   } else {
200ecc77c7aSBarry Smith     *ia = a->i;
201ecc77c7aSBarry Smith     if (ja) *ja = a->j;
202a2ce50c7SBarry Smith   }
2033a40ed3dSBarry Smith   PetscFunctionReturn(0);
204a2744918SBarry Smith }
205a2744918SBarry Smith 
2064a2ae208SSatish Balay #undef __FUNCT__
2074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
2081a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2096945ee14SBarry Smith {
210dfbe8321SBarry Smith   PetscErrorCode ierr;
2116945ee14SBarry Smith 
2123a40ed3dSBarry Smith   PetscFunctionBegin;
2133a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
214bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
215606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
216ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
217bcd2baecSBarry Smith   }
2183a40ed3dSBarry Smith   PetscFunctionReturn(0);
21917ab2063SBarry Smith }
22017ab2063SBarry Smith 
2214a2ae208SSatish Balay #undef __FUNCT__
2224a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
2231a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2243b2fbd54SBarry Smith {
2253b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226dfbe8321SBarry Smith   PetscErrorCode ierr;
227d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
22897f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2293b2fbd54SBarry Smith 
2303a40ed3dSBarry Smith   PetscFunctionBegin;
231899cda47SBarry Smith   *nn = n;
2323a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2333b2fbd54SBarry Smith   if (symmetric) {
2341a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2353b2fbd54SBarry Smith   } else {
2361795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
237785e854fSJed Brown     ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
238785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
2393b2fbd54SBarry Smith     jj   = a->j;
2403b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
241bfeeae90SHong Zhang       collengths[jj[i]]++;
2423b2fbd54SBarry Smith     }
2433b2fbd54SBarry Smith     cia[0] = oshift;
2443b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2453b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2463b2fbd54SBarry Smith     }
24797f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2483b2fbd54SBarry Smith     jj   = a->j;
249a93ec695SBarry Smith     for (row=0; row<m; row++) {
250a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
251a93ec695SBarry Smith       for (i=0; i<mr; i++) {
252bfeeae90SHong Zhang         col = *jj++;
2532205254eSKarl Rupp 
2543b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2553b2fbd54SBarry Smith       }
2563b2fbd54SBarry Smith     }
257606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2583b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2593b2fbd54SBarry Smith   }
2603a40ed3dSBarry Smith   PetscFunctionReturn(0);
2613b2fbd54SBarry Smith }
2623b2fbd54SBarry Smith 
2634a2ae208SSatish Balay #undef __FUNCT__
2644a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2651a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2663b2fbd54SBarry Smith {
267dfbe8321SBarry Smith   PetscErrorCode ierr;
268606d414cSSatish Balay 
2693a40ed3dSBarry Smith   PetscFunctionBegin;
2703a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2713b2fbd54SBarry Smith 
272606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
273606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2743a40ed3dSBarry Smith   PetscFunctionReturn(0);
2753b2fbd54SBarry Smith }
2763b2fbd54SBarry Smith 
2777cee066cSHong Zhang /*
2787cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2797cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
280040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2817cee066cSHong Zhang */
2827cee066cSHong Zhang #undef __FUNCT__
2837cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
2847cee066cSHong 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)
2857cee066cSHong Zhang {
2867cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2877cee066cSHong Zhang   PetscErrorCode ierr;
2887cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2897cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2907cee066cSHong Zhang   PetscInt       *cspidx;
2917cee066cSHong Zhang 
2927cee066cSHong Zhang   PetscFunctionBegin;
2937cee066cSHong Zhang   *nn = n;
2947cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
295625f6d37SHong Zhang 
2961795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
297785e854fSJed Brown   ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
298785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
299785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr);
3007cee066cSHong Zhang   jj   = a->j;
3017cee066cSHong Zhang   for (i=0; i<nz; i++) {
3027cee066cSHong Zhang     collengths[jj[i]]++;
3037cee066cSHong Zhang   }
3047cee066cSHong Zhang   cia[0] = oshift;
3057cee066cSHong Zhang   for (i=0; i<n; i++) {
3067cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3077cee066cSHong Zhang   }
3087cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3097cee066cSHong Zhang   jj   = a->j;
3107cee066cSHong Zhang   for (row=0; row<m; row++) {
3117cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3127cee066cSHong Zhang     for (i=0; i<mr; i++) {
3137cee066cSHong Zhang       col = *jj++;
3147cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3157cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3167cee066cSHong Zhang     }
3177cee066cSHong Zhang   }
3187cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3197cee066cSHong Zhang   *ia    = cia; *ja = cja;
3207cee066cSHong Zhang   *spidx = cspidx;
3217cee066cSHong Zhang   PetscFunctionReturn(0);
3227cee066cSHong Zhang }
3237cee066cSHong Zhang 
3247cee066cSHong Zhang #undef __FUNCT__
3257cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3267cee066cSHong 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)
3277cee066cSHong Zhang {
3287cee066cSHong Zhang   PetscErrorCode ierr;
3297cee066cSHong Zhang 
3307cee066cSHong Zhang   PetscFunctionBegin;
3315243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3327cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3337cee066cSHong Zhang   PetscFunctionReturn(0);
3347cee066cSHong Zhang }
3357cee066cSHong Zhang 
33687d4246cSBarry Smith #undef __FUNCT__
33787d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
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 
3494a2ae208SSatish Balay #undef __FUNCT__
3504a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
35197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
35217ab2063SBarry Smith {
353416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
354e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
35597f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3566849ba73SBarry Smith   PetscErrorCode ierr;
357e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
35854f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
359ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
360ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
36117ab2063SBarry Smith 
3623a40ed3dSBarry Smith   PetscFunctionBegin;
36371fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
36417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
365416022c9SBarry Smith     row = im[k];
3665ef9f2a5SBarry Smith     if (row < 0) continue;
3672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
368e32f2f54SBarry 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);
3693b2fbd54SBarry Smith #endif
370bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
37117ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
372416022c9SBarry Smith     low  = 0;
373c71e6ed7SBarry Smith     high = nrow;
37417ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3755ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3762515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
377e32f2f54SBarry 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);
3783b2fbd54SBarry Smith #endif
379bfeeae90SHong Zhang       col = in[l];
38016371a99SBarry Smith       if (v) {
3814b0e389bSBarry Smith         if (roworiented) {
3825ef9f2a5SBarry Smith           value = v[l + k*n];
383bef8e0ddSBarry Smith         } else {
3844b0e389bSBarry Smith           value = v[k + l*m];
3854b0e389bSBarry Smith         }
38616371a99SBarry Smith       } else {
38775567043SBarry Smith         value = 0.;
38816371a99SBarry Smith       }
389abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
39036db0b34SBarry Smith 
3912205254eSKarl Rupp       if (col <= lastcol) low = 0;
3922205254eSKarl Rupp       else high = nrow;
393e2ee6c50SBarry Smith       lastcol = col;
394416022c9SBarry Smith       while (high-low > 5) {
395416022c9SBarry Smith         t = (low+high)/2;
396416022c9SBarry Smith         if (rp[t] > col) high = t;
397416022c9SBarry Smith         else low = t;
39817ab2063SBarry Smith       }
399416022c9SBarry Smith       for (i=low; i<high; i++) {
40017ab2063SBarry Smith         if (rp[i] > col) break;
40117ab2063SBarry Smith         if (rp[i] == col) {
402416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
40317ab2063SBarry Smith           else ap[i] = value;
404e44c0bd4SBarry Smith           low = i + 1;
40517ab2063SBarry Smith           goto noinsert;
40617ab2063SBarry Smith         }
40717ab2063SBarry Smith       }
408abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
409c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
410e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
411fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
412c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
413416022c9SBarry Smith       /* shift up all the later entries in this row */
414416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
41517ab2063SBarry Smith         rp[ii+1] = rp[ii];
41617ab2063SBarry Smith         ap[ii+1] = ap[ii];
41717ab2063SBarry Smith       }
41817ab2063SBarry Smith       rp[i] = col;
41917ab2063SBarry Smith       ap[i] = value;
420416022c9SBarry Smith       low   = i + 1;
421e44c0bd4SBarry Smith noinsert:;
42217ab2063SBarry Smith     }
42317ab2063SBarry Smith     ailen[row] = nrow;
42417ab2063SBarry Smith   }
42588e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4263a40ed3dSBarry Smith   PetscFunctionReturn(0);
42717ab2063SBarry Smith }
42817ab2063SBarry Smith 
42981824310SBarry Smith 
4304a2ae208SSatish Balay #undef __FUNCT__
4314a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
432a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4337eb43aa7SLois Curfman McInnes {
4347eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
43597f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
43697f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
43754f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4387eb43aa7SLois Curfman McInnes 
4393a40ed3dSBarry Smith   PetscFunctionBegin;
4407eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4417eb43aa7SLois Curfman McInnes     row = im[k];
442e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
443e32f2f54SBarry 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);
444bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4457eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4467eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
447e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
448e32f2f54SBarry 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);
449bfeeae90SHong Zhang       col  = in[l];
4507eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4517eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4527eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4537eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4547eb43aa7SLois Curfman McInnes         else low = t;
4557eb43aa7SLois Curfman McInnes       }
4567eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4577eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4587eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
459b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4607eb43aa7SLois Curfman McInnes           goto finished;
4617eb43aa7SLois Curfman McInnes         }
4627eb43aa7SLois Curfman McInnes       }
46397e567efSBarry Smith       *v++ = 0.0;
4647eb43aa7SLois Curfman McInnes finished:;
4657eb43aa7SLois Curfman McInnes     }
4667eb43aa7SLois Curfman McInnes   }
4673a40ed3dSBarry Smith   PetscFunctionReturn(0);
4687eb43aa7SLois Curfman McInnes }
4697eb43aa7SLois Curfman McInnes 
47017ab2063SBarry Smith 
4714a2ae208SSatish Balay #undef __FUNCT__
4724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
473dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
47417ab2063SBarry Smith {
475416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4766849ba73SBarry Smith   PetscErrorCode ierr;
4776f69ff64SBarry Smith   PetscInt       i,*col_lens;
4786f69ff64SBarry Smith   int            fd;
479b37d52dbSMark F. Adams   FILE           *file;
48017ab2063SBarry Smith 
4813a40ed3dSBarry Smith   PetscFunctionBegin;
482b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
483785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
4842205254eSKarl Rupp 
4850700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
486d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
487d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
488416022c9SBarry Smith   col_lens[3] = a->nz;
489416022c9SBarry Smith 
490416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
491d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
492416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
49317ab2063SBarry Smith   }
494d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
495606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
496416022c9SBarry Smith 
497416022c9SBarry Smith   /* store column indices (zero start index) */
4986f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
499416022c9SBarry Smith 
500416022c9SBarry Smith   /* store nonzero values */
5016f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
502b37d52dbSMark F. Adams 
503b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
504b37d52dbSMark F. Adams   if (file) {
505b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
506b37d52dbSMark F. Adams   }
5073a40ed3dSBarry Smith   PetscFunctionReturn(0);
50817ab2063SBarry Smith }
509416022c9SBarry Smith 
51009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
511cd155464SBarry Smith 
5124a2ae208SSatish Balay #undef __FUNCT__
5134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
514dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
515416022c9SBarry Smith {
516416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
517dfbe8321SBarry Smith   PetscErrorCode    ierr;
51860e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
519e060cb09SBarry Smith   const char        *name;
520f3ef73ceSBarry Smith   PetscViewerFormat format;
52117ab2063SBarry Smith 
5223a40ed3dSBarry Smith   PetscFunctionBegin;
523b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
52471c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
52597f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
52660e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
527d00d2cf4SBarry Smith       nofinalvalue = 1;
528d00d2cf4SBarry Smith     }
529d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
530d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
53177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
53277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
533b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
53417ab2063SBarry Smith 
53517ab2063SBarry Smith     for (i=0; i<m; i++) {
53660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
537aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
53860e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e + %18.16ei \n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
53917ab2063SBarry Smith #else
54060e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
54117ab2063SBarry Smith #endif
54217ab2063SBarry Smith       }
54317ab2063SBarry Smith     }
544d00d2cf4SBarry Smith     if (nofinalvalue) {
545d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
546d00d2cf4SBarry Smith     }
547317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
548fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
549d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
55068369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
551cd155464SBarry Smith     PetscFunctionReturn(0);
552fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
553d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
554dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
55544cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
55677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
55760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
558aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
55936db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
56060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56136db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
56260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56336db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
56460e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
5656831982aSBarry Smith         }
56644cd7ae7SLois Curfman McInnes #else
56760e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
56844cd7ae7SLois Curfman McInnes #endif
56944cd7ae7SLois Curfman McInnes       }
570b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57144cd7ae7SLois Curfman McInnes     }
572d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
573fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
57497f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
575d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
576dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
577785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
578496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
579496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
58060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
581496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
582aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
584496be53dSLois Curfman McInnes #else
585496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
586496be53dSLois Curfman McInnes #endif
587496be53dSLois Curfman McInnes         }
588496be53dSLois Curfman McInnes       }
589496be53dSLois Curfman McInnes     }
5902e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
59177431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5922e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
5932205254eSKarl Rupp       if (i+4<m) {
5942205254eSKarl 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);
5952205254eSKarl Rupp       } else if (i+3<m) {
5962205254eSKarl 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);
5972205254eSKarl Rupp       } else if (i+2<m) {
5982205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
5992205254eSKarl Rupp       } else if (i+1<m) {
6002205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6012205254eSKarl Rupp       } else if (i<m) {
6022205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6032205254eSKarl Rupp       } else {
6042205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6052205254eSKarl Rupp       }
606496be53dSLois Curfman McInnes     }
607b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
608606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
609496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
61060e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
61177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
612496be53dSLois Curfman McInnes       }
613b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
614496be53dSLois Curfman McInnes     }
615b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
616496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
61760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
618496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
619aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
62160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6226831982aSBarry Smith           }
623496be53dSLois Curfman McInnes #else
62460e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
625496be53dSLois Curfman McInnes #endif
626496be53dSLois Curfman McInnes         }
627496be53dSLois Curfman McInnes       }
628b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
629496be53dSLois Curfman McInnes     }
630d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
631fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
63297f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
63387828ca2SBarry Smith     PetscScalar value;
63468f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
63568f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
63668f1ed48SBarry Smith 
63768f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
63868f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
63968f1ed48SBarry Smith         realonly = PETSC_FALSE;
64068f1ed48SBarry Smith         break;
64168f1ed48SBarry Smith       }
64268f1ed48SBarry Smith     }
64368f1ed48SBarry Smith #endif
64402594712SBarry Smith 
645d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
646dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
64702594712SBarry Smith     for (i=0; i<m; i++) {
64802594712SBarry Smith       jcnt = 0;
649d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
650e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
65102594712SBarry Smith           value = a->a[cnt++];
652e24b481bSBarry Smith           jcnt++;
65302594712SBarry Smith         } else {
65402594712SBarry Smith           value = 0.0;
65502594712SBarry Smith         }
656aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
65768f1ed48SBarry Smith         if (realonly) {
65860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
65968f1ed48SBarry Smith         } else {
66060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
66168f1ed48SBarry Smith         }
66202594712SBarry Smith #else
66360e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
66402594712SBarry Smith #endif
66502594712SBarry Smith       }
666b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
66702594712SBarry Smith     }
668d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6693c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
670150b93efSMatthew G. Knepley     PetscInt fshift=1;
671d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
6723c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6733c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6743c215bfdSMatthew Knepley #else
6753c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6763c215bfdSMatthew Knepley #endif
677d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6783c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
67960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
6803c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6813c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
68260e0710aSBarry Smith           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);
6833c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
68460e0710aSBarry Smith           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);
6853c215bfdSMatthew Knepley         } else {
68660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6873c215bfdSMatthew Knepley         }
6883c215bfdSMatthew Knepley #else
689150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
6903c215bfdSMatthew Knepley #endif
6913c215bfdSMatthew Knepley       }
6923c215bfdSMatthew Knepley     }
693d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6943a40ed3dSBarry Smith   } else {
695d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
696dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
697d5f3da31SBarry Smith     if (A->factortype) {
69816cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
69916cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
70016cd7e1dSShri Abhyankar         /* L part */
70160e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
70216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
70316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
70460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
70516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
706*6712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
70716cd7e1dSShri Abhyankar           } else {
70860e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
70916cd7e1dSShri Abhyankar           }
71016cd7e1dSShri Abhyankar #else
71160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
71216cd7e1dSShri Abhyankar #endif
71316cd7e1dSShri Abhyankar         }
71416cd7e1dSShri Abhyankar         /* diagonal */
71516cd7e1dSShri Abhyankar         j = a->diag[i];
71616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
71716cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
71860e0710aSBarry 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);
71916cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
720*6712e2f1SBarry 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);
72116cd7e1dSShri Abhyankar         } else {
72260e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
72316cd7e1dSShri Abhyankar         }
72416cd7e1dSShri Abhyankar #else
72560e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
72616cd7e1dSShri Abhyankar #endif
72716cd7e1dSShri Abhyankar 
72816cd7e1dSShri Abhyankar         /* U part */
72960e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
73016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
73116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
73260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
734*6712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]t,(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
73516cd7e1dSShri Abhyankar           } else {
73660e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
73716cd7e1dSShri Abhyankar           }
73816cd7e1dSShri Abhyankar #else
73960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
74016cd7e1dSShri Abhyankar #endif
74116cd7e1dSShri Abhyankar         }
74216cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74316cd7e1dSShri Abhyankar       }
74416cd7e1dSShri Abhyankar     } else {
74517ab2063SBarry Smith       for (i=0; i<m; i++) {
74677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
74760e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
748aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
74936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
75060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
75136db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
75260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7533a40ed3dSBarry Smith           } else {
75460e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
75517ab2063SBarry Smith           }
75617ab2063SBarry Smith #else
75760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
75817ab2063SBarry Smith #endif
75917ab2063SBarry Smith         }
760b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
76117ab2063SBarry Smith       }
76216cd7e1dSShri Abhyankar     }
763d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
76417ab2063SBarry Smith   }
765b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7663a40ed3dSBarry Smith   PetscFunctionReturn(0);
767416022c9SBarry Smith }
768416022c9SBarry Smith 
7699804daf3SBarry Smith #include <petscdraw.h>
7704a2ae208SSatish Balay #undef __FUNCT__
7714a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
772dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
773416022c9SBarry Smith {
774480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
775416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
776dfbe8321SBarry Smith   PetscErrorCode    ierr;
777d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
77836db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
779b0a32e0cSBarry Smith   PetscViewer       viewer;
780f3ef73ceSBarry Smith   PetscViewerFormat format;
781cddf8d76SBarry Smith 
7823a40ed3dSBarry Smith   PetscFunctionBegin;
783480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
784b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
78519bcc07fSBarry Smith 
786b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
787416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7880513a670SBarry Smith 
789fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7900513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
791b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
792416022c9SBarry Smith     for (i=0; i<m; i++) {
793cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
794bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
795bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
79636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
797b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
798cddf8d76SBarry Smith       }
799cddf8d76SBarry Smith     }
800b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
801cddf8d76SBarry Smith     for (i=0; i<m; i++) {
802cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
803bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
804bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
805cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
806b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
807cddf8d76SBarry Smith       }
808cddf8d76SBarry Smith     }
809b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
810cddf8d76SBarry Smith     for (i=0; i<m; i++) {
811cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
812bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
813bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
81436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
815b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
816416022c9SBarry Smith       }
817416022c9SBarry Smith     }
8180513a670SBarry Smith   } else {
8190513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8200513a670SBarry Smith     /* first determine max of all nonzero values */
82197f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
822b0a32e0cSBarry Smith     PetscDraw popup;
82336db0b34SBarry Smith     PetscReal scale;
8240513a670SBarry Smith 
8250513a670SBarry Smith     for (i=0; i<nz; i++) {
8260513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8270513a670SBarry Smith     }
828b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
829b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8302205254eSKarl Rupp     if (popup) {
8312205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8322205254eSKarl Rupp     }
8330513a670SBarry Smith     count = 0;
8340513a670SBarry Smith     for (i=0; i<m; i++) {
8350513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
836bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
837bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
83897f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
839b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8400513a670SBarry Smith         count++;
8410513a670SBarry Smith       }
8420513a670SBarry Smith     }
8430513a670SBarry Smith   }
844480ef9eaSBarry Smith   PetscFunctionReturn(0);
845480ef9eaSBarry Smith }
846cddf8d76SBarry Smith 
8479804daf3SBarry Smith #include <petscdraw.h>
8484a2ae208SSatish Balay #undef __FUNCT__
8494a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
850dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
851480ef9eaSBarry Smith {
852dfbe8321SBarry Smith   PetscErrorCode ierr;
853b0a32e0cSBarry Smith   PetscDraw      draw;
85436db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
855ace3abfcSBarry Smith   PetscBool      isnull;
856480ef9eaSBarry Smith 
857480ef9eaSBarry Smith   PetscFunctionBegin;
858b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
859b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
860480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
861480ef9eaSBarry Smith 
862480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
863d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
864480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
865b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
866b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8670298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8683a40ed3dSBarry Smith   PetscFunctionReturn(0);
869416022c9SBarry Smith }
870416022c9SBarry Smith 
8714a2ae208SSatish Balay #undef __FUNCT__
8724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
873dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
874416022c9SBarry Smith {
875dfbe8321SBarry Smith   PetscErrorCode ierr;
876ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
877416022c9SBarry Smith 
8783a40ed3dSBarry Smith   PetscFunctionBegin;
879251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
880251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
881251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
882c45a1595SBarry Smith   if (iascii) {
8833a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8840f5bd95cSBarry Smith   } else if (isbinary) {
8853a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8860f5bd95cSBarry Smith   } else if (isdraw) {
8873a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
88811aeaf0aSBarry Smith   }
8894108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8903a40ed3dSBarry Smith   PetscFunctionReturn(0);
89117ab2063SBarry Smith }
89219bcc07fSBarry Smith 
8934a2ae208SSatish Balay #undef __FUNCT__
8944a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
895dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
89617ab2063SBarry Smith {
897416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8986849ba73SBarry Smith   PetscErrorCode ierr;
89997f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
900d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
90154f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9023447b6efSHong Zhang   PetscReal      ratio  = 0.6;
90317ab2063SBarry Smith 
9043a40ed3dSBarry Smith   PetscFunctionBegin;
9053a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
90617ab2063SBarry Smith 
90743ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
90817ab2063SBarry Smith   for (i=1; i<m; i++) {
909416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
91017ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
91194a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
91217ab2063SBarry Smith     if (fshift) {
913bfeeae90SHong Zhang       ip = aj + ai[i];
914bfeeae90SHong Zhang       ap = aa + ai[i];
91517ab2063SBarry Smith       N  = ailen[i];
91617ab2063SBarry Smith       for (j=0; j<N; j++) {
91717ab2063SBarry Smith         ip[j-fshift] = ip[j];
91817ab2063SBarry Smith         ap[j-fshift] = ap[j];
91917ab2063SBarry Smith       }
92017ab2063SBarry Smith     }
92117ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
92217ab2063SBarry Smith   }
92317ab2063SBarry Smith   if (m) {
92417ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
92517ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
92617ab2063SBarry Smith   }
9277b083b7cSBarry Smith 
92817ab2063SBarry Smith   /* reset ilen and imax for each row */
9297b083b7cSBarry Smith   a->nonzerorowcnt = 0;
93017ab2063SBarry Smith   for (i=0; i<m; i++) {
93117ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9327b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
93317ab2063SBarry Smith   }
934bfeeae90SHong Zhang   a->nz = ai[m];
93565e19b50SBarry 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);
93617ab2063SBarry Smith 
93709f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
938d0f46423SBarry 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);
939ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
940ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9412205254eSKarl Rupp 
9428e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
943dd5f02e7SSatish Balay   a->reallocs         = 0;
944*6712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
94536db0b34SBarry Smith   a->rmax             = rmax;
9464e220ebcSLois Curfman McInnes 
94711e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9482205254eSKarl Rupp 
94988e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
95071c2f376SKris Buschelman 
9514108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
95271f1c65dSBarry Smith 
953acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9543a40ed3dSBarry Smith   PetscFunctionReturn(0);
95517ab2063SBarry Smith }
95617ab2063SBarry Smith 
9574a2ae208SSatish Balay #undef __FUNCT__
95899cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
95999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
96099cafbc1SBarry Smith {
96199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
96354f21887SBarry Smith   MatScalar      *aa = a->a;
964acf2f550SJed Brown   PetscErrorCode ierr;
96599cafbc1SBarry Smith 
96699cafbc1SBarry Smith   PetscFunctionBegin;
96799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
968acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
96999cafbc1SBarry Smith   PetscFunctionReturn(0);
97099cafbc1SBarry Smith }
97199cafbc1SBarry Smith 
97299cafbc1SBarry Smith #undef __FUNCT__
97399cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
97499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
97599cafbc1SBarry Smith {
97699cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
97799cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
97854f21887SBarry Smith   MatScalar      *aa = a->a;
979acf2f550SJed Brown   PetscErrorCode ierr;
98099cafbc1SBarry Smith 
98199cafbc1SBarry Smith   PetscFunctionBegin;
98299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
983acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
98499cafbc1SBarry Smith   PetscFunctionReturn(0);
98599cafbc1SBarry Smith }
98699cafbc1SBarry Smith 
98778b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
98878b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
98978b84d54SShri Abhyankar {
99078b84d54SShri Abhyankar   PetscErrorCode ierr;
99178b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
99278b84d54SShri Abhyankar   PetscInt       n,start,end;
99378b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
99478b84d54SShri Abhyankar 
99578b84d54SShri Abhyankar   start = trstarts[thread_id];
99678b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
99719baf141SJed Brown   n     = a->i[end] - a->i[start];
99819baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
99978b84d54SShri Abhyankar   return 0;
100078b84d54SShri Abhyankar }
100178b84d54SShri Abhyankar 
100278b84d54SShri Abhyankar #undef __FUNCT__
100378b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
100478b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
100578b84d54SShri Abhyankar {
100678b84d54SShri Abhyankar   PetscErrorCode ierr;
100778b84d54SShri Abhyankar 
100878b84d54SShri Abhyankar   PetscFunctionBegin;
1009ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1010acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101178b84d54SShri Abhyankar   PetscFunctionReturn(0);
101278b84d54SShri Abhyankar }
101378b84d54SShri Abhyankar #else
101499cafbc1SBarry Smith #undef __FUNCT__
10154a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1016dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
101717ab2063SBarry Smith {
1018416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1019dfbe8321SBarry Smith   PetscErrorCode ierr;
10203a40ed3dSBarry Smith 
10213a40ed3dSBarry Smith   PetscFunctionBegin;
1022d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1023acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10243a40ed3dSBarry Smith   PetscFunctionReturn(0);
102517ab2063SBarry Smith }
102678b84d54SShri Abhyankar #endif
1027416022c9SBarry Smith 
10284a2ae208SSatish Balay #undef __FUNCT__
10294a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1030dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
103117ab2063SBarry Smith {
1032416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1033dfbe8321SBarry Smith   PetscErrorCode ierr;
1034d5d45c9bSBarry Smith 
10353a40ed3dSBarry Smith   PetscFunctionBegin;
1036aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1037d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
103817ab2063SBarry Smith #endif
1039e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10406bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10416bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
104205b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1043d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
104405b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
104571f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
104605b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10476bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
104805b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10496bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
105005b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10516bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1052cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10530b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1054a30b2313SHong Zhang 
10554108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1056bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1057901853e0SKris Buschelman 
1058dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1059bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1060bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1061bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1062bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1063bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1064bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1065bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1066bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1067bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10693a40ed3dSBarry Smith   PetscFunctionReturn(0);
107017ab2063SBarry Smith }
107117ab2063SBarry Smith 
10724a2ae208SSatish Balay #undef __FUNCT__
10734a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1074ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
107517ab2063SBarry Smith {
1076416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10774846f1f5SKris Buschelman   PetscErrorCode ierr;
10783a40ed3dSBarry Smith 
10793a40ed3dSBarry Smith   PetscFunctionBegin;
1080a65d3064SKris Buschelman   switch (op) {
1081a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10824e0d8c25SBarry Smith     a->roworiented = flg;
1083a65d3064SKris Buschelman     break;
1084a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1085a9817697SBarry Smith     a->keepnonzeropattern = flg;
1086a65d3064SKris Buschelman     break;
1087512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1088512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1089a65d3064SKris Buschelman     break;
1090a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10914e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1092a65d3064SKris Buschelman     break;
1093a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10944e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1095a65d3064SKris Buschelman     break;
109628b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
109728b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
109828b2fa4aSMatthew Knepley     break;
1099a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11004e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11010df259c2SBarry Smith     break;
11023d472b54SHong Zhang   case MAT_SPD:
1103b1646e73SJed Brown   case MAT_SYMMETRIC:
1104b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1105b1646e73SJed Brown   case MAT_HERMITIAN:
1106b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11075021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11085021d80fSJed Brown     break;
11094e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1110a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1111a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1112290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1113a65d3064SKris Buschelman     break;
1114b87ac2d8SJed Brown   case MAT_USE_INODES:
1115b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1116b87ac2d8SJed Brown     break;
1117a65d3064SKris Buschelman   default:
1118e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1119a65d3064SKris Buschelman   }
11204108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11213a40ed3dSBarry Smith   PetscFunctionReturn(0);
112217ab2063SBarry Smith }
112317ab2063SBarry Smith 
11244a2ae208SSatish Balay #undef __FUNCT__
11254a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1126dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
112717ab2063SBarry Smith {
1128416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11296849ba73SBarry Smith   PetscErrorCode ierr;
1130d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
113135e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
113217ab2063SBarry Smith 
11333a40ed3dSBarry Smith   PetscFunctionBegin;
1134d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1135e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
113635e7444dSHong Zhang 
1137d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1138d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
113935e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11402c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
114135e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
114235e7444dSHong Zhang     PetscFunctionReturn(0);
114335e7444dSHong Zhang   }
114435e7444dSHong Zhang 
11452dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11461ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
114735e7444dSHong Zhang   for (i=0; i<n; i++) {
114835e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11492f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
115035e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
115135e7444dSHong Zhang       if (aj[j] == i) {
115235e7444dSHong Zhang         x[i] = aa[j];
115317ab2063SBarry Smith         break;
115417ab2063SBarry Smith       }
115517ab2063SBarry Smith     }
115617ab2063SBarry Smith   }
11571ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11583a40ed3dSBarry Smith   PetscFunctionReturn(0);
115917ab2063SBarry Smith }
116017ab2063SBarry Smith 
1161c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11624a2ae208SSatish Balay #undef __FUNCT__
11634a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1164dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
116517ab2063SBarry Smith {
1166416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11675c897100SBarry Smith   PetscScalar    *x,*y;
1168dfbe8321SBarry Smith   PetscErrorCode ierr;
1169d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11705c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1171a77337e4SBarry Smith   MatScalar         *v;
1172a77337e4SBarry Smith   PetscScalar       alpha;
11730298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11743447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1175ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11765c897100SBarry Smith #endif
117717ab2063SBarry Smith 
11783a40ed3dSBarry Smith   PetscFunctionBegin;
11792e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11801ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11811ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11825c897100SBarry Smith 
11835c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1184bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11855c897100SBarry Smith #else
11863447b6efSHong Zhang   if (usecprow) {
11873447b6efSHong Zhang     m    = cprow.nrows;
11883447b6efSHong Zhang     ii   = cprow.i;
11897b2bb3b9SHong Zhang     ridx = cprow.rindex;
11903447b6efSHong Zhang   } else {
11913447b6efSHong Zhang     ii = a->i;
11923447b6efSHong Zhang   }
119317ab2063SBarry Smith   for (i=0; i<m; i++) {
11943447b6efSHong Zhang     idx = a->j + ii[i];
11953447b6efSHong Zhang     v   = a->a + ii[i];
11963447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11973447b6efSHong Zhang     if (usecprow) {
11987b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11993447b6efSHong Zhang     } else {
120017ab2063SBarry Smith       alpha = x[i];
12013447b6efSHong Zhang     }
120204fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
120317ab2063SBarry Smith   }
12045c897100SBarry Smith #endif
1205dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
12061ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12071ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12083a40ed3dSBarry Smith   PetscFunctionReturn(0);
120917ab2063SBarry Smith }
121017ab2063SBarry Smith 
12114a2ae208SSatish Balay #undef __FUNCT__
12125c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1213dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12145c897100SBarry Smith {
1215dfbe8321SBarry Smith   PetscErrorCode ierr;
12165c897100SBarry Smith 
12175c897100SBarry Smith   PetscFunctionBegin;
1218170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12195c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12205c897100SBarry Smith   PetscFunctionReturn(0);
12215c897100SBarry Smith }
12225c897100SBarry Smith 
1223c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
122478b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
122578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
122678b84d54SShri Abhyankar {
122778b84d54SShri Abhyankar   PetscErrorCode    ierr;
122878b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
122978b84d54SShri Abhyankar   PetscScalar       *y;
123078b84d54SShri Abhyankar   const PetscScalar *x;
123178b84d54SShri Abhyankar   const MatScalar   *aa;
123278b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
123378b84d54SShri Abhyankar   PetscInt          n,start,end,i;
123478b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
123578b84d54SShri Abhyankar   PetscScalar       sum;
123678b84d54SShri Abhyankar 
123778b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
123878b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
123978b84d54SShri Abhyankar   start = trstarts[thread_id];
124078b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
124178b84d54SShri Abhyankar   aj    = a->j;
124278b84d54SShri Abhyankar   aa    = a->a;
124378b84d54SShri Abhyankar   ai    = a->i;
124478b84d54SShri Abhyankar   for (i=start; i<end; i++) {
124578b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
124678b84d54SShri Abhyankar     aj  = a->j + ai[i];
124778b84d54SShri Abhyankar     aa  = a->a + ai[i];
124878b84d54SShri Abhyankar     sum = 0.0;
124978b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
125078b84d54SShri Abhyankar     y[i] = sum;
125178b84d54SShri Abhyankar   }
125278b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
125378b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
125478b84d54SShri Abhyankar   return 0;
125578b84d54SShri Abhyankar }
125678b84d54SShri Abhyankar 
125778b84d54SShri Abhyankar #undef __FUNCT__
125878b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
125978b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
126078b84d54SShri Abhyankar {
126178b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
126278b84d54SShri Abhyankar   PetscScalar       *y;
126378b84d54SShri Abhyankar   const PetscScalar *x;
126478b84d54SShri Abhyankar   const MatScalar   *aa;
126578b84d54SShri Abhyankar   PetscErrorCode    ierr;
126678b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12670298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12687b083b7cSBarry Smith   PetscInt          n,i;
126978b84d54SShri Abhyankar   PetscScalar       sum;
127078b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
127178b84d54SShri Abhyankar 
127278b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
127378b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
127478b84d54SShri Abhyankar #endif
127578b84d54SShri Abhyankar 
127678b84d54SShri Abhyankar   PetscFunctionBegin;
127778b84d54SShri Abhyankar   aj = a->j;
127878b84d54SShri Abhyankar   aa = a->a;
127978b84d54SShri Abhyankar   ii = a->i;
128078b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
128178b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
128278b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
128378b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
128478b84d54SShri Abhyankar     ii   = a->compressedrow.i;
128578b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
128678b84d54SShri Abhyankar     for (i=0; i<m; i++) {
128778b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
128878b84d54SShri Abhyankar       aj          = a->j + ii[i];
128978b84d54SShri Abhyankar       aa          = a->a + ii[i];
129078b84d54SShri Abhyankar       sum         = 0.0;
129178b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
129278b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
129378b84d54SShri Abhyankar       y[*ridx++] = sum;
129478b84d54SShri Abhyankar     }
129578b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
129678b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
129778b84d54SShri Abhyankar   } else { /* do not use compressed row format */
129878b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
129978b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
130078b84d54SShri Abhyankar #else
1301ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
130278b84d54SShri Abhyankar #endif
130378b84d54SShri Abhyankar   }
13047b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
130578b84d54SShri Abhyankar   PetscFunctionReturn(0);
130678b84d54SShri Abhyankar }
130778b84d54SShri Abhyankar #else
13085c897100SBarry Smith #undef __FUNCT__
13094a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1310dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
131117ab2063SBarry Smith {
1312416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1313d9fead3dSBarry Smith   PetscScalar       *y;
131454f21887SBarry Smith   const PetscScalar *x;
131554f21887SBarry Smith   const MatScalar   *aa;
1316dfbe8321SBarry Smith   PetscErrorCode    ierr;
1317003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13180298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13197b083b7cSBarry Smith   PetscInt          n,i;
1320362ced78SSatish Balay   PetscScalar       sum;
1321ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
132217ab2063SBarry Smith 
1323b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
132497952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1325fee21e36SBarry Smith #endif
1326fee21e36SBarry Smith 
13273a40ed3dSBarry Smith   PetscFunctionBegin;
13283649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13291ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
133097952fefSHong Zhang   aj   = a->j;
133197952fefSHong Zhang   aa   = a->a;
1332416022c9SBarry Smith   ii   = a->i;
13334eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
133497952fefSHong Zhang     m    = a->compressedrow.nrows;
133597952fefSHong Zhang     ii   = a->compressedrow.i;
133697952fefSHong Zhang     ridx = a->compressedrow.rindex;
133797952fefSHong Zhang     for (i=0; i<m; i++) {
133897952fefSHong Zhang       n           = ii[i+1] - ii[i];
133997952fefSHong Zhang       aj          = a->j + ii[i];
134097952fefSHong Zhang       aa          = a->a + ii[i];
134197952fefSHong Zhang       sum         = 0.0;
1342003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1343003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
134497952fefSHong Zhang       y[*ridx++] = sum;
134597952fefSHong Zhang     }
134697952fefSHong Zhang   } else { /* do not use compressed row format */
1347b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1348b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1349b05257ddSBarry Smith #else
135078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1351ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
135278b84d54SShri Abhyankar #else
135317ab2063SBarry Smith     for (i=0; i<m; i++) {
1354003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1355003131ecSBarry Smith       aj          = a->j + ii[i];
1356003131ecSBarry Smith       aa          = a->a + ii[i];
135717ab2063SBarry Smith       sum         = 0.0;
1358003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
135917ab2063SBarry Smith       y[i] = sum;
136017ab2063SBarry Smith     }
13618d195f9aSBarry Smith #endif
136278b84d54SShri Abhyankar #endif
1363b05257ddSBarry Smith   }
13647b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13653649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13661ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13673a40ed3dSBarry Smith   PetscFunctionReturn(0);
136817ab2063SBarry Smith }
136978b84d54SShri Abhyankar #endif
137017ab2063SBarry Smith 
1371b434eb95SMatthew G. Knepley #undef __FUNCT__
1372b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1373b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1374b434eb95SMatthew G. Knepley {
1375b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1376b434eb95SMatthew G. Knepley   PetscScalar       *y;
1377b434eb95SMatthew G. Knepley   const PetscScalar *x;
1378b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1379b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1380b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1381b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1382b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1383b434eb95SMatthew G. Knepley   PetscScalar       sum;
1384b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1385b434eb95SMatthew G. Knepley 
1386b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1387b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1388b434eb95SMatthew G. Knepley #endif
1389b434eb95SMatthew G. Knepley 
1390b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1391b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1392b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1393b434eb95SMatthew G. Knepley   aj   = a->j;
1394b434eb95SMatthew G. Knepley   aa   = a->a;
1395b434eb95SMatthew G. Knepley   ii   = a->i;
1396b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1397b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1398b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1399b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1400b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1401b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1402b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1403b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1404b434eb95SMatthew G. Knepley       sum         = 0.0;
1405b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1406b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1407b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1408b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1409b434eb95SMatthew G. Knepley     }
1410b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1411b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1412b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1413b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1414b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1415b434eb95SMatthew G. Knepley       sum         = 0.0;
1416b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1417b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1418b434eb95SMatthew G. Knepley       y[i] = sum;
1419b434eb95SMatthew G. Knepley     }
1420b434eb95SMatthew G. Knepley   }
1421b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1422b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1423b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1424b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1425b434eb95SMatthew G. Knepley }
1426b434eb95SMatthew G. Knepley 
1427b434eb95SMatthew G. Knepley #undef __FUNCT__
1428b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1429b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1430b434eb95SMatthew G. Knepley {
1431b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1432b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1433b434eb95SMatthew G. Knepley   const PetscScalar *x;
1434b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1435b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1436b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1437b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1438b434eb95SMatthew G. Knepley   PetscScalar       sum;
1439b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1440b434eb95SMatthew G. Knepley 
1441b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1442b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1443b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1444b434eb95SMatthew G. Knepley   if (zz != yy) {
1445b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1446b434eb95SMatthew G. Knepley   } else {
1447b434eb95SMatthew G. Knepley     z = y;
1448b434eb95SMatthew G. Knepley   }
1449b434eb95SMatthew G. Knepley 
1450b434eb95SMatthew G. Knepley   aj = a->j;
1451b434eb95SMatthew G. Knepley   aa = a->a;
1452b434eb95SMatthew G. Knepley   ii = a->i;
1453b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1454b434eb95SMatthew G. Knepley     if (zz != yy) {
1455b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1456b434eb95SMatthew G. Knepley     }
1457b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1458b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1459b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1460b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1461b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1462b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1463b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1464b434eb95SMatthew G. Knepley       sum = y[*ridx];
1465b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1466b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1467b434eb95SMatthew G. Knepley     }
1468b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1469b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1470b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1471b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1472b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1473b434eb95SMatthew G. Knepley       sum = y[i];
1474b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1475b434eb95SMatthew G. Knepley       z[i] = sum;
1476b434eb95SMatthew G. Knepley     }
1477b434eb95SMatthew G. Knepley   }
1478b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1479b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1480b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1481b434eb95SMatthew G. Knepley   if (zz != yy) {
1482b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1483b434eb95SMatthew G. Knepley   }
1484b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1485b434eb95SMatthew G. Knepley }
1486b434eb95SMatthew G. Knepley 
1487c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14884a2ae208SSatish Balay #undef __FUNCT__
14894a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1490dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
149117ab2063SBarry Smith {
1492416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1493f15663dcSBarry Smith   PetscScalar       *y,*z;
1494f15663dcSBarry Smith   const PetscScalar *x;
149554f21887SBarry Smith   const MatScalar   *aa;
1496dfbe8321SBarry Smith   PetscErrorCode    ierr;
1497d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14980298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1499362ced78SSatish Balay   PetscScalar       sum;
1500ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
15019ea0dfa2SSatish Balay 
15023a40ed3dSBarry Smith   PetscFunctionBegin;
1503f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15041ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15052e8a6d31SBarry Smith   if (zz != yy) {
15061ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15072e8a6d31SBarry Smith   } else {
15082e8a6d31SBarry Smith     z = y;
15092e8a6d31SBarry Smith   }
1510bfeeae90SHong Zhang 
151197952fefSHong Zhang   aj = a->j;
151297952fefSHong Zhang   aa = a->a;
1513cddf8d76SBarry Smith   ii = a->i;
15144eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15154eb6d288SHong Zhang     if (zz != yy) {
15164eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15174eb6d288SHong Zhang     }
151897952fefSHong Zhang     m    = a->compressedrow.nrows;
151997952fefSHong Zhang     ii   = a->compressedrow.i;
152097952fefSHong Zhang     ridx = a->compressedrow.rindex;
152197952fefSHong Zhang     for (i=0; i<m; i++) {
152297952fefSHong Zhang       n   = ii[i+1] - ii[i];
152397952fefSHong Zhang       aj  = a->j + ii[i];
152497952fefSHong Zhang       aa  = a->a + ii[i];
152597952fefSHong Zhang       sum = y[*ridx];
1526f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152797952fefSHong Zhang       z[*ridx++] = sum;
152897952fefSHong Zhang     }
152997952fefSHong Zhang   } else { /* do not use compressed row format */
1530f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1531f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1532f15663dcSBarry Smith #else
153317ab2063SBarry Smith     for (i=0; i<m; i++) {
1534f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1535f15663dcSBarry Smith       aj  = a->j + ii[i];
1536f15663dcSBarry Smith       aa  = a->a + ii[i];
153717ab2063SBarry Smith       sum = y[i];
1538f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153917ab2063SBarry Smith       z[i] = sum;
154017ab2063SBarry Smith     }
154102ab625aSSatish Balay #endif
1542f15663dcSBarry Smith   }
1543dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1544f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15451ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15462e8a6d31SBarry Smith   if (zz != yy) {
15471ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15482e8a6d31SBarry Smith   }
15498154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15506b375ea7SVictor Minden   /*
1551918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1552918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1553918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15546b375ea7SVictor Minden   */
1555918e98c3SVictor Minden #endif
15563a40ed3dSBarry Smith   PetscFunctionReturn(0);
155717ab2063SBarry Smith }
155817ab2063SBarry Smith 
155917ab2063SBarry Smith /*
156017ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
156117ab2063SBarry Smith */
15624a2ae208SSatish Balay #undef __FUNCT__
15634a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1564dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
156517ab2063SBarry Smith {
1566416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15676849ba73SBarry Smith   PetscErrorCode ierr;
1568d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
156917ab2063SBarry Smith 
15703a40ed3dSBarry Smith   PetscFunctionBegin;
157109f38230SBarry Smith   if (!a->diag) {
1572785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
15733bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
157409f38230SBarry Smith   }
1575d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
157609f38230SBarry Smith     a->diag[i] = a->i[i+1];
1577bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1578bfeeae90SHong Zhang       if (a->j[j] == i) {
157909f38230SBarry Smith         a->diag[i] = j;
158017ab2063SBarry Smith         break;
158117ab2063SBarry Smith       }
158217ab2063SBarry Smith     }
158317ab2063SBarry Smith   }
15843a40ed3dSBarry Smith   PetscFunctionReturn(0);
158517ab2063SBarry Smith }
158617ab2063SBarry Smith 
1587be5855fcSBarry Smith /*
1588be5855fcSBarry Smith      Checks for missing diagonals
1589be5855fcSBarry Smith */
15904a2ae208SSatish Balay #undef __FUNCT__
15914a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1592ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1593be5855fcSBarry Smith {
1594be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
159597f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1596be5855fcSBarry Smith 
1597be5855fcSBarry Smith   PetscFunctionBegin;
159809f38230SBarry Smith   *missing = PETSC_FALSE;
1599d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
160009f38230SBarry Smith     *missing = PETSC_TRUE;
160109f38230SBarry Smith     if (d) *d = 0;
1602358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
160309f38230SBarry Smith   } else {
1604f1e2ffcdSBarry Smith     diag = a->diag;
1605d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1606bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
160709f38230SBarry Smith         *missing = PETSC_TRUE;
160809f38230SBarry Smith         if (d) *d = i;
160909f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1610358d2f5dSShri Abhyankar         break;
161109f38230SBarry Smith       }
1612be5855fcSBarry Smith     }
1613be5855fcSBarry Smith   }
1614be5855fcSBarry Smith   PetscFunctionReturn(0);
1615be5855fcSBarry Smith }
1616be5855fcSBarry Smith 
161771f1c65dSBarry Smith #undef __FUNCT__
161871f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16197087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
162071f1c65dSBarry Smith {
162171f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
162271f1c65dSBarry Smith   PetscErrorCode ierr;
1623d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
162454f21887SBarry Smith   MatScalar      *v = a->a;
162554f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
162671f1c65dSBarry Smith 
162771f1c65dSBarry Smith   PetscFunctionBegin;
162871f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
162971f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
163071f1c65dSBarry Smith   diag = a->diag;
163171f1c65dSBarry Smith   if (!a->idiag) {
1632dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
16333bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
163471f1c65dSBarry Smith     v    = a->a;
163571f1c65dSBarry Smith   }
163671f1c65dSBarry Smith   mdiag = a->mdiag;
163771f1c65dSBarry Smith   idiag = a->idiag;
163871f1c65dSBarry Smith 
1639028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
164071f1c65dSBarry Smith     for (i=0; i<m; i++) {
164171f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1642e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
164371f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
164471f1c65dSBarry Smith     }
164571f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
164671f1c65dSBarry Smith   } else {
164771f1c65dSBarry Smith     for (i=0; i<m; i++) {
164871f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
164971f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
165071f1c65dSBarry Smith     }
1651dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
165271f1c65dSBarry Smith   }
165371f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
165471f1c65dSBarry Smith   PetscFunctionReturn(0);
165571f1c65dSBarry Smith }
165671f1c65dSBarry Smith 
1657c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16584a2ae208SSatish Balay #undef __FUNCT__
165941f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
166041f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
166117ab2063SBarry Smith {
1662416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1663e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1664e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
166554f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1666dfbe8321SBarry Smith   PetscErrorCode    ierr;
1667d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
166897f1f81fSBarry Smith   const PetscInt    *idx,*diag;
166917ab2063SBarry Smith 
16703a40ed3dSBarry Smith   PetscFunctionBegin;
1671b965ef7fSBarry Smith   its = its*lits;
167291723122SBarry Smith 
167371f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
167471f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
167571f1c65dSBarry Smith   a->fshift = fshift;
167671f1c65dSBarry Smith   a->omega  = omega;
1677ed480e8bSBarry Smith 
167871f1c65dSBarry Smith   diag  = a->diag;
167971f1c65dSBarry Smith   t     = a->ssor_work;
1680ed480e8bSBarry Smith   idiag = a->idiag;
168171f1c65dSBarry Smith   mdiag = a->mdiag;
1682ed480e8bSBarry Smith 
16831ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16843649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1685ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
168617ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
168717ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1688ed480e8bSBarry Smith     bs = b;
168917ab2063SBarry Smith     for (i=0; i<m; i++) {
169071f1c65dSBarry Smith       d   = fshift + mdiag[i];
1691416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1692ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1693ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
169417ab2063SBarry Smith       sum = b[i]*d/omega;
1695003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
169617ab2063SBarry Smith       x[i] = sum;
169717ab2063SBarry Smith     }
16981ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16993649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1700efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17013a40ed3dSBarry Smith     PetscFunctionReturn(0);
170217ab2063SBarry Smith   }
1703c783ea89SBarry Smith 
17042205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17052205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
170617ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1707887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
170817ab2063SBarry Smith 
170917ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
171017ab2063SBarry Smith 
1711887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
171217ab2063SBarry Smith     */
171317ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
171417ab2063SBarry Smith 
171517ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
171617ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1717416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1718ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1719ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
172017ab2063SBarry Smith       sum = b[i];
1721e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1722ed480e8bSBarry Smith       x[i] = sum*idiag[i];
172317ab2063SBarry Smith     }
172417ab2063SBarry Smith 
172517ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1726416022c9SBarry Smith     v = a->a;
17272205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
172817ab2063SBarry Smith 
172917ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1730ed480e8bSBarry Smith     ts   = t;
1731416022c9SBarry Smith     diag = a->diag;
173217ab2063SBarry Smith     for (i=0; i<m; i++) {
1733416022c9SBarry Smith       n   = diag[i] - a->i[i];
1734ed480e8bSBarry Smith       idx = a->j + a->i[i];
1735ed480e8bSBarry Smith       v   = a->a + a->i[i];
173617ab2063SBarry Smith       sum = t[i];
1737003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1738ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1739733d66baSBarry Smith       /*  x = x + t */
1740733d66baSBarry Smith       x[i] += t[i];
174117ab2063SBarry Smith     }
174217ab2063SBarry Smith 
1743dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17441ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17453649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17463a40ed3dSBarry Smith     PetscFunctionReturn(0);
174717ab2063SBarry Smith   }
174817ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
174917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
175017ab2063SBarry Smith       for (i=0; i<m; i++) {
1751416022c9SBarry Smith         n   = diag[i] - a->i[i];
1752ed480e8bSBarry Smith         idx = a->j + a->i[i];
1753ed480e8bSBarry Smith         v   = a->a + a->i[i];
175417ab2063SBarry Smith         sum = b[i];
1755e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17565c99c7daSBarry Smith         t[i] = sum;
1757ed480e8bSBarry Smith         x[i] = sum*idiag[i];
175817ab2063SBarry Smith       }
17595c99c7daSBarry Smith       xb   = t;
1760efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17613a40ed3dSBarry Smith     } else xb = b;
176217ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
176317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1764416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1765ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1766ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
176717ab2063SBarry Smith         sum = xb[i];
1768e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17695c99c7daSBarry Smith         if (xb == b) {
1770ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17715c99c7daSBarry Smith         } else {
1772b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
177317ab2063SBarry Smith         }
17745c99c7daSBarry Smith       }
1775b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
177617ab2063SBarry Smith     }
177717ab2063SBarry Smith     its--;
177817ab2063SBarry Smith   }
177917ab2063SBarry Smith   while (its--) {
178017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
178117ab2063SBarry Smith       for (i=0; i<m; i++) {
1782b19a5dc2SMark Adams         /* lower */
1783b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1784ed480e8bSBarry Smith         idx = a->j + a->i[i];
1785ed480e8bSBarry Smith         v   = a->a + a->i[i];
178617ab2063SBarry Smith         sum = b[i];
1787e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1788b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1789b19a5dc2SMark Adams         /* upper */
1790b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1791b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1792b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1793b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1794b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
179517ab2063SBarry Smith       }
1796b19a5dc2SMark Adams       xb   = t;
17979f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1798b19a5dc2SMark Adams     } else xb = b;
179917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
180017ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1801b19a5dc2SMark Adams         sum = xb[i];
1802b19a5dc2SMark Adams         if (xb == b) {
1803b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1804416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1805ed480e8bSBarry Smith           idx = a->j + a->i[i];
1806ed480e8bSBarry Smith           v   = a->a + a->i[i];
1807e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1808ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1809b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1810b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1811b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1812b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1813b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1814b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
181517ab2063SBarry Smith         }
1816b19a5dc2SMark Adams       }
1817b19a5dc2SMark Adams       if (xb == b) {
18189f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1819b19a5dc2SMark Adams       } else {
1820b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1821b19a5dc2SMark Adams       }
182217ab2063SBarry Smith     }
182317ab2063SBarry Smith   }
18241ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18253649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1826365a8a9eSBarry Smith   PetscFunctionReturn(0);
182717ab2063SBarry Smith }
182817ab2063SBarry Smith 
18292af78befSBarry Smith 
18304a2ae208SSatish Balay #undef __FUNCT__
18314a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1832dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
183317ab2063SBarry Smith {
1834416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18354e220ebcSLois Curfman McInnes 
18363a40ed3dSBarry Smith   PetscFunctionBegin;
18374e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18384e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18394e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18404e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18414e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18428e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18437adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1844d5f3da31SBarry Smith   if (A->factortype) {
18454e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18464e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18474e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18484e220ebcSLois Curfman McInnes   } else {
18494e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18504e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18514e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18524e220ebcSLois Curfman McInnes   }
18533a40ed3dSBarry Smith   PetscFunctionReturn(0);
185417ab2063SBarry Smith }
185517ab2063SBarry Smith 
18564a2ae208SSatish Balay #undef __FUNCT__
18574a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18582b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
185917ab2063SBarry Smith {
1860416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18613b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18626849ba73SBarry Smith   PetscErrorCode    ierr;
186397b48c8fSBarry Smith   const PetscScalar *xx;
186497b48c8fSBarry Smith   PetscScalar       *bb;
1865ace3abfcSBarry Smith   PetscBool         missing;
186617ab2063SBarry Smith 
18673a40ed3dSBarry Smith   PetscFunctionBegin;
186897b48c8fSBarry Smith   if (x && b) {
186997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
187097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
187197b48c8fSBarry Smith     for (i=0; i<N; i++) {
187297b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
187397b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
187497b48c8fSBarry Smith     }
187597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
187697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
187797b48c8fSBarry Smith   }
187897b48c8fSBarry Smith 
1879a9817697SBarry Smith   if (a->keepnonzeropattern) {
1880f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1881e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1882bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1883f1e2ffcdSBarry Smith     }
1884f4df32b1SMatthew Knepley     if (diag != 0.0) {
188509f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1886e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1887f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1888f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1889f1e2ffcdSBarry Smith       }
1890f1e2ffcdSBarry Smith     }
189188e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1892f1e2ffcdSBarry Smith   } else {
1893f4df32b1SMatthew Knepley     if (diag != 0.0) {
189417ab2063SBarry Smith       for (i=0; i<N; i++) {
1895e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18967ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1897416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1898f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1899bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
19007ae801bdSBarry Smith         } else { /* in case row was completely empty */
1901f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
190217ab2063SBarry Smith         }
190317ab2063SBarry Smith       }
19043a40ed3dSBarry Smith     } else {
190517ab2063SBarry Smith       for (i=0; i<N; i++) {
1906e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1907416022c9SBarry Smith         a->ilen[rows[i]] = 0;
190817ab2063SBarry Smith       }
190917ab2063SBarry Smith     }
191088e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1911f1e2ffcdSBarry Smith   }
191243a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19133a40ed3dSBarry Smith   PetscFunctionReturn(0);
191417ab2063SBarry Smith }
191517ab2063SBarry Smith 
19164a2ae208SSatish Balay #undef __FUNCT__
19176e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19186e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19196e169961SBarry Smith {
19206e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19216e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19226e169961SBarry Smith   PetscErrorCode    ierr;
19232b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19246e169961SBarry Smith   const PetscScalar *xx;
19256e169961SBarry Smith   PetscScalar       *bb;
19266e169961SBarry Smith 
19276e169961SBarry Smith   PetscFunctionBegin;
19286e169961SBarry Smith   if (x && b) {
19296e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19306e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19312b40b63fSBarry Smith     vecs = PETSC_TRUE;
19326e169961SBarry Smith   }
19331795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
19346e169961SBarry Smith   for (i=0; i<N; i++) {
19356e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19366e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19372205254eSKarl Rupp 
19386e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19396e169961SBarry Smith   }
19406e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19416e169961SBarry Smith     if (!zeroed[i]) {
19426e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19436e169961SBarry Smith         if (zeroed[a->j[j]]) {
19442b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19456e169961SBarry Smith           a->a[j] = 0.0;
19466e169961SBarry Smith         }
19476e169961SBarry Smith       }
19482b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19496e169961SBarry Smith   }
19506e169961SBarry Smith   if (x && b) {
19516e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19526e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19536e169961SBarry Smith   }
19546e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19556e169961SBarry Smith   if (diag != 0.0) {
19566e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19576e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19586e169961SBarry Smith     for (i=0; i<N; i++) {
19596e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19606e169961SBarry Smith     }
19616e169961SBarry Smith   }
19626e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19636e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19646e169961SBarry Smith   PetscFunctionReturn(0);
19656e169961SBarry Smith }
19666e169961SBarry Smith 
19676e169961SBarry Smith #undef __FUNCT__
19684a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1969a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
197017ab2063SBarry Smith {
1971416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
197297f1f81fSBarry Smith   PetscInt   *itmp;
197317ab2063SBarry Smith 
19743a40ed3dSBarry Smith   PetscFunctionBegin;
1975e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
197617ab2063SBarry Smith 
1977416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1978bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
197917ab2063SBarry Smith   if (idx) {
1980bfeeae90SHong Zhang     itmp = a->j + a->i[row];
198126fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
198217ab2063SBarry Smith     else *idx = 0;
198317ab2063SBarry Smith   }
19843a40ed3dSBarry Smith   PetscFunctionReturn(0);
198517ab2063SBarry Smith }
198617ab2063SBarry Smith 
1987bfeeae90SHong Zhang /* remove this function? */
19884a2ae208SSatish Balay #undef __FUNCT__
19894a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1990a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
199117ab2063SBarry Smith {
19923a40ed3dSBarry Smith   PetscFunctionBegin;
19933a40ed3dSBarry Smith   PetscFunctionReturn(0);
199417ab2063SBarry Smith }
199517ab2063SBarry Smith 
19964a2ae208SSatish Balay #undef __FUNCT__
19974a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1998dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
199917ab2063SBarry Smith {
2000416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
200154f21887SBarry Smith   MatScalar      *v  = a->a;
200236db0b34SBarry Smith   PetscReal      sum = 0.0;
20036849ba73SBarry Smith   PetscErrorCode ierr;
200497f1f81fSBarry Smith   PetscInt       i,j;
200517ab2063SBarry Smith 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
200717ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2008416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
200936db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
201017ab2063SBarry Smith     }
20118f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20123a40ed3dSBarry Smith   } else if (type == NORM_1) {
201336db0b34SBarry Smith     PetscReal *tmp;
201497f1f81fSBarry Smith     PetscInt  *jj = a->j;
20151795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2016064f8208SBarry Smith     *nrm = 0.0;
2017416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2018bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
201917ab2063SBarry Smith     }
2020d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2021064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
202217ab2063SBarry Smith     }
2023606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20243a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2025064f8208SBarry Smith     *nrm = 0.0;
2026d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2027bfeeae90SHong Zhang       v   = a->a + a->i[j];
202817ab2063SBarry Smith       sum = 0.0;
2029416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2030cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
203117ab2063SBarry Smith       }
2032064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
203317ab2063SBarry Smith     }
2034f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20353a40ed3dSBarry Smith   PetscFunctionReturn(0);
203617ab2063SBarry Smith }
203717ab2063SBarry Smith 
20384e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20394e938277SHong Zhang #undef __FUNCT__
20404e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20414e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20424e938277SHong Zhang {
20434e938277SHong Zhang   PetscErrorCode ierr;
20444e938277SHong Zhang   PetscInt       i,j,anzj;
20454e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20464e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20474e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20484e938277SHong Zhang 
20494e938277SHong Zhang   PetscFunctionBegin;
20504e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20511795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2052785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2053785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
20544e938277SHong Zhang 
20554e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20564e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
205726fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20584e938277SHong Zhang   /* Form ati for csr format of A^T. */
205926fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20604e938277SHong Zhang 
20614e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20624e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20634e938277SHong Zhang 
20644e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20654e938277SHong Zhang   for (i=0;i<am;i++) {
20664e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20674e938277SHong Zhang     for (j=0;j<anzj;j++) {
20684e938277SHong Zhang       atj[atfill[*aj]] = i;
20694e938277SHong Zhang       atfill[*aj++]   += 1;
20704e938277SHong Zhang     }
20714e938277SHong Zhang   }
20724e938277SHong Zhang 
20734e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20744e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2075ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20762205254eSKarl Rupp 
2077a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2078a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2079a2f3521dSMark F. Adams 
20804e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20814e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20824e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20834e938277SHong Zhang   b->nonew   = 0;
20844e938277SHong Zhang   PetscFunctionReturn(0);
20854e938277SHong Zhang }
20864e938277SHong Zhang 
20874a2ae208SSatish Balay #undef __FUNCT__
20884a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2089fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
209017ab2063SBarry Smith {
2091416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2092416022c9SBarry Smith   Mat            C;
20936849ba73SBarry Smith   PetscErrorCode ierr;
2094d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
209554f21887SBarry Smith   MatScalar      *array = a->a;
209617ab2063SBarry Smith 
20973a40ed3dSBarry Smith   PetscFunctionBegin;
2098e32f2f54SBarry Smith   if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2099fc4dec0aSBarry Smith 
2100fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
21011795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2102bfeeae90SHong Zhang 
2103bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2104ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2105d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2106a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21077adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2108ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2109606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2110a541d17aSBarry Smith   } else {
2111a541d17aSBarry Smith     C = *B;
2112a541d17aSBarry Smith   }
2113a541d17aSBarry Smith 
211417ab2063SBarry Smith   for (i=0; i<m; i++) {
211517ab2063SBarry Smith     len    = ai[i+1]-ai[i];
211687d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2117b9b97703SBarry Smith     array += len;
2118b9b97703SBarry Smith     aj    += len;
211917ab2063SBarry Smith   }
21206d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21216d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
212217ab2063SBarry Smith 
2123815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2124416022c9SBarry Smith     *B = C;
212517ab2063SBarry Smith   } else {
2126eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
212717ab2063SBarry Smith   }
21283a40ed3dSBarry Smith   PetscFunctionReturn(0);
212917ab2063SBarry Smith }
213017ab2063SBarry Smith 
2131cd0d46ebSvictorle #undef __FUNCT__
21325fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21337087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2134cd0d46ebSvictorle {
2135cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
213654f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
213754f21887SBarry Smith   MatScalar      *va,*vb;
21386849ba73SBarry Smith   PetscErrorCode ierr;
213997f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2140cd0d46ebSvictorle 
2141cd0d46ebSvictorle   PetscFunctionBegin;
2142cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2143cd0d46ebSvictorle 
2144cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2145cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21465485867bSBarry Smith   if (ma!=nb || na!=mb) {
21475485867bSBarry Smith     *f = PETSC_FALSE;
21485485867bSBarry Smith     PetscFunctionReturn(0);
21495485867bSBarry Smith   }
2150cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2151cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2152cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2153785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2154785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2155cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2156cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2157cd0d46ebSvictorle 
2158cd0d46ebSvictorle   *f = PETSC_TRUE;
2159cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2160cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
216197f1f81fSBarry Smith       PetscInt    idc,idr;
21625485867bSBarry Smith       PetscScalar vc,vr;
2163cd0d46ebSvictorle       /* column/row index/value */
21645485867bSBarry Smith       idc = adx[aptr[i]];
21655485867bSBarry Smith       idr = bdx[bptr[idc]];
21665485867bSBarry Smith       vc  = va[aptr[i]];
21675485867bSBarry Smith       vr  = vb[bptr[idc]];
21685485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21695485867bSBarry Smith         *f = PETSC_FALSE;
21705485867bSBarry Smith         goto done;
2171cd0d46ebSvictorle       } else {
21725485867bSBarry Smith         aptr[i]++;
21735485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2174cd0d46ebSvictorle       }
2175cd0d46ebSvictorle     }
2176cd0d46ebSvictorle   }
2177cd0d46ebSvictorle done:
2178cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21793aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2180cd0d46ebSvictorle   PetscFunctionReturn(0);
2181cd0d46ebSvictorle }
2182cd0d46ebSvictorle 
21831cbb95d3SBarry Smith #undef __FUNCT__
21841cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21857087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21861cbb95d3SBarry Smith {
21871cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
218854f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
218954f21887SBarry Smith   MatScalar      *va,*vb;
21901cbb95d3SBarry Smith   PetscErrorCode ierr;
21911cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21921cbb95d3SBarry Smith 
21931cbb95d3SBarry Smith   PetscFunctionBegin;
21941cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21951cbb95d3SBarry Smith 
21961cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21971cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21981cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21991cbb95d3SBarry Smith     *f = PETSC_FALSE;
22001cbb95d3SBarry Smith     PetscFunctionReturn(0);
22011cbb95d3SBarry Smith   }
22021cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22031cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22041cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2205785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2206785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
22071cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22081cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22091cbb95d3SBarry Smith 
22101cbb95d3SBarry Smith   *f = PETSC_TRUE;
22111cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22121cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22131cbb95d3SBarry Smith       PetscInt    idc,idr;
22141cbb95d3SBarry Smith       PetscScalar vc,vr;
22151cbb95d3SBarry Smith       /* column/row index/value */
22161cbb95d3SBarry Smith       idc = adx[aptr[i]];
22171cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22181cbb95d3SBarry Smith       vc  = va[aptr[i]];
22191cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22201cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22211cbb95d3SBarry Smith         *f = PETSC_FALSE;
22221cbb95d3SBarry Smith         goto done;
22231cbb95d3SBarry Smith       } else {
22241cbb95d3SBarry Smith         aptr[i]++;
22251cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22261cbb95d3SBarry Smith       }
22271cbb95d3SBarry Smith     }
22281cbb95d3SBarry Smith   }
22291cbb95d3SBarry Smith done:
22301cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22311cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22321cbb95d3SBarry Smith   PetscFunctionReturn(0);
22331cbb95d3SBarry Smith }
22341cbb95d3SBarry Smith 
22359e29f15eSvictorle #undef __FUNCT__
22369e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2237ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22389e29f15eSvictorle {
2239dfbe8321SBarry Smith   PetscErrorCode ierr;
22406e111a19SKarl Rupp 
22419e29f15eSvictorle   PetscFunctionBegin;
22425485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22439e29f15eSvictorle   PetscFunctionReturn(0);
22449e29f15eSvictorle }
22459e29f15eSvictorle 
22464a2ae208SSatish Balay #undef __FUNCT__
22471cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2248ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22491cbb95d3SBarry Smith {
22501cbb95d3SBarry Smith   PetscErrorCode ierr;
22516e111a19SKarl Rupp 
22521cbb95d3SBarry Smith   PetscFunctionBegin;
22531cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22541cbb95d3SBarry Smith   PetscFunctionReturn(0);
22551cbb95d3SBarry Smith }
22561cbb95d3SBarry Smith 
22571cbb95d3SBarry Smith #undef __FUNCT__
22584a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2259dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
226017ab2063SBarry Smith {
2261416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226254f21887SBarry Smith   PetscScalar    *l,*r,x;
226354f21887SBarry Smith   MatScalar      *v;
2264dfbe8321SBarry Smith   PetscErrorCode ierr;
2265d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
226617ab2063SBarry Smith 
22673a40ed3dSBarry Smith   PetscFunctionBegin;
226817ab2063SBarry Smith   if (ll) {
22693ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22703ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2271e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2272e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22731ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2274416022c9SBarry Smith     v    = a->a;
227517ab2063SBarry Smith     for (i=0; i<m; i++) {
227617ab2063SBarry Smith       x = l[i];
2277416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22782205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
227917ab2063SBarry Smith     }
22801ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2281efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228217ab2063SBarry Smith   }
228317ab2063SBarry Smith   if (rr) {
2284e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2285e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22861ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2287416022c9SBarry Smith     v    = a->a; jj = a->j;
22882205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22891ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2290efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
229117ab2063SBarry Smith   }
2292acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22933a40ed3dSBarry Smith   PetscFunctionReturn(0);
229417ab2063SBarry Smith }
229517ab2063SBarry Smith 
22964a2ae208SSatish Balay #undef __FUNCT__
22974a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
229897f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
229917ab2063SBarry Smith {
2300db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23016849ba73SBarry Smith   PetscErrorCode ierr;
2302d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
230397f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23045d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23055d0c19d7SBarry Smith   PetscInt       nrows,ncols;
230697f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
230754f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2308416022c9SBarry Smith   Mat            C;
2309ace3abfcSBarry Smith   PetscBool      stride,sorted;
231017ab2063SBarry Smith 
23113a40ed3dSBarry Smith   PetscFunctionBegin;
231214ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2313e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
231414ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2315e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
231699141d43SSatish Balay 
231717ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2318b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2319b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
232017ab2063SBarry Smith 
2321fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2322251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2323fee21e36SBarry Smith   if (stride && step == 1) {
232402834360SBarry Smith     /* special case of contiguous rows */
2325dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
232602834360SBarry Smith     /* loop over new rows determining lens and starting points */
232702834360SBarry Smith     for (i=0; i<nrows; i++) {
2328bfeeae90SHong Zhang       kstart = ai[irow[i]];
2329a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
233002834360SBarry Smith       for (k=kstart; k<kend; k++) {
2331bfeeae90SHong Zhang         if (aj[k] >= first) {
233202834360SBarry Smith           starts[i] = k;
233302834360SBarry Smith           break;
233402834360SBarry Smith         }
233502834360SBarry Smith       }
2336a2744918SBarry Smith       sum = 0;
233702834360SBarry Smith       while (k < kend) {
2338bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2339a2744918SBarry Smith         sum++;
234002834360SBarry Smith       }
2341a2744918SBarry Smith       lens[i] = sum;
234202834360SBarry Smith     }
234302834360SBarry Smith     /* create submatrix */
2344cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
234597f1f81fSBarry Smith       PetscInt n_cols,n_rows;
234608480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2347e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2348d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
234908480c60SBarry Smith       C    = *B;
23503a40ed3dSBarry Smith     } else {
23513bef6203SJed Brown       PetscInt rbs,cbs;
2352ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2353f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23543bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23553bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23563bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23577adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2358ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
235908480c60SBarry Smith     }
2360db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2361db02288aSLois Curfman McInnes 
236202834360SBarry Smith     /* loop over rows inserting into submatrix */
2363db02288aSLois Curfman McInnes     a_new = c->a;
2364db02288aSLois Curfman McInnes     j_new = c->j;
2365db02288aSLois Curfman McInnes     i_new = c->i;
2366bfeeae90SHong Zhang 
236702834360SBarry Smith     for (i=0; i<nrows; i++) {
2368a2744918SBarry Smith       ii    = starts[i];
2369a2744918SBarry Smith       lensi = lens[i];
2370a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2371a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
237202834360SBarry Smith       }
237387828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2374a2744918SBarry Smith       a_new     += lensi;
2375a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2376a2744918SBarry Smith       c->ilen[i] = lensi;
237702834360SBarry Smith     }
23780e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23793a40ed3dSBarry Smith   } else {
238002834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23811795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2382785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
23834dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23844dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23854dcab191SBarry 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);
23864dcab191SBarry Smith #endif
23874dcab191SBarry Smith       smap[icol[i]] = i+1;
23884dcab191SBarry Smith     }
23894dcab191SBarry Smith 
239002834360SBarry Smith     /* determine lens of each row */
239102834360SBarry Smith     for (i=0; i<nrows; i++) {
2392bfeeae90SHong Zhang       kstart  = ai[irow[i]];
239302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
239402834360SBarry Smith       lens[i] = 0;
239502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2396bfeeae90SHong Zhang         if (smap[aj[k]]) {
239702834360SBarry Smith           lens[i]++;
239802834360SBarry Smith         }
239902834360SBarry Smith       }
240002834360SBarry Smith     }
240117ab2063SBarry Smith     /* Create and fill new matrix */
2402a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2403ace3abfcSBarry Smith       PetscBool equal;
24040f5bd95cSBarry Smith 
240599141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2406e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2407d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2408f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2409d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
241008480c60SBarry Smith       C    = *B;
24113a40ed3dSBarry Smith     } else {
24123bef6203SJed Brown       PetscInt rbs,cbs;
2413ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2414f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24153bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24163bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24173bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24187adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2419ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
242008480c60SBarry Smith     }
242199141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
242217ab2063SBarry Smith     for (i=0; i<nrows; i++) {
242399141d43SSatish Balay       row      = irow[i];
2424bfeeae90SHong Zhang       kstart   = ai[row];
242599141d43SSatish Balay       kend     = kstart + a->ilen[row];
2426bfeeae90SHong Zhang       mat_i    = c->i[i];
242799141d43SSatish Balay       mat_j    = c->j + mat_i;
242899141d43SSatish Balay       mat_a    = c->a + mat_i;
242999141d43SSatish Balay       mat_ilen = c->ilen + i;
243017ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2431bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2432ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
243399141d43SSatish Balay           *mat_a++ = a->a[k];
243499141d43SSatish Balay           (*mat_ilen)++;
243599141d43SSatish Balay 
243617ab2063SBarry Smith         }
243717ab2063SBarry Smith       }
243817ab2063SBarry Smith     }
243902834360SBarry Smith     /* Free work space */
244002834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2441606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2442606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
244302834360SBarry Smith   }
24446d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24456d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244617ab2063SBarry Smith 
244717ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2448416022c9SBarry Smith   *B   = C;
24493a40ed3dSBarry Smith   PetscFunctionReturn(0);
245017ab2063SBarry Smith }
245117ab2063SBarry Smith 
24521df811f5SHong Zhang #undef __FUNCT__
245382d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2454fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
245582d44351SHong Zhang {
245682d44351SHong Zhang   PetscErrorCode ierr;
245782d44351SHong Zhang   Mat            B;
245882d44351SHong Zhang 
245982d44351SHong Zhang   PetscFunctionBegin;
2460c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
246182d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
246282d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2463a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
246482d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
246582d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
246682d44351SHong Zhang     *subMat = B;
2467c2d650bdSHong Zhang   } else {
2468c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2469c2d650bdSHong Zhang   }
247082d44351SHong Zhang   PetscFunctionReturn(0);
247182d44351SHong Zhang }
247282d44351SHong Zhang 
247382d44351SHong Zhang #undef __FUNCT__
24744a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24750481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2476a871dcd8SBarry Smith {
247763b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2478dfbe8321SBarry Smith   PetscErrorCode ierr;
247963b91edcSBarry Smith   Mat            outA;
2480ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
248163b91edcSBarry Smith 
24823a40ed3dSBarry Smith   PetscFunctionBegin;
2483e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24841df811f5SHong Zhang 
2485b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2486b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2487a871dcd8SBarry Smith 
248863b91edcSBarry Smith   outA             = inA;
2489d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24902205254eSKarl Rupp 
2491c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24926bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24932205254eSKarl Rupp 
2494c3122656SLisandro Dalcin   a->row = row;
24952205254eSKarl Rupp 
2496c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24976bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24982205254eSKarl Rupp 
2499c3122656SLisandro Dalcin   a->col = col;
250063b91edcSBarry Smith 
250136db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
25026bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
25034c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25043bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2505f0ec6fceSSatish Balay 
250694a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2507785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
25083bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
250994a9d846SBarry Smith   }
251063b91edcSBarry Smith 
2511f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2512137fb511SHong Zhang   if (row_identity && col_identity) {
2513ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2514137fb511SHong Zhang   } else {
2515719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2516137fb511SHong Zhang   }
25173a40ed3dSBarry Smith   PetscFunctionReturn(0);
2518a871dcd8SBarry Smith }
2519a871dcd8SBarry Smith 
25204a2ae208SSatish Balay #undef __FUNCT__
25214a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2522f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2523f0b747eeSBarry Smith {
2524f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2525f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2526efee365bSSatish Balay   PetscErrorCode ierr;
2527c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25283a40ed3dSBarry Smith 
25293a40ed3dSBarry Smith   PetscFunctionBegin;
2530c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25318b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2532efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2533acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2535f0b747eeSBarry Smith }
2536f0b747eeSBarry Smith 
25374a2ae208SSatish Balay #undef __FUNCT__
25384a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
253997f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2540cddf8d76SBarry Smith {
2541dfbe8321SBarry Smith   PetscErrorCode ierr;
254297f1f81fSBarry Smith   PetscInt       i;
2543cddf8d76SBarry Smith 
25443a40ed3dSBarry Smith   PetscFunctionBegin;
2545cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2546785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2547cddf8d76SBarry Smith   }
2548cddf8d76SBarry Smith 
2549cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25506a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2551cddf8d76SBarry Smith   }
25523a40ed3dSBarry Smith   PetscFunctionReturn(0);
2553cddf8d76SBarry Smith }
2554cddf8d76SBarry Smith 
25554a2ae208SSatish Balay #undef __FUNCT__
25564a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
255797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25584dcbc457SBarry Smith {
2559e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25606849ba73SBarry Smith   PetscErrorCode ierr;
25615d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25625d0c19d7SBarry Smith   const PetscInt *idx;
256397f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2564f1af5d2fSBarry Smith   PetscBT        table;
2565bbd702dbSSatish Balay 
25663a40ed3dSBarry Smith   PetscFunctionBegin;
2567d0f46423SBarry Smith   m  = A->rmap->n;
2568e4d965acSSatish Balay   ai = a->i;
2569bfeeae90SHong Zhang   aj = a->j;
25708a047759SSatish Balay 
2571e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
257206763907SSatish Balay 
2573785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
257453b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
257506763907SSatish Balay 
2576e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2577b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2578e4d965acSSatish Balay     isz  = 0;
25796831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2580e4d965acSSatish Balay 
2581e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25824dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2583b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2584e4d965acSSatish Balay 
2585dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2586e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25872205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25884dcbc457SBarry Smith     }
258906763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25906bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2591e4d965acSSatish Balay 
259204a348a9SBarry Smith     k = 0;
259304a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
259404a348a9SBarry Smith       n = isz;
259506763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2596e4d965acSSatish Balay         row   = nidx[k];
2597e4d965acSSatish Balay         start = ai[row];
2598e4d965acSSatish Balay         end   = ai[row+1];
259904a348a9SBarry Smith         for (l = start; l<end; l++) {
2600efb16452SHong Zhang           val = aj[l];
26012205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2602e4d965acSSatish Balay         }
2603e4d965acSSatish Balay       }
2604e4d965acSSatish Balay     }
260570b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2606e4d965acSSatish Balay   }
260794bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2608606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26093a40ed3dSBarry Smith   PetscFunctionReturn(0);
26104dcbc457SBarry Smith }
261117ab2063SBarry Smith 
26120513a670SBarry Smith /* -------------------------------------------------------------- */
26134a2ae208SSatish Balay #undef __FUNCT__
26144a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2615dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26160513a670SBarry Smith {
26170513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26186849ba73SBarry Smith   PetscErrorCode ierr;
26193b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26205d0c19d7SBarry Smith   const PetscInt *row,*col;
26215d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
262256cd22aeSBarry Smith   IS             icolp,irowp;
26230298fd71SBarry Smith   PetscInt       *cwork = NULL;
26240298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26250513a670SBarry Smith 
26263a40ed3dSBarry Smith   PetscFunctionBegin;
26274c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
262856cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26294c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
263056cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26310513a670SBarry Smith 
26320513a670SBarry Smith   /* determine lengths of permuted rows */
2633785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
26342205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2635ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2636f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2637a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26387adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2639ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2640606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26410513a670SBarry Smith 
2642785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26430513a670SBarry Smith   for (i=0; i<m; i++) {
264432ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26452205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2646cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
264732ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26480513a670SBarry Smith   }
2649606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26502205254eSKarl Rupp 
26513c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26522205254eSKarl Rupp 
26530513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26540513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
265556cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
265656cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26576bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26586bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26593a40ed3dSBarry Smith   PetscFunctionReturn(0);
26600513a670SBarry Smith }
26610513a670SBarry Smith 
26624a2ae208SSatish Balay #undef __FUNCT__
26634a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2664dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2665cb5b572fSBarry Smith {
2666dfbe8321SBarry Smith   PetscErrorCode ierr;
2667cb5b572fSBarry Smith 
2668cb5b572fSBarry Smith   PetscFunctionBegin;
266933f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
267033f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2671be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2672be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2673be6bf707SBarry Smith 
2674700c5bfcSBarry 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");
2675d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2676cb5b572fSBarry Smith   } else {
2677cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2678cb5b572fSBarry Smith   }
2679cb5b572fSBarry Smith   PetscFunctionReturn(0);
2680cb5b572fSBarry Smith }
2681cb5b572fSBarry Smith 
26824a2ae208SSatish Balay #undef __FUNCT__
26834994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26844994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2685273d9f13SBarry Smith {
2686dfbe8321SBarry Smith   PetscErrorCode ierr;
2687273d9f13SBarry Smith 
2688273d9f13SBarry Smith   PetscFunctionBegin;
2689ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2690273d9f13SBarry Smith   PetscFunctionReturn(0);
2691273d9f13SBarry Smith }
2692273d9f13SBarry Smith 
26934a2ae208SSatish Balay #undef __FUNCT__
26948c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
26958c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26966c0721eeSBarry Smith {
26976c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26986e111a19SKarl Rupp 
26996c0721eeSBarry Smith   PetscFunctionBegin;
27006c0721eeSBarry Smith   *array = a->a;
27016c0721eeSBarry Smith   PetscFunctionReturn(0);
27026c0721eeSBarry Smith }
27036c0721eeSBarry Smith 
27044a2ae208SSatish Balay #undef __FUNCT__
27058c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27068c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27076c0721eeSBarry Smith {
27086c0721eeSBarry Smith   PetscFunctionBegin;
27096c0721eeSBarry Smith   PetscFunctionReturn(0);
27106c0721eeSBarry Smith }
2711273d9f13SBarry Smith 
27128229c054SShri Abhyankar /*
27138229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27148229c054SShri Abhyankar    have different nonzero structure.
27158229c054SShri Abhyankar */
2716ac90fabeSBarry Smith #undef __FUNCT__
27178229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27188229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2719ec7775f6SShri Abhyankar {
27208229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2721ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2722ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2723ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2724ec7775f6SShri Abhyankar 
2725ec7775f6SShri Abhyankar   PetscFunctionBegin;
2726ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2727ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27288af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27298af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27308af7cee1SJed Brown     nnz[i] = 0;
27318af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27328af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27338af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27348af7cee1SJed Brown       nnz[i]++;
27358af7cee1SJed Brown     }
27368af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2737ec7775f6SShri Abhyankar   }
2738ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2739ec7775f6SShri Abhyankar }
2740ec7775f6SShri Abhyankar 
2741ec7775f6SShri Abhyankar #undef __FUNCT__
2742ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2743f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2744ac90fabeSBarry Smith {
2745dfbe8321SBarry Smith   PetscErrorCode ierr;
274697f1f81fSBarry Smith   PetscInt       i;
2747ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2748c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2749ac90fabeSBarry Smith 
2750ac90fabeSBarry Smith   PetscFunctionBegin;
2751c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2752ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2753f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27548b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2755acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2756c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2757a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2758a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27596bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2760a30b2313SHong Zhang     }
2761a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27620298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2763a30b2313SHong Zhang       y->XtoY = X;
2764407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2765c537a176SHong Zhang     }
2766f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2767*6712e2f1SBarry Smith     ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %D/%D = %g\n",x->nz,y->nz,(double)((PetscReal)(x->nz)/(y->nz+1)));CHKERRQ(ierr);
2768ac90fabeSBarry Smith   } else {
27698229c054SShri Abhyankar     Mat      B;
27708229c054SShri Abhyankar     PetscInt *nnz;
2771785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2772ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2773bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27744aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2775a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2776176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27778229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2778ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2779ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2780ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27818229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2782ac90fabeSBarry Smith   }
2783ac90fabeSBarry Smith   PetscFunctionReturn(0);
2784ac90fabeSBarry Smith }
2785ac90fabeSBarry Smith 
2786521d7252SBarry Smith #undef __FUNCT__
2787354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27887087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2789354c94deSBarry Smith {
2790354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2791354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2792354c94deSBarry Smith   PetscInt    i,nz;
2793354c94deSBarry Smith   PetscScalar *a;
2794354c94deSBarry Smith 
2795354c94deSBarry Smith   PetscFunctionBegin;
2796354c94deSBarry Smith   nz = aij->nz;
2797354c94deSBarry Smith   a  = aij->a;
27982205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2799354c94deSBarry Smith #else
2800354c94deSBarry Smith   PetscFunctionBegin;
2801354c94deSBarry Smith #endif
2802354c94deSBarry Smith   PetscFunctionReturn(0);
2803354c94deSBarry Smith }
2804354c94deSBarry Smith 
2805e34fafa9SBarry Smith #undef __FUNCT__
2806985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2807985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2808e34fafa9SBarry Smith {
2809e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2810e34fafa9SBarry Smith   PetscErrorCode ierr;
2811d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2812e34fafa9SBarry Smith   PetscReal      atmp;
2813985db425SBarry Smith   PetscScalar    *x;
2814e34fafa9SBarry Smith   MatScalar      *aa;
2815e34fafa9SBarry Smith 
2816e34fafa9SBarry Smith   PetscFunctionBegin;
2817e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2818e34fafa9SBarry Smith   aa = a->a;
2819e34fafa9SBarry Smith   ai = a->i;
2820e34fafa9SBarry Smith   aj = a->j;
2821e34fafa9SBarry Smith 
2822985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2823e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2824e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2825e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2826e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2827e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28289189402eSHong Zhang     x[i]  = 0.0;
2829e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2830985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2831985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2832985db425SBarry Smith       aa++; aj++;
2833985db425SBarry Smith     }
2834985db425SBarry Smith   }
2835985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2836985db425SBarry Smith   PetscFunctionReturn(0);
2837985db425SBarry Smith }
2838985db425SBarry Smith 
2839985db425SBarry Smith #undef __FUNCT__
2840985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2841985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2842985db425SBarry Smith {
2843985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2844985db425SBarry Smith   PetscErrorCode ierr;
2845d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2846985db425SBarry Smith   PetscScalar    *x;
2847985db425SBarry Smith   MatScalar      *aa;
2848985db425SBarry Smith 
2849985db425SBarry Smith   PetscFunctionBegin;
2850e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2851985db425SBarry Smith   aa = a->a;
2852985db425SBarry Smith   ai = a->i;
2853985db425SBarry Smith   aj = a->j;
2854985db425SBarry Smith 
2855985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2856985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2857985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2858e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2859985db425SBarry Smith   for (i=0; i<m; i++) {
2860985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2861d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2862985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2863985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2864985db425SBarry Smith       x[i] = 0.0;
2865985db425SBarry Smith       if (idx) {
2866985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2867985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2868985db425SBarry Smith           if (aj[j] > j) {
2869985db425SBarry Smith             idx[i] = j;
2870985db425SBarry Smith             break;
2871985db425SBarry Smith           }
2872985db425SBarry Smith         }
2873985db425SBarry Smith       }
2874985db425SBarry Smith     }
2875985db425SBarry Smith     for (j=0; j<ncols; j++) {
2876985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2877985db425SBarry Smith       aa++; aj++;
2878985db425SBarry Smith     }
2879985db425SBarry Smith   }
2880985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2881985db425SBarry Smith   PetscFunctionReturn(0);
2882985db425SBarry Smith }
2883985db425SBarry Smith 
2884985db425SBarry Smith #undef __FUNCT__
2885c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2886c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2887c87e5d42SMatthew Knepley {
2888c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2889c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2890c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2891c87e5d42SMatthew Knepley   PetscReal      atmp;
2892c87e5d42SMatthew Knepley   PetscScalar    *x;
2893c87e5d42SMatthew Knepley   MatScalar      *aa;
2894c87e5d42SMatthew Knepley 
2895c87e5d42SMatthew Knepley   PetscFunctionBegin;
2896e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2897c87e5d42SMatthew Knepley   aa = a->a;
2898c87e5d42SMatthew Knepley   ai = a->i;
2899c87e5d42SMatthew Knepley   aj = a->j;
2900c87e5d42SMatthew Knepley 
2901c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2902c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2903c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
290460e0710aSBarry 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);
2905c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2906c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2907289a08f5SMatthew Knepley     if (ncols) {
2908289a08f5SMatthew Knepley       /* Get first nonzero */
2909289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2910289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29112205254eSKarl Rupp         if (atmp > 1.0e-12) {
29122205254eSKarl Rupp           x[i] = atmp;
29132205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29142205254eSKarl Rupp           break;
29152205254eSKarl Rupp         }
2916289a08f5SMatthew Knepley       }
291712431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2918289a08f5SMatthew Knepley     } else {
2919289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2920289a08f5SMatthew Knepley     }
2921c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2922c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2923289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2924c87e5d42SMatthew Knepley       aa++; aj++;
2925c87e5d42SMatthew Knepley     }
2926c87e5d42SMatthew Knepley   }
2927c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2928c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2929c87e5d42SMatthew Knepley }
2930c87e5d42SMatthew Knepley 
2931c87e5d42SMatthew Knepley #undef __FUNCT__
2932985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2933985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2934985db425SBarry Smith {
2935985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2936985db425SBarry Smith   PetscErrorCode ierr;
2937d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2938985db425SBarry Smith   PetscScalar    *x;
2939985db425SBarry Smith   MatScalar      *aa;
2940985db425SBarry Smith 
2941985db425SBarry Smith   PetscFunctionBegin;
2942e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2943985db425SBarry Smith   aa = a->a;
2944985db425SBarry Smith   ai = a->i;
2945985db425SBarry Smith   aj = a->j;
2946985db425SBarry Smith 
2947985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2948985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2949985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2950e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2951985db425SBarry Smith   for (i=0; i<m; i++) {
2952985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2953d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2954985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2955985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2956985db425SBarry Smith       x[i] = 0.0;
2957985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2958985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2959985db425SBarry Smith         for (j=0; j<ncols; j++) {
2960985db425SBarry Smith           if (aj[j] > j) {
2961985db425SBarry Smith             idx[i] = j;
2962985db425SBarry Smith             break;
2963985db425SBarry Smith           }
2964985db425SBarry Smith         }
2965985db425SBarry Smith       }
2966985db425SBarry Smith     }
2967985db425SBarry Smith     for (j=0; j<ncols; j++) {
2968985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2969985db425SBarry Smith       aa++; aj++;
2970e34fafa9SBarry Smith     }
2971e34fafa9SBarry Smith   }
2972e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2973e34fafa9SBarry Smith   PetscFunctionReturn(0);
2974e34fafa9SBarry Smith }
2975bbead8a2SBarry Smith 
2976bbead8a2SBarry Smith #include <petscblaslapack.h>
297706873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
2978bbead8a2SBarry Smith 
2979bbead8a2SBarry Smith #undef __FUNCT__
2980bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2981713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2982bbead8a2SBarry Smith {
2983bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2984bbead8a2SBarry Smith   PetscErrorCode ierr;
298534fc4b71SJed Brown   PetscInt       i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2986bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2987bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2988bbead8a2SBarry Smith 
2989bbead8a2SBarry Smith   PetscFunctionBegin;
29904a0d0026SBarry Smith   if (a->ibdiagvalid) {
29914a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29924a0d0026SBarry Smith     PetscFunctionReturn(0);
29934a0d0026SBarry Smith   }
2994bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2995bbead8a2SBarry Smith   if (!a->ibdiag) {
2996785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29973bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2998bbead8a2SBarry Smith   }
2999bbead8a2SBarry Smith   diag = a->ibdiag;
3000bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3001bbead8a2SBarry Smith   /* factor and invert each block */
3002bbead8a2SBarry Smith   switch (bs) {
3003bbead8a2SBarry Smith   case 1:
3004bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3005bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3006bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3007bbead8a2SBarry Smith     }
3008bbead8a2SBarry Smith     break;
3009bbead8a2SBarry Smith   case 2:
3010bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3011bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3012bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
301396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
301496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3015bbead8a2SBarry Smith       diag += 4;
3016bbead8a2SBarry Smith     }
3017bbead8a2SBarry Smith     break;
3018bbead8a2SBarry Smith   case 3:
3019bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3020bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3021bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
302296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
302396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3024bbead8a2SBarry Smith       diag += 9;
3025bbead8a2SBarry Smith     }
3026bbead8a2SBarry Smith     break;
3027bbead8a2SBarry Smith   case 4:
3028bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3029bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3030bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
303196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
303296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3033bbead8a2SBarry Smith       diag += 16;
3034bbead8a2SBarry Smith     }
3035bbead8a2SBarry Smith     break;
3036bbead8a2SBarry Smith   case 5:
3037bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3038bbead8a2SBarry 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;
3039bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
304096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
304196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3042bbead8a2SBarry Smith       diag += 25;
3043bbead8a2SBarry Smith     }
3044bbead8a2SBarry Smith     break;
3045bbead8a2SBarry Smith   case 6:
3046bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3047bbead8a2SBarry 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;
3048bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
304996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
305096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3051bbead8a2SBarry Smith       diag += 36;
3052bbead8a2SBarry Smith     }
3053bbead8a2SBarry Smith     break;
3054bbead8a2SBarry Smith   case 7:
3055bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3056bbead8a2SBarry 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;
3057bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
305896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
305996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3060bbead8a2SBarry Smith       diag += 49;
3061bbead8a2SBarry Smith     }
3062bbead8a2SBarry Smith     break;
3063bbead8a2SBarry Smith   default:
3064dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3065bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3066bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3067bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3068bbead8a2SBarry Smith       }
3069bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
307096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
307196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3072bbead8a2SBarry Smith       diag += bs2;
3073bbead8a2SBarry Smith     }
3074bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3075bbead8a2SBarry Smith   }
3076bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3077bbead8a2SBarry Smith   PetscFunctionReturn(0);
3078bbead8a2SBarry Smith }
3079bbead8a2SBarry Smith 
308073a71a0fSBarry Smith #undef __FUNCT__
308173a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
308273a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
308373a71a0fSBarry Smith {
308473a71a0fSBarry Smith   PetscErrorCode ierr;
308573a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
308673a71a0fSBarry Smith   PetscScalar    a;
308773a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
308873a71a0fSBarry Smith 
308973a71a0fSBarry Smith   PetscFunctionBegin;
309073a71a0fSBarry Smith   if (!x->assembled) {
309173a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
309273a71a0fSBarry Smith     for (i=0; i<m; i++) {
309373a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
309473a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
309573a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
309673a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
309773a71a0fSBarry Smith       }
309873a71a0fSBarry Smith     }
309973a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
310073a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
310173a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
310273a71a0fSBarry Smith   PetscFunctionReturn(0);
310373a71a0fSBarry Smith }
310473a71a0fSBarry Smith 
3105682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31060a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3107cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3108cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3109cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
311097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31117c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31127c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3113db4efbfdSBarry Smith                                         0,
3114db4efbfdSBarry Smith                                         0,
3115db4efbfdSBarry Smith                                         0,
3116db4efbfdSBarry Smith                                 /* 10*/ 0,
3117cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3118cb5b572fSBarry Smith                                         0,
311941f059aeSBarry Smith                                         MatSOR_SeqAIJ,
312017ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
312197304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3122cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3123cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3124cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3125cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
312697304618SKris Buschelman                                 /* 20*/ 0,
3127cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3128cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3129cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3130d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3131db4efbfdSBarry Smith                                         0,
3132db4efbfdSBarry Smith                                         0,
3133db4efbfdSBarry Smith                                         0,
3134db4efbfdSBarry Smith                                         0,
31354994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3136db4efbfdSBarry Smith                                         0,
3137db4efbfdSBarry Smith                                         0,
31388c778c55SBarry Smith                                         0,
31398c778c55SBarry Smith                                         0,
3140d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3141cb5b572fSBarry Smith                                         0,
3142cb5b572fSBarry Smith                                         0,
3143cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3144cb5b572fSBarry Smith                                         0,
3145d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3146cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3147cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3148cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3149cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3150d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3151cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3152cb5b572fSBarry Smith                                         0,
315379299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31546e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
315573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31563b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31573b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31583b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3159a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
316093dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3161b9617806SBarry Smith                                         0,
31620513a670SBarry Smith                                         0,
3163cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3164cda55fadSBarry Smith                                         0,
3165d519adbfSMatthew Knepley                                 /* 59*/ 0,
3166b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3167b9b97703SBarry Smith                                         MatView_SeqAIJ,
3168357abbc8SBarry Smith                                         0,
3169321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3170321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3171321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3172ee4f033dSBarry Smith                                         0,
3173ee4f033dSBarry Smith                                         0,
3174ee4f033dSBarry Smith                                         0,
3175d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3176c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3177ee4f033dSBarry Smith                                         0,
3178ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3179dcf5cc72SBarry Smith                                         0,
3180d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31813acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
318297304618SKris Buschelman                                         0,
318397304618SKris Buschelman                                         0,
318497304618SKris Buschelman                                         0,
31856ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
318697304618SKris Buschelman                                         0,
318797304618SKris Buschelman                                         0,
318897304618SKris Buschelman                                         0,
3189bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3190d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31911cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31926284ec50SHong Zhang                                         0,
31936284ec50SHong Zhang                                         0,
3194bc011b1eSHong Zhang                                         0,
3195d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
319626be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
319726be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
319865e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31994a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
320065e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
32016fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
32026fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
32036fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32042121bac1SHong Zhang                                         0,
32052121bac1SHong Zhang                                 /* 99*/ 0,
3206609c6c4dSKris Buschelman                                         0,
3207609c6c4dSKris Buschelman                                         0,
320887d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
320987d4246cSBarry Smith                                         0,
3210d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
321199cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3212f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3213f5edf698SHong Zhang                                         0,
32142bebee5dSHong Zhang                                         0,
3215cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3216985db425SBarry Smith                                         0,
32172af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32182af78befSBarry Smith                                         0,
3219599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3220d519adbfSMatthew Knepley                                 /*114*/ 0,
3221599ef60dSHong Zhang                                         0,
32223c2a7987SHong Zhang                                         0,
3223fe97e370SBarry Smith                                         0,
3224fbdbba38SShri Abhyankar                                         0,
3225fbdbba38SShri Abhyankar                                 /*119*/ 0,
3226fbdbba38SShri Abhyankar                                         0,
3227fbdbba38SShri Abhyankar                                         0,
322882d44351SHong Zhang                                         0,
3229b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32300716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3231bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
323237868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
323337868618SMatthew G Knepley                                         0,
323437868618SMatthew G Knepley                                         0,
32355df89d91SHong Zhang                                 /*129*/ 0,
323675648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
323775648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
323875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3239b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3240b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32412b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32422b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32432b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32443964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32453964eb88SJed Brown                                  /*139*/0,
3246f9426fe0SMark Adams                                         0,
32471919a2e2SJed Brown                                         0,
3248f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32499e29f15eSvictorle };
325017ab2063SBarry Smith 
32514a2ae208SSatish Balay #undef __FUNCT__
32524a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32537087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3254bef8e0ddSBarry Smith {
3255bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325697f1f81fSBarry Smith   PetscInt   i,nz,n;
3257bef8e0ddSBarry Smith 
3258bef8e0ddSBarry Smith   PetscFunctionBegin;
3259bef8e0ddSBarry Smith   nz = aij->maxnz;
3260d0f46423SBarry Smith   n  = mat->rmap->n;
3261bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3262bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3263bef8e0ddSBarry Smith   }
3264bef8e0ddSBarry Smith   aij->nz = nz;
3265bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3266bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3267bef8e0ddSBarry Smith   }
3268bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3269bef8e0ddSBarry Smith }
3270bef8e0ddSBarry Smith 
32714a2ae208SSatish Balay #undef __FUNCT__
32724a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3273bef8e0ddSBarry Smith /*@
3274bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3275bef8e0ddSBarry Smith        in the matrix.
3276bef8e0ddSBarry Smith 
3277bef8e0ddSBarry Smith   Input Parameters:
3278bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3279bef8e0ddSBarry Smith -  indices - the column indices
3280bef8e0ddSBarry Smith 
328115091d37SBarry Smith   Level: advanced
328215091d37SBarry Smith 
3283bef8e0ddSBarry Smith   Notes:
3284bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3285bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3286bef8e0ddSBarry Smith   of the MatSetValues() operation.
3287bef8e0ddSBarry Smith 
3288bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3289d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3290bef8e0ddSBarry Smith 
3291bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3292bef8e0ddSBarry Smith 
3293b9617806SBarry Smith     The indices should start with zero, not one.
3294b9617806SBarry Smith 
3295bef8e0ddSBarry Smith @*/
32967087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3297bef8e0ddSBarry Smith {
32984ac538c5SBarry Smith   PetscErrorCode ierr;
3299bef8e0ddSBarry Smith 
3300bef8e0ddSBarry Smith   PetscFunctionBegin;
33010700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33024482741eSBarry Smith   PetscValidPointer(indices,2);
33034ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3304bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3305bef8e0ddSBarry Smith }
3306bef8e0ddSBarry Smith 
3307be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3308be6bf707SBarry Smith 
33094a2ae208SSatish Balay #undef __FUNCT__
33104a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33117087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3312be6bf707SBarry Smith {
3313be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33146849ba73SBarry Smith   PetscErrorCode ierr;
3315d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3316be6bf707SBarry Smith 
3317be6bf707SBarry Smith   PetscFunctionBegin;
3318f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3319be6bf707SBarry Smith 
3320be6bf707SBarry Smith   /* allocate space for values if not already there */
3321be6bf707SBarry Smith   if (!aij->saved_values) {
3322785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
33233bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3324be6bf707SBarry Smith   }
3325be6bf707SBarry Smith 
3326be6bf707SBarry Smith   /* copy values over */
332787828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3328be6bf707SBarry Smith   PetscFunctionReturn(0);
3329be6bf707SBarry Smith }
3330be6bf707SBarry Smith 
33314a2ae208SSatish Balay #undef __FUNCT__
3332b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3333be6bf707SBarry Smith /*@
3334be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3335be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3336be6bf707SBarry Smith        nonlinear portion.
3337be6bf707SBarry Smith 
3338be6bf707SBarry Smith    Collect on Mat
3339be6bf707SBarry Smith 
3340be6bf707SBarry Smith   Input Parameters:
33410e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3342be6bf707SBarry Smith 
334315091d37SBarry Smith   Level: advanced
334415091d37SBarry Smith 
3345be6bf707SBarry Smith   Common Usage, with SNESSolve():
3346be6bf707SBarry Smith $    Create Jacobian matrix
3347be6bf707SBarry Smith $    Set linear terms into matrix
3348be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3349be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3350be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3351512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3352be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3353be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3354be6bf707SBarry Smith $    In your Jacobian routine
3355be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3356be6bf707SBarry Smith $      Set nonlinear terms in matrix
3357be6bf707SBarry Smith 
3358be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3359be6bf707SBarry Smith $    // build linear portion of Jacobian
3360512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3361be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3362be6bf707SBarry Smith $    loop over nonlinear iterations
3363be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3364be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3365be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3366be6bf707SBarry Smith $       Solve linear system with Jacobian
3367be6bf707SBarry Smith $    endloop
3368be6bf707SBarry Smith 
3369be6bf707SBarry Smith   Notes:
3370be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3371512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3372be6bf707SBarry Smith     calling this routine.
3373be6bf707SBarry Smith 
33740c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33750c468ba9SBarry Smith     and does not allocated additional space.
33760c468ba9SBarry Smith 
3377be6bf707SBarry Smith .seealso: MatRetrieveValues()
3378be6bf707SBarry Smith 
3379be6bf707SBarry Smith @*/
33807087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3381be6bf707SBarry Smith {
33824ac538c5SBarry Smith   PetscErrorCode ierr;
3383be6bf707SBarry Smith 
3384be6bf707SBarry Smith   PetscFunctionBegin;
33850700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3386e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3387e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33884ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3389be6bf707SBarry Smith   PetscFunctionReturn(0);
3390be6bf707SBarry Smith }
3391be6bf707SBarry Smith 
33924a2ae208SSatish Balay #undef __FUNCT__
33934a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33947087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3395be6bf707SBarry Smith {
3396be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33976849ba73SBarry Smith   PetscErrorCode ierr;
3398d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3399be6bf707SBarry Smith 
3400be6bf707SBarry Smith   PetscFunctionBegin;
3401f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3402f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3403be6bf707SBarry Smith   /* copy values over */
340487828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3405be6bf707SBarry Smith   PetscFunctionReturn(0);
3406be6bf707SBarry Smith }
3407be6bf707SBarry Smith 
34084a2ae208SSatish Balay #undef __FUNCT__
34094a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3410be6bf707SBarry Smith /*@
3411be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3412be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3413be6bf707SBarry Smith        nonlinear portion.
3414be6bf707SBarry Smith 
3415be6bf707SBarry Smith    Collect on Mat
3416be6bf707SBarry Smith 
3417be6bf707SBarry Smith   Input Parameters:
3418be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3419be6bf707SBarry Smith 
342015091d37SBarry Smith   Level: advanced
342115091d37SBarry Smith 
3422be6bf707SBarry Smith .seealso: MatStoreValues()
3423be6bf707SBarry Smith 
3424be6bf707SBarry Smith @*/
34257087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3426be6bf707SBarry Smith {
34274ac538c5SBarry Smith   PetscErrorCode ierr;
3428be6bf707SBarry Smith 
3429be6bf707SBarry Smith   PetscFunctionBegin;
34300700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3431e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3432e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34334ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3434be6bf707SBarry Smith   PetscFunctionReturn(0);
3435be6bf707SBarry Smith }
3436be6bf707SBarry Smith 
3437f83d6046SBarry Smith 
3438be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34394a2ae208SSatish Balay #undef __FUNCT__
34404a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
344117ab2063SBarry Smith /*@C
3442682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34430d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34446e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
344551c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34462bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344717ab2063SBarry Smith 
3448db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3449db81eaa0SLois Curfman McInnes 
345017ab2063SBarry Smith    Input Parameters:
3451db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
345217ab2063SBarry Smith .  m - number of rows
345317ab2063SBarry Smith .  n - number of columns
345417ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
345551c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34560298fd71SBarry Smith          (possibly different for each row) or NULL
345717ab2063SBarry Smith 
345817ab2063SBarry Smith    Output Parameter:
3459416022c9SBarry Smith .  A - the matrix
346017ab2063SBarry Smith 
3461175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3462ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3463175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3464175b88e8SBarry Smith 
3465b259b22eSLois Curfman McInnes    Notes:
346649a6f317SBarry Smith    If nnz is given then nz is ignored
346749a6f317SBarry Smith 
346817ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346917ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34700002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
347144cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
347217ab2063SBarry Smith 
347317ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34740298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34753d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34766da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347717ab2063SBarry Smith 
3478682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34794fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3480682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34816c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34826c7ebb05SLois Curfman McInnes 
34836c7ebb05SLois Curfman McInnes    Options Database Keys:
3484698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34859db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348617ab2063SBarry Smith 
3487027ccd11SLois Curfman McInnes    Level: intermediate
3488027ccd11SLois Curfman McInnes 
348969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
349036db0b34SBarry Smith 
349117ab2063SBarry Smith @*/
34927087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
349317ab2063SBarry Smith {
3494dfbe8321SBarry Smith   PetscErrorCode ierr;
34956945ee14SBarry Smith 
34963a40ed3dSBarry Smith   PetscFunctionBegin;
3497f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3498117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3499c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3500d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3501273d9f13SBarry Smith   PetscFunctionReturn(0);
3502273d9f13SBarry Smith }
3503273d9f13SBarry Smith 
35044a2ae208SSatish Balay #undef __FUNCT__
35054a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3506273d9f13SBarry Smith /*@C
3507273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3508273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3509273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3510273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3511273d9f13SBarry Smith 
3512273d9f13SBarry Smith    Collective on MPI_Comm
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith    Input Parameters:
3515117016b1SBarry Smith +  B - The matrix-free
3516273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3517273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35180298fd71SBarry Smith          (possibly different for each row) or NULL
3519273d9f13SBarry Smith 
3520273d9f13SBarry Smith    Notes:
352149a6f317SBarry Smith      If nnz is given then nz is ignored
352249a6f317SBarry Smith 
3523273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3524273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3525273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3526273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3527273d9f13SBarry Smith 
3528273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35290298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3530273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3531273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3532273d9f13SBarry Smith 
3533aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3534aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3535aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3536aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3537aa95bbe8SBarry Smith 
3538a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3539a96a251dSBarry Smith    entries or columns indices
3540a96a251dSBarry Smith 
3541273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3542273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3543273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3544273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3545273d9f13SBarry Smith 
3546273d9f13SBarry Smith    Options Database Keys:
3547698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3548698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3549273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3550273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3551273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3552273d9f13SBarry Smith 
3553273d9f13SBarry Smith    Level: intermediate
3554273d9f13SBarry Smith 
355569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3556273d9f13SBarry Smith 
3557273d9f13SBarry Smith @*/
35587087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3559273d9f13SBarry Smith {
35604ac538c5SBarry Smith   PetscErrorCode ierr;
3561a23d5eceSKris Buschelman 
3562a23d5eceSKris Buschelman   PetscFunctionBegin;
35636ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35646ba663aaSJed Brown   PetscValidType(B,1);
35654ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3566a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3567a23d5eceSKris Buschelman }
3568a23d5eceSKris Buschelman 
3569a23d5eceSKris Buschelman #undef __FUNCT__
3570a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35717087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3572a23d5eceSKris Buschelman {
3573273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35742576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35756849ba73SBarry Smith   PetscErrorCode ierr;
357697f1f81fSBarry Smith   PetscInt       i;
3577273d9f13SBarry Smith 
3578273d9f13SBarry Smith   PetscFunctionBegin;
35792576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3580a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3581c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3582c461c341SBarry Smith     nz             = 0;
3583c461c341SBarry Smith   }
3584c461c341SBarry Smith 
358526283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358626283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3587899cda47SBarry Smith 
3588435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
358960e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3590b73539f3SBarry Smith   if (nnz) {
3591d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
359260e0710aSBarry 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]);
359360e0710aSBarry 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);
3594b73539f3SBarry Smith     }
3595b73539f3SBarry Smith   }
3596b73539f3SBarry Smith 
3597273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35982205254eSKarl Rupp 
3599273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3600273d9f13SBarry Smith 
3601ab93d7beSBarry Smith   if (!skipallocation) {
36022ee49352SLisandro Dalcin     if (!b->imax) {
3603dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
36043bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36052ee49352SLisandro Dalcin     }
3606273d9f13SBarry Smith     if (!nnz) {
3607435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3608c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3609d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3610d0f46423SBarry Smith       nz = nz*B->rmap->n;
3611273d9f13SBarry Smith     } else {
3612273d9f13SBarry Smith       nz = 0;
3613d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3614273d9f13SBarry Smith     }
3615ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36162205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3617ab93d7beSBarry Smith 
3618273d9f13SBarry Smith     /* allocate the matrix space */
36192ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3620dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
36213bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3622bfeeae90SHong Zhang     b->i[0] = 0;
3623d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36245da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36255da197adSKris Buschelman     }
3626273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3627e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3628e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3629b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3630b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3631b31eba2aSShri Abhyankar #endif
3632c461c341SBarry Smith   } else {
3633e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3634e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3635c461c341SBarry Smith   }
3636273d9f13SBarry Smith 
3637273d9f13SBarry Smith   b->nz               = 0;
3638273d9f13SBarry Smith   b->maxnz            = nz;
3639273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36402205254eSKarl Rupp   if (realalloc) {
36412205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36422205254eSKarl Rupp   }
3643273d9f13SBarry Smith   PetscFunctionReturn(0);
3644273d9f13SBarry Smith }
3645273d9f13SBarry Smith 
3646a1661176SMatthew Knepley #undef  __FUNCT__
3647a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364858d36128SBarry Smith /*@
3649a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3650a1661176SMatthew Knepley 
3651a1661176SMatthew Knepley    Input Parameters:
3652a1661176SMatthew Knepley +  B - the matrix
3653a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3654a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3655a1661176SMatthew Knepley -  v - optional values in the matrix
3656a1661176SMatthew Knepley 
3657a1661176SMatthew Knepley    Level: developer
3658a1661176SMatthew Knepley 
365958d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
366058d36128SBarry Smith 
3661a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3662a1661176SMatthew Knepley 
3663a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3664a1661176SMatthew Knepley @*/
3665a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3666a1661176SMatthew Knepley {
3667a1661176SMatthew Knepley   PetscErrorCode ierr;
3668a1661176SMatthew Knepley 
3669a1661176SMatthew Knepley   PetscFunctionBegin;
36700700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36716ba663aaSJed Brown   PetscValidType(B,1);
36724ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3673a1661176SMatthew Knepley   PetscFunctionReturn(0);
3674a1661176SMatthew Knepley }
3675a1661176SMatthew Knepley 
3676a1661176SMatthew Knepley #undef  __FUNCT__
3677a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36787087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3679a1661176SMatthew Knepley {
3680a1661176SMatthew Knepley   PetscInt       i;
3681a1661176SMatthew Knepley   PetscInt       m,n;
3682a1661176SMatthew Knepley   PetscInt       nz;
3683a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3684a1661176SMatthew Knepley   PetscScalar    *values;
3685a1661176SMatthew Knepley   PetscErrorCode ierr;
3686a1661176SMatthew Knepley 
3687a1661176SMatthew Knepley   PetscFunctionBegin;
368865e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3689779a8d59SSatish Balay 
3690779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3691779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3692779a8d59SSatish Balay 
3693779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3694785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3695a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3696b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3697a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369865e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3699a1661176SMatthew Knepley     nnz[i] = nz;
3700a1661176SMatthew Knepley   }
3701a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3702a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3703a1661176SMatthew Knepley 
3704a1661176SMatthew Knepley   if (v) {
3705a1661176SMatthew Knepley     values = (PetscScalar*) v;
3706a1661176SMatthew Knepley   } else {
37071795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3708a1661176SMatthew Knepley   }
3709a1661176SMatthew Knepley 
3710a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3711b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3712b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3713a1661176SMatthew Knepley   }
3714a1661176SMatthew Knepley 
3715a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3716a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3717a1661176SMatthew Knepley 
3718a1661176SMatthew Knepley   if (!v) {
3719a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3720a1661176SMatthew Knepley   }
37217827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3722a1661176SMatthew Knepley   PetscFunctionReturn(0);
3723a1661176SMatthew Knepley }
3724a1661176SMatthew Knepley 
3725c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372606873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3727170fe5c8SBarry Smith 
3728170fe5c8SBarry Smith #undef __FUNCT__
3729170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3730170fe5c8SBarry Smith /*
3731170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3732170fe5c8SBarry Smith 
3733170fe5c8SBarry Smith                n                       p                          p
3734170fe5c8SBarry Smith         (              )       (              )         (                  )
3735170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3736170fe5c8SBarry Smith         (              )       (              )         (                  )
3737170fe5c8SBarry Smith 
3738170fe5c8SBarry Smith */
3739170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3740170fe5c8SBarry Smith {
3741170fe5c8SBarry Smith   PetscErrorCode    ierr;
3742170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3743170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3744170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37451de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3746170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3747170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3748170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3749170fe5c8SBarry Smith 
3750170fe5c8SBarry Smith   PetscFunctionBegin;
3751d0f46423SBarry Smith   m    = A->rmap->n;
3752d0f46423SBarry Smith   n    = A->cmap->n;
3753d0f46423SBarry Smith   p    = B->cmap->n;
3754170fe5c8SBarry Smith   a    = sub_a->v;
3755170fe5c8SBarry Smith   b    = sub_b->a;
3756170fe5c8SBarry Smith   c    = sub_c->v;
3757170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3758170fe5c8SBarry Smith 
3759170fe5c8SBarry Smith   ii  = sub_b->i;
3760170fe5c8SBarry Smith   idx = sub_b->j;
3761170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3762170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3763170fe5c8SBarry Smith     while (q-->0) {
3764170fe5c8SBarry Smith       c_q = c + m*(*idx);
3765170fe5c8SBarry Smith       a_q = a + m*i;
3766854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3767170fe5c8SBarry Smith       idx++;
3768170fe5c8SBarry Smith       b++;
3769170fe5c8SBarry Smith     }
3770170fe5c8SBarry Smith   }
3771170fe5c8SBarry Smith   PetscFunctionReturn(0);
3772170fe5c8SBarry Smith }
3773170fe5c8SBarry Smith 
3774170fe5c8SBarry Smith #undef __FUNCT__
3775170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3776170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3777170fe5c8SBarry Smith {
3778170fe5c8SBarry Smith   PetscErrorCode ierr;
3779d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3780170fe5c8SBarry Smith   Mat            Cmat;
3781170fe5c8SBarry Smith 
3782170fe5c8SBarry Smith   PetscFunctionBegin;
378360e0710aSBarry 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);
3784ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3785170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3786a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3787170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37880298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3789d73949e8SHong Zhang 
3790d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37912205254eSKarl Rupp 
3792170fe5c8SBarry Smith   *C = Cmat;
3793170fe5c8SBarry Smith   PetscFunctionReturn(0);
3794170fe5c8SBarry Smith }
3795170fe5c8SBarry Smith 
3796170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3797170fe5c8SBarry Smith #undef __FUNCT__
3798170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3799170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3800170fe5c8SBarry Smith {
3801170fe5c8SBarry Smith   PetscErrorCode ierr;
3802170fe5c8SBarry Smith 
3803170fe5c8SBarry Smith   PetscFunctionBegin;
3804170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38053ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3806170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38073ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3808170fe5c8SBarry Smith   }
38093ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3810170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38113ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3812170fe5c8SBarry Smith   PetscFunctionReturn(0);
3813170fe5c8SBarry Smith }
3814170fe5c8SBarry Smith 
3815170fe5c8SBarry Smith 
38160bad9183SKris Buschelman /*MC
3817fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38180bad9183SKris Buschelman    based on compressed sparse row format.
38190bad9183SKris Buschelman 
38200bad9183SKris Buschelman    Options Database Keys:
38210bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38220bad9183SKris Buschelman 
38230bad9183SKris Buschelman   Level: beginner
38240bad9183SKris Buschelman 
3825f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38260bad9183SKris Buschelman M*/
38270bad9183SKris Buschelman 
3828ccd284c7SBarry Smith /*MC
3829ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3830ccd284c7SBarry Smith 
3831ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3832ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3833ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3834ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3835ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3836ccd284c7SBarry Smith 
3837ccd284c7SBarry Smith    Options Database Keys:
3838ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3839ccd284c7SBarry Smith 
3840ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3841ccd284c7SBarry Smith    enough exist.
3842ccd284c7SBarry Smith 
3843ccd284c7SBarry Smith   Level: beginner
3844ccd284c7SBarry Smith 
3845ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3846ccd284c7SBarry Smith M*/
3847ccd284c7SBarry Smith 
3848ccd284c7SBarry Smith /*MC
3849ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3850ccd284c7SBarry Smith 
3851ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3852ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3853ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3854ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3855ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3856ccd284c7SBarry Smith 
3857ccd284c7SBarry Smith    Options Database Keys:
3858ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3859ccd284c7SBarry Smith 
3860ccd284c7SBarry Smith   Level: beginner
3861ccd284c7SBarry Smith 
3862ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3863ccd284c7SBarry Smith M*/
3864ccd284c7SBarry Smith 
3865b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3867b5e56a35SBarry Smith #endif
3868ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3870af1023dbSSatish Balay #endif
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38747087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3875611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3877611f576cSBarry Smith #endif
3878611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3880611f576cSBarry Smith #endif
3881f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3883f3c0ef26SHong Zhang #endif
3884eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3886eb3b5408SSatish Balay #endif
3887586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3889586621ddSJed Brown #endif
3890719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3892719d5645SBarry Smith #endif
3893b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38957087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38967087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3897b3866ffcSBarry Smith #endif
389817f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
390017f1a0eaSHong Zhang #endif
390117667f90SBarry Smith 
3902c0c8ee5eSDmitry Karpeev 
39038c778c55SBarry Smith #undef __FUNCT__
39048c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39058c778c55SBarry Smith /*@C
39068c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39078c778c55SBarry Smith 
39088c778c55SBarry Smith    Not Collective
39098c778c55SBarry Smith 
39108c778c55SBarry Smith    Input Parameter:
39118c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39128c778c55SBarry Smith 
39138c778c55SBarry Smith    Output Parameter:
39148c778c55SBarry Smith .   array - pointer to the data
39158c778c55SBarry Smith 
39168c778c55SBarry Smith    Level: intermediate
39178c778c55SBarry Smith 
3918774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39198c778c55SBarry Smith @*/
39208c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39218c778c55SBarry Smith {
39228c778c55SBarry Smith   PetscErrorCode ierr;
39238c778c55SBarry Smith 
39248c778c55SBarry Smith   PetscFunctionBegin;
39258c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39268c778c55SBarry Smith   PetscFunctionReturn(0);
39278c778c55SBarry Smith }
39288c778c55SBarry Smith 
39298c778c55SBarry Smith #undef __FUNCT__
39308c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39318c778c55SBarry Smith /*@C
39328c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39338c778c55SBarry Smith 
39348c778c55SBarry Smith    Not Collective
39358c778c55SBarry Smith 
39368c778c55SBarry Smith    Input Parameters:
39378c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39388c778c55SBarry Smith .  array - pointer to the data
39398c778c55SBarry Smith 
39408c778c55SBarry Smith    Level: intermediate
39418c778c55SBarry Smith 
3942774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39438c778c55SBarry Smith @*/
39448c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39458c778c55SBarry Smith {
39468c778c55SBarry Smith   PetscErrorCode ierr;
39478c778c55SBarry Smith 
39488c778c55SBarry Smith   PetscFunctionBegin;
39498c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39508c778c55SBarry Smith   PetscFunctionReturn(0);
39518c778c55SBarry Smith }
39528c778c55SBarry Smith 
39534a2ae208SSatish Balay #undef __FUNCT__
39544a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3956273d9f13SBarry Smith {
3957273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3958dfbe8321SBarry Smith   PetscErrorCode ierr;
395938baddfdSBarry Smith   PetscMPIInt    size;
3960273d9f13SBarry Smith 
3961273d9f13SBarry Smith   PetscFunctionBegin;
3962ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3963e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3964273d9f13SBarry Smith 
3965b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39662205254eSKarl Rupp 
3967b0a32e0cSBarry Smith   B->data = (void*)b;
39682205254eSKarl Rupp 
3969549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39702205254eSKarl Rupp 
3971416022c9SBarry Smith   b->row                = 0;
3972416022c9SBarry Smith   b->col                = 0;
397382bf6240SBarry Smith   b->icol               = 0;
3974b810aeb4SBarry Smith   b->reallocs           = 0;
397536db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3976f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3977416022c9SBarry Smith   b->nonew              = 0;
3978416022c9SBarry Smith   b->diag               = 0;
3979416022c9SBarry Smith   b->solve_work         = 0;
39802a1b7f2aSHong Zhang   B->spptr              = 0;
3981be6bf707SBarry Smith   b->saved_values       = 0;
3982d7f994e1SBarry Smith   b->idiag              = 0;
398371f1c65dSBarry Smith   b->mdiag              = 0;
398471f1c65dSBarry Smith   b->ssor_work          = 0;
398571f1c65dSBarry Smith   b->omega              = 1.0;
398671f1c65dSBarry Smith   b->fshift             = 0.0;
398771f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3988bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3989a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3990a30b2313SHong Zhang   b->xtoy               = 0;
3991a30b2313SHong Zhang   b->XtoY               = 0;
399288e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
399317ab2063SBarry Smith 
399435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39978c778c55SBarry Smith 
3998b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3999bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4000bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4001bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4002b3866ffcSBarry Smith #endif
4003b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4004bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4005b5e56a35SBarry Smith #endif
4006ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4008719d5645SBarry Smith #endif
4009611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4010bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4011611f576cSBarry Smith #endif
4012f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4013bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4014f3c0ef26SHong Zhang #endif
4015611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4016bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4017611f576cSBarry Smith #endif
4018eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4020eb3b5408SSatish Balay #endif
4021586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4022bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4023586621ddSJed Brown #endif
4024719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4026719d5645SBarry Smith #endif
402717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402917f1a0eaSHong Zhang #endif
403017f1a0eaSHong Zhang 
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40494108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
405017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40513a40ed3dSBarry Smith   PetscFunctionReturn(0);
405217ab2063SBarry Smith }
405317ab2063SBarry Smith 
40544a2ae208SSatish Balay #undef __FUNCT__
4055b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4056b24902e0SBarry Smith /*
4057b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4058b24902e0SBarry Smith */
4059ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
406017ab2063SBarry Smith {
4061416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40626849ba73SBarry Smith   PetscErrorCode ierr;
4063d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
406417ab2063SBarry Smith 
40653a40ed3dSBarry Smith   PetscFunctionBegin;
4066273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4067273d9f13SBarry Smith 
4068d5f3da31SBarry Smith   C->factortype = A->factortype;
4069416022c9SBarry Smith   c->row        = 0;
4070416022c9SBarry Smith   c->col        = 0;
407182bf6240SBarry Smith   c->icol       = 0;
40726ad4291fSHong Zhang   c->reallocs   = 0;
407317ab2063SBarry Smith 
40746ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407517ab2063SBarry Smith 
4076aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4077aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4078eec197d1SBarry Smith 
4079dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40803bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
408117ab2063SBarry Smith   for (i=0; i<m; i++) {
4082416022c9SBarry Smith     c->imax[i] = a->imax[i];
4083416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
408417ab2063SBarry Smith   }
408517ab2063SBarry Smith 
408617ab2063SBarry Smith   /* allocate the matrix space */
4087f77e22a1SHong Zhang   if (mallocmatspace) {
4088dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40893bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40902205254eSKarl Rupp 
4091f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40922205254eSKarl Rupp 
409397f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409417ab2063SBarry Smith     if (m > 0) {
409597f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4096be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4097bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4098be6bf707SBarry Smith       } else {
4099bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
410017ab2063SBarry Smith       }
410108480c60SBarry Smith     }
4102f77e22a1SHong Zhang   }
410317ab2063SBarry Smith 
41046ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4105416022c9SBarry Smith   c->roworiented       = a->roworiented;
4106416022c9SBarry Smith   c->nonew             = a->nonew;
4107416022c9SBarry Smith   if (a->diag) {
4108785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
41093bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
411017ab2063SBarry Smith     for (i=0; i<m; i++) {
4111416022c9SBarry Smith       c->diag[i] = a->diag[i];
411217ab2063SBarry Smith     }
41133a40ed3dSBarry Smith   } else c->diag = 0;
41142205254eSKarl Rupp 
41156ad4291fSHong Zhang   c->solve_work         = 0;
41166ad4291fSHong Zhang   c->saved_values       = 0;
41176ad4291fSHong Zhang   c->idiag              = 0;
411871f1c65dSBarry Smith   c->ssor_work          = 0;
4119a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4120e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4121e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41226ad4291fSHong Zhang   c->xtoy               = 0;
41236ad4291fSHong Zhang   c->XtoY               = 0;
41246ad4291fSHong Zhang 
4125893ad86cSHong Zhang   c->rmax         = a->rmax;
4126416022c9SBarry Smith   c->nz           = a->nz;
41278ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4128273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4129754ec7b1SSatish Balay 
41306ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41316ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4132cd6b891eSBarry Smith   if (a->compressedrow.use) {
41336ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4134dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
41356ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41366ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413727ea64f8SHong Zhang   } else {
413827ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41390298fd71SBarry Smith     c->compressedrow.i      = NULL;
41400298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41416ad4291fSHong Zhang   }
414288e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41434846f1f5SKris Buschelman 
41442205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4145140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41463a40ed3dSBarry Smith   PetscFunctionReturn(0);
414717ab2063SBarry Smith }
414817ab2063SBarry Smith 
41494a2ae208SSatish Balay #undef __FUNCT__
4150b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4151b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4152b24902e0SBarry Smith {
4153b24902e0SBarry Smith   PetscErrorCode ierr;
4154b24902e0SBarry Smith 
4155b24902e0SBarry Smith   PetscFunctionBegin;
4156ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41574b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4158a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4159a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4160f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4161b24902e0SBarry Smith   PetscFunctionReturn(0);
4162b24902e0SBarry Smith }
4163b24902e0SBarry Smith 
4164b24902e0SBarry Smith #undef __FUNCT__
41654a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4166112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4167fbdbba38SShri Abhyankar {
4168fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4169fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4170fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4171fbdbba38SShri Abhyankar   int            fd;
4172fbdbba38SShri Abhyankar   PetscMPIInt    size;
4173fbdbba38SShri Abhyankar   MPI_Comm       comm;
4174bbead8a2SBarry Smith   PetscInt       bs = 1;
4175fbdbba38SShri Abhyankar 
4176fbdbba38SShri Abhyankar   PetscFunctionBegin;
4177fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4178fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4179fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4180bbead8a2SBarry Smith 
41810298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41820298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4183bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41841814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4185bbead8a2SBarry Smith 
4186fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4187fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4188fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4189fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4190fbdbba38SShri Abhyankar 
4191bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4192fbdbba38SShri Abhyankar 
4193fbdbba38SShri Abhyankar   /* read in row lengths */
4194785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4195fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4196fbdbba38SShri Abhyankar 
4197fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4198fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
419960e0710aSBarry 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);
4200fbdbba38SShri Abhyankar 
4201fbdbba38SShri Abhyankar   /* set global size if not set already*/
4202f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4203fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4204aabbc4fbSShri Abhyankar   } else {
4205fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4206fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42074c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42084c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42094c5b953cSHong Zhang     }
421060e0710aSBarry 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);
4211aabbc4fbSShri Abhyankar   }
4212fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4213fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4214fbdbba38SShri Abhyankar 
4215fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4216fbdbba38SShri Abhyankar 
4217fbdbba38SShri Abhyankar   /* read in nonzero values */
4218fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4219fbdbba38SShri Abhyankar 
4220fbdbba38SShri Abhyankar   /* set matrix "i" values */
4221fbdbba38SShri Abhyankar   a->i[0] = 0;
4222fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4223fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4224fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4225fbdbba38SShri Abhyankar   }
4226fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4227fbdbba38SShri Abhyankar 
4228fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4229fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4230fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4231fbdbba38SShri Abhyankar }
4232fbdbba38SShri Abhyankar 
4233fbdbba38SShri Abhyankar #undef __FUNCT__
4234b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4235ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42367264ac53SSatish Balay {
42377264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4238dfbe8321SBarry Smith   PetscErrorCode ierr;
4239eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4240eeffb40dSHong Zhang   PetscInt k;
4241eeffb40dSHong Zhang #endif
42427264ac53SSatish Balay 
42433a40ed3dSBarry Smith   PetscFunctionBegin;
4244bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4245d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4246ca44d042SBarry Smith     *flg = PETSC_FALSE;
4247ca44d042SBarry Smith     PetscFunctionReturn(0);
4248bcd2baecSBarry Smith   }
42497264ac53SSatish Balay 
42507264ac53SSatish Balay   /* if the a->i are the same */
4251d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4252abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42537264ac53SSatish Balay 
42547264ac53SSatish Balay   /* if a->j are the same */
425597f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4256abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4257bcd2baecSBarry Smith 
4258bcd2baecSBarry Smith   /* if a->a are the same */
4259eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4260eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4261eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4262eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42633a40ed3dSBarry Smith       PetscFunctionReturn(0);
4264eeffb40dSHong Zhang     }
4265eeffb40dSHong Zhang   }
4266eeffb40dSHong Zhang #else
4267eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4268eeffb40dSHong Zhang #endif
4269eeffb40dSHong Zhang   PetscFunctionReturn(0);
42707264ac53SSatish Balay }
427136db0b34SBarry Smith 
42724a2ae208SSatish Balay #undef __FUNCT__
42734a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
427405869f15SSatish Balay /*@
427536db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427636db0b34SBarry Smith               provided by the user.
427736db0b34SBarry Smith 
4278c75a6043SHong Zhang       Collective on MPI_Comm
427936db0b34SBarry Smith 
428036db0b34SBarry Smith    Input Parameters:
428136db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
428236db0b34SBarry Smith .   m - number of rows
428336db0b34SBarry Smith .   n - number of columns
428436db0b34SBarry Smith .   i - row indices
428536db0b34SBarry Smith .   j - column indices
428636db0b34SBarry Smith -   a - matrix values
428736db0b34SBarry Smith 
428836db0b34SBarry Smith    Output Parameter:
428936db0b34SBarry Smith .   mat - the matrix
429036db0b34SBarry Smith 
429136db0b34SBarry Smith    Level: intermediate
429236db0b34SBarry Smith 
429336db0b34SBarry Smith    Notes:
42940551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4295292fb18eSBarry Smith     once the matrix is destroyed and not before
429636db0b34SBarry Smith 
429736db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429836db0b34SBarry Smith 
4299bfeeae90SHong Zhang        The i and j indices are 0 based
430036db0b34SBarry Smith 
4301a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4302a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4303a4552177SSatish Balay     as shown:
4304a4552177SSatish Balay 
4305a4552177SSatish Balay         1 0 0
4306a4552177SSatish Balay         2 0 3
4307a4552177SSatish Balay         4 5 6
4308a4552177SSatish Balay 
4309a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43109985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4311a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4312a4552177SSatish Balay 
43139985e31cSBarry Smith 
431469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
431536db0b34SBarry Smith 
431636db0b34SBarry Smith @*/
43177087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431836db0b34SBarry Smith {
4319dfbe8321SBarry Smith   PetscErrorCode ierr;
4320cbcfb4deSHong Zhang   PetscInt       ii;
432136db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4322cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4323cbcfb4deSHong Zhang   PetscInt jj;
4324cbcfb4deSHong Zhang #endif
432536db0b34SBarry Smith 
432636db0b34SBarry Smith   PetscFunctionBegin;
4327f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4328f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4329f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4330a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4331ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4332ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4333ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4334dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4335ab93d7beSBarry Smith 
433636db0b34SBarry Smith   aij->i            = i;
433736db0b34SBarry Smith   aij->j            = j;
433836db0b34SBarry Smith   aij->a            = a;
433936db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
434036db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4341e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4342e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
434336db0b34SBarry Smith 
434436db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
434536db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43462515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
434760e0710aSBarry 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]);
43489985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4349e32f2f54SBarry 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);
4350e32f2f54SBarry 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);
43519985e31cSBarry Smith     }
435236db0b34SBarry Smith #endif
435336db0b34SBarry Smith   }
43542515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435536db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
435660e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
435760e0710aSBarry 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]);
435836db0b34SBarry Smith   }
435936db0b34SBarry Smith #endif
436036db0b34SBarry Smith 
4361b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4362b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
436336db0b34SBarry Smith   PetscFunctionReturn(0);
436436db0b34SBarry Smith }
43658a0b0e6bSVictor Minden #undef __FUNCT__
43668a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436780ef6e79SMatthew G Knepley /*@C
4368d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43698a0b0e6bSVictor Minden               provided by the user.
43708a0b0e6bSVictor Minden 
43718a0b0e6bSVictor Minden       Collective on MPI_Comm
43728a0b0e6bSVictor Minden 
43738a0b0e6bSVictor Minden    Input Parameters:
43748a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43758a0b0e6bSVictor Minden .   m   - number of rows
43768a0b0e6bSVictor Minden .   n   - number of columns
43778a0b0e6bSVictor Minden .   i   - row indices
43788a0b0e6bSVictor Minden .   j   - column indices
43791230e6d1SVictor Minden .   a   - matrix values
43801230e6d1SVictor Minden .   nz  - number of nonzeros
43811230e6d1SVictor Minden -   idx - 0 or 1 based
43828a0b0e6bSVictor Minden 
43838a0b0e6bSVictor Minden    Output Parameter:
43848a0b0e6bSVictor Minden .   mat - the matrix
43858a0b0e6bSVictor Minden 
43868a0b0e6bSVictor Minden    Level: intermediate
43878a0b0e6bSVictor Minden 
43888a0b0e6bSVictor Minden    Notes:
43898a0b0e6bSVictor Minden        The i and j indices are 0 based
43908a0b0e6bSVictor Minden 
43918a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43928a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43938a0b0e6bSVictor Minden     as shown:
43948a0b0e6bSVictor Minden 
43958a0b0e6bSVictor Minden         1 0 0
43968a0b0e6bSVictor Minden         2 0 3
43978a0b0e6bSVictor Minden         4 5 6
43988a0b0e6bSVictor Minden 
43998a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
44008a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
44018a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44028a0b0e6bSVictor Minden 
44038a0b0e6bSVictor Minden 
440469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44058a0b0e6bSVictor Minden 
44068a0b0e6bSVictor Minden @*/
44071230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44088a0b0e6bSVictor Minden {
44098a0b0e6bSVictor Minden   PetscErrorCode ierr;
4410d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44118a0b0e6bSVictor Minden 
44128a0b0e6bSVictor Minden 
44138a0b0e6bSVictor Minden   PetscFunctionBegin;
44141795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
44151230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4416c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
44171230e6d1SVictor Minden   }
44188a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44198a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
44208a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44211230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44221230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44231230e6d1SVictor Minden     if (idx) {
44241230e6d1SVictor Minden       row = i[ii] - 1;
44251230e6d1SVictor Minden       col = j[ii] - 1;
44261230e6d1SVictor Minden     } else {
44271230e6d1SVictor Minden       row = i[ii];
44281230e6d1SVictor Minden       col = j[ii];
44298a0b0e6bSVictor Minden     }
44301230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44318a0b0e6bSVictor Minden   }
44328a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44338a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4434d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44358a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44368a0b0e6bSVictor Minden }
443736db0b34SBarry Smith 
4438cc8ba8e1SBarry Smith #undef __FUNCT__
4439ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4440dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4441cc8ba8e1SBarry Smith {
4442dfbe8321SBarry Smith   PetscErrorCode ierr;
4443cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444436db0b34SBarry Smith 
4445cc8ba8e1SBarry Smith   PetscFunctionBegin;
44468ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4447cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4448cc8ba8e1SBarry Smith     a->coloring = coloring;
444912c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
445097f1f81fSBarry Smith     PetscInt        i,*larray;
445112c595b3SBarry Smith     ISColoring      ocoloring;
445208b6dcc0SBarry Smith     ISColoringValue *colors;
445312c595b3SBarry Smith 
445412c595b3SBarry Smith     /* set coloring for diagonal portion */
4455785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
44562205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44570298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4458785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
44592205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
446012c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4461d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446212c595b3SBarry Smith     a->coloring = ocoloring;
446312c595b3SBarry Smith   }
4464cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4465cc8ba8e1SBarry Smith }
4466cc8ba8e1SBarry Smith 
4467ee4f033dSBarry Smith #undef __FUNCT__
4468ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4470ee4f033dSBarry Smith {
4471ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4472d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447354f21887SBarry Smith   MatScalar       *v      = a->a;
447454f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447508b6dcc0SBarry Smith   ISColoringValue *color;
4476ee4f033dSBarry Smith 
4477ee4f033dSBarry Smith   PetscFunctionBegin;
4478e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4479ee4f033dSBarry Smith   color = a->coloring->colors;
4480ee4f033dSBarry Smith   /* loop over rows */
4481ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4482ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4483ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44842205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4485ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4486cc8ba8e1SBarry Smith   }
4487cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4488cc8ba8e1SBarry Smith }
448936db0b34SBarry Smith 
4490acf2f550SJed Brown #undef __FUNCT__
4491acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4492acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4493acf2f550SJed Brown {
4494acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4495acf2f550SJed Brown   PetscErrorCode ierr;
4496acf2f550SJed Brown 
4497acf2f550SJed Brown   PetscFunctionBegin;
4498acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4499acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45002205254eSKarl Rupp 
4501acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4502acf2f550SJed Brown   PetscFunctionReturn(0);
4503acf2f550SJed Brown }
4504acf2f550SJed Brown 
450581824310SBarry Smith /*
450681824310SBarry Smith     Special version for direct calls from Fortran
450781824310SBarry Smith */
4508b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
450981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
451081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
451181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451381824310SBarry Smith #endif
451481824310SBarry Smith 
451581824310SBarry Smith /* Change these macros so can be used in void function */
451681824310SBarry Smith #undef CHKERRQ
4517ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
451881824310SBarry Smith #undef SETERRQ2
4519e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45204994cf47SJed Brown #undef SETERRQ3
45214994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452281824310SBarry Smith 
452381824310SBarry Smith #undef __FUNCT__
452481824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45258cc058d9SJed 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)
452681824310SBarry Smith {
452781824310SBarry Smith   Mat            A  = *AA;
452881824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
452981824310SBarry Smith   InsertMode     is = *isis;
453081824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
453181824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453281824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453381824310SBarry Smith   PetscErrorCode ierr;
453481824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453554f21887SBarry Smith   MatScalar      *ap,value,*aa;
4536ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4537ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
453881824310SBarry Smith 
453981824310SBarry Smith   PetscFunctionBegin;
45404994cf47SJed Brown   MatCheckPreallocated(A,1);
454181824310SBarry Smith   imax  = a->imax;
454281824310SBarry Smith   ai    = a->i;
454381824310SBarry Smith   ailen = a->ilen;
454481824310SBarry Smith   aj    = a->j;
454581824310SBarry Smith   aa    = a->a;
454681824310SBarry Smith 
454781824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
454881824310SBarry Smith     row = im[k];
454981824310SBarry Smith     if (row < 0) continue;
455081824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4551ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455281824310SBarry Smith #endif
455381824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455481824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455581824310SBarry Smith     low  = 0;
455681824310SBarry Smith     high = nrow;
455781824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
455881824310SBarry Smith       if (in[l] < 0) continue;
455981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4560ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
456181824310SBarry Smith #endif
456281824310SBarry Smith       col = in[l];
45632205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45642205254eSKarl Rupp       else value = v[k + l*m];
45652205254eSKarl Rupp 
456681824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456781824310SBarry Smith 
45682205254eSKarl Rupp       if (col <= lastcol) low = 0;
45692205254eSKarl Rupp       else high = nrow;
457081824310SBarry Smith       lastcol = col;
457181824310SBarry Smith       while (high-low > 5) {
457281824310SBarry Smith         t = (low+high)/2;
457381824310SBarry Smith         if (rp[t] > col) high = t;
457481824310SBarry Smith         else             low  = t;
457581824310SBarry Smith       }
457681824310SBarry Smith       for (i=low; i<high; i++) {
457781824310SBarry Smith         if (rp[i] > col) break;
457881824310SBarry Smith         if (rp[i] == col) {
457981824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
458081824310SBarry Smith           else                  ap[i] = value;
458181824310SBarry Smith           goto noinsert;
458281824310SBarry Smith         }
458381824310SBarry Smith       }
458481824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458581824310SBarry Smith       if (nonew == 1) goto noinsert;
4586ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4587fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
458881824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
458981824310SBarry Smith       /* shift up all the later entries in this row */
459081824310SBarry Smith       for (ii=N; ii>=i; ii--) {
459181824310SBarry Smith         rp[ii+1] = rp[ii];
459281824310SBarry Smith         ap[ii+1] = ap[ii];
459381824310SBarry Smith       }
459481824310SBarry Smith       rp[i] = col;
459581824310SBarry Smith       ap[i] = value;
459681824310SBarry Smith noinsert:;
459781824310SBarry Smith       low = i + 1;
459881824310SBarry Smith     }
459981824310SBarry Smith     ailen[row] = nrow;
460081824310SBarry Smith   }
460181824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460281824310SBarry Smith   PetscFunctionReturnVoid();
460381824310SBarry Smith }
46049f7953f8SBarry Smith 
460562298a1eSBarry Smith 
4606