xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 040ebd07df7f48cdffac40673e8597e52ed39091)
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   }
666ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&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);
120b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&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 */
1901a83f524SJed Brown     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),&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;
1951a83f524SJed Brown       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&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 {
23697f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
23797f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
23897f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
23997f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
2403b2fbd54SBarry Smith     jj   = a->j;
2413b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
242bfeeae90SHong Zhang       collengths[jj[i]]++;
2433b2fbd54SBarry Smith     }
2443b2fbd54SBarry Smith     cia[0] = oshift;
2453b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2463b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2473b2fbd54SBarry Smith     }
24897f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2493b2fbd54SBarry Smith     jj   = a->j;
250a93ec695SBarry Smith     for (row=0; row<m; row++) {
251a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
252a93ec695SBarry Smith       for (i=0; i<mr; i++) {
253bfeeae90SHong Zhang         col = *jj++;
2542205254eSKarl Rupp 
2553b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2563b2fbd54SBarry Smith       }
2573b2fbd54SBarry Smith     }
258606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2593b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2603b2fbd54SBarry Smith   }
2613a40ed3dSBarry Smith   PetscFunctionReturn(0);
2623b2fbd54SBarry Smith }
2633b2fbd54SBarry Smith 
2644a2ae208SSatish Balay #undef __FUNCT__
2654a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2661a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2673b2fbd54SBarry Smith {
268dfbe8321SBarry Smith   PetscErrorCode ierr;
269606d414cSSatish Balay 
2703a40ed3dSBarry Smith   PetscFunctionBegin;
2713a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2723b2fbd54SBarry Smith 
273606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
274606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2753a40ed3dSBarry Smith   PetscFunctionReturn(0);
2763b2fbd54SBarry Smith }
2773b2fbd54SBarry Smith 
2787cee066cSHong Zhang /*
2797cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2807cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
281*040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2827cee066cSHong Zhang */
2837cee066cSHong Zhang #undef __FUNCT__
2847cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
2857cee066cSHong 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)
2867cee066cSHong Zhang {
2877cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2887cee066cSHong Zhang   PetscErrorCode ierr;
2897cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2907cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2917cee066cSHong Zhang   PetscInt       *cspidx;
2927cee066cSHong Zhang 
2937cee066cSHong Zhang   PetscFunctionBegin;
2947cee066cSHong Zhang   *nn = n;
2957cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
2967cee066cSHong Zhang   if (symmetric) {
2977cee066cSHong Zhang     SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatGetColumnIJ_SeqAIJ_Color() not supported for the case symmetric");
2987cee066cSHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2997cee066cSHong Zhang   } else {
3007cee066cSHong Zhang     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
3017cee066cSHong Zhang     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3027cee066cSHong Zhang     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
3037cee066cSHong Zhang     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
3047cee066cSHong Zhang     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr);
3057cee066cSHong Zhang     jj   = a->j;
3067cee066cSHong Zhang     for (i=0; i<nz; i++) {
3077cee066cSHong Zhang       collengths[jj[i]]++;
3087cee066cSHong Zhang     }
3097cee066cSHong Zhang     cia[0] = oshift;
3107cee066cSHong Zhang     for (i=0; i<n; i++) {
3117cee066cSHong Zhang       cia[i+1] = cia[i] + collengths[i];
3127cee066cSHong Zhang     }
3137cee066cSHong Zhang     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3147cee066cSHong Zhang     jj   = a->j;
3157cee066cSHong Zhang     for (row=0; row<m; row++) {
3167cee066cSHong Zhang       mr = a->i[row+1] - a->i[row];
3177cee066cSHong Zhang       for (i=0; i<mr; i++) {
3187cee066cSHong Zhang         col = *jj++;
3197cee066cSHong Zhang         cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3207cee066cSHong Zhang         cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3217cee066cSHong Zhang       }
3227cee066cSHong Zhang     }
3237cee066cSHong Zhang     ierr   = PetscFree(collengths);CHKERRQ(ierr);
3247cee066cSHong Zhang     *ia    = cia; *ja = cja;
3257cee066cSHong Zhang     *spidx = cspidx;
3267cee066cSHong Zhang   }
3277cee066cSHong Zhang   PetscFunctionReturn(0);
3287cee066cSHong Zhang }
3297cee066cSHong Zhang 
3307cee066cSHong Zhang #undef __FUNCT__
3317cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3327cee066cSHong 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)
3337cee066cSHong Zhang {
3347cee066cSHong Zhang   PetscErrorCode ierr;
3357cee066cSHong Zhang 
3367cee066cSHong Zhang   PetscFunctionBegin;
3375243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3387cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3397cee066cSHong Zhang   PetscFunctionReturn(0);
3407cee066cSHong Zhang }
3417cee066cSHong Zhang 
34287d4246cSBarry Smith #undef __FUNCT__
34387d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
34487d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
34587d4246cSBarry Smith {
34687d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34787d4246cSBarry Smith   PetscInt       *ai = a->i;
34887d4246cSBarry Smith   PetscErrorCode ierr;
34987d4246cSBarry Smith 
35087d4246cSBarry Smith   PetscFunctionBegin;
35187d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
35287d4246cSBarry Smith   PetscFunctionReturn(0);
35387d4246cSBarry Smith }
35487d4246cSBarry Smith 
3554a2ae208SSatish Balay #undef __FUNCT__
3564a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
35797f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
35817ab2063SBarry Smith {
359416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
360e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
36197f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3626849ba73SBarry Smith   PetscErrorCode ierr;
363e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
36454f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
365ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
366ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
36717ab2063SBarry Smith 
3683a40ed3dSBarry Smith   PetscFunctionBegin;
36971fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
37017ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
371416022c9SBarry Smith     row = im[k];
3725ef9f2a5SBarry Smith     if (row < 0) continue;
3732515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
374e32f2f54SBarry 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);
3753b2fbd54SBarry Smith #endif
376bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
37717ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
378416022c9SBarry Smith     low  = 0;
379c71e6ed7SBarry Smith     high = nrow;
38017ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3815ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3822515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
383e32f2f54SBarry 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);
3843b2fbd54SBarry Smith #endif
385bfeeae90SHong Zhang       col = in[l];
38616371a99SBarry Smith       if (v) {
3874b0e389bSBarry Smith         if (roworiented) {
3885ef9f2a5SBarry Smith           value = v[l + k*n];
389bef8e0ddSBarry Smith         } else {
3904b0e389bSBarry Smith           value = v[k + l*m];
3914b0e389bSBarry Smith         }
39216371a99SBarry Smith       } else {
39375567043SBarry Smith         value = 0.;
39416371a99SBarry Smith       }
395abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
39636db0b34SBarry Smith 
3972205254eSKarl Rupp       if (col <= lastcol) low = 0;
3982205254eSKarl Rupp       else high = nrow;
399e2ee6c50SBarry Smith       lastcol = col;
400416022c9SBarry Smith       while (high-low > 5) {
401416022c9SBarry Smith         t = (low+high)/2;
402416022c9SBarry Smith         if (rp[t] > col) high = t;
403416022c9SBarry Smith         else low = t;
40417ab2063SBarry Smith       }
405416022c9SBarry Smith       for (i=low; i<high; i++) {
40617ab2063SBarry Smith         if (rp[i] > col) break;
40717ab2063SBarry Smith         if (rp[i] == col) {
408416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
40917ab2063SBarry Smith           else ap[i] = value;
410e44c0bd4SBarry Smith           low = i + 1;
41117ab2063SBarry Smith           goto noinsert;
41217ab2063SBarry Smith         }
41317ab2063SBarry Smith       }
414abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
415c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
416e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
417fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
418c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
419416022c9SBarry Smith       /* shift up all the later entries in this row */
420416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
42117ab2063SBarry Smith         rp[ii+1] = rp[ii];
42217ab2063SBarry Smith         ap[ii+1] = ap[ii];
42317ab2063SBarry Smith       }
42417ab2063SBarry Smith       rp[i] = col;
42517ab2063SBarry Smith       ap[i] = value;
426416022c9SBarry Smith       low   = i + 1;
427e44c0bd4SBarry Smith noinsert:;
42817ab2063SBarry Smith     }
42917ab2063SBarry Smith     ailen[row] = nrow;
43017ab2063SBarry Smith   }
43188e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4323a40ed3dSBarry Smith   PetscFunctionReturn(0);
43317ab2063SBarry Smith }
43417ab2063SBarry Smith 
43581824310SBarry Smith 
4364a2ae208SSatish Balay #undef __FUNCT__
4374a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
438a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4397eb43aa7SLois Curfman McInnes {
4407eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
44197f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
44297f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
44354f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4447eb43aa7SLois Curfman McInnes 
4453a40ed3dSBarry Smith   PetscFunctionBegin;
4467eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4477eb43aa7SLois Curfman McInnes     row = im[k];
448e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
449e32f2f54SBarry 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);
450bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4517eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4527eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
453e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
454e32f2f54SBarry 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);
455bfeeae90SHong Zhang       col  = in[l];
4567eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4577eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4587eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4597eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4607eb43aa7SLois Curfman McInnes         else low = t;
4617eb43aa7SLois Curfman McInnes       }
4627eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4637eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4647eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
465b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4667eb43aa7SLois Curfman McInnes           goto finished;
4677eb43aa7SLois Curfman McInnes         }
4687eb43aa7SLois Curfman McInnes       }
46997e567efSBarry Smith       *v++ = 0.0;
4707eb43aa7SLois Curfman McInnes finished:;
4717eb43aa7SLois Curfman McInnes     }
4727eb43aa7SLois Curfman McInnes   }
4733a40ed3dSBarry Smith   PetscFunctionReturn(0);
4747eb43aa7SLois Curfman McInnes }
4757eb43aa7SLois Curfman McInnes 
47617ab2063SBarry Smith 
4774a2ae208SSatish Balay #undef __FUNCT__
4784a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
479dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
48017ab2063SBarry Smith {
481416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4826849ba73SBarry Smith   PetscErrorCode ierr;
4836f69ff64SBarry Smith   PetscInt       i,*col_lens;
4846f69ff64SBarry Smith   int            fd;
485b37d52dbSMark F. Adams   FILE           *file;
48617ab2063SBarry Smith 
4873a40ed3dSBarry Smith   PetscFunctionBegin;
488b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
489d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4902205254eSKarl Rupp 
4910700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
492d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
493d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
494416022c9SBarry Smith   col_lens[3] = a->nz;
495416022c9SBarry Smith 
496416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
497d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
498416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
49917ab2063SBarry Smith   }
500d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
501606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
502416022c9SBarry Smith 
503416022c9SBarry Smith   /* store column indices (zero start index) */
5046f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
505416022c9SBarry Smith 
506416022c9SBarry Smith   /* store nonzero values */
5076f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
508b37d52dbSMark F. Adams 
509b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
510b37d52dbSMark F. Adams   if (file) {
511b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
512b37d52dbSMark F. Adams   }
5133a40ed3dSBarry Smith   PetscFunctionReturn(0);
51417ab2063SBarry Smith }
515416022c9SBarry Smith 
51609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
517cd155464SBarry Smith 
5184a2ae208SSatish Balay #undef __FUNCT__
5194a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
520dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
521416022c9SBarry Smith {
522416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
523dfbe8321SBarry Smith   PetscErrorCode    ierr;
524d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
525e060cb09SBarry Smith   const char        *name;
526f3ef73ceSBarry Smith   PetscViewerFormat format;
52717ab2063SBarry Smith 
5283a40ed3dSBarry Smith   PetscFunctionBegin;
529b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
53071c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
53197f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
532014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
533d00d2cf4SBarry Smith       nofinalvalue = 1;
534d00d2cf4SBarry Smith     }
535d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
536d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
53777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
53877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
539b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
54017ab2063SBarry Smith 
54117ab2063SBarry Smith     for (i=0; i<m; i++) {
542416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
543aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
54477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
54517ab2063SBarry Smith #else
54677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
54717ab2063SBarry Smith #endif
54817ab2063SBarry Smith       }
54917ab2063SBarry Smith     }
550d00d2cf4SBarry Smith     if (nofinalvalue) {
551d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
552d00d2cf4SBarry Smith     }
553317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
554fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
555d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
55668369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
557cd155464SBarry Smith     PetscFunctionReturn(0);
558fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
559d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
560dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
56144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
56277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
56344cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
564aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
56536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
566ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
568ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
570ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5716831982aSBarry Smith         }
57244cd7ae7SLois Curfman McInnes #else
573ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
57444cd7ae7SLois Curfman McInnes #endif
57544cd7ae7SLois Curfman McInnes       }
576b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57744cd7ae7SLois Curfman McInnes     }
578d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
579fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
58097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
581d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
582dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
58397f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
584496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
585496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
586496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
587496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
588aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
590496be53dSLois Curfman McInnes #else
591496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
592496be53dSLois Curfman McInnes #endif
593496be53dSLois Curfman McInnes         }
594496be53dSLois Curfman McInnes       }
595496be53dSLois Curfman McInnes     }
5962e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
59777431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5982e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
5992205254eSKarl Rupp       if (i+4<m) {
6002205254eSKarl 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);
6012205254eSKarl Rupp       } else if (i+3<m) {
6022205254eSKarl 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);
6032205254eSKarl Rupp       } else if (i+2<m) {
6042205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6052205254eSKarl Rupp       } else if (i+1<m) {
6062205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6072205254eSKarl Rupp       } else if (i<m) {
6082205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6092205254eSKarl Rupp       } else {
6102205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6112205254eSKarl Rupp       }
612496be53dSLois Curfman McInnes     }
613b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
614606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
615496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
616496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
61777431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
618496be53dSLois Curfman McInnes       }
619b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
620496be53dSLois Curfman McInnes     }
621b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
622496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
623496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
624496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
625aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
627b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6286831982aSBarry Smith           }
629496be53dSLois Curfman McInnes #else
630b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
631496be53dSLois Curfman McInnes #endif
632496be53dSLois Curfman McInnes         }
633496be53dSLois Curfman McInnes       }
634b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
635496be53dSLois Curfman McInnes     }
636d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
637fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
63897f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
63987828ca2SBarry Smith     PetscScalar value;
64002594712SBarry Smith 
641d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
642dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
64302594712SBarry Smith     for (i=0; i<m; i++) {
64402594712SBarry Smith       jcnt = 0;
645d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
646e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
64702594712SBarry Smith           value = a->a[cnt++];
648e24b481bSBarry Smith           jcnt++;
64902594712SBarry Smith         } else {
65002594712SBarry Smith           value = 0.0;
65102594712SBarry Smith         }
652aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
653b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
65402594712SBarry Smith #else
655b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
65602594712SBarry Smith #endif
65702594712SBarry Smith       }
658b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65902594712SBarry Smith     }
660d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6613c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
662d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
663dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
6643c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6653c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6663c215bfdSMatthew Knepley #else
6673c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6683c215bfdSMatthew Knepley #endif
669d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6703c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
6713c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
6723c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6733c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
674ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6753c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
676ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6773c215bfdSMatthew Knepley         } else {
678ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6793c215bfdSMatthew Knepley         }
6803c215bfdSMatthew Knepley #else
681ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr);
6823c215bfdSMatthew Knepley #endif
6833c215bfdSMatthew Knepley       }
6843c215bfdSMatthew Knepley     }
685d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6863a40ed3dSBarry Smith   } else {
687d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
688dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
689d5f3da31SBarry Smith     if (A->factortype) {
69016cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
69116cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
69216cd7e1dSShri Abhyankar         /* L part */
69316cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
69416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
69516cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
696ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69716cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
698ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69916cd7e1dSShri Abhyankar           } else {
700ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
70116cd7e1dSShri Abhyankar           }
70216cd7e1dSShri Abhyankar #else
703ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
70416cd7e1dSShri Abhyankar #endif
70516cd7e1dSShri Abhyankar         }
70616cd7e1dSShri Abhyankar         /* diagonal */
70716cd7e1dSShri Abhyankar         j = a->diag[i];
70816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
70916cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
710ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
71116cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
712ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
71316cd7e1dSShri Abhyankar         } else {
714ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
71516cd7e1dSShri Abhyankar         }
71616cd7e1dSShri Abhyankar #else
717ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
71816cd7e1dSShri Abhyankar #endif
71916cd7e1dSShri Abhyankar 
72016cd7e1dSShri Abhyankar         /* U part */
72116cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
72216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
72316cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
724ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72516cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
726ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72716cd7e1dSShri Abhyankar           } else {
728ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
72916cd7e1dSShri Abhyankar           }
73016cd7e1dSShri Abhyankar #else
731ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
73216cd7e1dSShri Abhyankar #endif
73316cd7e1dSShri Abhyankar         }
73416cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
73516cd7e1dSShri Abhyankar       }
73616cd7e1dSShri Abhyankar     } else {
73717ab2063SBarry Smith       for (i=0; i<m; i++) {
73877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
739416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
740aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
74136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
742ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
74336db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
744ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7453a40ed3dSBarry Smith           } else {
746ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
74717ab2063SBarry Smith           }
74817ab2063SBarry Smith #else
749ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
75017ab2063SBarry Smith #endif
75117ab2063SBarry Smith         }
752b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
75317ab2063SBarry Smith       }
75416cd7e1dSShri Abhyankar     }
755d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
75617ab2063SBarry Smith   }
757b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7583a40ed3dSBarry Smith   PetscFunctionReturn(0);
759416022c9SBarry Smith }
760416022c9SBarry Smith 
7619804daf3SBarry Smith #include <petscdraw.h>
7624a2ae208SSatish Balay #undef __FUNCT__
7634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
764dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
765416022c9SBarry Smith {
766480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
767416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
768dfbe8321SBarry Smith   PetscErrorCode    ierr;
769d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
77036db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
771b0a32e0cSBarry Smith   PetscViewer       viewer;
772f3ef73ceSBarry Smith   PetscViewerFormat format;
773cddf8d76SBarry Smith 
7743a40ed3dSBarry Smith   PetscFunctionBegin;
775480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
776b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
77719bcc07fSBarry Smith 
778b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
779416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7800513a670SBarry Smith 
781fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7820513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
783b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
784416022c9SBarry Smith     for (i=0; i<m; i++) {
785cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
786bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
787bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
78836db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
789b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
790cddf8d76SBarry Smith       }
791cddf8d76SBarry Smith     }
792b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
793cddf8d76SBarry Smith     for (i=0; i<m; i++) {
794cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
795bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
796bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
797cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
798b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
799cddf8d76SBarry Smith       }
800cddf8d76SBarry Smith     }
801b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
802cddf8d76SBarry Smith     for (i=0; i<m; i++) {
803cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
804bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
805bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
80636db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
807b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
808416022c9SBarry Smith       }
809416022c9SBarry Smith     }
8100513a670SBarry Smith   } else {
8110513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8120513a670SBarry Smith     /* first determine max of all nonzero values */
81397f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
814b0a32e0cSBarry Smith     PetscDraw popup;
81536db0b34SBarry Smith     PetscReal scale;
8160513a670SBarry Smith 
8170513a670SBarry Smith     for (i=0; i<nz; i++) {
8180513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8190513a670SBarry Smith     }
820b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
821b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8222205254eSKarl Rupp     if (popup) {
8232205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8242205254eSKarl Rupp     }
8250513a670SBarry Smith     count = 0;
8260513a670SBarry Smith     for (i=0; i<m; i++) {
8270513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
828bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
829bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
83097f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
831b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8320513a670SBarry Smith         count++;
8330513a670SBarry Smith       }
8340513a670SBarry Smith     }
8350513a670SBarry Smith   }
836480ef9eaSBarry Smith   PetscFunctionReturn(0);
837480ef9eaSBarry Smith }
838cddf8d76SBarry Smith 
8399804daf3SBarry Smith #include <petscdraw.h>
8404a2ae208SSatish Balay #undef __FUNCT__
8414a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
842dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
843480ef9eaSBarry Smith {
844dfbe8321SBarry Smith   PetscErrorCode ierr;
845b0a32e0cSBarry Smith   PetscDraw      draw;
84636db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
847ace3abfcSBarry Smith   PetscBool      isnull;
848480ef9eaSBarry Smith 
849480ef9eaSBarry Smith   PetscFunctionBegin;
850b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
851b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
852480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
853480ef9eaSBarry Smith 
854480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
855d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
856480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
857b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
858b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8590298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8603a40ed3dSBarry Smith   PetscFunctionReturn(0);
861416022c9SBarry Smith }
862416022c9SBarry Smith 
8634a2ae208SSatish Balay #undef __FUNCT__
8644a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
865dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
866416022c9SBarry Smith {
867dfbe8321SBarry Smith   PetscErrorCode ierr;
868ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
869416022c9SBarry Smith 
8703a40ed3dSBarry Smith   PetscFunctionBegin;
871251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
872251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
873251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
874c45a1595SBarry Smith   if (iascii) {
8753a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8760f5bd95cSBarry Smith   } else if (isbinary) {
8773a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8780f5bd95cSBarry Smith   } else if (isdraw) {
8793a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
88011aeaf0aSBarry Smith   }
8814108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8823a40ed3dSBarry Smith   PetscFunctionReturn(0);
88317ab2063SBarry Smith }
88419bcc07fSBarry Smith 
8854a2ae208SSatish Balay #undef __FUNCT__
8864a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
887dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
88817ab2063SBarry Smith {
889416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8906849ba73SBarry Smith   PetscErrorCode ierr;
89197f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
892d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
89354f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
8943447b6efSHong Zhang   PetscReal      ratio  = 0.6;
89517ab2063SBarry Smith 
8963a40ed3dSBarry Smith   PetscFunctionBegin;
8973a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
89817ab2063SBarry Smith 
89943ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
90017ab2063SBarry Smith   for (i=1; i<m; i++) {
901416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
90217ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
90394a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
90417ab2063SBarry Smith     if (fshift) {
905bfeeae90SHong Zhang       ip = aj + ai[i];
906bfeeae90SHong Zhang       ap = aa + ai[i];
90717ab2063SBarry Smith       N  = ailen[i];
90817ab2063SBarry Smith       for (j=0; j<N; j++) {
90917ab2063SBarry Smith         ip[j-fshift] = ip[j];
91017ab2063SBarry Smith         ap[j-fshift] = ap[j];
91117ab2063SBarry Smith       }
91217ab2063SBarry Smith     }
91317ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
91417ab2063SBarry Smith   }
91517ab2063SBarry Smith   if (m) {
91617ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
91717ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
91817ab2063SBarry Smith   }
91917ab2063SBarry Smith   /* reset ilen and imax for each row */
92017ab2063SBarry Smith   for (i=0; i<m; i++) {
92117ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
92217ab2063SBarry Smith   }
923bfeeae90SHong Zhang   a->nz = ai[m];
92465e19b50SBarry 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);
92517ab2063SBarry Smith 
92609f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
927d0f46423SBarry 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);
928ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
929ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9302205254eSKarl Rupp 
9318e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
932dd5f02e7SSatish Balay   a->reallocs         = 0;
9334e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
93436db0b34SBarry Smith   a->rmax             = rmax;
9354e220ebcSLois Curfman McInnes 
936cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9372205254eSKarl Rupp 
93888e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
93971c2f376SKris Buschelman 
9404108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
94171f1c65dSBarry Smith 
942acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9433a40ed3dSBarry Smith   PetscFunctionReturn(0);
94417ab2063SBarry Smith }
94517ab2063SBarry Smith 
9464a2ae208SSatish Balay #undef __FUNCT__
94799cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
94899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
94999cafbc1SBarry Smith {
95099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
95199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
95254f21887SBarry Smith   MatScalar      *aa = a->a;
953acf2f550SJed Brown   PetscErrorCode ierr;
95499cafbc1SBarry Smith 
95599cafbc1SBarry Smith   PetscFunctionBegin;
95699cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
957acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
95899cafbc1SBarry Smith   PetscFunctionReturn(0);
95999cafbc1SBarry Smith }
96099cafbc1SBarry Smith 
96199cafbc1SBarry Smith #undef __FUNCT__
96299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
96399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
96499cafbc1SBarry Smith {
96599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
96754f21887SBarry Smith   MatScalar      *aa = a->a;
968acf2f550SJed Brown   PetscErrorCode ierr;
96999cafbc1SBarry Smith 
97099cafbc1SBarry Smith   PetscFunctionBegin;
97199cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
972acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
97399cafbc1SBarry Smith   PetscFunctionReturn(0);
97499cafbc1SBarry Smith }
97599cafbc1SBarry Smith 
97678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
97778b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
97878b84d54SShri Abhyankar {
97978b84d54SShri Abhyankar   PetscErrorCode ierr;
98078b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
98178b84d54SShri Abhyankar   PetscInt       n,start,end;
98278b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98378b84d54SShri Abhyankar 
98478b84d54SShri Abhyankar   start = trstarts[thread_id];
98578b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
98619baf141SJed Brown   n     = a->i[end] - a->i[start];
98719baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
98878b84d54SShri Abhyankar   return 0;
98978b84d54SShri Abhyankar }
99078b84d54SShri Abhyankar 
99178b84d54SShri Abhyankar #undef __FUNCT__
99278b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
99378b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
99478b84d54SShri Abhyankar {
99578b84d54SShri Abhyankar   PetscErrorCode ierr;
99678b84d54SShri Abhyankar 
99778b84d54SShri Abhyankar   PetscFunctionBegin;
998ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
999acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
100078b84d54SShri Abhyankar   PetscFunctionReturn(0);
100178b84d54SShri Abhyankar }
100278b84d54SShri Abhyankar #else
100399cafbc1SBarry Smith #undef __FUNCT__
10044a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1005dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
100617ab2063SBarry Smith {
1007416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1008dfbe8321SBarry Smith   PetscErrorCode ierr;
10093a40ed3dSBarry Smith 
10103a40ed3dSBarry Smith   PetscFunctionBegin;
1011d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1012acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10133a40ed3dSBarry Smith   PetscFunctionReturn(0);
101417ab2063SBarry Smith }
101578b84d54SShri Abhyankar #endif
1016416022c9SBarry Smith 
10174a2ae208SSatish Balay #undef __FUNCT__
10184a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1019dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
102017ab2063SBarry Smith {
1021416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1022dfbe8321SBarry Smith   PetscErrorCode ierr;
1023d5d45c9bSBarry Smith 
10243a40ed3dSBarry Smith   PetscFunctionBegin;
1025aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1026d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
102717ab2063SBarry Smith #endif
1028e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10296bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10306bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
103105b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1032d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
103305b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
103471f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
103505b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10366bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
103705b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10386bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
103905b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10406bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1041cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10420b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1043a30b2313SHong Zhang 
10444108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1045bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1046901853e0SKris Buschelman 
1047dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10583a40ed3dSBarry Smith   PetscFunctionReturn(0);
105917ab2063SBarry Smith }
106017ab2063SBarry Smith 
10614a2ae208SSatish Balay #undef __FUNCT__
10624a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1063ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
106417ab2063SBarry Smith {
1065416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10664846f1f5SKris Buschelman   PetscErrorCode ierr;
10673a40ed3dSBarry Smith 
10683a40ed3dSBarry Smith   PetscFunctionBegin;
1069a65d3064SKris Buschelman   switch (op) {
1070a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10714e0d8c25SBarry Smith     a->roworiented = flg;
1072a65d3064SKris Buschelman     break;
1073a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1074a9817697SBarry Smith     a->keepnonzeropattern = flg;
1075a65d3064SKris Buschelman     break;
1076512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1077512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1078a65d3064SKris Buschelman     break;
1079a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10804e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1081a65d3064SKris Buschelman     break;
1082a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10834e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1084a65d3064SKris Buschelman     break;
108528b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
108628b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
108728b2fa4aSMatthew Knepley     break;
1088a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10894e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10900df259c2SBarry Smith     break;
1091cd6b891eSBarry Smith   case MAT_CHECK_COMPRESSED_ROW:
1092cd6b891eSBarry Smith     a->compressedrow.check = flg;
1093d487561eSHong Zhang     break;
10943d472b54SHong Zhang   case MAT_SPD:
1095b1646e73SJed Brown   case MAT_SYMMETRIC:
1096b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1097b1646e73SJed Brown   case MAT_HERMITIAN:
1098b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
10995021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11005021d80fSJed Brown     break;
11014e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1102a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1103a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1104290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1105a65d3064SKris Buschelman     break;
1106b87ac2d8SJed Brown   case MAT_USE_INODES:
1107b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1108b87ac2d8SJed Brown     break;
1109a65d3064SKris Buschelman   default:
1110e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1111a65d3064SKris Buschelman   }
11124108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11133a40ed3dSBarry Smith   PetscFunctionReturn(0);
111417ab2063SBarry Smith }
111517ab2063SBarry Smith 
11164a2ae208SSatish Balay #undef __FUNCT__
11174a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1118dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
111917ab2063SBarry Smith {
1120416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11216849ba73SBarry Smith   PetscErrorCode ierr;
1122d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
112335e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
112417ab2063SBarry Smith 
11253a40ed3dSBarry Smith   PetscFunctionBegin;
1126d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1127e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
112835e7444dSHong Zhang 
1129d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1130d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
113135e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11322c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
113335e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
113435e7444dSHong Zhang     PetscFunctionReturn(0);
113535e7444dSHong Zhang   }
113635e7444dSHong Zhang 
11372dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11381ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
113935e7444dSHong Zhang   for (i=0; i<n; i++) {
114035e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11412f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
114235e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
114335e7444dSHong Zhang       if (aj[j] == i) {
114435e7444dSHong Zhang         x[i] = aa[j];
114517ab2063SBarry Smith         break;
114617ab2063SBarry Smith       }
114717ab2063SBarry Smith     }
114817ab2063SBarry Smith   }
11491ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
115117ab2063SBarry Smith }
115217ab2063SBarry Smith 
1153c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11544a2ae208SSatish Balay #undef __FUNCT__
11554a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1156dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
115717ab2063SBarry Smith {
1158416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11595c897100SBarry Smith   PetscScalar    *x,*y;
1160dfbe8321SBarry Smith   PetscErrorCode ierr;
1161d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11625c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1163a77337e4SBarry Smith   MatScalar         *v;
1164a77337e4SBarry Smith   PetscScalar       alpha;
11650298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11663447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1167ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11685c897100SBarry Smith #endif
116917ab2063SBarry Smith 
11703a40ed3dSBarry Smith   PetscFunctionBegin;
11712e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11721ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11731ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11745c897100SBarry Smith 
11755c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1176bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11775c897100SBarry Smith #else
11783447b6efSHong Zhang   if (usecprow) {
11793447b6efSHong Zhang     m    = cprow.nrows;
11803447b6efSHong Zhang     ii   = cprow.i;
11817b2bb3b9SHong Zhang     ridx = cprow.rindex;
11823447b6efSHong Zhang   } else {
11833447b6efSHong Zhang     ii = a->i;
11843447b6efSHong Zhang   }
118517ab2063SBarry Smith   for (i=0; i<m; i++) {
11863447b6efSHong Zhang     idx = a->j + ii[i];
11873447b6efSHong Zhang     v   = a->a + ii[i];
11883447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11893447b6efSHong Zhang     if (usecprow) {
11907b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11913447b6efSHong Zhang     } else {
119217ab2063SBarry Smith       alpha = x[i];
11933447b6efSHong Zhang     }
119404fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
119517ab2063SBarry Smith   }
11965c897100SBarry Smith #endif
1197dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11981ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11991ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
120117ab2063SBarry Smith }
120217ab2063SBarry Smith 
12034a2ae208SSatish Balay #undef __FUNCT__
12045c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1205dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12065c897100SBarry Smith {
1207dfbe8321SBarry Smith   PetscErrorCode ierr;
12085c897100SBarry Smith 
12095c897100SBarry Smith   PetscFunctionBegin;
1210170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12115c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12125c897100SBarry Smith   PetscFunctionReturn(0);
12135c897100SBarry Smith }
12145c897100SBarry Smith 
1215c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
121678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
121778b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
121878b84d54SShri Abhyankar {
121978b84d54SShri Abhyankar   PetscErrorCode    ierr;
122078b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
122178b84d54SShri Abhyankar   PetscScalar       *y;
122278b84d54SShri Abhyankar   const PetscScalar *x;
122378b84d54SShri Abhyankar   const MatScalar   *aa;
122478b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
122578b84d54SShri Abhyankar   PetscInt          n,start,end,i;
122678b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
122778b84d54SShri Abhyankar   PetscScalar       sum;
122878b84d54SShri Abhyankar 
122978b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
123078b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
123178b84d54SShri Abhyankar   start = trstarts[thread_id];
123278b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
123378b84d54SShri Abhyankar   aj    = a->j;
123478b84d54SShri Abhyankar   aa    = a->a;
123578b84d54SShri Abhyankar   ai    = a->i;
123678b84d54SShri Abhyankar   for (i=start; i<end; i++) {
123778b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
123878b84d54SShri Abhyankar     aj  = a->j + ai[i];
123978b84d54SShri Abhyankar     aa  = a->a + ai[i];
124078b84d54SShri Abhyankar     sum = 0.0;
124178b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
124278b84d54SShri Abhyankar     y[i] = sum;
124378b84d54SShri Abhyankar   }
124478b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
124578b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
124678b84d54SShri Abhyankar   return 0;
124778b84d54SShri Abhyankar }
124878b84d54SShri Abhyankar 
124978b84d54SShri Abhyankar #undef __FUNCT__
125078b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
125178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
125278b84d54SShri Abhyankar {
125378b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
125478b84d54SShri Abhyankar   PetscScalar       *y;
125578b84d54SShri Abhyankar   const PetscScalar *x;
125678b84d54SShri Abhyankar   const MatScalar   *aa;
125778b84d54SShri Abhyankar   PetscErrorCode    ierr;
125878b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12590298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
126078b84d54SShri Abhyankar   PetscInt          n,i,nonzerorow=0;
126178b84d54SShri Abhyankar   PetscScalar       sum;
126278b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
126378b84d54SShri Abhyankar 
126478b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
126578b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
126678b84d54SShri Abhyankar #endif
126778b84d54SShri Abhyankar 
126878b84d54SShri Abhyankar   PetscFunctionBegin;
126978b84d54SShri Abhyankar   aj = a->j;
127078b84d54SShri Abhyankar   aa = a->a;
127178b84d54SShri Abhyankar   ii = a->i;
127278b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
127378b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
127478b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
127578b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
127678b84d54SShri Abhyankar     ii   = a->compressedrow.i;
127778b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
127878b84d54SShri Abhyankar     for (i=0; i<m; i++) {
127978b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
128078b84d54SShri Abhyankar       aj          = a->j + ii[i];
128178b84d54SShri Abhyankar       aa          = a->a + ii[i];
128278b84d54SShri Abhyankar       sum         = 0.0;
128378b84d54SShri Abhyankar       nonzerorow += (n>0);
128478b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128578b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
128678b84d54SShri Abhyankar       y[*ridx++] = sum;
128778b84d54SShri Abhyankar     }
128878b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
128978b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
129078b84d54SShri Abhyankar   } else { /* do not use compressed row format */
129178b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
129278b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
129378b84d54SShri Abhyankar #else
1294ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
129578b84d54SShri Abhyankar #endif
129678b84d54SShri Abhyankar   }
129778b84d54SShri Abhyankar   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
129878b84d54SShri Abhyankar   PetscFunctionReturn(0);
129978b84d54SShri Abhyankar }
130078b84d54SShri Abhyankar #else
13015c897100SBarry Smith #undef __FUNCT__
13024a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1303dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
130417ab2063SBarry Smith {
1305416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1306d9fead3dSBarry Smith   PetscScalar       *y;
130754f21887SBarry Smith   const PetscScalar *x;
130854f21887SBarry Smith   const MatScalar   *aa;
1309dfbe8321SBarry Smith   PetscErrorCode    ierr;
1310003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13110298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13128aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1313362ced78SSatish Balay   PetscScalar       sum;
1314ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
131517ab2063SBarry Smith 
1316b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
131797952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1318fee21e36SBarry Smith #endif
1319fee21e36SBarry Smith 
13203a40ed3dSBarry Smith   PetscFunctionBegin;
13213649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13221ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
132397952fefSHong Zhang   aj   = a->j;
132497952fefSHong Zhang   aa   = a->a;
1325416022c9SBarry Smith   ii   = a->i;
13264eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
132797952fefSHong Zhang     m    = a->compressedrow.nrows;
132897952fefSHong Zhang     ii   = a->compressedrow.i;
132997952fefSHong Zhang     ridx = a->compressedrow.rindex;
133097952fefSHong Zhang     for (i=0; i<m; i++) {
133197952fefSHong Zhang       n           = ii[i+1] - ii[i];
133297952fefSHong Zhang       aj          = a->j + ii[i];
133397952fefSHong Zhang       aa          = a->a + ii[i];
133497952fefSHong Zhang       sum         = 0.0;
1335a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1336003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1337003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
133897952fefSHong Zhang       y[*ridx++] = sum;
133997952fefSHong Zhang     }
134097952fefSHong Zhang   } else { /* do not use compressed row format */
1341b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1342b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1343b05257ddSBarry Smith #else
134478b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1345ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
134678b84d54SShri Abhyankar #else
134717ab2063SBarry Smith     for (i=0; i<m; i++) {
1348003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1349003131ecSBarry Smith       aj          = a->j + ii[i];
1350003131ecSBarry Smith       aa          = a->a + ii[i];
135117ab2063SBarry Smith       sum         = 0.0;
1352a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1353003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
135417ab2063SBarry Smith       y[i] = sum;
135517ab2063SBarry Smith     }
13568d195f9aSBarry Smith #endif
135778b84d54SShri Abhyankar #endif
1358b05257ddSBarry Smith   }
1359dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
13603649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13611ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13623a40ed3dSBarry Smith   PetscFunctionReturn(0);
136317ab2063SBarry Smith }
136478b84d54SShri Abhyankar #endif
136517ab2063SBarry Smith 
1366b434eb95SMatthew G. Knepley #undef __FUNCT__
1367b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1368b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1369b434eb95SMatthew G. Knepley {
1370b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1371b434eb95SMatthew G. Knepley   PetscScalar       *y;
1372b434eb95SMatthew G. Knepley   const PetscScalar *x;
1373b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1374b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1375b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1376b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1377b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1378b434eb95SMatthew G. Knepley   PetscScalar       sum;
1379b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1380b434eb95SMatthew G. Knepley 
1381b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1382b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1383b434eb95SMatthew G. Knepley #endif
1384b434eb95SMatthew G. Knepley 
1385b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1386b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1387b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1388b434eb95SMatthew G. Knepley   aj   = a->j;
1389b434eb95SMatthew G. Knepley   aa   = a->a;
1390b434eb95SMatthew G. Knepley   ii   = a->i;
1391b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1392b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1393b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1394b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1395b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1396b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1397b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1398b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1399b434eb95SMatthew G. Knepley       sum         = 0.0;
1400b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1401b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1402b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1403b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1404b434eb95SMatthew G. Knepley     }
1405b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1406b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1407b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1408b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1409b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1410b434eb95SMatthew G. Knepley       sum         = 0.0;
1411b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1412b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1413b434eb95SMatthew G. Knepley       y[i] = sum;
1414b434eb95SMatthew G. Knepley     }
1415b434eb95SMatthew G. Knepley   }
1416b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1417b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1418b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1419b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1420b434eb95SMatthew G. Knepley }
1421b434eb95SMatthew G. Knepley 
1422b434eb95SMatthew G. Knepley #undef __FUNCT__
1423b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1424b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1425b434eb95SMatthew G. Knepley {
1426b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1427b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1428b434eb95SMatthew G. Knepley   const PetscScalar *x;
1429b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1430b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1431b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1432b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1433b434eb95SMatthew G. Knepley   PetscScalar       sum;
1434b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1435b434eb95SMatthew G. Knepley 
1436b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1437b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1438b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1439b434eb95SMatthew G. Knepley   if (zz != yy) {
1440b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1441b434eb95SMatthew G. Knepley   } else {
1442b434eb95SMatthew G. Knepley     z = y;
1443b434eb95SMatthew G. Knepley   }
1444b434eb95SMatthew G. Knepley 
1445b434eb95SMatthew G. Knepley   aj = a->j;
1446b434eb95SMatthew G. Knepley   aa = a->a;
1447b434eb95SMatthew G. Knepley   ii = a->i;
1448b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1449b434eb95SMatthew G. Knepley     if (zz != yy) {
1450b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1451b434eb95SMatthew G. Knepley     }
1452b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1453b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1454b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1455b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1456b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1457b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1458b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1459b434eb95SMatthew G. Knepley       sum = y[*ridx];
1460b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1461b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1462b434eb95SMatthew G. Knepley     }
1463b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1464b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1465b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1466b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1467b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1468b434eb95SMatthew G. Knepley       sum = y[i];
1469b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1470b434eb95SMatthew G. Knepley       z[i] = sum;
1471b434eb95SMatthew G. Knepley     }
1472b434eb95SMatthew G. Knepley   }
1473b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1474b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1475b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1476b434eb95SMatthew G. Knepley   if (zz != yy) {
1477b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1478b434eb95SMatthew G. Knepley   }
1479b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1480b434eb95SMatthew G. Knepley }
1481b434eb95SMatthew G. Knepley 
1482c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14834a2ae208SSatish Balay #undef __FUNCT__
14844a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1485dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
148617ab2063SBarry Smith {
1487416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1488f15663dcSBarry Smith   PetscScalar       *y,*z;
1489f15663dcSBarry Smith   const PetscScalar *x;
149054f21887SBarry Smith   const MatScalar   *aa;
1491dfbe8321SBarry Smith   PetscErrorCode    ierr;
1492d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14930298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1494362ced78SSatish Balay   PetscScalar       sum;
1495ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14969ea0dfa2SSatish Balay 
14973a40ed3dSBarry Smith   PetscFunctionBegin;
1498f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14991ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15002e8a6d31SBarry Smith   if (zz != yy) {
15011ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15022e8a6d31SBarry Smith   } else {
15032e8a6d31SBarry Smith     z = y;
15042e8a6d31SBarry Smith   }
1505bfeeae90SHong Zhang 
150697952fefSHong Zhang   aj = a->j;
150797952fefSHong Zhang   aa = a->a;
1508cddf8d76SBarry Smith   ii = a->i;
15094eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15104eb6d288SHong Zhang     if (zz != yy) {
15114eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15124eb6d288SHong Zhang     }
151397952fefSHong Zhang     m    = a->compressedrow.nrows;
151497952fefSHong Zhang     ii   = a->compressedrow.i;
151597952fefSHong Zhang     ridx = a->compressedrow.rindex;
151697952fefSHong Zhang     for (i=0; i<m; i++) {
151797952fefSHong Zhang       n   = ii[i+1] - ii[i];
151897952fefSHong Zhang       aj  = a->j + ii[i];
151997952fefSHong Zhang       aa  = a->a + ii[i];
152097952fefSHong Zhang       sum = y[*ridx];
1521f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152297952fefSHong Zhang       z[*ridx++] = sum;
152397952fefSHong Zhang     }
152497952fefSHong Zhang   } else { /* do not use compressed row format */
1525f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1526f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1527f15663dcSBarry Smith #else
152817ab2063SBarry Smith     for (i=0; i<m; i++) {
1529f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1530f15663dcSBarry Smith       aj  = a->j + ii[i];
1531f15663dcSBarry Smith       aa  = a->a + ii[i];
153217ab2063SBarry Smith       sum = y[i];
1533f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153417ab2063SBarry Smith       z[i] = sum;
153517ab2063SBarry Smith     }
153602ab625aSSatish Balay #endif
1537f15663dcSBarry Smith   }
1538dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1539f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15401ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15412e8a6d31SBarry Smith   if (zz != yy) {
15421ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15432e8a6d31SBarry Smith   }
15448154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15456b375ea7SVictor Minden   /*
1546918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1547918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1548918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15496b375ea7SVictor Minden   */
1550918e98c3SVictor Minden #endif
15513a40ed3dSBarry Smith   PetscFunctionReturn(0);
155217ab2063SBarry Smith }
155317ab2063SBarry Smith 
155417ab2063SBarry Smith /*
155517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
155617ab2063SBarry Smith */
15574a2ae208SSatish Balay #undef __FUNCT__
15584a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1559dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
156017ab2063SBarry Smith {
1561416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15626849ba73SBarry Smith   PetscErrorCode ierr;
1563d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
156417ab2063SBarry Smith 
15653a40ed3dSBarry Smith   PetscFunctionBegin;
156609f38230SBarry Smith   if (!a->diag) {
156709f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
15683bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
156909f38230SBarry Smith   }
1570d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
157109f38230SBarry Smith     a->diag[i] = a->i[i+1];
1572bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1573bfeeae90SHong Zhang       if (a->j[j] == i) {
157409f38230SBarry Smith         a->diag[i] = j;
157517ab2063SBarry Smith         break;
157617ab2063SBarry Smith       }
157717ab2063SBarry Smith     }
157817ab2063SBarry Smith   }
15793a40ed3dSBarry Smith   PetscFunctionReturn(0);
158017ab2063SBarry Smith }
158117ab2063SBarry Smith 
1582be5855fcSBarry Smith /*
1583be5855fcSBarry Smith      Checks for missing diagonals
1584be5855fcSBarry Smith */
15854a2ae208SSatish Balay #undef __FUNCT__
15864a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1587ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1588be5855fcSBarry Smith {
1589be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
159097f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1591be5855fcSBarry Smith 
1592be5855fcSBarry Smith   PetscFunctionBegin;
159309f38230SBarry Smith   *missing = PETSC_FALSE;
1594d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
159509f38230SBarry Smith     *missing = PETSC_TRUE;
159609f38230SBarry Smith     if (d) *d = 0;
1597358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
159809f38230SBarry Smith   } else {
1599f1e2ffcdSBarry Smith     diag = a->diag;
1600d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1601bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
160209f38230SBarry Smith         *missing = PETSC_TRUE;
160309f38230SBarry Smith         if (d) *d = i;
160409f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1605358d2f5dSShri Abhyankar         break;
160609f38230SBarry Smith       }
1607be5855fcSBarry Smith     }
1608be5855fcSBarry Smith   }
1609be5855fcSBarry Smith   PetscFunctionReturn(0);
1610be5855fcSBarry Smith }
1611be5855fcSBarry Smith 
161271f1c65dSBarry Smith #undef __FUNCT__
161371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16147087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
161571f1c65dSBarry Smith {
161671f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
161771f1c65dSBarry Smith   PetscErrorCode ierr;
1618d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
161954f21887SBarry Smith   MatScalar      *v = a->a;
162054f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
162171f1c65dSBarry Smith 
162271f1c65dSBarry Smith   PetscFunctionBegin;
162371f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
162471f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
162571f1c65dSBarry Smith   diag = a->diag;
162671f1c65dSBarry Smith   if (!a->idiag) {
162771f1c65dSBarry Smith     ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
16283bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
162971f1c65dSBarry Smith     v    = a->a;
163071f1c65dSBarry Smith   }
163171f1c65dSBarry Smith   mdiag = a->mdiag;
163271f1c65dSBarry Smith   idiag = a->idiag;
163371f1c65dSBarry Smith 
1634028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
163571f1c65dSBarry Smith     for (i=0; i<m; i++) {
163671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1637e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
163871f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
163971f1c65dSBarry Smith     }
164071f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
164171f1c65dSBarry Smith   } else {
164271f1c65dSBarry Smith     for (i=0; i<m; i++) {
164371f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
164471f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
164571f1c65dSBarry Smith     }
1646dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
164771f1c65dSBarry Smith   }
164871f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
164971f1c65dSBarry Smith   PetscFunctionReturn(0);
165071f1c65dSBarry Smith }
165171f1c65dSBarry Smith 
1652c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16534a2ae208SSatish Balay #undef __FUNCT__
165441f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
165541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
165617ab2063SBarry Smith {
1657416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1658e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1659e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
166054f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1661dfbe8321SBarry Smith   PetscErrorCode    ierr;
1662d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
166397f1f81fSBarry Smith   const PetscInt    *idx,*diag;
166417ab2063SBarry Smith 
16653a40ed3dSBarry Smith   PetscFunctionBegin;
1666b965ef7fSBarry Smith   its = its*lits;
166791723122SBarry Smith 
166871f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
166971f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
167071f1c65dSBarry Smith   a->fshift = fshift;
167171f1c65dSBarry Smith   a->omega  = omega;
1672ed480e8bSBarry Smith 
167371f1c65dSBarry Smith   diag  = a->diag;
167471f1c65dSBarry Smith   t     = a->ssor_work;
1675ed480e8bSBarry Smith   idiag = a->idiag;
167671f1c65dSBarry Smith   mdiag = a->mdiag;
1677ed480e8bSBarry Smith 
16781ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16793649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1680ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
168117ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
168217ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1683ed480e8bSBarry Smith     bs = b;
168417ab2063SBarry Smith     for (i=0; i<m; i++) {
168571f1c65dSBarry Smith       d   = fshift + mdiag[i];
1686416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1687ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1688ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
168917ab2063SBarry Smith       sum = b[i]*d/omega;
1690003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
169117ab2063SBarry Smith       x[i] = sum;
169217ab2063SBarry Smith     }
16931ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16943649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1695efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16963a40ed3dSBarry Smith     PetscFunctionReturn(0);
169717ab2063SBarry Smith   }
1698c783ea89SBarry Smith 
16992205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17002205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
170117ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1702887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
170317ab2063SBarry Smith 
170417ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
170517ab2063SBarry Smith 
1706887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
170717ab2063SBarry Smith     */
170817ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
170917ab2063SBarry Smith 
171017ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
171117ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1712416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1713ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1714ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
171517ab2063SBarry Smith       sum = b[i];
1716e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1717ed480e8bSBarry Smith       x[i] = sum*idiag[i];
171817ab2063SBarry Smith     }
171917ab2063SBarry Smith 
172017ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1721416022c9SBarry Smith     v = a->a;
17222205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
172317ab2063SBarry Smith 
172417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1725ed480e8bSBarry Smith     ts   = t;
1726416022c9SBarry Smith     diag = a->diag;
172717ab2063SBarry Smith     for (i=0; i<m; i++) {
1728416022c9SBarry Smith       n   = diag[i] - a->i[i];
1729ed480e8bSBarry Smith       idx = a->j + a->i[i];
1730ed480e8bSBarry Smith       v   = a->a + a->i[i];
173117ab2063SBarry Smith       sum = t[i];
1732003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1733ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1734733d66baSBarry Smith       /*  x = x + t */
1735733d66baSBarry Smith       x[i] += t[i];
173617ab2063SBarry Smith     }
173717ab2063SBarry Smith 
1738dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17391ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17403649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17413a40ed3dSBarry Smith     PetscFunctionReturn(0);
174217ab2063SBarry Smith   }
174317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
174417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
174517ab2063SBarry Smith       for (i=0; i<m; i++) {
1746416022c9SBarry Smith         n   = diag[i] - a->i[i];
1747ed480e8bSBarry Smith         idx = a->j + a->i[i];
1748ed480e8bSBarry Smith         v   = a->a + a->i[i];
174917ab2063SBarry Smith         sum = b[i];
1750e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17515c99c7daSBarry Smith         t[i] = sum;
1752ed480e8bSBarry Smith         x[i] = sum*idiag[i];
175317ab2063SBarry Smith       }
17545c99c7daSBarry Smith       xb   = t;
1755efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17563a40ed3dSBarry Smith     } else xb = b;
175717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
175817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1759416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1760ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1761ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
176217ab2063SBarry Smith         sum = xb[i];
1763e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17645c99c7daSBarry Smith         if (xb == b) {
1765ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17665c99c7daSBarry Smith         } else {
1767b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
176817ab2063SBarry Smith         }
17695c99c7daSBarry Smith       }
1770b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
177117ab2063SBarry Smith     }
177217ab2063SBarry Smith     its--;
177317ab2063SBarry Smith   }
177417ab2063SBarry Smith   while (its--) {
177517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
177617ab2063SBarry Smith       for (i=0; i<m; i++) {
1777b19a5dc2SMark Adams         /* lower */
1778b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1779ed480e8bSBarry Smith         idx = a->j + a->i[i];
1780ed480e8bSBarry Smith         v   = a->a + a->i[i];
178117ab2063SBarry Smith         sum = b[i];
1782e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1783b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1784b19a5dc2SMark Adams         /* upper */
1785b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1786b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1787b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1788b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1789b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
179017ab2063SBarry Smith       }
1791b19a5dc2SMark Adams       xb   = t;
17929f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1793b19a5dc2SMark Adams     } else xb = b;
179417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
179517ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1796b19a5dc2SMark Adams         sum = xb[i];
1797b19a5dc2SMark Adams         if (xb == b) {
1798b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1799416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1800ed480e8bSBarry Smith           idx = a->j + a->i[i];
1801ed480e8bSBarry Smith           v   = a->a + a->i[i];
1802e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1803ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1804b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1805b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1806b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1807b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1808b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1809b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
181017ab2063SBarry Smith         }
1811b19a5dc2SMark Adams       }
1812b19a5dc2SMark Adams       if (xb == b) {
18139f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1814b19a5dc2SMark Adams       } else {
1815b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1816b19a5dc2SMark Adams       }
181717ab2063SBarry Smith     }
181817ab2063SBarry Smith   }
18191ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18203649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1821365a8a9eSBarry Smith   PetscFunctionReturn(0);
182217ab2063SBarry Smith }
182317ab2063SBarry Smith 
18242af78befSBarry Smith 
18254a2ae208SSatish Balay #undef __FUNCT__
18264a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1827dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
182817ab2063SBarry Smith {
1829416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18304e220ebcSLois Curfman McInnes 
18313a40ed3dSBarry Smith   PetscFunctionBegin;
18324e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18334e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18344e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18354e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18364e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18378e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18387adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1839d5f3da31SBarry Smith   if (A->factortype) {
18404e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18414e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18424e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18434e220ebcSLois Curfman McInnes   } else {
18444e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18454e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18464e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18474e220ebcSLois Curfman McInnes   }
18483a40ed3dSBarry Smith   PetscFunctionReturn(0);
184917ab2063SBarry Smith }
185017ab2063SBarry Smith 
18514a2ae208SSatish Balay #undef __FUNCT__
18524a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18532b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
185417ab2063SBarry Smith {
1855416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18563b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18576849ba73SBarry Smith   PetscErrorCode    ierr;
185897b48c8fSBarry Smith   const PetscScalar *xx;
185997b48c8fSBarry Smith   PetscScalar       *bb;
1860ace3abfcSBarry Smith   PetscBool         missing;
186117ab2063SBarry Smith 
18623a40ed3dSBarry Smith   PetscFunctionBegin;
186397b48c8fSBarry Smith   if (x && b) {
186497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
186597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
186697b48c8fSBarry Smith     for (i=0; i<N; i++) {
186797b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
186897b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
186997b48c8fSBarry Smith     }
187097b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
187197b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
187297b48c8fSBarry Smith   }
187397b48c8fSBarry Smith 
1874a9817697SBarry Smith   if (a->keepnonzeropattern) {
1875f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1876e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1877bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1878f1e2ffcdSBarry Smith     }
1879f4df32b1SMatthew Knepley     if (diag != 0.0) {
188009f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1881e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1882f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1883f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1884f1e2ffcdSBarry Smith       }
1885f1e2ffcdSBarry Smith     }
188688e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1887f1e2ffcdSBarry Smith   } else {
1888f4df32b1SMatthew Knepley     if (diag != 0.0) {
188917ab2063SBarry Smith       for (i=0; i<N; i++) {
1890e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18917ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1892416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1893f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1894bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18957ae801bdSBarry Smith         } else { /* in case row was completely empty */
1896f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
189717ab2063SBarry Smith         }
189817ab2063SBarry Smith       }
18993a40ed3dSBarry Smith     } else {
190017ab2063SBarry Smith       for (i=0; i<N; i++) {
1901e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1902416022c9SBarry Smith         a->ilen[rows[i]] = 0;
190317ab2063SBarry Smith       }
190417ab2063SBarry Smith     }
190588e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1906f1e2ffcdSBarry Smith   }
190743a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19083a40ed3dSBarry Smith   PetscFunctionReturn(0);
190917ab2063SBarry Smith }
191017ab2063SBarry Smith 
19114a2ae208SSatish Balay #undef __FUNCT__
19126e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19136e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19146e169961SBarry Smith {
19156e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19166e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19176e169961SBarry Smith   PetscErrorCode    ierr;
19182b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19196e169961SBarry Smith   const PetscScalar *xx;
19206e169961SBarry Smith   PetscScalar       *bb;
19216e169961SBarry Smith 
19226e169961SBarry Smith   PetscFunctionBegin;
19236e169961SBarry Smith   if (x && b) {
19246e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19256e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19262b40b63fSBarry Smith     vecs = PETSC_TRUE;
19276e169961SBarry Smith   }
19286e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
19296e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
19306e169961SBarry Smith   for (i=0; i<N; i++) {
19316e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19326e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19332205254eSKarl Rupp 
19346e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19356e169961SBarry Smith   }
19366e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19376e169961SBarry Smith     if (!zeroed[i]) {
19386e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19396e169961SBarry Smith         if (zeroed[a->j[j]]) {
19402b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19416e169961SBarry Smith           a->a[j] = 0.0;
19426e169961SBarry Smith         }
19436e169961SBarry Smith       }
19442b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19456e169961SBarry Smith   }
19466e169961SBarry Smith   if (x && b) {
19476e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19486e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19496e169961SBarry Smith   }
19506e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19516e169961SBarry Smith   if (diag != 0.0) {
19526e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19536e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19546e169961SBarry Smith     for (i=0; i<N; i++) {
19556e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19566e169961SBarry Smith     }
19576e169961SBarry Smith   }
19586e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19596e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19606e169961SBarry Smith   PetscFunctionReturn(0);
19616e169961SBarry Smith }
19626e169961SBarry Smith 
19636e169961SBarry Smith #undef __FUNCT__
19644a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1965a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
196617ab2063SBarry Smith {
1967416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
196897f1f81fSBarry Smith   PetscInt   *itmp;
196917ab2063SBarry Smith 
19703a40ed3dSBarry Smith   PetscFunctionBegin;
1971e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
197217ab2063SBarry Smith 
1973416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1974bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
197517ab2063SBarry Smith   if (idx) {
1976bfeeae90SHong Zhang     itmp = a->j + a->i[row];
197726fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
197817ab2063SBarry Smith     else *idx = 0;
197917ab2063SBarry Smith   }
19803a40ed3dSBarry Smith   PetscFunctionReturn(0);
198117ab2063SBarry Smith }
198217ab2063SBarry Smith 
1983bfeeae90SHong Zhang /* remove this function? */
19844a2ae208SSatish Balay #undef __FUNCT__
19854a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1986a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
198717ab2063SBarry Smith {
19883a40ed3dSBarry Smith   PetscFunctionBegin;
19893a40ed3dSBarry Smith   PetscFunctionReturn(0);
199017ab2063SBarry Smith }
199117ab2063SBarry Smith 
19924a2ae208SSatish Balay #undef __FUNCT__
19934a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1994dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
199517ab2063SBarry Smith {
1996416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
199754f21887SBarry Smith   MatScalar      *v  = a->a;
199836db0b34SBarry Smith   PetscReal      sum = 0.0;
19996849ba73SBarry Smith   PetscErrorCode ierr;
200097f1f81fSBarry Smith   PetscInt       i,j;
200117ab2063SBarry Smith 
20023a40ed3dSBarry Smith   PetscFunctionBegin;
200317ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2004416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
200536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
200617ab2063SBarry Smith     }
20078f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20083a40ed3dSBarry Smith   } else if (type == NORM_1) {
200936db0b34SBarry Smith     PetscReal *tmp;
201097f1f81fSBarry Smith     PetscInt  *jj = a->j;
2011d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
2012d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
2013064f8208SBarry Smith     *nrm = 0.0;
2014416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2015bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
201617ab2063SBarry Smith     }
2017d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2018064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
201917ab2063SBarry Smith     }
2020606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20213a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2022064f8208SBarry Smith     *nrm = 0.0;
2023d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2024bfeeae90SHong Zhang       v   = a->a + a->i[j];
202517ab2063SBarry Smith       sum = 0.0;
2026416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2027cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
202817ab2063SBarry Smith       }
2029064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
203017ab2063SBarry Smith     }
2031f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20323a40ed3dSBarry Smith   PetscFunctionReturn(0);
203317ab2063SBarry Smith }
203417ab2063SBarry Smith 
20354e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20364e938277SHong Zhang #undef __FUNCT__
20374e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20384e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20394e938277SHong Zhang {
20404e938277SHong Zhang   PetscErrorCode ierr;
20414e938277SHong Zhang   PetscInt       i,j,anzj;
20424e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20434e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20444e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20454e938277SHong Zhang 
20464e938277SHong Zhang   PetscFunctionBegin;
20474e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20484e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
20494e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
20504e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
20514e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
20524e938277SHong Zhang 
20534e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20544e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
205526fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20564e938277SHong Zhang   /* Form ati for csr format of A^T. */
205726fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20584e938277SHong Zhang 
20594e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20604e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20614e938277SHong Zhang 
20624e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20634e938277SHong Zhang   for (i=0;i<am;i++) {
20644e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20654e938277SHong Zhang     for (j=0;j<anzj;j++) {
20664e938277SHong Zhang       atj[atfill[*aj]] = i;
20674e938277SHong Zhang       atfill[*aj++]   += 1;
20684e938277SHong Zhang     }
20694e938277SHong Zhang   }
20704e938277SHong Zhang 
20714e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20724e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2073ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20742205254eSKarl Rupp 
2075a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2076a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2077a2f3521dSMark F. Adams 
20784e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20794e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20804e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20814e938277SHong Zhang   b->nonew   = 0;
20824e938277SHong Zhang   PetscFunctionReturn(0);
20834e938277SHong Zhang }
20844e938277SHong Zhang 
20854a2ae208SSatish Balay #undef __FUNCT__
20864a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2087fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
208817ab2063SBarry Smith {
2089416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2090416022c9SBarry Smith   Mat            C;
20916849ba73SBarry Smith   PetscErrorCode ierr;
2092d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
209354f21887SBarry Smith   MatScalar      *array = a->a;
209417ab2063SBarry Smith 
20953a40ed3dSBarry Smith   PetscFunctionBegin;
2096e32f2f54SBarry 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");
2097fc4dec0aSBarry Smith 
2098fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
2099d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
2100d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
2101bfeeae90SHong Zhang 
2102bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2103ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2104d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2105a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21067adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2107ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2108606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2109a541d17aSBarry Smith   } else {
2110a541d17aSBarry Smith     C = *B;
2111a541d17aSBarry Smith   }
2112a541d17aSBarry Smith 
211317ab2063SBarry Smith   for (i=0; i<m; i++) {
211417ab2063SBarry Smith     len    = ai[i+1]-ai[i];
211587d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2116b9b97703SBarry Smith     array += len;
2117b9b97703SBarry Smith     aj    += len;
211817ab2063SBarry Smith   }
21196d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21206d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
212117ab2063SBarry Smith 
2122815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2123416022c9SBarry Smith     *B = C;
212417ab2063SBarry Smith   } else {
2125eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
212617ab2063SBarry Smith   }
21273a40ed3dSBarry Smith   PetscFunctionReturn(0);
212817ab2063SBarry Smith }
212917ab2063SBarry Smith 
2130cd0d46ebSvictorle #undef __FUNCT__
21315fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21327087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2133cd0d46ebSvictorle {
2134cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
213554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
213654f21887SBarry Smith   MatScalar      *va,*vb;
21376849ba73SBarry Smith   PetscErrorCode ierr;
213897f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2139cd0d46ebSvictorle 
2140cd0d46ebSvictorle   PetscFunctionBegin;
2141cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2142cd0d46ebSvictorle 
2143cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2144cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21455485867bSBarry Smith   if (ma!=nb || na!=mb) {
21465485867bSBarry Smith     *f = PETSC_FALSE;
21475485867bSBarry Smith     PetscFunctionReturn(0);
21485485867bSBarry Smith   }
2149cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2150cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2151cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
215297f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
215397f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2154cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2155cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2156cd0d46ebSvictorle 
2157cd0d46ebSvictorle   *f = PETSC_TRUE;
2158cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2159cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
216097f1f81fSBarry Smith       PetscInt    idc,idr;
21615485867bSBarry Smith       PetscScalar vc,vr;
2162cd0d46ebSvictorle       /* column/row index/value */
21635485867bSBarry Smith       idc = adx[aptr[i]];
21645485867bSBarry Smith       idr = bdx[bptr[idc]];
21655485867bSBarry Smith       vc  = va[aptr[i]];
21665485867bSBarry Smith       vr  = vb[bptr[idc]];
21675485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21685485867bSBarry Smith         *f = PETSC_FALSE;
21695485867bSBarry Smith         goto done;
2170cd0d46ebSvictorle       } else {
21715485867bSBarry Smith         aptr[i]++;
21725485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2173cd0d46ebSvictorle       }
2174cd0d46ebSvictorle     }
2175cd0d46ebSvictorle   }
2176cd0d46ebSvictorle done:
2177cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21783aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2179cd0d46ebSvictorle   PetscFunctionReturn(0);
2180cd0d46ebSvictorle }
2181cd0d46ebSvictorle 
21821cbb95d3SBarry Smith #undef __FUNCT__
21831cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21847087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21851cbb95d3SBarry Smith {
21861cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
218754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
218854f21887SBarry Smith   MatScalar      *va,*vb;
21891cbb95d3SBarry Smith   PetscErrorCode ierr;
21901cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21911cbb95d3SBarry Smith 
21921cbb95d3SBarry Smith   PetscFunctionBegin;
21931cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21941cbb95d3SBarry Smith 
21951cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21961cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21971cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21981cbb95d3SBarry Smith     *f = PETSC_FALSE;
21991cbb95d3SBarry Smith     PetscFunctionReturn(0);
22001cbb95d3SBarry Smith   }
22011cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22021cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22031cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
22041cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
22051cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
22061cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22071cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22081cbb95d3SBarry Smith 
22091cbb95d3SBarry Smith   *f = PETSC_TRUE;
22101cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22111cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22121cbb95d3SBarry Smith       PetscInt    idc,idr;
22131cbb95d3SBarry Smith       PetscScalar vc,vr;
22141cbb95d3SBarry Smith       /* column/row index/value */
22151cbb95d3SBarry Smith       idc = adx[aptr[i]];
22161cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22171cbb95d3SBarry Smith       vc  = va[aptr[i]];
22181cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22191cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22201cbb95d3SBarry Smith         *f = PETSC_FALSE;
22211cbb95d3SBarry Smith         goto done;
22221cbb95d3SBarry Smith       } else {
22231cbb95d3SBarry Smith         aptr[i]++;
22241cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22251cbb95d3SBarry Smith       }
22261cbb95d3SBarry Smith     }
22271cbb95d3SBarry Smith   }
22281cbb95d3SBarry Smith done:
22291cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22301cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22311cbb95d3SBarry Smith   PetscFunctionReturn(0);
22321cbb95d3SBarry Smith }
22331cbb95d3SBarry Smith 
22349e29f15eSvictorle #undef __FUNCT__
22359e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2236ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22379e29f15eSvictorle {
2238dfbe8321SBarry Smith   PetscErrorCode ierr;
22396e111a19SKarl Rupp 
22409e29f15eSvictorle   PetscFunctionBegin;
22415485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22429e29f15eSvictorle   PetscFunctionReturn(0);
22439e29f15eSvictorle }
22449e29f15eSvictorle 
22454a2ae208SSatish Balay #undef __FUNCT__
22461cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2247ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22481cbb95d3SBarry Smith {
22491cbb95d3SBarry Smith   PetscErrorCode ierr;
22506e111a19SKarl Rupp 
22511cbb95d3SBarry Smith   PetscFunctionBegin;
22521cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22531cbb95d3SBarry Smith   PetscFunctionReturn(0);
22541cbb95d3SBarry Smith }
22551cbb95d3SBarry Smith 
22561cbb95d3SBarry Smith #undef __FUNCT__
22574a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2258dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
225917ab2063SBarry Smith {
2260416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226154f21887SBarry Smith   PetscScalar    *l,*r,x;
226254f21887SBarry Smith   MatScalar      *v;
2263dfbe8321SBarry Smith   PetscErrorCode ierr;
2264d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
226517ab2063SBarry Smith 
22663a40ed3dSBarry Smith   PetscFunctionBegin;
226717ab2063SBarry Smith   if (ll) {
22683ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22693ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2270e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2271e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22721ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2273416022c9SBarry Smith     v    = a->a;
227417ab2063SBarry Smith     for (i=0; i<m; i++) {
227517ab2063SBarry Smith       x = l[i];
2276416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22772205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
227817ab2063SBarry Smith     }
22791ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2280efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228117ab2063SBarry Smith   }
228217ab2063SBarry Smith   if (rr) {
2283e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2284e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22851ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2286416022c9SBarry Smith     v    = a->a; jj = a->j;
22872205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22881ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2289efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
229017ab2063SBarry Smith   }
2291acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22923a40ed3dSBarry Smith   PetscFunctionReturn(0);
229317ab2063SBarry Smith }
229417ab2063SBarry Smith 
22954a2ae208SSatish Balay #undef __FUNCT__
22964a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
229797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
229817ab2063SBarry Smith {
2299db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23006849ba73SBarry Smith   PetscErrorCode ierr;
2301d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
230297f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23035d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23045d0c19d7SBarry Smith   PetscInt       nrows,ncols;
230597f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
230654f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2307416022c9SBarry Smith   Mat            C;
2308ace3abfcSBarry Smith   PetscBool      stride,sorted;
230917ab2063SBarry Smith 
23103a40ed3dSBarry Smith   PetscFunctionBegin;
231114ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2312e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
231314ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2314e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
231599141d43SSatish Balay 
231617ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2317b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2318b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
231917ab2063SBarry Smith 
2320fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2321251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2322fee21e36SBarry Smith   if (stride && step == 1) {
232302834360SBarry Smith     /* special case of contiguous rows */
23240e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
232502834360SBarry Smith     /* loop over new rows determining lens and starting points */
232602834360SBarry Smith     for (i=0; i<nrows; i++) {
2327bfeeae90SHong Zhang       kstart = ai[irow[i]];
2328a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
232902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2330bfeeae90SHong Zhang         if (aj[k] >= first) {
233102834360SBarry Smith           starts[i] = k;
233202834360SBarry Smith           break;
233302834360SBarry Smith         }
233402834360SBarry Smith       }
2335a2744918SBarry Smith       sum = 0;
233602834360SBarry Smith       while (k < kend) {
2337bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2338a2744918SBarry Smith         sum++;
233902834360SBarry Smith       }
2340a2744918SBarry Smith       lens[i] = sum;
234102834360SBarry Smith     }
234202834360SBarry Smith     /* create submatrix */
2343cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
234497f1f81fSBarry Smith       PetscInt n_cols,n_rows;
234508480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2346e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2347d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
234808480c60SBarry Smith       C    = *B;
23493a40ed3dSBarry Smith     } else {
23503bef6203SJed Brown       PetscInt rbs,cbs;
2351ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2352f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23533bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23543bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23553bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23567adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2357ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
235808480c60SBarry Smith     }
2359db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2360db02288aSLois Curfman McInnes 
236102834360SBarry Smith     /* loop over rows inserting into submatrix */
2362db02288aSLois Curfman McInnes     a_new = c->a;
2363db02288aSLois Curfman McInnes     j_new = c->j;
2364db02288aSLois Curfman McInnes     i_new = c->i;
2365bfeeae90SHong Zhang 
236602834360SBarry Smith     for (i=0; i<nrows; i++) {
2367a2744918SBarry Smith       ii    = starts[i];
2368a2744918SBarry Smith       lensi = lens[i];
2369a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2370a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
237102834360SBarry Smith       }
237287828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2373a2744918SBarry Smith       a_new     += lensi;
2374a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2375a2744918SBarry Smith       c->ilen[i] = lensi;
237602834360SBarry Smith     }
23770e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23783a40ed3dSBarry Smith   } else {
237902834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23800e83c824SBarry Smith     ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
238197f1f81fSBarry Smith     ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
23820e83c824SBarry Smith     ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&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 */
2507d0f46423SBarry Smith     ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&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) {
2546b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),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 
257397f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&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 */
263397f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&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 
264297f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&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]);
2767ba0e910bSBarry 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;
277116b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&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);
29043bb78c5cSMatthew G Knepley   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) {
2996bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&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:
3064bbead8a2SBarry Smith     ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&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,
3160*040ebd07SHong 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,
32463964eb88SJed Brown                                         0
32479e29f15eSvictorle };
324817ab2063SBarry Smith 
32494a2ae208SSatish Balay #undef __FUNCT__
32504a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32517087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3252bef8e0ddSBarry Smith {
3253bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325497f1f81fSBarry Smith   PetscInt   i,nz,n;
3255bef8e0ddSBarry Smith 
3256bef8e0ddSBarry Smith   PetscFunctionBegin;
3257bef8e0ddSBarry Smith   nz = aij->maxnz;
3258d0f46423SBarry Smith   n  = mat->rmap->n;
3259bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3260bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3261bef8e0ddSBarry Smith   }
3262bef8e0ddSBarry Smith   aij->nz = nz;
3263bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3264bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3265bef8e0ddSBarry Smith   }
3266bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3267bef8e0ddSBarry Smith }
3268bef8e0ddSBarry Smith 
32694a2ae208SSatish Balay #undef __FUNCT__
32704a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3271bef8e0ddSBarry Smith /*@
3272bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3273bef8e0ddSBarry Smith        in the matrix.
3274bef8e0ddSBarry Smith 
3275bef8e0ddSBarry Smith   Input Parameters:
3276bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3277bef8e0ddSBarry Smith -  indices - the column indices
3278bef8e0ddSBarry Smith 
327915091d37SBarry Smith   Level: advanced
328015091d37SBarry Smith 
3281bef8e0ddSBarry Smith   Notes:
3282bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3283bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3284bef8e0ddSBarry Smith   of the MatSetValues() operation.
3285bef8e0ddSBarry Smith 
3286bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3287d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3288bef8e0ddSBarry Smith 
3289bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3290bef8e0ddSBarry Smith 
3291b9617806SBarry Smith     The indices should start with zero, not one.
3292b9617806SBarry Smith 
3293bef8e0ddSBarry Smith @*/
32947087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3295bef8e0ddSBarry Smith {
32964ac538c5SBarry Smith   PetscErrorCode ierr;
3297bef8e0ddSBarry Smith 
3298bef8e0ddSBarry Smith   PetscFunctionBegin;
32990700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33004482741eSBarry Smith   PetscValidPointer(indices,2);
33014ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3302bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3303bef8e0ddSBarry Smith }
3304bef8e0ddSBarry Smith 
3305be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3306be6bf707SBarry Smith 
33074a2ae208SSatish Balay #undef __FUNCT__
33084a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33097087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3310be6bf707SBarry Smith {
3311be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33126849ba73SBarry Smith   PetscErrorCode ierr;
3313d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3314be6bf707SBarry Smith 
3315be6bf707SBarry Smith   PetscFunctionBegin;
3316f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3317be6bf707SBarry Smith 
3318be6bf707SBarry Smith   /* allocate space for values if not already there */
3319be6bf707SBarry Smith   if (!aij->saved_values) {
332087828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33213bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3322be6bf707SBarry Smith   }
3323be6bf707SBarry Smith 
3324be6bf707SBarry Smith   /* copy values over */
332587828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3326be6bf707SBarry Smith   PetscFunctionReturn(0);
3327be6bf707SBarry Smith }
3328be6bf707SBarry Smith 
33294a2ae208SSatish Balay #undef __FUNCT__
3330b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3331be6bf707SBarry Smith /*@
3332be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3333be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3334be6bf707SBarry Smith        nonlinear portion.
3335be6bf707SBarry Smith 
3336be6bf707SBarry Smith    Collect on Mat
3337be6bf707SBarry Smith 
3338be6bf707SBarry Smith   Input Parameters:
33390e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3340be6bf707SBarry Smith 
334115091d37SBarry Smith   Level: advanced
334215091d37SBarry Smith 
3343be6bf707SBarry Smith   Common Usage, with SNESSolve():
3344be6bf707SBarry Smith $    Create Jacobian matrix
3345be6bf707SBarry Smith $    Set linear terms into matrix
3346be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3347be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3348be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3349512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3350be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3351be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3352be6bf707SBarry Smith $    In your Jacobian routine
3353be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3354be6bf707SBarry Smith $      Set nonlinear terms in matrix
3355be6bf707SBarry Smith 
3356be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3357be6bf707SBarry Smith $    // build linear portion of Jacobian
3358512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3359be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3360be6bf707SBarry Smith $    loop over nonlinear iterations
3361be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3362be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3363be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3364be6bf707SBarry Smith $       Solve linear system with Jacobian
3365be6bf707SBarry Smith $    endloop
3366be6bf707SBarry Smith 
3367be6bf707SBarry Smith   Notes:
3368be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3369512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3370be6bf707SBarry Smith     calling this routine.
3371be6bf707SBarry Smith 
33720c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33730c468ba9SBarry Smith     and does not allocated additional space.
33740c468ba9SBarry Smith 
3375be6bf707SBarry Smith .seealso: MatRetrieveValues()
3376be6bf707SBarry Smith 
3377be6bf707SBarry Smith @*/
33787087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3379be6bf707SBarry Smith {
33804ac538c5SBarry Smith   PetscErrorCode ierr;
3381be6bf707SBarry Smith 
3382be6bf707SBarry Smith   PetscFunctionBegin;
33830700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3384e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3385e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33864ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3387be6bf707SBarry Smith   PetscFunctionReturn(0);
3388be6bf707SBarry Smith }
3389be6bf707SBarry Smith 
33904a2ae208SSatish Balay #undef __FUNCT__
33914a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33927087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3393be6bf707SBarry Smith {
3394be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33956849ba73SBarry Smith   PetscErrorCode ierr;
3396d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3397be6bf707SBarry Smith 
3398be6bf707SBarry Smith   PetscFunctionBegin;
3399f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3400f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3401be6bf707SBarry Smith   /* copy values over */
340287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3403be6bf707SBarry Smith   PetscFunctionReturn(0);
3404be6bf707SBarry Smith }
3405be6bf707SBarry Smith 
34064a2ae208SSatish Balay #undef __FUNCT__
34074a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3408be6bf707SBarry Smith /*@
3409be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3410be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3411be6bf707SBarry Smith        nonlinear portion.
3412be6bf707SBarry Smith 
3413be6bf707SBarry Smith    Collect on Mat
3414be6bf707SBarry Smith 
3415be6bf707SBarry Smith   Input Parameters:
3416be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3417be6bf707SBarry Smith 
341815091d37SBarry Smith   Level: advanced
341915091d37SBarry Smith 
3420be6bf707SBarry Smith .seealso: MatStoreValues()
3421be6bf707SBarry Smith 
3422be6bf707SBarry Smith @*/
34237087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3424be6bf707SBarry Smith {
34254ac538c5SBarry Smith   PetscErrorCode ierr;
3426be6bf707SBarry Smith 
3427be6bf707SBarry Smith   PetscFunctionBegin;
34280700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3429e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3430e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34314ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3432be6bf707SBarry Smith   PetscFunctionReturn(0);
3433be6bf707SBarry Smith }
3434be6bf707SBarry Smith 
3435f83d6046SBarry Smith 
3436be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34374a2ae208SSatish Balay #undef __FUNCT__
34384a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
343917ab2063SBarry Smith /*@C
3440682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34410d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34426e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
344351c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34442bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344517ab2063SBarry Smith 
3446db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3447db81eaa0SLois Curfman McInnes 
344817ab2063SBarry Smith    Input Parameters:
3449db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
345017ab2063SBarry Smith .  m - number of rows
345117ab2063SBarry Smith .  n - number of columns
345217ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
345351c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34540298fd71SBarry Smith          (possibly different for each row) or NULL
345517ab2063SBarry Smith 
345617ab2063SBarry Smith    Output Parameter:
3457416022c9SBarry Smith .  A - the matrix
345817ab2063SBarry Smith 
3459175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3460ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3461175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3462175b88e8SBarry Smith 
3463b259b22eSLois Curfman McInnes    Notes:
346449a6f317SBarry Smith    If nnz is given then nz is ignored
346549a6f317SBarry Smith 
346617ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346717ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34680002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
346944cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
347017ab2063SBarry Smith 
347117ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34720298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34733d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34746da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347517ab2063SBarry Smith 
3476682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34774fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3478682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34796c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34806c7ebb05SLois Curfman McInnes 
34816c7ebb05SLois Curfman McInnes    Options Database Keys:
3482698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34839db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348417ab2063SBarry Smith 
3485027ccd11SLois Curfman McInnes    Level: intermediate
3486027ccd11SLois Curfman McInnes 
348769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348836db0b34SBarry Smith 
348917ab2063SBarry Smith @*/
34907087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
349117ab2063SBarry Smith {
3492dfbe8321SBarry Smith   PetscErrorCode ierr;
34936945ee14SBarry Smith 
34943a40ed3dSBarry Smith   PetscFunctionBegin;
3495f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3496117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3497c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3498d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3499273d9f13SBarry Smith   PetscFunctionReturn(0);
3500273d9f13SBarry Smith }
3501273d9f13SBarry Smith 
35024a2ae208SSatish Balay #undef __FUNCT__
35034a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3504273d9f13SBarry Smith /*@C
3505273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3506273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3507273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3508273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3509273d9f13SBarry Smith 
3510273d9f13SBarry Smith    Collective on MPI_Comm
3511273d9f13SBarry Smith 
3512273d9f13SBarry Smith    Input Parameters:
3513117016b1SBarry Smith +  B - The matrix-free
3514273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3515273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35160298fd71SBarry Smith          (possibly different for each row) or NULL
3517273d9f13SBarry Smith 
3518273d9f13SBarry Smith    Notes:
351949a6f317SBarry Smith      If nnz is given then nz is ignored
352049a6f317SBarry Smith 
3521273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3522273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3523273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3524273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3525273d9f13SBarry Smith 
3526273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35270298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3528273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3529273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3530273d9f13SBarry Smith 
3531aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3532aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3533aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3534aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3535aa95bbe8SBarry Smith 
3536a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3537a96a251dSBarry Smith    entries or columns indices
3538a96a251dSBarry Smith 
3539273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3540273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3541273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3542273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3543273d9f13SBarry Smith 
3544273d9f13SBarry Smith    Options Database Keys:
3545698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3546698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3547273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3548273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3549273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3550273d9f13SBarry Smith 
3551273d9f13SBarry Smith    Level: intermediate
3552273d9f13SBarry Smith 
355369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3554273d9f13SBarry Smith 
3555273d9f13SBarry Smith @*/
35567087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3557273d9f13SBarry Smith {
35584ac538c5SBarry Smith   PetscErrorCode ierr;
3559a23d5eceSKris Buschelman 
3560a23d5eceSKris Buschelman   PetscFunctionBegin;
35616ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35626ba663aaSJed Brown   PetscValidType(B,1);
35634ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3564a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3565a23d5eceSKris Buschelman }
3566a23d5eceSKris Buschelman 
3567a23d5eceSKris Buschelman #undef __FUNCT__
3568a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35697087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3570a23d5eceSKris Buschelman {
3571273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35722576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35736849ba73SBarry Smith   PetscErrorCode ierr;
357497f1f81fSBarry Smith   PetscInt       i;
3575273d9f13SBarry Smith 
3576273d9f13SBarry Smith   PetscFunctionBegin;
35772576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3578a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3579c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3580c461c341SBarry Smith     nz             = 0;
3581c461c341SBarry Smith   }
3582c461c341SBarry Smith 
358326283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358426283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3585899cda47SBarry Smith 
3586435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3587e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3588b73539f3SBarry Smith   if (nnz) {
3589d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3590e32f2f54SBarry 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]);
3591e32f2f54SBarry 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);
3592b73539f3SBarry Smith     }
3593b73539f3SBarry Smith   }
3594b73539f3SBarry Smith 
3595273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35962205254eSKarl Rupp 
3597273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3598273d9f13SBarry Smith 
3599ab93d7beSBarry Smith   if (!skipallocation) {
36002ee49352SLisandro Dalcin     if (!b->imax) {
3601d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
36023bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36032ee49352SLisandro Dalcin     }
3604273d9f13SBarry Smith     if (!nnz) {
3605435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3606c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3607d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3608d0f46423SBarry Smith       nz = nz*B->rmap->n;
3609273d9f13SBarry Smith     } else {
3610273d9f13SBarry Smith       nz = 0;
3611d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3612273d9f13SBarry Smith     }
3613ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36142205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3615ab93d7beSBarry Smith 
3616273d9f13SBarry Smith     /* allocate the matrix space */
36172ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3618d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
36193bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3620bfeeae90SHong Zhang     b->i[0] = 0;
3621d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36225da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36235da197adSKris Buschelman     }
3624273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3625e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3626e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3627b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3628b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3629b31eba2aSShri Abhyankar #endif
3630c461c341SBarry Smith   } else {
3631e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3632e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3633c461c341SBarry Smith   }
3634273d9f13SBarry Smith 
3635273d9f13SBarry Smith   b->nz               = 0;
3636273d9f13SBarry Smith   b->maxnz            = nz;
3637273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36382205254eSKarl Rupp   if (realalloc) {
36392205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36402205254eSKarl Rupp   }
3641273d9f13SBarry Smith   PetscFunctionReturn(0);
3642273d9f13SBarry Smith }
3643273d9f13SBarry Smith 
3644a1661176SMatthew Knepley #undef  __FUNCT__
3645a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364658d36128SBarry Smith /*@
3647a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3648a1661176SMatthew Knepley 
3649a1661176SMatthew Knepley    Input Parameters:
3650a1661176SMatthew Knepley +  B - the matrix
3651a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3652a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3653a1661176SMatthew Knepley -  v - optional values in the matrix
3654a1661176SMatthew Knepley 
3655a1661176SMatthew Knepley    Level: developer
3656a1661176SMatthew Knepley 
365758d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365858d36128SBarry Smith 
3659a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3660a1661176SMatthew Knepley 
3661a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3662a1661176SMatthew Knepley @*/
3663a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3664a1661176SMatthew Knepley {
3665a1661176SMatthew Knepley   PetscErrorCode ierr;
3666a1661176SMatthew Knepley 
3667a1661176SMatthew Knepley   PetscFunctionBegin;
36680700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36696ba663aaSJed Brown   PetscValidType(B,1);
36704ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3671a1661176SMatthew Knepley   PetscFunctionReturn(0);
3672a1661176SMatthew Knepley }
3673a1661176SMatthew Knepley 
3674a1661176SMatthew Knepley #undef  __FUNCT__
3675a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36767087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3677a1661176SMatthew Knepley {
3678a1661176SMatthew Knepley   PetscInt       i;
3679a1661176SMatthew Knepley   PetscInt       m,n;
3680a1661176SMatthew Knepley   PetscInt       nz;
3681a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3682a1661176SMatthew Knepley   PetscScalar    *values;
3683a1661176SMatthew Knepley   PetscErrorCode ierr;
3684a1661176SMatthew Knepley 
3685a1661176SMatthew Knepley   PetscFunctionBegin;
368665e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3687779a8d59SSatish Balay 
3688779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3689779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3690779a8d59SSatish Balay 
3691779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3692a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3693a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3694b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3695a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369665e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3697a1661176SMatthew Knepley     nnz[i] = nz;
3698a1661176SMatthew Knepley   }
3699a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3700a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3701a1661176SMatthew Knepley 
3702a1661176SMatthew Knepley   if (v) {
3703a1661176SMatthew Knepley     values = (PetscScalar*) v;
3704a1661176SMatthew Knepley   } else {
37050e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3706a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3707a1661176SMatthew Knepley   }
3708a1661176SMatthew Knepley 
3709a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3710b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3711b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3712a1661176SMatthew Knepley   }
3713a1661176SMatthew Knepley 
3714a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3715a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3716a1661176SMatthew Knepley 
3717a1661176SMatthew Knepley   if (!v) {
3718a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3719a1661176SMatthew Knepley   }
37207827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3721a1661176SMatthew Knepley   PetscFunctionReturn(0);
3722a1661176SMatthew Knepley }
3723a1661176SMatthew Knepley 
3724c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372506873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3726170fe5c8SBarry Smith 
3727170fe5c8SBarry Smith #undef __FUNCT__
3728170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3729170fe5c8SBarry Smith /*
3730170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3731170fe5c8SBarry Smith 
3732170fe5c8SBarry Smith                n                       p                          p
3733170fe5c8SBarry Smith         (              )       (              )         (                  )
3734170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3735170fe5c8SBarry Smith         (              )       (              )         (                  )
3736170fe5c8SBarry Smith 
3737170fe5c8SBarry Smith */
3738170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3739170fe5c8SBarry Smith {
3740170fe5c8SBarry Smith   PetscErrorCode    ierr;
3741170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3742170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3743170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37441de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3745170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3746170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3747170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3748170fe5c8SBarry Smith 
3749170fe5c8SBarry Smith   PetscFunctionBegin;
3750d0f46423SBarry Smith   m    = A->rmap->n;
3751d0f46423SBarry Smith   n    = A->cmap->n;
3752d0f46423SBarry Smith   p    = B->cmap->n;
3753170fe5c8SBarry Smith   a    = sub_a->v;
3754170fe5c8SBarry Smith   b    = sub_b->a;
3755170fe5c8SBarry Smith   c    = sub_c->v;
3756170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3757170fe5c8SBarry Smith 
3758170fe5c8SBarry Smith   ii  = sub_b->i;
3759170fe5c8SBarry Smith   idx = sub_b->j;
3760170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3761170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3762170fe5c8SBarry Smith     while (q-->0) {
3763170fe5c8SBarry Smith       c_q = c + m*(*idx);
3764170fe5c8SBarry Smith       a_q = a + m*i;
3765854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3766170fe5c8SBarry Smith       idx++;
3767170fe5c8SBarry Smith       b++;
3768170fe5c8SBarry Smith     }
3769170fe5c8SBarry Smith   }
3770170fe5c8SBarry Smith   PetscFunctionReturn(0);
3771170fe5c8SBarry Smith }
3772170fe5c8SBarry Smith 
3773170fe5c8SBarry Smith #undef __FUNCT__
3774170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3775170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3776170fe5c8SBarry Smith {
3777170fe5c8SBarry Smith   PetscErrorCode ierr;
3778d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3779170fe5c8SBarry Smith   Mat            Cmat;
3780170fe5c8SBarry Smith 
3781170fe5c8SBarry Smith   PetscFunctionBegin;
3782e32f2f54SBarry 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);
3783ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3784170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3785a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3786170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37870298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3788d73949e8SHong Zhang 
3789d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37902205254eSKarl Rupp 
3791170fe5c8SBarry Smith   *C = Cmat;
3792170fe5c8SBarry Smith   PetscFunctionReturn(0);
3793170fe5c8SBarry Smith }
3794170fe5c8SBarry Smith 
3795170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3796170fe5c8SBarry Smith #undef __FUNCT__
3797170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3798170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3799170fe5c8SBarry Smith {
3800170fe5c8SBarry Smith   PetscErrorCode ierr;
3801170fe5c8SBarry Smith 
3802170fe5c8SBarry Smith   PetscFunctionBegin;
3803170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38043ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3805170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38063ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3807170fe5c8SBarry Smith   }
38083ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3809170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38103ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3811170fe5c8SBarry Smith   PetscFunctionReturn(0);
3812170fe5c8SBarry Smith }
3813170fe5c8SBarry Smith 
3814170fe5c8SBarry Smith 
38150bad9183SKris Buschelman /*MC
3816fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38170bad9183SKris Buschelman    based on compressed sparse row format.
38180bad9183SKris Buschelman 
38190bad9183SKris Buschelman    Options Database Keys:
38200bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38210bad9183SKris Buschelman 
38220bad9183SKris Buschelman   Level: beginner
38230bad9183SKris Buschelman 
3824f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38250bad9183SKris Buschelman M*/
38260bad9183SKris Buschelman 
3827ccd284c7SBarry Smith /*MC
3828ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3829ccd284c7SBarry Smith 
3830ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3831ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3832ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3833ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3834ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3835ccd284c7SBarry Smith 
3836ccd284c7SBarry Smith    Options Database Keys:
3837ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3838ccd284c7SBarry Smith 
3839ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3840ccd284c7SBarry Smith    enough exist.
3841ccd284c7SBarry Smith 
3842ccd284c7SBarry Smith   Level: beginner
3843ccd284c7SBarry Smith 
3844ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3845ccd284c7SBarry Smith M*/
3846ccd284c7SBarry Smith 
3847ccd284c7SBarry Smith /*MC
3848ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3849ccd284c7SBarry Smith 
3850ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3851ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3852ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3853ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3854ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3855ccd284c7SBarry Smith 
3856ccd284c7SBarry Smith    Options Database Keys:
3857ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3858ccd284c7SBarry Smith 
3859ccd284c7SBarry Smith   Level: beginner
3860ccd284c7SBarry Smith 
3861ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3862ccd284c7SBarry Smith M*/
3863ccd284c7SBarry Smith 
3864b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3866b5e56a35SBarry Smith #endif
3867ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3869af1023dbSSatish Balay #endif
38708cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38737087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3874611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3876611f576cSBarry Smith #endif
3877611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3879611f576cSBarry Smith #endif
3880f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3882f3c0ef26SHong Zhang #endif
3883eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3885eb3b5408SSatish Balay #endif
3886586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38878cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3888586621ddSJed Brown #endif
3889719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38908cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3891719d5645SBarry Smith #endif
3892b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38947087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38957087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3896b3866ffcSBarry Smith #endif
389717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
389917f1a0eaSHong Zhang #endif
390017667f90SBarry Smith 
3901c0c8ee5eSDmitry Karpeev 
39028c778c55SBarry Smith #undef __FUNCT__
39038c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39048c778c55SBarry Smith /*@C
39058c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39068c778c55SBarry Smith 
39078c778c55SBarry Smith    Not Collective
39088c778c55SBarry Smith 
39098c778c55SBarry Smith    Input Parameter:
39108c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39118c778c55SBarry Smith 
39128c778c55SBarry Smith    Output Parameter:
39138c778c55SBarry Smith .   array - pointer to the data
39148c778c55SBarry Smith 
39158c778c55SBarry Smith    Level: intermediate
39168c778c55SBarry Smith 
3917774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39188c778c55SBarry Smith @*/
39198c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39208c778c55SBarry Smith {
39218c778c55SBarry Smith   PetscErrorCode ierr;
39228c778c55SBarry Smith 
39238c778c55SBarry Smith   PetscFunctionBegin;
39248c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39258c778c55SBarry Smith   PetscFunctionReturn(0);
39268c778c55SBarry Smith }
39278c778c55SBarry Smith 
39288c778c55SBarry Smith #undef __FUNCT__
39298c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39308c778c55SBarry Smith /*@C
39318c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39328c778c55SBarry Smith 
39338c778c55SBarry Smith    Not Collective
39348c778c55SBarry Smith 
39358c778c55SBarry Smith    Input Parameters:
39368c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39378c778c55SBarry Smith .  array - pointer to the data
39388c778c55SBarry Smith 
39398c778c55SBarry Smith    Level: intermediate
39408c778c55SBarry Smith 
3941774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39428c778c55SBarry Smith @*/
39438c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39448c778c55SBarry Smith {
39458c778c55SBarry Smith   PetscErrorCode ierr;
39468c778c55SBarry Smith 
39478c778c55SBarry Smith   PetscFunctionBegin;
39488c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39498c778c55SBarry Smith   PetscFunctionReturn(0);
39508c778c55SBarry Smith }
39518c778c55SBarry Smith 
39524a2ae208SSatish Balay #undef __FUNCT__
39534a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39548cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3955273d9f13SBarry Smith {
3956273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3957dfbe8321SBarry Smith   PetscErrorCode ierr;
395838baddfdSBarry Smith   PetscMPIInt    size;
3959273d9f13SBarry Smith 
3960273d9f13SBarry Smith   PetscFunctionBegin;
3961ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3962e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3963273d9f13SBarry Smith 
396438f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39652205254eSKarl Rupp 
3966b0a32e0cSBarry Smith   B->data = (void*)b;
39672205254eSKarl Rupp 
3968549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39692205254eSKarl Rupp 
3970416022c9SBarry Smith   b->row                = 0;
3971416022c9SBarry Smith   b->col                = 0;
397282bf6240SBarry Smith   b->icol               = 0;
3973b810aeb4SBarry Smith   b->reallocs           = 0;
397436db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3975f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3976416022c9SBarry Smith   b->nonew              = 0;
3977416022c9SBarry Smith   b->diag               = 0;
3978416022c9SBarry Smith   b->solve_work         = 0;
39792a1b7f2aSHong Zhang   B->spptr              = 0;
3980be6bf707SBarry Smith   b->saved_values       = 0;
3981d7f994e1SBarry Smith   b->idiag              = 0;
398271f1c65dSBarry Smith   b->mdiag              = 0;
398371f1c65dSBarry Smith   b->ssor_work          = 0;
398471f1c65dSBarry Smith   b->omega              = 1.0;
398571f1c65dSBarry Smith   b->fshift             = 0.0;
398671f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3987bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3988a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3989a30b2313SHong Zhang   b->xtoy               = 0;
3990a30b2313SHong Zhang   b->XtoY               = 0;
399188e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
399217ab2063SBarry Smith 
399335d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3994bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39968c778c55SBarry Smith 
3997b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3998bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3999bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4000bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4001b3866ffcSBarry Smith #endif
4002b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4003bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4004b5e56a35SBarry Smith #endif
4005ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4006bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4007719d5645SBarry Smith #endif
4008611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4009bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4010611f576cSBarry Smith #endif
4011f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4012bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4013f3c0ef26SHong Zhang #endif
4014611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4015bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4016611f576cSBarry Smith #endif
4017eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4018bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4019eb3b5408SSatish Balay #endif
4020586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4021bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4022586621ddSJed Brown #endif
4023719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4024bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4025719d5645SBarry Smith #endif
402617f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4027bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402817f1a0eaSHong Zhang #endif
402917f1a0eaSHong Zhang 
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40484108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
404917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40503a40ed3dSBarry Smith   PetscFunctionReturn(0);
405117ab2063SBarry Smith }
405217ab2063SBarry Smith 
40534a2ae208SSatish Balay #undef __FUNCT__
4054b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4055b24902e0SBarry Smith /*
4056b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4057b24902e0SBarry Smith */
4058ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
405917ab2063SBarry Smith {
4060416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40616849ba73SBarry Smith   PetscErrorCode ierr;
4062d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
406317ab2063SBarry Smith 
40643a40ed3dSBarry Smith   PetscFunctionBegin;
4065273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4066273d9f13SBarry Smith 
4067d5f3da31SBarry Smith   C->factortype = A->factortype;
4068416022c9SBarry Smith   c->row        = 0;
4069416022c9SBarry Smith   c->col        = 0;
407082bf6240SBarry Smith   c->icol       = 0;
40716ad4291fSHong Zhang   c->reallocs   = 0;
407217ab2063SBarry Smith 
40736ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407417ab2063SBarry Smith 
4075aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4076aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4077eec197d1SBarry Smith 
407833b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40793bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
408017ab2063SBarry Smith   for (i=0; i<m; i++) {
4081416022c9SBarry Smith     c->imax[i] = a->imax[i];
4082416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
408317ab2063SBarry Smith   }
408417ab2063SBarry Smith 
408517ab2063SBarry Smith   /* allocate the matrix space */
4086f77e22a1SHong Zhang   if (mallocmatspace) {
4087a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40883bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40892205254eSKarl Rupp 
4090f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40912205254eSKarl Rupp 
409297f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409317ab2063SBarry Smith     if (m > 0) {
409497f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4095be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4096bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4097be6bf707SBarry Smith       } else {
4098bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
409917ab2063SBarry Smith       }
410008480c60SBarry Smith     }
4101f77e22a1SHong Zhang   }
410217ab2063SBarry Smith 
41036ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4104416022c9SBarry Smith   c->roworiented       = a->roworiented;
4105416022c9SBarry Smith   c->nonew             = a->nonew;
4106416022c9SBarry Smith   if (a->diag) {
410797f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41083bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410917ab2063SBarry Smith     for (i=0; i<m; i++) {
4110416022c9SBarry Smith       c->diag[i] = a->diag[i];
411117ab2063SBarry Smith     }
41123a40ed3dSBarry Smith   } else c->diag = 0;
41132205254eSKarl Rupp 
41146ad4291fSHong Zhang   c->solve_work         = 0;
41156ad4291fSHong Zhang   c->saved_values       = 0;
41166ad4291fSHong Zhang   c->idiag              = 0;
411771f1c65dSBarry Smith   c->ssor_work          = 0;
4118a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4119e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4120e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41216ad4291fSHong Zhang   c->xtoy               = 0;
41226ad4291fSHong Zhang   c->XtoY               = 0;
41236ad4291fSHong Zhang 
4124893ad86cSHong Zhang   c->rmax         = a->rmax;
4125416022c9SBarry Smith   c->nz           = a->nz;
41268ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4127273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4128754ec7b1SSatish Balay 
41296ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41306ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4131cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4132cd6b891eSBarry Smith   if (a->compressedrow.use) {
41336ad4291fSHong Zhang     i    = a->compressedrow.nrows;
41340e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&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 */
4194fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&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];
4199fbdbba38SShri Abhyankar   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, 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     }
4210f501eaabSShri Abhyankar     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;
4334ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&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)
4347e32f2f54SBarry 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++) {
4356e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4357e32f2f54SBarry 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;
4414d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44151230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44161230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44171230e6d1SVictor Minden     nnz[i[ii]] += 1;
44181230e6d1SVictor Minden   }
44198a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44208a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4421a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
44228a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44231230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44241230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44251230e6d1SVictor Minden     if (idx) {
44261230e6d1SVictor Minden       row = i[ii] - 1;
44271230e6d1SVictor Minden       col = j[ii] - 1;
44281230e6d1SVictor Minden     } else {
44291230e6d1SVictor Minden       row = i[ii];
44301230e6d1SVictor Minden       col = j[ii];
44318a0b0e6bSVictor Minden     }
44321230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44338a0b0e6bSVictor Minden   }
44348a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44358a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4436d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44378a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44388a0b0e6bSVictor Minden }
443936db0b34SBarry Smith 
4440cc8ba8e1SBarry Smith #undef __FUNCT__
4441ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4442dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4443cc8ba8e1SBarry Smith {
4444dfbe8321SBarry Smith   PetscErrorCode ierr;
4445cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444636db0b34SBarry Smith 
4447cc8ba8e1SBarry Smith   PetscFunctionBegin;
44488ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4449cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4450cc8ba8e1SBarry Smith     a->coloring = coloring;
445112c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
445297f1f81fSBarry Smith     PetscInt        i,*larray;
445312c595b3SBarry Smith     ISColoring      ocoloring;
445408b6dcc0SBarry Smith     ISColoringValue *colors;
445512c595b3SBarry Smith 
445612c595b3SBarry Smith     /* set coloring for diagonal portion */
44570e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44582205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44590298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44600e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44612205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
446212c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4463d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446412c595b3SBarry Smith     a->coloring = ocoloring;
446512c595b3SBarry Smith   }
4466cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4467cc8ba8e1SBarry Smith }
4468cc8ba8e1SBarry Smith 
4469ee4f033dSBarry Smith #undef __FUNCT__
4470ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
447197f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4472ee4f033dSBarry Smith {
4473ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4474d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447554f21887SBarry Smith   MatScalar       *v      = a->a;
447654f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447708b6dcc0SBarry Smith   ISColoringValue *color;
4478ee4f033dSBarry Smith 
4479ee4f033dSBarry Smith   PetscFunctionBegin;
4480e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4481ee4f033dSBarry Smith   color = a->coloring->colors;
4482ee4f033dSBarry Smith   /* loop over rows */
4483ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4484ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4485ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44862205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4487ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4488cc8ba8e1SBarry Smith   }
4489cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4490cc8ba8e1SBarry Smith }
449136db0b34SBarry Smith 
4492acf2f550SJed Brown #undef __FUNCT__
4493acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4494acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4495acf2f550SJed Brown {
4496acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4497acf2f550SJed Brown   PetscErrorCode ierr;
4498acf2f550SJed Brown 
4499acf2f550SJed Brown   PetscFunctionBegin;
4500acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4501acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45022205254eSKarl Rupp 
4503acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4504acf2f550SJed Brown   PetscFunctionReturn(0);
4505acf2f550SJed Brown }
4506acf2f550SJed Brown 
450781824310SBarry Smith /*
450881824310SBarry Smith     Special version for direct calls from Fortran
450981824310SBarry Smith */
4510b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
451181824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
451281824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
451381824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451481824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451581824310SBarry Smith #endif
451681824310SBarry Smith 
451781824310SBarry Smith /* Change these macros so can be used in void function */
451881824310SBarry Smith #undef CHKERRQ
4519ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
452081824310SBarry Smith #undef SETERRQ2
4521e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45224994cf47SJed Brown #undef SETERRQ3
45234994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452481824310SBarry Smith 
452581824310SBarry Smith #undef __FUNCT__
452681824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45278cc058d9SJed 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)
452881824310SBarry Smith {
452981824310SBarry Smith   Mat            A  = *AA;
453081824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
453181824310SBarry Smith   InsertMode     is = *isis;
453281824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
453381824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453481824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453581824310SBarry Smith   PetscErrorCode ierr;
453681824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453754f21887SBarry Smith   MatScalar      *ap,value,*aa;
4538ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4539ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
454081824310SBarry Smith 
454181824310SBarry Smith   PetscFunctionBegin;
45424994cf47SJed Brown   MatCheckPreallocated(A,1);
454381824310SBarry Smith   imax  = a->imax;
454481824310SBarry Smith   ai    = a->i;
454581824310SBarry Smith   ailen = a->ilen;
454681824310SBarry Smith   aj    = a->j;
454781824310SBarry Smith   aa    = a->a;
454881824310SBarry Smith 
454981824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
455081824310SBarry Smith     row = im[k];
455181824310SBarry Smith     if (row < 0) continue;
455281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4553ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455481824310SBarry Smith #endif
455581824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455681824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455781824310SBarry Smith     low  = 0;
455881824310SBarry Smith     high = nrow;
455981824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
456081824310SBarry Smith       if (in[l] < 0) continue;
456181824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4562ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
456381824310SBarry Smith #endif
456481824310SBarry Smith       col = in[l];
45652205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45662205254eSKarl Rupp       else value = v[k + l*m];
45672205254eSKarl Rupp 
456881824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456981824310SBarry Smith 
45702205254eSKarl Rupp       if (col <= lastcol) low = 0;
45712205254eSKarl Rupp       else high = nrow;
457281824310SBarry Smith       lastcol = col;
457381824310SBarry Smith       while (high-low > 5) {
457481824310SBarry Smith         t = (low+high)/2;
457581824310SBarry Smith         if (rp[t] > col) high = t;
457681824310SBarry Smith         else             low  = t;
457781824310SBarry Smith       }
457881824310SBarry Smith       for (i=low; i<high; i++) {
457981824310SBarry Smith         if (rp[i] > col) break;
458081824310SBarry Smith         if (rp[i] == col) {
458181824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
458281824310SBarry Smith           else                  ap[i] = value;
458381824310SBarry Smith           goto noinsert;
458481824310SBarry Smith         }
458581824310SBarry Smith       }
458681824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458781824310SBarry Smith       if (nonew == 1) goto noinsert;
4588ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4589fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
459081824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
459181824310SBarry Smith       /* shift up all the later entries in this row */
459281824310SBarry Smith       for (ii=N; ii>=i; ii--) {
459381824310SBarry Smith         rp[ii+1] = rp[ii];
459481824310SBarry Smith         ap[ii+1] = ap[ii];
459581824310SBarry Smith       }
459681824310SBarry Smith       rp[i] = col;
459781824310SBarry Smith       ap[i] = value;
459881824310SBarry Smith noinsert:;
459981824310SBarry Smith       low = i + 1;
460081824310SBarry Smith     }
460181824310SBarry Smith     ailen[row] = nrow;
460281824310SBarry Smith   }
460381824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460481824310SBarry Smith   PetscFunctionReturnVoid();
460581824310SBarry Smith }
46069f7953f8SBarry Smith 
460762298a1eSBarry Smith 
4608