xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 5243ef75d99433ae111d41004081d2e7a4c2ee9e)
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
2817cee066cSHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqAIJ()
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;
337*5243ef75SHong 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 
31057087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
3106682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31070a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3108cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3109cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3110cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
311197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31127c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31137c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3114db4efbfdSBarry Smith                                         0,
3115db4efbfdSBarry Smith                                         0,
3116db4efbfdSBarry Smith                                         0,
3117db4efbfdSBarry Smith                                 /* 10*/ 0,
3118cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3119cb5b572fSBarry Smith                                         0,
312041f059aeSBarry Smith                                         MatSOR_SeqAIJ,
312117ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
312297304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3123cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3124cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3125cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3126cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
312797304618SKris Buschelman                                 /* 20*/ 0,
3128cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3129cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3130cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3131d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3132db4efbfdSBarry Smith                                         0,
3133db4efbfdSBarry Smith                                         0,
3134db4efbfdSBarry Smith                                         0,
3135db4efbfdSBarry Smith                                         0,
31364994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3137db4efbfdSBarry Smith                                         0,
3138db4efbfdSBarry Smith                                         0,
31398c778c55SBarry Smith                                         0,
31408c778c55SBarry Smith                                         0,
3141d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3142cb5b572fSBarry Smith                                         0,
3143cb5b572fSBarry Smith                                         0,
3144cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3145cb5b572fSBarry Smith                                         0,
3146d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3147cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3148cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3149cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3150cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3151d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3152cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3153cb5b572fSBarry Smith                                         0,
315479299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31556e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
315673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31573b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31583b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31593b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3160a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
3161d519adbfSMatthew Knepley                                 /* 54*/ MatFDColoringCreate_SeqAIJ,
3162b9617806SBarry Smith                                         0,
31630513a670SBarry Smith                                         0,
3164cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3165cda55fadSBarry Smith                                         0,
3166d519adbfSMatthew Knepley                                 /* 59*/ 0,
3167b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3168b9b97703SBarry Smith                                         MatView_SeqAIJ,
3169357abbc8SBarry Smith                                         0,
3170321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3171321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3172321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3173ee4f033dSBarry Smith                                         0,
3174ee4f033dSBarry Smith                                         0,
3175ee4f033dSBarry Smith                                         0,
3176d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3177c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3178ee4f033dSBarry Smith                                         0,
3179ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3180dcf5cc72SBarry Smith                                         0,
3181d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31823acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
318397304618SKris Buschelman                                         0,
318497304618SKris Buschelman                                         0,
318597304618SKris Buschelman                                         0,
31866ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
318797304618SKris Buschelman                                         0,
318897304618SKris Buschelman                                         0,
318997304618SKris Buschelman                                         0,
3190bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3191d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31921cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31936284ec50SHong Zhang                                         0,
31946284ec50SHong Zhang                                         0,
3195bc011b1eSHong Zhang                                         0,
3196d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
319726be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
319826be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
319965e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
32004a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
320165e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
32026fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
32036fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
32046fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32052121bac1SHong Zhang                                         0,
32062121bac1SHong Zhang                                 /* 99*/ 0,
3207609c6c4dSKris Buschelman                                         0,
3208609c6c4dSKris Buschelman                                         0,
320987d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
321087d4246cSBarry Smith                                         0,
3211d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
321299cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3213f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3214f5edf698SHong Zhang                                         0,
32152bebee5dSHong Zhang                                         0,
3216cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3217985db425SBarry Smith                                         0,
32182af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32192af78befSBarry Smith                                         0,
3220599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3221d519adbfSMatthew Knepley                                 /*114*/ 0,
3222599ef60dSHong Zhang                                         0,
32233c2a7987SHong Zhang                                         0,
3224fe97e370SBarry Smith                                         0,
3225fbdbba38SShri Abhyankar                                         0,
3226fbdbba38SShri Abhyankar                                 /*119*/ 0,
3227fbdbba38SShri Abhyankar                                         0,
3228fbdbba38SShri Abhyankar                                         0,
322982d44351SHong Zhang                                         0,
3230b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32310716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3232bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
323337868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
323437868618SMatthew G Knepley                                         0,
323537868618SMatthew G Knepley                                         0,
32365df89d91SHong Zhang                                 /*129*/ 0,
323775648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
323875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
323975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3240b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3241b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32422b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32432b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32442b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32453964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32463964eb88SJed Brown                                  /*139*/0,
32473964eb88SJed Brown                                         0
32489e29f15eSvictorle };
324917ab2063SBarry Smith 
32504a2ae208SSatish Balay #undef __FUNCT__
32514a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32527087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3253bef8e0ddSBarry Smith {
3254bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325597f1f81fSBarry Smith   PetscInt   i,nz,n;
3256bef8e0ddSBarry Smith 
3257bef8e0ddSBarry Smith   PetscFunctionBegin;
3258bef8e0ddSBarry Smith   nz = aij->maxnz;
3259d0f46423SBarry Smith   n  = mat->rmap->n;
3260bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3261bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3262bef8e0ddSBarry Smith   }
3263bef8e0ddSBarry Smith   aij->nz = nz;
3264bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3265bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3266bef8e0ddSBarry Smith   }
3267bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3268bef8e0ddSBarry Smith }
3269bef8e0ddSBarry Smith 
32704a2ae208SSatish Balay #undef __FUNCT__
32714a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3272bef8e0ddSBarry Smith /*@
3273bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3274bef8e0ddSBarry Smith        in the matrix.
3275bef8e0ddSBarry Smith 
3276bef8e0ddSBarry Smith   Input Parameters:
3277bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3278bef8e0ddSBarry Smith -  indices - the column indices
3279bef8e0ddSBarry Smith 
328015091d37SBarry Smith   Level: advanced
328115091d37SBarry Smith 
3282bef8e0ddSBarry Smith   Notes:
3283bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3284bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3285bef8e0ddSBarry Smith   of the MatSetValues() operation.
3286bef8e0ddSBarry Smith 
3287bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3288d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3289bef8e0ddSBarry Smith 
3290bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3291bef8e0ddSBarry Smith 
3292b9617806SBarry Smith     The indices should start with zero, not one.
3293b9617806SBarry Smith 
3294bef8e0ddSBarry Smith @*/
32957087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3296bef8e0ddSBarry Smith {
32974ac538c5SBarry Smith   PetscErrorCode ierr;
3298bef8e0ddSBarry Smith 
3299bef8e0ddSBarry Smith   PetscFunctionBegin;
33000700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33014482741eSBarry Smith   PetscValidPointer(indices,2);
33024ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3303bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3304bef8e0ddSBarry Smith }
3305bef8e0ddSBarry Smith 
3306be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3307be6bf707SBarry Smith 
33084a2ae208SSatish Balay #undef __FUNCT__
33094a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33107087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3311be6bf707SBarry Smith {
3312be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33136849ba73SBarry Smith   PetscErrorCode ierr;
3314d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3315be6bf707SBarry Smith 
3316be6bf707SBarry Smith   PetscFunctionBegin;
3317f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3318be6bf707SBarry Smith 
3319be6bf707SBarry Smith   /* allocate space for values if not already there */
3320be6bf707SBarry Smith   if (!aij->saved_values) {
332187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33223bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3323be6bf707SBarry Smith   }
3324be6bf707SBarry Smith 
3325be6bf707SBarry Smith   /* copy values over */
332687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3327be6bf707SBarry Smith   PetscFunctionReturn(0);
3328be6bf707SBarry Smith }
3329be6bf707SBarry Smith 
33304a2ae208SSatish Balay #undef __FUNCT__
3331b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3332be6bf707SBarry Smith /*@
3333be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3334be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3335be6bf707SBarry Smith        nonlinear portion.
3336be6bf707SBarry Smith 
3337be6bf707SBarry Smith    Collect on Mat
3338be6bf707SBarry Smith 
3339be6bf707SBarry Smith   Input Parameters:
33400e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3341be6bf707SBarry Smith 
334215091d37SBarry Smith   Level: advanced
334315091d37SBarry Smith 
3344be6bf707SBarry Smith   Common Usage, with SNESSolve():
3345be6bf707SBarry Smith $    Create Jacobian matrix
3346be6bf707SBarry Smith $    Set linear terms into matrix
3347be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3348be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3349be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3350512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3351be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3352be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3353be6bf707SBarry Smith $    In your Jacobian routine
3354be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3355be6bf707SBarry Smith $      Set nonlinear terms in matrix
3356be6bf707SBarry Smith 
3357be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3358be6bf707SBarry Smith $    // build linear portion of Jacobian
3359512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3360be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3361be6bf707SBarry Smith $    loop over nonlinear iterations
3362be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3363be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3364be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3365be6bf707SBarry Smith $       Solve linear system with Jacobian
3366be6bf707SBarry Smith $    endloop
3367be6bf707SBarry Smith 
3368be6bf707SBarry Smith   Notes:
3369be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3370512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3371be6bf707SBarry Smith     calling this routine.
3372be6bf707SBarry Smith 
33730c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33740c468ba9SBarry Smith     and does not allocated additional space.
33750c468ba9SBarry Smith 
3376be6bf707SBarry Smith .seealso: MatRetrieveValues()
3377be6bf707SBarry Smith 
3378be6bf707SBarry Smith @*/
33797087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3380be6bf707SBarry Smith {
33814ac538c5SBarry Smith   PetscErrorCode ierr;
3382be6bf707SBarry Smith 
3383be6bf707SBarry Smith   PetscFunctionBegin;
33840700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3385e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3386e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33874ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3388be6bf707SBarry Smith   PetscFunctionReturn(0);
3389be6bf707SBarry Smith }
3390be6bf707SBarry Smith 
33914a2ae208SSatish Balay #undef __FUNCT__
33924a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33937087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3394be6bf707SBarry Smith {
3395be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33966849ba73SBarry Smith   PetscErrorCode ierr;
3397d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3398be6bf707SBarry Smith 
3399be6bf707SBarry Smith   PetscFunctionBegin;
3400f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3401f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3402be6bf707SBarry Smith   /* copy values over */
340387828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3404be6bf707SBarry Smith   PetscFunctionReturn(0);
3405be6bf707SBarry Smith }
3406be6bf707SBarry Smith 
34074a2ae208SSatish Balay #undef __FUNCT__
34084a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3409be6bf707SBarry Smith /*@
3410be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3411be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3412be6bf707SBarry Smith        nonlinear portion.
3413be6bf707SBarry Smith 
3414be6bf707SBarry Smith    Collect on Mat
3415be6bf707SBarry Smith 
3416be6bf707SBarry Smith   Input Parameters:
3417be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3418be6bf707SBarry Smith 
341915091d37SBarry Smith   Level: advanced
342015091d37SBarry Smith 
3421be6bf707SBarry Smith .seealso: MatStoreValues()
3422be6bf707SBarry Smith 
3423be6bf707SBarry Smith @*/
34247087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3425be6bf707SBarry Smith {
34264ac538c5SBarry Smith   PetscErrorCode ierr;
3427be6bf707SBarry Smith 
3428be6bf707SBarry Smith   PetscFunctionBegin;
34290700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3430e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3431e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34324ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3433be6bf707SBarry Smith   PetscFunctionReturn(0);
3434be6bf707SBarry Smith }
3435be6bf707SBarry Smith 
3436f83d6046SBarry Smith 
3437be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34384a2ae208SSatish Balay #undef __FUNCT__
34394a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
344017ab2063SBarry Smith /*@C
3441682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34420d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34436e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
344451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34452bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344617ab2063SBarry Smith 
3447db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3448db81eaa0SLois Curfman McInnes 
344917ab2063SBarry Smith    Input Parameters:
3450db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
345117ab2063SBarry Smith .  m - number of rows
345217ab2063SBarry Smith .  n - number of columns
345317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
345451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34550298fd71SBarry Smith          (possibly different for each row) or NULL
345617ab2063SBarry Smith 
345717ab2063SBarry Smith    Output Parameter:
3458416022c9SBarry Smith .  A - the matrix
345917ab2063SBarry Smith 
3460175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3461ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3462175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3463175b88e8SBarry Smith 
3464b259b22eSLois Curfman McInnes    Notes:
346549a6f317SBarry Smith    If nnz is given then nz is ignored
346649a6f317SBarry Smith 
346717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34690002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
347044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
347117ab2063SBarry Smith 
347217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34730298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34743d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34756da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347617ab2063SBarry Smith 
3477682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34784fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3479682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34806c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34816c7ebb05SLois Curfman McInnes 
34826c7ebb05SLois Curfman McInnes    Options Database Keys:
3483698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34849db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348517ab2063SBarry Smith 
3486027ccd11SLois Curfman McInnes    Level: intermediate
3487027ccd11SLois Curfman McInnes 
348869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348936db0b34SBarry Smith 
349017ab2063SBarry Smith @*/
34917087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
349217ab2063SBarry Smith {
3493dfbe8321SBarry Smith   PetscErrorCode ierr;
34946945ee14SBarry Smith 
34953a40ed3dSBarry Smith   PetscFunctionBegin;
3496f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3497117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3498c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3499d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3500273d9f13SBarry Smith   PetscFunctionReturn(0);
3501273d9f13SBarry Smith }
3502273d9f13SBarry Smith 
35034a2ae208SSatish Balay #undef __FUNCT__
35044a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3505273d9f13SBarry Smith /*@C
3506273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3507273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3508273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3509273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3510273d9f13SBarry Smith 
3511273d9f13SBarry Smith    Collective on MPI_Comm
3512273d9f13SBarry Smith 
3513273d9f13SBarry Smith    Input Parameters:
3514117016b1SBarry Smith +  B - The matrix-free
3515273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3516273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35170298fd71SBarry Smith          (possibly different for each row) or NULL
3518273d9f13SBarry Smith 
3519273d9f13SBarry Smith    Notes:
352049a6f317SBarry Smith      If nnz is given then nz is ignored
352149a6f317SBarry Smith 
3522273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3523273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3524273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3525273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3526273d9f13SBarry Smith 
3527273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35280298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3529273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3530273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3531273d9f13SBarry Smith 
3532aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3533aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3534aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3535aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3536aa95bbe8SBarry Smith 
3537a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3538a96a251dSBarry Smith    entries or columns indices
3539a96a251dSBarry Smith 
3540273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3541273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3542273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3543273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3544273d9f13SBarry Smith 
3545273d9f13SBarry Smith    Options Database Keys:
3546698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3547698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3548273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3549273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3550273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3551273d9f13SBarry Smith 
3552273d9f13SBarry Smith    Level: intermediate
3553273d9f13SBarry Smith 
355469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3555273d9f13SBarry Smith 
3556273d9f13SBarry Smith @*/
35577087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3558273d9f13SBarry Smith {
35594ac538c5SBarry Smith   PetscErrorCode ierr;
3560a23d5eceSKris Buschelman 
3561a23d5eceSKris Buschelman   PetscFunctionBegin;
35626ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35636ba663aaSJed Brown   PetscValidType(B,1);
35644ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3565a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3566a23d5eceSKris Buschelman }
3567a23d5eceSKris Buschelman 
3568a23d5eceSKris Buschelman #undef __FUNCT__
3569a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35707087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3571a23d5eceSKris Buschelman {
3572273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35732576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35746849ba73SBarry Smith   PetscErrorCode ierr;
357597f1f81fSBarry Smith   PetscInt       i;
3576273d9f13SBarry Smith 
3577273d9f13SBarry Smith   PetscFunctionBegin;
35782576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3579a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3580c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3581c461c341SBarry Smith     nz             = 0;
3582c461c341SBarry Smith   }
3583c461c341SBarry Smith 
358426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3586899cda47SBarry Smith 
3587435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3588e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3589b73539f3SBarry Smith   if (nnz) {
3590d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3591e32f2f54SBarry 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]);
3592e32f2f54SBarry 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);
3593b73539f3SBarry Smith     }
3594b73539f3SBarry Smith   }
3595b73539f3SBarry Smith 
3596273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35972205254eSKarl Rupp 
3598273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3599273d9f13SBarry Smith 
3600ab93d7beSBarry Smith   if (!skipallocation) {
36012ee49352SLisandro Dalcin     if (!b->imax) {
3602d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
36033bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36042ee49352SLisandro Dalcin     }
3605273d9f13SBarry Smith     if (!nnz) {
3606435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3607c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3608d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3609d0f46423SBarry Smith       nz = nz*B->rmap->n;
3610273d9f13SBarry Smith     } else {
3611273d9f13SBarry Smith       nz = 0;
3612d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3613273d9f13SBarry Smith     }
3614ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36152205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3616ab93d7beSBarry Smith 
3617273d9f13SBarry Smith     /* allocate the matrix space */
36182ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3619d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
36203bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3621bfeeae90SHong Zhang     b->i[0] = 0;
3622d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36235da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36245da197adSKris Buschelman     }
3625273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3626e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3627e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3628b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3629b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3630b31eba2aSShri Abhyankar #endif
3631c461c341SBarry Smith   } else {
3632e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3633e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3634c461c341SBarry Smith   }
3635273d9f13SBarry Smith 
3636273d9f13SBarry Smith   b->nz               = 0;
3637273d9f13SBarry Smith   b->maxnz            = nz;
3638273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36392205254eSKarl Rupp   if (realalloc) {
36402205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36412205254eSKarl Rupp   }
3642273d9f13SBarry Smith   PetscFunctionReturn(0);
3643273d9f13SBarry Smith }
3644273d9f13SBarry Smith 
3645a1661176SMatthew Knepley #undef  __FUNCT__
3646a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364758d36128SBarry Smith /*@
3648a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3649a1661176SMatthew Knepley 
3650a1661176SMatthew Knepley    Input Parameters:
3651a1661176SMatthew Knepley +  B - the matrix
3652a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3653a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3654a1661176SMatthew Knepley -  v - optional values in the matrix
3655a1661176SMatthew Knepley 
3656a1661176SMatthew Knepley    Level: developer
3657a1661176SMatthew Knepley 
365858d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365958d36128SBarry Smith 
3660a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3661a1661176SMatthew Knepley 
3662a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3663a1661176SMatthew Knepley @*/
3664a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3665a1661176SMatthew Knepley {
3666a1661176SMatthew Knepley   PetscErrorCode ierr;
3667a1661176SMatthew Knepley 
3668a1661176SMatthew Knepley   PetscFunctionBegin;
36690700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36706ba663aaSJed Brown   PetscValidType(B,1);
36714ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3672a1661176SMatthew Knepley   PetscFunctionReturn(0);
3673a1661176SMatthew Knepley }
3674a1661176SMatthew Knepley 
3675a1661176SMatthew Knepley #undef  __FUNCT__
3676a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36777087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3678a1661176SMatthew Knepley {
3679a1661176SMatthew Knepley   PetscInt       i;
3680a1661176SMatthew Knepley   PetscInt       m,n;
3681a1661176SMatthew Knepley   PetscInt       nz;
3682a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3683a1661176SMatthew Knepley   PetscScalar    *values;
3684a1661176SMatthew Knepley   PetscErrorCode ierr;
3685a1661176SMatthew Knepley 
3686a1661176SMatthew Knepley   PetscFunctionBegin;
368765e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3688779a8d59SSatish Balay 
3689779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3690779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3691779a8d59SSatish Balay 
3692779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3693a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3694a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3695b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3696a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369765e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3698a1661176SMatthew Knepley     nnz[i] = nz;
3699a1661176SMatthew Knepley   }
3700a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3701a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3702a1661176SMatthew Knepley 
3703a1661176SMatthew Knepley   if (v) {
3704a1661176SMatthew Knepley     values = (PetscScalar*) v;
3705a1661176SMatthew Knepley   } else {
37060e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3707a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3708a1661176SMatthew Knepley   }
3709a1661176SMatthew Knepley 
3710a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3711b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3712b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3713a1661176SMatthew Knepley   }
3714a1661176SMatthew Knepley 
3715a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3716a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3717a1661176SMatthew Knepley 
3718a1661176SMatthew Knepley   if (!v) {
3719a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3720a1661176SMatthew Knepley   }
37217827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3722a1661176SMatthew Knepley   PetscFunctionReturn(0);
3723a1661176SMatthew Knepley }
3724a1661176SMatthew Knepley 
3725c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372606873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3727170fe5c8SBarry Smith 
3728170fe5c8SBarry Smith #undef __FUNCT__
3729170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3730170fe5c8SBarry Smith /*
3731170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3732170fe5c8SBarry Smith 
3733170fe5c8SBarry Smith                n                       p                          p
3734170fe5c8SBarry Smith         (              )       (              )         (                  )
3735170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3736170fe5c8SBarry Smith         (              )       (              )         (                  )
3737170fe5c8SBarry Smith 
3738170fe5c8SBarry Smith */
3739170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3740170fe5c8SBarry Smith {
3741170fe5c8SBarry Smith   PetscErrorCode    ierr;
3742170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3743170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3744170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37451de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3746170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3747170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3748170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3749170fe5c8SBarry Smith 
3750170fe5c8SBarry Smith   PetscFunctionBegin;
3751d0f46423SBarry Smith   m    = A->rmap->n;
3752d0f46423SBarry Smith   n    = A->cmap->n;
3753d0f46423SBarry Smith   p    = B->cmap->n;
3754170fe5c8SBarry Smith   a    = sub_a->v;
3755170fe5c8SBarry Smith   b    = sub_b->a;
3756170fe5c8SBarry Smith   c    = sub_c->v;
3757170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3758170fe5c8SBarry Smith 
3759170fe5c8SBarry Smith   ii  = sub_b->i;
3760170fe5c8SBarry Smith   idx = sub_b->j;
3761170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3762170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3763170fe5c8SBarry Smith     while (q-->0) {
3764170fe5c8SBarry Smith       c_q = c + m*(*idx);
3765170fe5c8SBarry Smith       a_q = a + m*i;
3766854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3767170fe5c8SBarry Smith       idx++;
3768170fe5c8SBarry Smith       b++;
3769170fe5c8SBarry Smith     }
3770170fe5c8SBarry Smith   }
3771170fe5c8SBarry Smith   PetscFunctionReturn(0);
3772170fe5c8SBarry Smith }
3773170fe5c8SBarry Smith 
3774170fe5c8SBarry Smith #undef __FUNCT__
3775170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3776170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3777170fe5c8SBarry Smith {
3778170fe5c8SBarry Smith   PetscErrorCode ierr;
3779d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3780170fe5c8SBarry Smith   Mat            Cmat;
3781170fe5c8SBarry Smith 
3782170fe5c8SBarry Smith   PetscFunctionBegin;
3783e32f2f54SBarry Smith   if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n);
3784ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3785170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3786a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3787170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37880298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3789d73949e8SHong Zhang 
3790d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37912205254eSKarl Rupp 
3792170fe5c8SBarry Smith   *C = Cmat;
3793170fe5c8SBarry Smith   PetscFunctionReturn(0);
3794170fe5c8SBarry Smith }
3795170fe5c8SBarry Smith 
3796170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3797170fe5c8SBarry Smith #undef __FUNCT__
3798170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3799170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3800170fe5c8SBarry Smith {
3801170fe5c8SBarry Smith   PetscErrorCode ierr;
3802170fe5c8SBarry Smith 
3803170fe5c8SBarry Smith   PetscFunctionBegin;
3804170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38053ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3806170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38073ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3808170fe5c8SBarry Smith   }
38093ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3810170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38113ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3812170fe5c8SBarry Smith   PetscFunctionReturn(0);
3813170fe5c8SBarry Smith }
3814170fe5c8SBarry Smith 
3815170fe5c8SBarry Smith 
38160bad9183SKris Buschelman /*MC
3817fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38180bad9183SKris Buschelman    based on compressed sparse row format.
38190bad9183SKris Buschelman 
38200bad9183SKris Buschelman    Options Database Keys:
38210bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38220bad9183SKris Buschelman 
38230bad9183SKris Buschelman   Level: beginner
38240bad9183SKris Buschelman 
3825f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38260bad9183SKris Buschelman M*/
38270bad9183SKris Buschelman 
3828ccd284c7SBarry Smith /*MC
3829ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3830ccd284c7SBarry Smith 
3831ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3832ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3833ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3834ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3835ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3836ccd284c7SBarry Smith 
3837ccd284c7SBarry Smith    Options Database Keys:
3838ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3839ccd284c7SBarry Smith 
3840ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3841ccd284c7SBarry Smith    enough exist.
3842ccd284c7SBarry Smith 
3843ccd284c7SBarry Smith   Level: beginner
3844ccd284c7SBarry Smith 
3845ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3846ccd284c7SBarry Smith M*/
3847ccd284c7SBarry Smith 
3848ccd284c7SBarry Smith /*MC
3849ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3850ccd284c7SBarry Smith 
3851ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3852ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3853ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3854ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3855ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3856ccd284c7SBarry Smith 
3857ccd284c7SBarry Smith    Options Database Keys:
3858ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3859ccd284c7SBarry Smith 
3860ccd284c7SBarry Smith   Level: beginner
3861ccd284c7SBarry Smith 
3862ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3863ccd284c7SBarry Smith M*/
3864ccd284c7SBarry Smith 
3865b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3867b5e56a35SBarry Smith #endif
3868ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3870af1023dbSSatish Balay #endif
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38747087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3875611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3877611f576cSBarry Smith #endif
3878611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3880611f576cSBarry Smith #endif
3881f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3883f3c0ef26SHong Zhang #endif
3884eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3886eb3b5408SSatish Balay #endif
3887586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3889586621ddSJed Brown #endif
3890719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3892719d5645SBarry Smith #endif
3893b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38957087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38967087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3897b3866ffcSBarry Smith #endif
389817f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
390017f1a0eaSHong Zhang #endif
390117667f90SBarry Smith 
3902c0c8ee5eSDmitry Karpeev 
39038c778c55SBarry Smith #undef __FUNCT__
39048c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39058c778c55SBarry Smith /*@C
39068c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39078c778c55SBarry Smith 
39088c778c55SBarry Smith    Not Collective
39098c778c55SBarry Smith 
39108c778c55SBarry Smith    Input Parameter:
39118c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39128c778c55SBarry Smith 
39138c778c55SBarry Smith    Output Parameter:
39148c778c55SBarry Smith .   array - pointer to the data
39158c778c55SBarry Smith 
39168c778c55SBarry Smith    Level: intermediate
39178c778c55SBarry Smith 
3918774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39198c778c55SBarry Smith @*/
39208c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39218c778c55SBarry Smith {
39228c778c55SBarry Smith   PetscErrorCode ierr;
39238c778c55SBarry Smith 
39248c778c55SBarry Smith   PetscFunctionBegin;
39258c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39268c778c55SBarry Smith   PetscFunctionReturn(0);
39278c778c55SBarry Smith }
39288c778c55SBarry Smith 
39298c778c55SBarry Smith #undef __FUNCT__
39308c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39318c778c55SBarry Smith /*@C
39328c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39338c778c55SBarry Smith 
39348c778c55SBarry Smith    Not Collective
39358c778c55SBarry Smith 
39368c778c55SBarry Smith    Input Parameters:
39378c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39388c778c55SBarry Smith .  array - pointer to the data
39398c778c55SBarry Smith 
39408c778c55SBarry Smith    Level: intermediate
39418c778c55SBarry Smith 
3942774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39438c778c55SBarry Smith @*/
39448c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39458c778c55SBarry Smith {
39468c778c55SBarry Smith   PetscErrorCode ierr;
39478c778c55SBarry Smith 
39488c778c55SBarry Smith   PetscFunctionBegin;
39498c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39508c778c55SBarry Smith   PetscFunctionReturn(0);
39518c778c55SBarry Smith }
39528c778c55SBarry Smith 
39534a2ae208SSatish Balay #undef __FUNCT__
39544a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3956273d9f13SBarry Smith {
3957273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3958dfbe8321SBarry Smith   PetscErrorCode ierr;
395938baddfdSBarry Smith   PetscMPIInt    size;
3960273d9f13SBarry Smith 
3961273d9f13SBarry Smith   PetscFunctionBegin;
3962ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3963e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3964273d9f13SBarry Smith 
396538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39662205254eSKarl Rupp 
3967b0a32e0cSBarry Smith   B->data = (void*)b;
39682205254eSKarl Rupp 
3969549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39702205254eSKarl Rupp 
3971416022c9SBarry Smith   b->row                = 0;
3972416022c9SBarry Smith   b->col                = 0;
397382bf6240SBarry Smith   b->icol               = 0;
3974b810aeb4SBarry Smith   b->reallocs           = 0;
397536db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3976f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3977416022c9SBarry Smith   b->nonew              = 0;
3978416022c9SBarry Smith   b->diag               = 0;
3979416022c9SBarry Smith   b->solve_work         = 0;
39802a1b7f2aSHong Zhang   B->spptr              = 0;
3981be6bf707SBarry Smith   b->saved_values       = 0;
3982d7f994e1SBarry Smith   b->idiag              = 0;
398371f1c65dSBarry Smith   b->mdiag              = 0;
398471f1c65dSBarry Smith   b->ssor_work          = 0;
398571f1c65dSBarry Smith   b->omega              = 1.0;
398671f1c65dSBarry Smith   b->fshift             = 0.0;
398771f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3988bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3989a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3990a30b2313SHong Zhang   b->xtoy               = 0;
3991a30b2313SHong Zhang   b->XtoY               = 0;
399288e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
399317ab2063SBarry Smith 
399435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39978c778c55SBarry Smith 
3998b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3999bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4000bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4001bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4002b3866ffcSBarry Smith #endif
4003b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4004bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4005b5e56a35SBarry Smith #endif
4006ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4008719d5645SBarry Smith #endif
4009611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4010bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4011611f576cSBarry Smith #endif
4012f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4013bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4014f3c0ef26SHong Zhang #endif
4015611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4016bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4017611f576cSBarry Smith #endif
4018eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4020eb3b5408SSatish Balay #endif
4021586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4022bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4023586621ddSJed Brown #endif
4024719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4026719d5645SBarry Smith #endif
402717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402917f1a0eaSHong Zhang #endif
403017f1a0eaSHong Zhang 
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40494108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
405017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40513a40ed3dSBarry Smith   PetscFunctionReturn(0);
405217ab2063SBarry Smith }
405317ab2063SBarry Smith 
40544a2ae208SSatish Balay #undef __FUNCT__
4055b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4056b24902e0SBarry Smith /*
4057b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4058b24902e0SBarry Smith */
4059ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
406017ab2063SBarry Smith {
4061416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40626849ba73SBarry Smith   PetscErrorCode ierr;
4063d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
406417ab2063SBarry Smith 
40653a40ed3dSBarry Smith   PetscFunctionBegin;
4066273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4067273d9f13SBarry Smith 
4068d5f3da31SBarry Smith   C->factortype = A->factortype;
4069416022c9SBarry Smith   c->row        = 0;
4070416022c9SBarry Smith   c->col        = 0;
407182bf6240SBarry Smith   c->icol       = 0;
40726ad4291fSHong Zhang   c->reallocs   = 0;
407317ab2063SBarry Smith 
40746ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407517ab2063SBarry Smith 
4076aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4077aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4078eec197d1SBarry Smith 
407933b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40803bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
408117ab2063SBarry Smith   for (i=0; i<m; i++) {
4082416022c9SBarry Smith     c->imax[i] = a->imax[i];
4083416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
408417ab2063SBarry Smith   }
408517ab2063SBarry Smith 
408617ab2063SBarry Smith   /* allocate the matrix space */
4087f77e22a1SHong Zhang   if (mallocmatspace) {
4088a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40893bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40902205254eSKarl Rupp 
4091f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40922205254eSKarl Rupp 
409397f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409417ab2063SBarry Smith     if (m > 0) {
409597f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4096be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4097bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4098be6bf707SBarry Smith       } else {
4099bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
410017ab2063SBarry Smith       }
410108480c60SBarry Smith     }
4102f77e22a1SHong Zhang   }
410317ab2063SBarry Smith 
41046ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4105416022c9SBarry Smith   c->roworiented       = a->roworiented;
4106416022c9SBarry Smith   c->nonew             = a->nonew;
4107416022c9SBarry Smith   if (a->diag) {
410897f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41093bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
411017ab2063SBarry Smith     for (i=0; i<m; i++) {
4111416022c9SBarry Smith       c->diag[i] = a->diag[i];
411217ab2063SBarry Smith     }
41133a40ed3dSBarry Smith   } else c->diag = 0;
41142205254eSKarl Rupp 
41156ad4291fSHong Zhang   c->solve_work         = 0;
41166ad4291fSHong Zhang   c->saved_values       = 0;
41176ad4291fSHong Zhang   c->idiag              = 0;
411871f1c65dSBarry Smith   c->ssor_work          = 0;
4119a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4120e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4121e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41226ad4291fSHong Zhang   c->xtoy               = 0;
41236ad4291fSHong Zhang   c->XtoY               = 0;
41246ad4291fSHong Zhang 
4125893ad86cSHong Zhang   c->rmax         = a->rmax;
4126416022c9SBarry Smith   c->nz           = a->nz;
41278ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4128273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4129754ec7b1SSatish Balay 
41306ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41316ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4132cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4133cd6b891eSBarry Smith   if (a->compressedrow.use) {
41346ad4291fSHong Zhang     i    = a->compressedrow.nrows;
41350e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
41366ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41376ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413827ea64f8SHong Zhang   } else {
413927ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41400298fd71SBarry Smith     c->compressedrow.i      = NULL;
41410298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41426ad4291fSHong Zhang   }
414388e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41444846f1f5SKris Buschelman 
41452205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4146140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41473a40ed3dSBarry Smith   PetscFunctionReturn(0);
414817ab2063SBarry Smith }
414917ab2063SBarry Smith 
41504a2ae208SSatish Balay #undef __FUNCT__
4151b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4152b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4153b24902e0SBarry Smith {
4154b24902e0SBarry Smith   PetscErrorCode ierr;
4155b24902e0SBarry Smith 
4156b24902e0SBarry Smith   PetscFunctionBegin;
4157ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41584b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4159a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4160a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4161f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4162b24902e0SBarry Smith   PetscFunctionReturn(0);
4163b24902e0SBarry Smith }
4164b24902e0SBarry Smith 
4165b24902e0SBarry Smith #undef __FUNCT__
41664a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4167112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4168fbdbba38SShri Abhyankar {
4169fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4170fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4171fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4172fbdbba38SShri Abhyankar   int            fd;
4173fbdbba38SShri Abhyankar   PetscMPIInt    size;
4174fbdbba38SShri Abhyankar   MPI_Comm       comm;
4175bbead8a2SBarry Smith   PetscInt       bs = 1;
4176fbdbba38SShri Abhyankar 
4177fbdbba38SShri Abhyankar   PetscFunctionBegin;
4178fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4179fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4180fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4181bbead8a2SBarry Smith 
41820298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41830298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4184bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41851814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4186bbead8a2SBarry Smith 
4187fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4188fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4189fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4190fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4191fbdbba38SShri Abhyankar 
4192bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4193fbdbba38SShri Abhyankar 
4194fbdbba38SShri Abhyankar   /* read in row lengths */
4195fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4196fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4197fbdbba38SShri Abhyankar 
4198fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4199fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4200fbdbba38SShri 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);
4201fbdbba38SShri Abhyankar 
4202fbdbba38SShri Abhyankar   /* set global size if not set already*/
4203f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4204fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4205aabbc4fbSShri Abhyankar   } else {
4206fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4207fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42084c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42094c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42104c5b953cSHong Zhang     }
4211f501eaabSShri 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);
4212aabbc4fbSShri Abhyankar   }
4213fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4214fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4215fbdbba38SShri Abhyankar 
4216fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4217fbdbba38SShri Abhyankar 
4218fbdbba38SShri Abhyankar   /* read in nonzero values */
4219fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4220fbdbba38SShri Abhyankar 
4221fbdbba38SShri Abhyankar   /* set matrix "i" values */
4222fbdbba38SShri Abhyankar   a->i[0] = 0;
4223fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4224fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4225fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4226fbdbba38SShri Abhyankar   }
4227fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4228fbdbba38SShri Abhyankar 
4229fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4230fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4231fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4232fbdbba38SShri Abhyankar }
4233fbdbba38SShri Abhyankar 
4234fbdbba38SShri Abhyankar #undef __FUNCT__
4235b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4236ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42377264ac53SSatish Balay {
42387264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4239dfbe8321SBarry Smith   PetscErrorCode ierr;
4240eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4241eeffb40dSHong Zhang   PetscInt k;
4242eeffb40dSHong Zhang #endif
42437264ac53SSatish Balay 
42443a40ed3dSBarry Smith   PetscFunctionBegin;
4245bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4246d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4247ca44d042SBarry Smith     *flg = PETSC_FALSE;
4248ca44d042SBarry Smith     PetscFunctionReturn(0);
4249bcd2baecSBarry Smith   }
42507264ac53SSatish Balay 
42517264ac53SSatish Balay   /* if the a->i are the same */
4252d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4253abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42547264ac53SSatish Balay 
42557264ac53SSatish Balay   /* if a->j are the same */
425697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4257abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4258bcd2baecSBarry Smith 
4259bcd2baecSBarry Smith   /* if a->a are the same */
4260eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4261eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4262eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4263eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42643a40ed3dSBarry Smith       PetscFunctionReturn(0);
4265eeffb40dSHong Zhang     }
4266eeffb40dSHong Zhang   }
4267eeffb40dSHong Zhang #else
4268eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4269eeffb40dSHong Zhang #endif
4270eeffb40dSHong Zhang   PetscFunctionReturn(0);
42717264ac53SSatish Balay }
427236db0b34SBarry Smith 
42734a2ae208SSatish Balay #undef __FUNCT__
42744a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
427505869f15SSatish Balay /*@
427636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427736db0b34SBarry Smith               provided by the user.
427836db0b34SBarry Smith 
4279c75a6043SHong Zhang       Collective on MPI_Comm
428036db0b34SBarry Smith 
428136db0b34SBarry Smith    Input Parameters:
428236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
428336db0b34SBarry Smith .   m - number of rows
428436db0b34SBarry Smith .   n - number of columns
428536db0b34SBarry Smith .   i - row indices
428636db0b34SBarry Smith .   j - column indices
428736db0b34SBarry Smith -   a - matrix values
428836db0b34SBarry Smith 
428936db0b34SBarry Smith    Output Parameter:
429036db0b34SBarry Smith .   mat - the matrix
429136db0b34SBarry Smith 
429236db0b34SBarry Smith    Level: intermediate
429336db0b34SBarry Smith 
429436db0b34SBarry Smith    Notes:
42950551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4296292fb18eSBarry Smith     once the matrix is destroyed and not before
429736db0b34SBarry Smith 
429836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429936db0b34SBarry Smith 
4300bfeeae90SHong Zhang        The i and j indices are 0 based
430136db0b34SBarry Smith 
4302a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4303a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4304a4552177SSatish Balay     as shown:
4305a4552177SSatish Balay 
4306a4552177SSatish Balay         1 0 0
4307a4552177SSatish Balay         2 0 3
4308a4552177SSatish Balay         4 5 6
4309a4552177SSatish Balay 
4310a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43119985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4312a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4313a4552177SSatish Balay 
43149985e31cSBarry Smith 
431569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
431636db0b34SBarry Smith 
431736db0b34SBarry Smith @*/
43187087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431936db0b34SBarry Smith {
4320dfbe8321SBarry Smith   PetscErrorCode ierr;
4321cbcfb4deSHong Zhang   PetscInt       ii;
432236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4323cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4324cbcfb4deSHong Zhang   PetscInt jj;
4325cbcfb4deSHong Zhang #endif
432636db0b34SBarry Smith 
432736db0b34SBarry Smith   PetscFunctionBegin;
4328f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4329f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4330f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4331a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4332ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4333ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4334ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4335ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4336ab93d7beSBarry Smith 
433736db0b34SBarry Smith   aij->i            = i;
433836db0b34SBarry Smith   aij->j            = j;
433936db0b34SBarry Smith   aij->a            = a;
434036db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
434136db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4342e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4343e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
434436db0b34SBarry Smith 
434536db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
434636db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43472515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4348e32f2f54SBarry 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]);
43499985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
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 not sorted",jj-i[ii],j[jj],ii);
4351e32f2f54SBarry 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);
43529985e31cSBarry Smith     }
435336db0b34SBarry Smith #endif
435436db0b34SBarry Smith   }
43552515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435636db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4357e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4358e32f2f54SBarry 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]);
435936db0b34SBarry Smith   }
436036db0b34SBarry Smith #endif
436136db0b34SBarry Smith 
4362b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4363b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
436436db0b34SBarry Smith   PetscFunctionReturn(0);
436536db0b34SBarry Smith }
43668a0b0e6bSVictor Minden #undef __FUNCT__
43678a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436880ef6e79SMatthew G Knepley /*@C
4369d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43708a0b0e6bSVictor Minden               provided by the user.
43718a0b0e6bSVictor Minden 
43728a0b0e6bSVictor Minden       Collective on MPI_Comm
43738a0b0e6bSVictor Minden 
43748a0b0e6bSVictor Minden    Input Parameters:
43758a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43768a0b0e6bSVictor Minden .   m   - number of rows
43778a0b0e6bSVictor Minden .   n   - number of columns
43788a0b0e6bSVictor Minden .   i   - row indices
43798a0b0e6bSVictor Minden .   j   - column indices
43801230e6d1SVictor Minden .   a   - matrix values
43811230e6d1SVictor Minden .   nz  - number of nonzeros
43821230e6d1SVictor Minden -   idx - 0 or 1 based
43838a0b0e6bSVictor Minden 
43848a0b0e6bSVictor Minden    Output Parameter:
43858a0b0e6bSVictor Minden .   mat - the matrix
43868a0b0e6bSVictor Minden 
43878a0b0e6bSVictor Minden    Level: intermediate
43888a0b0e6bSVictor Minden 
43898a0b0e6bSVictor Minden    Notes:
43908a0b0e6bSVictor Minden        The i and j indices are 0 based
43918a0b0e6bSVictor Minden 
43928a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43938a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43948a0b0e6bSVictor Minden     as shown:
43958a0b0e6bSVictor Minden 
43968a0b0e6bSVictor Minden         1 0 0
43978a0b0e6bSVictor Minden         2 0 3
43988a0b0e6bSVictor Minden         4 5 6
43998a0b0e6bSVictor Minden 
44008a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
44018a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
44028a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44038a0b0e6bSVictor Minden 
44048a0b0e6bSVictor Minden 
440569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44068a0b0e6bSVictor Minden 
44078a0b0e6bSVictor Minden @*/
44081230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44098a0b0e6bSVictor Minden {
44108a0b0e6bSVictor Minden   PetscErrorCode ierr;
4411d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44128a0b0e6bSVictor Minden 
44138a0b0e6bSVictor Minden 
44148a0b0e6bSVictor Minden   PetscFunctionBegin;
4415d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44161230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44171230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44181230e6d1SVictor Minden     nnz[i[ii]] += 1;
44191230e6d1SVictor Minden   }
44208a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44218a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4422a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
44238a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44241230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44251230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44261230e6d1SVictor Minden     if (idx) {
44271230e6d1SVictor Minden       row = i[ii] - 1;
44281230e6d1SVictor Minden       col = j[ii] - 1;
44291230e6d1SVictor Minden     } else {
44301230e6d1SVictor Minden       row = i[ii];
44311230e6d1SVictor Minden       col = j[ii];
44328a0b0e6bSVictor Minden     }
44331230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44348a0b0e6bSVictor Minden   }
44358a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44368a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4437d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44388a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44398a0b0e6bSVictor Minden }
444036db0b34SBarry Smith 
4441cc8ba8e1SBarry Smith #undef __FUNCT__
4442ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4443dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4444cc8ba8e1SBarry Smith {
4445dfbe8321SBarry Smith   PetscErrorCode ierr;
4446cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444736db0b34SBarry Smith 
4448cc8ba8e1SBarry Smith   PetscFunctionBegin;
44498ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4450cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4451cc8ba8e1SBarry Smith     a->coloring = coloring;
445212c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
445397f1f81fSBarry Smith     PetscInt        i,*larray;
445412c595b3SBarry Smith     ISColoring      ocoloring;
445508b6dcc0SBarry Smith     ISColoringValue *colors;
445612c595b3SBarry Smith 
445712c595b3SBarry Smith     /* set coloring for diagonal portion */
44580e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44592205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44600298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44610e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44622205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
446312c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4464d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446512c595b3SBarry Smith     a->coloring = ocoloring;
446612c595b3SBarry Smith   }
4467cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4468cc8ba8e1SBarry Smith }
4469cc8ba8e1SBarry Smith 
4470ee4f033dSBarry Smith #undef __FUNCT__
4471ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
447297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4473ee4f033dSBarry Smith {
4474ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4475d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447654f21887SBarry Smith   MatScalar       *v      = a->a;
447754f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447808b6dcc0SBarry Smith   ISColoringValue *color;
4479ee4f033dSBarry Smith 
4480ee4f033dSBarry Smith   PetscFunctionBegin;
4481e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4482ee4f033dSBarry Smith   color = a->coloring->colors;
4483ee4f033dSBarry Smith   /* loop over rows */
4484ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4485ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4486ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44872205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4488ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4489cc8ba8e1SBarry Smith   }
4490cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4491cc8ba8e1SBarry Smith }
449236db0b34SBarry Smith 
4493acf2f550SJed Brown #undef __FUNCT__
4494acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4495acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4496acf2f550SJed Brown {
4497acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4498acf2f550SJed Brown   PetscErrorCode ierr;
4499acf2f550SJed Brown 
4500acf2f550SJed Brown   PetscFunctionBegin;
4501acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4502acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45032205254eSKarl Rupp 
4504acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4505acf2f550SJed Brown   PetscFunctionReturn(0);
4506acf2f550SJed Brown }
4507acf2f550SJed Brown 
450881824310SBarry Smith /*
450981824310SBarry Smith     Special version for direct calls from Fortran
451081824310SBarry Smith */
4511b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
451281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
451381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
451481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451681824310SBarry Smith #endif
451781824310SBarry Smith 
451881824310SBarry Smith /* Change these macros so can be used in void function */
451981824310SBarry Smith #undef CHKERRQ
4520ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
452181824310SBarry Smith #undef SETERRQ2
4522e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45234994cf47SJed Brown #undef SETERRQ3
45244994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452581824310SBarry Smith 
452681824310SBarry Smith #undef __FUNCT__
452781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45288cc058d9SJed 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)
452981824310SBarry Smith {
453081824310SBarry Smith   Mat            A  = *AA;
453181824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
453281824310SBarry Smith   InsertMode     is = *isis;
453381824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
453481824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453581824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453681824310SBarry Smith   PetscErrorCode ierr;
453781824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453854f21887SBarry Smith   MatScalar      *ap,value,*aa;
4539ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4540ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
454181824310SBarry Smith 
454281824310SBarry Smith   PetscFunctionBegin;
45434994cf47SJed Brown   MatCheckPreallocated(A,1);
454481824310SBarry Smith   imax  = a->imax;
454581824310SBarry Smith   ai    = a->i;
454681824310SBarry Smith   ailen = a->ilen;
454781824310SBarry Smith   aj    = a->j;
454881824310SBarry Smith   aa    = a->a;
454981824310SBarry Smith 
455081824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
455181824310SBarry Smith     row = im[k];
455281824310SBarry Smith     if (row < 0) continue;
455381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4554ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455581824310SBarry Smith #endif
455681824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455781824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455881824310SBarry Smith     low  = 0;
455981824310SBarry Smith     high = nrow;
456081824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
456181824310SBarry Smith       if (in[l] < 0) continue;
456281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4563ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
456481824310SBarry Smith #endif
456581824310SBarry Smith       col = in[l];
45662205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45672205254eSKarl Rupp       else value = v[k + l*m];
45682205254eSKarl Rupp 
456981824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
457081824310SBarry Smith 
45712205254eSKarl Rupp       if (col <= lastcol) low = 0;
45722205254eSKarl Rupp       else high = nrow;
457381824310SBarry Smith       lastcol = col;
457481824310SBarry Smith       while (high-low > 5) {
457581824310SBarry Smith         t = (low+high)/2;
457681824310SBarry Smith         if (rp[t] > col) high = t;
457781824310SBarry Smith         else             low  = t;
457881824310SBarry Smith       }
457981824310SBarry Smith       for (i=low; i<high; i++) {
458081824310SBarry Smith         if (rp[i] > col) break;
458181824310SBarry Smith         if (rp[i] == col) {
458281824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
458381824310SBarry Smith           else                  ap[i] = value;
458481824310SBarry Smith           goto noinsert;
458581824310SBarry Smith         }
458681824310SBarry Smith       }
458781824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458881824310SBarry Smith       if (nonew == 1) goto noinsert;
4589ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4590fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
459181824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
459281824310SBarry Smith       /* shift up all the later entries in this row */
459381824310SBarry Smith       for (ii=N; ii>=i; ii--) {
459481824310SBarry Smith         rp[ii+1] = rp[ii];
459581824310SBarry Smith         ap[ii+1] = ap[ii];
459681824310SBarry Smith       }
459781824310SBarry Smith       rp[i] = col;
459881824310SBarry Smith       ap[i] = value;
459981824310SBarry Smith noinsert:;
460081824310SBarry Smith       low = i + 1;
460181824310SBarry Smith     }
460281824310SBarry Smith     ailen[row] = nrow;
460381824310SBarry Smith   }
460481824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460581824310SBarry Smith   PetscFunctionReturnVoid();
460681824310SBarry Smith }
46079f7953f8SBarry Smith 
460862298a1eSBarry Smith 
4609