xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 625f6d37088ae665b5f7ef877d9e50ad1b233616)
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
281040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2827cee066cSHong Zhang */
2837cee066cSHong Zhang #undef __FUNCT__
2847cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
2857cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
2867cee066cSHong Zhang {
2877cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2887cee066cSHong Zhang   PetscErrorCode ierr;
2897cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2907cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2917cee066cSHong Zhang   PetscInt       *cspidx;
2927cee066cSHong Zhang 
2937cee066cSHong Zhang   PetscFunctionBegin;
2947cee066cSHong Zhang   *nn = n;
2957cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
296*625f6d37SHong Zhang 
2977cee066cSHong Zhang   ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
2987cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2997cee066cSHong Zhang   ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
3007cee066cSHong Zhang   ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
3017cee066cSHong Zhang   ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr);
3027cee066cSHong Zhang   jj   = a->j;
3037cee066cSHong Zhang   for (i=0; i<nz; i++) {
3047cee066cSHong Zhang     collengths[jj[i]]++;
3057cee066cSHong Zhang   }
3067cee066cSHong Zhang   cia[0] = oshift;
3077cee066cSHong Zhang   for (i=0; i<n; i++) {
3087cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3097cee066cSHong Zhang   }
3107cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3117cee066cSHong Zhang   jj   = a->j;
3127cee066cSHong Zhang   for (row=0; row<m; row++) {
3137cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3147cee066cSHong Zhang     for (i=0; i<mr; i++) {
3157cee066cSHong Zhang       col = *jj++;
3167cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3177cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3187cee066cSHong Zhang     }
3197cee066cSHong Zhang   }
3207cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3217cee066cSHong Zhang   *ia    = cia; *ja = cja;
3227cee066cSHong Zhang   *spidx = cspidx;
3237cee066cSHong Zhang   PetscFunctionReturn(0);
3247cee066cSHong Zhang }
3257cee066cSHong Zhang 
3267cee066cSHong Zhang #undef __FUNCT__
3277cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3287cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3297cee066cSHong Zhang {
3307cee066cSHong Zhang   PetscErrorCode ierr;
3317cee066cSHong Zhang 
3327cee066cSHong Zhang   PetscFunctionBegin;
3335243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3347cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3357cee066cSHong Zhang   PetscFunctionReturn(0);
3367cee066cSHong Zhang }
3377cee066cSHong Zhang 
33887d4246cSBarry Smith #undef __FUNCT__
33987d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
34087d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
34187d4246cSBarry Smith {
34287d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34387d4246cSBarry Smith   PetscInt       *ai = a->i;
34487d4246cSBarry Smith   PetscErrorCode ierr;
34587d4246cSBarry Smith 
34687d4246cSBarry Smith   PetscFunctionBegin;
34787d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
34887d4246cSBarry Smith   PetscFunctionReturn(0);
34987d4246cSBarry Smith }
35087d4246cSBarry Smith 
3514a2ae208SSatish Balay #undef __FUNCT__
3524a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
35397f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
35417ab2063SBarry Smith {
355416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
356e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
35797f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3586849ba73SBarry Smith   PetscErrorCode ierr;
359e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
36054f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
361ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
362ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
36317ab2063SBarry Smith 
3643a40ed3dSBarry Smith   PetscFunctionBegin;
36571fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
36617ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
367416022c9SBarry Smith     row = im[k];
3685ef9f2a5SBarry Smith     if (row < 0) continue;
3692515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
370e32f2f54SBarry 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);
3713b2fbd54SBarry Smith #endif
372bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
37317ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
374416022c9SBarry Smith     low  = 0;
375c71e6ed7SBarry Smith     high = nrow;
37617ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3775ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3782515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
379e32f2f54SBarry 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);
3803b2fbd54SBarry Smith #endif
381bfeeae90SHong Zhang       col = in[l];
38216371a99SBarry Smith       if (v) {
3834b0e389bSBarry Smith         if (roworiented) {
3845ef9f2a5SBarry Smith           value = v[l + k*n];
385bef8e0ddSBarry Smith         } else {
3864b0e389bSBarry Smith           value = v[k + l*m];
3874b0e389bSBarry Smith         }
38816371a99SBarry Smith       } else {
38975567043SBarry Smith         value = 0.;
39016371a99SBarry Smith       }
391abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
39236db0b34SBarry Smith 
3932205254eSKarl Rupp       if (col <= lastcol) low = 0;
3942205254eSKarl Rupp       else high = nrow;
395e2ee6c50SBarry Smith       lastcol = col;
396416022c9SBarry Smith       while (high-low > 5) {
397416022c9SBarry Smith         t = (low+high)/2;
398416022c9SBarry Smith         if (rp[t] > col) high = t;
399416022c9SBarry Smith         else low = t;
40017ab2063SBarry Smith       }
401416022c9SBarry Smith       for (i=low; i<high; i++) {
40217ab2063SBarry Smith         if (rp[i] > col) break;
40317ab2063SBarry Smith         if (rp[i] == col) {
404416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
40517ab2063SBarry Smith           else ap[i] = value;
406e44c0bd4SBarry Smith           low = i + 1;
40717ab2063SBarry Smith           goto noinsert;
40817ab2063SBarry Smith         }
40917ab2063SBarry Smith       }
410abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
411c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
412e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
413fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
414c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
415416022c9SBarry Smith       /* shift up all the later entries in this row */
416416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
41717ab2063SBarry Smith         rp[ii+1] = rp[ii];
41817ab2063SBarry Smith         ap[ii+1] = ap[ii];
41917ab2063SBarry Smith       }
42017ab2063SBarry Smith       rp[i] = col;
42117ab2063SBarry Smith       ap[i] = value;
422416022c9SBarry Smith       low   = i + 1;
423e44c0bd4SBarry Smith noinsert:;
42417ab2063SBarry Smith     }
42517ab2063SBarry Smith     ailen[row] = nrow;
42617ab2063SBarry Smith   }
42788e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4283a40ed3dSBarry Smith   PetscFunctionReturn(0);
42917ab2063SBarry Smith }
43017ab2063SBarry Smith 
43181824310SBarry Smith 
4324a2ae208SSatish Balay #undef __FUNCT__
4334a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
434a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4357eb43aa7SLois Curfman McInnes {
4367eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
43797f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
43897f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
43954f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4407eb43aa7SLois Curfman McInnes 
4413a40ed3dSBarry Smith   PetscFunctionBegin;
4427eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4437eb43aa7SLois Curfman McInnes     row = im[k];
444e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
445e32f2f54SBarry 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);
446bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4477eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4487eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
449e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
450e32f2f54SBarry 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);
451bfeeae90SHong Zhang       col  = in[l];
4527eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4537eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4547eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4557eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4567eb43aa7SLois Curfman McInnes         else low = t;
4577eb43aa7SLois Curfman McInnes       }
4587eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4597eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4607eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
461b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4627eb43aa7SLois Curfman McInnes           goto finished;
4637eb43aa7SLois Curfman McInnes         }
4647eb43aa7SLois Curfman McInnes       }
46597e567efSBarry Smith       *v++ = 0.0;
4667eb43aa7SLois Curfman McInnes finished:;
4677eb43aa7SLois Curfman McInnes     }
4687eb43aa7SLois Curfman McInnes   }
4693a40ed3dSBarry Smith   PetscFunctionReturn(0);
4707eb43aa7SLois Curfman McInnes }
4717eb43aa7SLois Curfman McInnes 
47217ab2063SBarry Smith 
4734a2ae208SSatish Balay #undef __FUNCT__
4744a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
475dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
47617ab2063SBarry Smith {
477416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4786849ba73SBarry Smith   PetscErrorCode ierr;
4796f69ff64SBarry Smith   PetscInt       i,*col_lens;
4806f69ff64SBarry Smith   int            fd;
481b37d52dbSMark F. Adams   FILE           *file;
48217ab2063SBarry Smith 
4833a40ed3dSBarry Smith   PetscFunctionBegin;
484b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
485d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4862205254eSKarl Rupp 
4870700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
488d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
489d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
490416022c9SBarry Smith   col_lens[3] = a->nz;
491416022c9SBarry Smith 
492416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
493d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
494416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
49517ab2063SBarry Smith   }
496d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
497606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
498416022c9SBarry Smith 
499416022c9SBarry Smith   /* store column indices (zero start index) */
5006f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
501416022c9SBarry Smith 
502416022c9SBarry Smith   /* store nonzero values */
5036f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
504b37d52dbSMark F. Adams 
505b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
506b37d52dbSMark F. Adams   if (file) {
507b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
508b37d52dbSMark F. Adams   }
5093a40ed3dSBarry Smith   PetscFunctionReturn(0);
51017ab2063SBarry Smith }
511416022c9SBarry Smith 
51209573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
513cd155464SBarry Smith 
5144a2ae208SSatish Balay #undef __FUNCT__
5154a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
516dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
517416022c9SBarry Smith {
518416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
519dfbe8321SBarry Smith   PetscErrorCode    ierr;
520d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
521e060cb09SBarry Smith   const char        *name;
522f3ef73ceSBarry Smith   PetscViewerFormat format;
52317ab2063SBarry Smith 
5243a40ed3dSBarry Smith   PetscFunctionBegin;
525b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
52671c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
52797f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
528014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
529d00d2cf4SBarry Smith       nofinalvalue = 1;
530d00d2cf4SBarry Smith     }
531d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
532d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
53377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
53477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
535b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
53617ab2063SBarry Smith 
53717ab2063SBarry Smith     for (i=0; i<m; i++) {
538416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
539aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
54077431f27SBarry 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);
54117ab2063SBarry Smith #else
54277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
54317ab2063SBarry Smith #endif
54417ab2063SBarry Smith       }
54517ab2063SBarry Smith     }
546d00d2cf4SBarry Smith     if (nofinalvalue) {
547d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
548d00d2cf4SBarry Smith     }
549317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
550fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
551d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
55268369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
553cd155464SBarry Smith     PetscFunctionReturn(0);
554fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
555d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
556dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
55744cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
55877431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
55944cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
560aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
56136db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
562ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56336db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
564ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56536db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
566ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5676831982aSBarry Smith         }
56844cd7ae7SLois Curfman McInnes #else
569ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
57044cd7ae7SLois Curfman McInnes #endif
57144cd7ae7SLois Curfman McInnes       }
572b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57344cd7ae7SLois Curfman McInnes     }
574d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
575fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
57697f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
577d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
578dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
57997f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
580496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
581496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
582496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
583496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
584aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
586496be53dSLois Curfman McInnes #else
587496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
588496be53dSLois Curfman McInnes #endif
589496be53dSLois Curfman McInnes         }
590496be53dSLois Curfman McInnes       }
591496be53dSLois Curfman McInnes     }
5922e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
59377431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5942e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
5952205254eSKarl Rupp       if (i+4<m) {
5962205254eSKarl 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);
5972205254eSKarl Rupp       } else if (i+3<m) {
5982205254eSKarl 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);
5992205254eSKarl Rupp       } else if (i+2<m) {
6002205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6012205254eSKarl Rupp       } else if (i+1<m) {
6022205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6032205254eSKarl Rupp       } else if (i<m) {
6042205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6052205254eSKarl Rupp       } else {
6062205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6072205254eSKarl Rupp       }
608496be53dSLois Curfman McInnes     }
609b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
610606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
611496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
612496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
61377431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
614496be53dSLois Curfman McInnes       }
615b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
616496be53dSLois Curfman McInnes     }
617b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
618496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
619496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
620496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
621aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
623b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6246831982aSBarry Smith           }
625496be53dSLois Curfman McInnes #else
626b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
627496be53dSLois Curfman McInnes #endif
628496be53dSLois Curfman McInnes         }
629496be53dSLois Curfman McInnes       }
630b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
631496be53dSLois Curfman McInnes     }
632d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
633fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
63497f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
63587828ca2SBarry Smith     PetscScalar value;
63602594712SBarry Smith 
637d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
638dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
63902594712SBarry Smith     for (i=0; i<m; i++) {
64002594712SBarry Smith       jcnt = 0;
641d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
642e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
64302594712SBarry Smith           value = a->a[cnt++];
644e24b481bSBarry Smith           jcnt++;
64502594712SBarry Smith         } else {
64602594712SBarry Smith           value = 0.0;
64702594712SBarry Smith         }
648aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
649b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
65002594712SBarry Smith #else
651b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
65202594712SBarry Smith #endif
65302594712SBarry Smith       }
654b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65502594712SBarry Smith     }
656d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6573c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
658d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
659dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
6603c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6613c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6623c215bfdSMatthew Knepley #else
6633c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6643c215bfdSMatthew Knepley #endif
665d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6663c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
6673c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
6683c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6693c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
670ba0e910bSBarry 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);
6713c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
672ba0e910bSBarry 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);
6733c215bfdSMatthew Knepley         } else {
674ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6753c215bfdSMatthew Knepley         }
6763c215bfdSMatthew Knepley #else
677ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr);
6783c215bfdSMatthew Knepley #endif
6793c215bfdSMatthew Knepley       }
6803c215bfdSMatthew Knepley     }
681d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6823a40ed3dSBarry Smith   } else {
683d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
684dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
685d5f3da31SBarry Smith     if (A->factortype) {
68616cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
68716cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
68816cd7e1dSShri Abhyankar         /* L part */
68916cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
69016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
69116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
692ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
694ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69516cd7e1dSShri Abhyankar           } else {
696ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
69716cd7e1dSShri Abhyankar           }
69816cd7e1dSShri Abhyankar #else
699ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
70016cd7e1dSShri Abhyankar #endif
70116cd7e1dSShri Abhyankar         }
70216cd7e1dSShri Abhyankar         /* diagonal */
70316cd7e1dSShri Abhyankar         j = a->diag[i];
70416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
70516cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
706ba0e910bSBarry 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);
70716cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
708ba0e910bSBarry 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);
70916cd7e1dSShri Abhyankar         } else {
710ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
71116cd7e1dSShri Abhyankar         }
71216cd7e1dSShri Abhyankar #else
713ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
71416cd7e1dSShri Abhyankar #endif
71516cd7e1dSShri Abhyankar 
71616cd7e1dSShri Abhyankar         /* U part */
71716cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
71816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
71916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
720ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
722ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72316cd7e1dSShri Abhyankar           } else {
724ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
72516cd7e1dSShri Abhyankar           }
72616cd7e1dSShri Abhyankar #else
727ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
72816cd7e1dSShri Abhyankar #endif
72916cd7e1dSShri Abhyankar         }
73016cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
73116cd7e1dSShri Abhyankar       }
73216cd7e1dSShri Abhyankar     } else {
73317ab2063SBarry Smith       for (i=0; i<m; i++) {
73477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
735416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
736aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73736db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
738ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73936db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
740ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7413a40ed3dSBarry Smith           } else {
742ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
74317ab2063SBarry Smith           }
74417ab2063SBarry Smith #else
745ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
74617ab2063SBarry Smith #endif
74717ab2063SBarry Smith         }
748b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74917ab2063SBarry Smith       }
75016cd7e1dSShri Abhyankar     }
751d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
75217ab2063SBarry Smith   }
753b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7543a40ed3dSBarry Smith   PetscFunctionReturn(0);
755416022c9SBarry Smith }
756416022c9SBarry Smith 
7579804daf3SBarry Smith #include <petscdraw.h>
7584a2ae208SSatish Balay #undef __FUNCT__
7594a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
760dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
761416022c9SBarry Smith {
762480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
763416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
764dfbe8321SBarry Smith   PetscErrorCode    ierr;
765d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
76636db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
767b0a32e0cSBarry Smith   PetscViewer       viewer;
768f3ef73ceSBarry Smith   PetscViewerFormat format;
769cddf8d76SBarry Smith 
7703a40ed3dSBarry Smith   PetscFunctionBegin;
771480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
772b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
77319bcc07fSBarry Smith 
774b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
775416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7760513a670SBarry Smith 
777fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7780513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
779b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
780416022c9SBarry Smith     for (i=0; i<m; i++) {
781cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
782bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
783bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
78436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
785b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
786cddf8d76SBarry Smith       }
787cddf8d76SBarry Smith     }
788b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
789cddf8d76SBarry Smith     for (i=0; i<m; i++) {
790cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
791bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
792bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
793cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
794b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
795cddf8d76SBarry Smith       }
796cddf8d76SBarry Smith     }
797b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
798cddf8d76SBarry Smith     for (i=0; i<m; i++) {
799cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
800bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
801bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
80236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
803b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
804416022c9SBarry Smith       }
805416022c9SBarry Smith     }
8060513a670SBarry Smith   } else {
8070513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8080513a670SBarry Smith     /* first determine max of all nonzero values */
80997f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
810b0a32e0cSBarry Smith     PetscDraw popup;
81136db0b34SBarry Smith     PetscReal scale;
8120513a670SBarry Smith 
8130513a670SBarry Smith     for (i=0; i<nz; i++) {
8140513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8150513a670SBarry Smith     }
816b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
817b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8182205254eSKarl Rupp     if (popup) {
8192205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8202205254eSKarl Rupp     }
8210513a670SBarry Smith     count = 0;
8220513a670SBarry Smith     for (i=0; i<m; i++) {
8230513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
824bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
825bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
82697f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
827b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8280513a670SBarry Smith         count++;
8290513a670SBarry Smith       }
8300513a670SBarry Smith     }
8310513a670SBarry Smith   }
832480ef9eaSBarry Smith   PetscFunctionReturn(0);
833480ef9eaSBarry Smith }
834cddf8d76SBarry Smith 
8359804daf3SBarry Smith #include <petscdraw.h>
8364a2ae208SSatish Balay #undef __FUNCT__
8374a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
838dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
839480ef9eaSBarry Smith {
840dfbe8321SBarry Smith   PetscErrorCode ierr;
841b0a32e0cSBarry Smith   PetscDraw      draw;
84236db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
843ace3abfcSBarry Smith   PetscBool      isnull;
844480ef9eaSBarry Smith 
845480ef9eaSBarry Smith   PetscFunctionBegin;
846b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
847b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
848480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
849480ef9eaSBarry Smith 
850480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
851d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
852480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
853b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
854b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8550298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8563a40ed3dSBarry Smith   PetscFunctionReturn(0);
857416022c9SBarry Smith }
858416022c9SBarry Smith 
8594a2ae208SSatish Balay #undef __FUNCT__
8604a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
861dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
862416022c9SBarry Smith {
863dfbe8321SBarry Smith   PetscErrorCode ierr;
864ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
865416022c9SBarry Smith 
8663a40ed3dSBarry Smith   PetscFunctionBegin;
867251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
868251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
869251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
870c45a1595SBarry Smith   if (iascii) {
8713a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8720f5bd95cSBarry Smith   } else if (isbinary) {
8733a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8740f5bd95cSBarry Smith   } else if (isdraw) {
8753a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
87611aeaf0aSBarry Smith   }
8774108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8783a40ed3dSBarry Smith   PetscFunctionReturn(0);
87917ab2063SBarry Smith }
88019bcc07fSBarry Smith 
8814a2ae208SSatish Balay #undef __FUNCT__
8824a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
883dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
88417ab2063SBarry Smith {
885416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8866849ba73SBarry Smith   PetscErrorCode ierr;
88797f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
888d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
88954f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
8903447b6efSHong Zhang   PetscReal      ratio  = 0.6;
89117ab2063SBarry Smith 
8923a40ed3dSBarry Smith   PetscFunctionBegin;
8933a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
89417ab2063SBarry Smith 
89543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
89617ab2063SBarry Smith   for (i=1; i<m; i++) {
897416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
89817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
89994a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
90017ab2063SBarry Smith     if (fshift) {
901bfeeae90SHong Zhang       ip = aj + ai[i];
902bfeeae90SHong Zhang       ap = aa + ai[i];
90317ab2063SBarry Smith       N  = ailen[i];
90417ab2063SBarry Smith       for (j=0; j<N; j++) {
90517ab2063SBarry Smith         ip[j-fshift] = ip[j];
90617ab2063SBarry Smith         ap[j-fshift] = ap[j];
90717ab2063SBarry Smith       }
90817ab2063SBarry Smith     }
90917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
91017ab2063SBarry Smith   }
91117ab2063SBarry Smith   if (m) {
91217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
91317ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
91417ab2063SBarry Smith   }
91517ab2063SBarry Smith   /* reset ilen and imax for each row */
91617ab2063SBarry Smith   for (i=0; i<m; i++) {
91717ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
91817ab2063SBarry Smith   }
919bfeeae90SHong Zhang   a->nz = ai[m];
92065e19b50SBarry 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);
92117ab2063SBarry Smith 
92209f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
923d0f46423SBarry 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);
924ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
925ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9262205254eSKarl Rupp 
9278e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
928dd5f02e7SSatish Balay   a->reallocs         = 0;
9294e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
93036db0b34SBarry Smith   a->rmax             = rmax;
9314e220ebcSLois Curfman McInnes 
932cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9332205254eSKarl Rupp 
93488e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
93571c2f376SKris Buschelman 
9364108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
93771f1c65dSBarry Smith 
938acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9393a40ed3dSBarry Smith   PetscFunctionReturn(0);
94017ab2063SBarry Smith }
94117ab2063SBarry Smith 
9424a2ae208SSatish Balay #undef __FUNCT__
94399cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
94499cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
94599cafbc1SBarry Smith {
94699cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
94799cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
94854f21887SBarry Smith   MatScalar      *aa = a->a;
949acf2f550SJed Brown   PetscErrorCode ierr;
95099cafbc1SBarry Smith 
95199cafbc1SBarry Smith   PetscFunctionBegin;
95299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
953acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
95499cafbc1SBarry Smith   PetscFunctionReturn(0);
95599cafbc1SBarry Smith }
95699cafbc1SBarry Smith 
95799cafbc1SBarry Smith #undef __FUNCT__
95899cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
95999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
96099cafbc1SBarry Smith {
96199cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96299cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
96354f21887SBarry Smith   MatScalar      *aa = a->a;
964acf2f550SJed Brown   PetscErrorCode ierr;
96599cafbc1SBarry Smith 
96699cafbc1SBarry Smith   PetscFunctionBegin;
96799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
968acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
96999cafbc1SBarry Smith   PetscFunctionReturn(0);
97099cafbc1SBarry Smith }
97199cafbc1SBarry Smith 
97278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
97378b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
97478b84d54SShri Abhyankar {
97578b84d54SShri Abhyankar   PetscErrorCode ierr;
97678b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
97778b84d54SShri Abhyankar   PetscInt       n,start,end;
97878b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
97978b84d54SShri Abhyankar 
98078b84d54SShri Abhyankar   start = trstarts[thread_id];
98178b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
98219baf141SJed Brown   n     = a->i[end] - a->i[start];
98319baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
98478b84d54SShri Abhyankar   return 0;
98578b84d54SShri Abhyankar }
98678b84d54SShri Abhyankar 
98778b84d54SShri Abhyankar #undef __FUNCT__
98878b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
98978b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
99078b84d54SShri Abhyankar {
99178b84d54SShri Abhyankar   PetscErrorCode ierr;
99278b84d54SShri Abhyankar 
99378b84d54SShri Abhyankar   PetscFunctionBegin;
994ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
995acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99678b84d54SShri Abhyankar   PetscFunctionReturn(0);
99778b84d54SShri Abhyankar }
99878b84d54SShri Abhyankar #else
99999cafbc1SBarry Smith #undef __FUNCT__
10004a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1001dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
100217ab2063SBarry Smith {
1003416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1004dfbe8321SBarry Smith   PetscErrorCode ierr;
10053a40ed3dSBarry Smith 
10063a40ed3dSBarry Smith   PetscFunctionBegin;
1007d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1008acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10093a40ed3dSBarry Smith   PetscFunctionReturn(0);
101017ab2063SBarry Smith }
101178b84d54SShri Abhyankar #endif
1012416022c9SBarry Smith 
10134a2ae208SSatish Balay #undef __FUNCT__
10144a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1015dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
101617ab2063SBarry Smith {
1017416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1018dfbe8321SBarry Smith   PetscErrorCode ierr;
1019d5d45c9bSBarry Smith 
10203a40ed3dSBarry Smith   PetscFunctionBegin;
1021aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1022d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
102317ab2063SBarry Smith #endif
1024e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10256bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10266bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
102705b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1028d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
102905b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
103071f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
103105b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10326bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
103305b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10346bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
103505b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10366bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1037cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10380b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1039a30b2313SHong Zhang 
10404108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1041bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1042901853e0SKris Buschelman 
1043dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10543a40ed3dSBarry Smith   PetscFunctionReturn(0);
105517ab2063SBarry Smith }
105617ab2063SBarry Smith 
10574a2ae208SSatish Balay #undef __FUNCT__
10584a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1059ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
106017ab2063SBarry Smith {
1061416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10624846f1f5SKris Buschelman   PetscErrorCode ierr;
10633a40ed3dSBarry Smith 
10643a40ed3dSBarry Smith   PetscFunctionBegin;
1065a65d3064SKris Buschelman   switch (op) {
1066a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10674e0d8c25SBarry Smith     a->roworiented = flg;
1068a65d3064SKris Buschelman     break;
1069a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1070a9817697SBarry Smith     a->keepnonzeropattern = flg;
1071a65d3064SKris Buschelman     break;
1072512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1073512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1074a65d3064SKris Buschelman     break;
1075a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10764e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1077a65d3064SKris Buschelman     break;
1078a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10794e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1080a65d3064SKris Buschelman     break;
108128b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
108228b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
108328b2fa4aSMatthew Knepley     break;
1084a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10854e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10860df259c2SBarry Smith     break;
1087cd6b891eSBarry Smith   case MAT_CHECK_COMPRESSED_ROW:
1088cd6b891eSBarry Smith     a->compressedrow.check = flg;
1089d487561eSHong Zhang     break;
10903d472b54SHong Zhang   case MAT_SPD:
1091b1646e73SJed Brown   case MAT_SYMMETRIC:
1092b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1093b1646e73SJed Brown   case MAT_HERMITIAN:
1094b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
10955021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
10965021d80fSJed Brown     break;
10974e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1098a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1099a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1100290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1101a65d3064SKris Buschelman     break;
1102b87ac2d8SJed Brown   case MAT_USE_INODES:
1103b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1104b87ac2d8SJed Brown     break;
1105a65d3064SKris Buschelman   default:
1106e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1107a65d3064SKris Buschelman   }
11084108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11093a40ed3dSBarry Smith   PetscFunctionReturn(0);
111017ab2063SBarry Smith }
111117ab2063SBarry Smith 
11124a2ae208SSatish Balay #undef __FUNCT__
11134a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1114dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
111517ab2063SBarry Smith {
1116416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11176849ba73SBarry Smith   PetscErrorCode ierr;
1118d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
111935e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
112017ab2063SBarry Smith 
11213a40ed3dSBarry Smith   PetscFunctionBegin;
1122d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1123e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
112435e7444dSHong Zhang 
1125d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1126d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
112735e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11282c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
112935e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
113035e7444dSHong Zhang     PetscFunctionReturn(0);
113135e7444dSHong Zhang   }
113235e7444dSHong Zhang 
11332dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11341ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
113535e7444dSHong Zhang   for (i=0; i<n; i++) {
113635e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11372f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
113835e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
113935e7444dSHong Zhang       if (aj[j] == i) {
114035e7444dSHong Zhang         x[i] = aa[j];
114117ab2063SBarry Smith         break;
114217ab2063SBarry Smith       }
114317ab2063SBarry Smith     }
114417ab2063SBarry Smith   }
11451ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11463a40ed3dSBarry Smith   PetscFunctionReturn(0);
114717ab2063SBarry Smith }
114817ab2063SBarry Smith 
1149c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11504a2ae208SSatish Balay #undef __FUNCT__
11514a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1152dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
115317ab2063SBarry Smith {
1154416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11555c897100SBarry Smith   PetscScalar    *x,*y;
1156dfbe8321SBarry Smith   PetscErrorCode ierr;
1157d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11585c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1159a77337e4SBarry Smith   MatScalar         *v;
1160a77337e4SBarry Smith   PetscScalar       alpha;
11610298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11623447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1163ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11645c897100SBarry Smith #endif
116517ab2063SBarry Smith 
11663a40ed3dSBarry Smith   PetscFunctionBegin;
11672e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11681ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11691ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11705c897100SBarry Smith 
11715c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1172bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11735c897100SBarry Smith #else
11743447b6efSHong Zhang   if (usecprow) {
11753447b6efSHong Zhang     m    = cprow.nrows;
11763447b6efSHong Zhang     ii   = cprow.i;
11777b2bb3b9SHong Zhang     ridx = cprow.rindex;
11783447b6efSHong Zhang   } else {
11793447b6efSHong Zhang     ii = a->i;
11803447b6efSHong Zhang   }
118117ab2063SBarry Smith   for (i=0; i<m; i++) {
11823447b6efSHong Zhang     idx = a->j + ii[i];
11833447b6efSHong Zhang     v   = a->a + ii[i];
11843447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11853447b6efSHong Zhang     if (usecprow) {
11867b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11873447b6efSHong Zhang     } else {
118817ab2063SBarry Smith       alpha = x[i];
11893447b6efSHong Zhang     }
119004fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
119117ab2063SBarry Smith   }
11925c897100SBarry Smith #endif
1193dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11941ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11951ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11963a40ed3dSBarry Smith   PetscFunctionReturn(0);
119717ab2063SBarry Smith }
119817ab2063SBarry Smith 
11994a2ae208SSatish Balay #undef __FUNCT__
12005c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1201dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12025c897100SBarry Smith {
1203dfbe8321SBarry Smith   PetscErrorCode ierr;
12045c897100SBarry Smith 
12055c897100SBarry Smith   PetscFunctionBegin;
1206170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12075c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12085c897100SBarry Smith   PetscFunctionReturn(0);
12095c897100SBarry Smith }
12105c897100SBarry Smith 
1211c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
121278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
121378b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
121478b84d54SShri Abhyankar {
121578b84d54SShri Abhyankar   PetscErrorCode    ierr;
121678b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
121778b84d54SShri Abhyankar   PetscScalar       *y;
121878b84d54SShri Abhyankar   const PetscScalar *x;
121978b84d54SShri Abhyankar   const MatScalar   *aa;
122078b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
122178b84d54SShri Abhyankar   PetscInt          n,start,end,i;
122278b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
122378b84d54SShri Abhyankar   PetscScalar       sum;
122478b84d54SShri Abhyankar 
122578b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
122678b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
122778b84d54SShri Abhyankar   start = trstarts[thread_id];
122878b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
122978b84d54SShri Abhyankar   aj    = a->j;
123078b84d54SShri Abhyankar   aa    = a->a;
123178b84d54SShri Abhyankar   ai    = a->i;
123278b84d54SShri Abhyankar   for (i=start; i<end; i++) {
123378b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
123478b84d54SShri Abhyankar     aj  = a->j + ai[i];
123578b84d54SShri Abhyankar     aa  = a->a + ai[i];
123678b84d54SShri Abhyankar     sum = 0.0;
123778b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
123878b84d54SShri Abhyankar     y[i] = sum;
123978b84d54SShri Abhyankar   }
124078b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
124178b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
124278b84d54SShri Abhyankar   return 0;
124378b84d54SShri Abhyankar }
124478b84d54SShri Abhyankar 
124578b84d54SShri Abhyankar #undef __FUNCT__
124678b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
124778b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
124878b84d54SShri Abhyankar {
124978b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
125078b84d54SShri Abhyankar   PetscScalar       *y;
125178b84d54SShri Abhyankar   const PetscScalar *x;
125278b84d54SShri Abhyankar   const MatScalar   *aa;
125378b84d54SShri Abhyankar   PetscErrorCode    ierr;
125478b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12550298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
125678b84d54SShri Abhyankar   PetscInt          n,i,nonzerorow=0;
125778b84d54SShri Abhyankar   PetscScalar       sum;
125878b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
125978b84d54SShri Abhyankar 
126078b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
126178b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
126278b84d54SShri Abhyankar #endif
126378b84d54SShri Abhyankar 
126478b84d54SShri Abhyankar   PetscFunctionBegin;
126578b84d54SShri Abhyankar   aj = a->j;
126678b84d54SShri Abhyankar   aa = a->a;
126778b84d54SShri Abhyankar   ii = a->i;
126878b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
126978b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
127078b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
127178b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
127278b84d54SShri Abhyankar     ii   = a->compressedrow.i;
127378b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
127478b84d54SShri Abhyankar     for (i=0; i<m; i++) {
127578b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
127678b84d54SShri Abhyankar       aj          = a->j + ii[i];
127778b84d54SShri Abhyankar       aa          = a->a + ii[i];
127878b84d54SShri Abhyankar       sum         = 0.0;
127978b84d54SShri Abhyankar       nonzerorow += (n>0);
128078b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128178b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
128278b84d54SShri Abhyankar       y[*ridx++] = sum;
128378b84d54SShri Abhyankar     }
128478b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
128578b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
128678b84d54SShri Abhyankar   } else { /* do not use compressed row format */
128778b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
128878b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
128978b84d54SShri Abhyankar #else
1290ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
129178b84d54SShri Abhyankar #endif
129278b84d54SShri Abhyankar   }
129378b84d54SShri Abhyankar   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
129478b84d54SShri Abhyankar   PetscFunctionReturn(0);
129578b84d54SShri Abhyankar }
129678b84d54SShri Abhyankar #else
12975c897100SBarry Smith #undef __FUNCT__
12984a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1299dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
130017ab2063SBarry Smith {
1301416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1302d9fead3dSBarry Smith   PetscScalar       *y;
130354f21887SBarry Smith   const PetscScalar *x;
130454f21887SBarry Smith   const MatScalar   *aa;
1305dfbe8321SBarry Smith   PetscErrorCode    ierr;
1306003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13070298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13088aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1309362ced78SSatish Balay   PetscScalar       sum;
1310ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
131117ab2063SBarry Smith 
1312b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
131397952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1314fee21e36SBarry Smith #endif
1315fee21e36SBarry Smith 
13163a40ed3dSBarry Smith   PetscFunctionBegin;
13173649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13181ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
131997952fefSHong Zhang   aj   = a->j;
132097952fefSHong Zhang   aa   = a->a;
1321416022c9SBarry Smith   ii   = a->i;
13224eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
132397952fefSHong Zhang     m    = a->compressedrow.nrows;
132497952fefSHong Zhang     ii   = a->compressedrow.i;
132597952fefSHong Zhang     ridx = a->compressedrow.rindex;
132697952fefSHong Zhang     for (i=0; i<m; i++) {
132797952fefSHong Zhang       n           = ii[i+1] - ii[i];
132897952fefSHong Zhang       aj          = a->j + ii[i];
132997952fefSHong Zhang       aa          = a->a + ii[i];
133097952fefSHong Zhang       sum         = 0.0;
1331a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1332003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1333003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
133497952fefSHong Zhang       y[*ridx++] = sum;
133597952fefSHong Zhang     }
133697952fefSHong Zhang   } else { /* do not use compressed row format */
1337b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1338b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1339b05257ddSBarry Smith #else
134078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1341ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
134278b84d54SShri Abhyankar #else
134317ab2063SBarry Smith     for (i=0; i<m; i++) {
1344003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1345003131ecSBarry Smith       aj          = a->j + ii[i];
1346003131ecSBarry Smith       aa          = a->a + ii[i];
134717ab2063SBarry Smith       sum         = 0.0;
1348a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1349003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
135017ab2063SBarry Smith       y[i] = sum;
135117ab2063SBarry Smith     }
13528d195f9aSBarry Smith #endif
135378b84d54SShri Abhyankar #endif
1354b05257ddSBarry Smith   }
1355dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
13563649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13571ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13583a40ed3dSBarry Smith   PetscFunctionReturn(0);
135917ab2063SBarry Smith }
136078b84d54SShri Abhyankar #endif
136117ab2063SBarry Smith 
1362b434eb95SMatthew G. Knepley #undef __FUNCT__
1363b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1364b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1365b434eb95SMatthew G. Knepley {
1366b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1367b434eb95SMatthew G. Knepley   PetscScalar       *y;
1368b434eb95SMatthew G. Knepley   const PetscScalar *x;
1369b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1370b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1371b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1372b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1373b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1374b434eb95SMatthew G. Knepley   PetscScalar       sum;
1375b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1376b434eb95SMatthew G. Knepley 
1377b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1378b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1379b434eb95SMatthew G. Knepley #endif
1380b434eb95SMatthew G. Knepley 
1381b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1382b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1383b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1384b434eb95SMatthew G. Knepley   aj   = a->j;
1385b434eb95SMatthew G. Knepley   aa   = a->a;
1386b434eb95SMatthew G. Knepley   ii   = a->i;
1387b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1388b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1389b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1390b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1391b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1392b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1393b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1394b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1395b434eb95SMatthew G. Knepley       sum         = 0.0;
1396b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1397b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1398b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1399b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1400b434eb95SMatthew G. Knepley     }
1401b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1402b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1403b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1404b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1405b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1406b434eb95SMatthew G. Knepley       sum         = 0.0;
1407b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1408b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1409b434eb95SMatthew G. Knepley       y[i] = sum;
1410b434eb95SMatthew G. Knepley     }
1411b434eb95SMatthew G. Knepley   }
1412b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1413b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1414b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1415b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1416b434eb95SMatthew G. Knepley }
1417b434eb95SMatthew G. Knepley 
1418b434eb95SMatthew G. Knepley #undef __FUNCT__
1419b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1420b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1421b434eb95SMatthew G. Knepley {
1422b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1423b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1424b434eb95SMatthew G. Knepley   const PetscScalar *x;
1425b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1426b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1427b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1428b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1429b434eb95SMatthew G. Knepley   PetscScalar       sum;
1430b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1431b434eb95SMatthew G. Knepley 
1432b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1433b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1434b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1435b434eb95SMatthew G. Knepley   if (zz != yy) {
1436b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1437b434eb95SMatthew G. Knepley   } else {
1438b434eb95SMatthew G. Knepley     z = y;
1439b434eb95SMatthew G. Knepley   }
1440b434eb95SMatthew G. Knepley 
1441b434eb95SMatthew G. Knepley   aj = a->j;
1442b434eb95SMatthew G. Knepley   aa = a->a;
1443b434eb95SMatthew G. Knepley   ii = a->i;
1444b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1445b434eb95SMatthew G. Knepley     if (zz != yy) {
1446b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1447b434eb95SMatthew G. Knepley     }
1448b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1449b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1450b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1451b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1452b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1453b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1454b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1455b434eb95SMatthew G. Knepley       sum = y[*ridx];
1456b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1457b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1458b434eb95SMatthew G. Knepley     }
1459b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1460b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1461b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1462b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1463b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1464b434eb95SMatthew G. Knepley       sum = y[i];
1465b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1466b434eb95SMatthew G. Knepley       z[i] = sum;
1467b434eb95SMatthew G. Knepley     }
1468b434eb95SMatthew G. Knepley   }
1469b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1470b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1471b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1472b434eb95SMatthew G. Knepley   if (zz != yy) {
1473b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1474b434eb95SMatthew G. Knepley   }
1475b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1476b434eb95SMatthew G. Knepley }
1477b434eb95SMatthew G. Knepley 
1478c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14794a2ae208SSatish Balay #undef __FUNCT__
14804a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1481dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
148217ab2063SBarry Smith {
1483416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1484f15663dcSBarry Smith   PetscScalar       *y,*z;
1485f15663dcSBarry Smith   const PetscScalar *x;
148654f21887SBarry Smith   const MatScalar   *aa;
1487dfbe8321SBarry Smith   PetscErrorCode    ierr;
1488d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14890298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1490362ced78SSatish Balay   PetscScalar       sum;
1491ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14929ea0dfa2SSatish Balay 
14933a40ed3dSBarry Smith   PetscFunctionBegin;
1494f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14951ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14962e8a6d31SBarry Smith   if (zz != yy) {
14971ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14982e8a6d31SBarry Smith   } else {
14992e8a6d31SBarry Smith     z = y;
15002e8a6d31SBarry Smith   }
1501bfeeae90SHong Zhang 
150297952fefSHong Zhang   aj = a->j;
150397952fefSHong Zhang   aa = a->a;
1504cddf8d76SBarry Smith   ii = a->i;
15054eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15064eb6d288SHong Zhang     if (zz != yy) {
15074eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15084eb6d288SHong Zhang     }
150997952fefSHong Zhang     m    = a->compressedrow.nrows;
151097952fefSHong Zhang     ii   = a->compressedrow.i;
151197952fefSHong Zhang     ridx = a->compressedrow.rindex;
151297952fefSHong Zhang     for (i=0; i<m; i++) {
151397952fefSHong Zhang       n   = ii[i+1] - ii[i];
151497952fefSHong Zhang       aj  = a->j + ii[i];
151597952fefSHong Zhang       aa  = a->a + ii[i];
151697952fefSHong Zhang       sum = y[*ridx];
1517f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
151897952fefSHong Zhang       z[*ridx++] = sum;
151997952fefSHong Zhang     }
152097952fefSHong Zhang   } else { /* do not use compressed row format */
1521f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1522f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1523f15663dcSBarry Smith #else
152417ab2063SBarry Smith     for (i=0; i<m; i++) {
1525f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1526f15663dcSBarry Smith       aj  = a->j + ii[i];
1527f15663dcSBarry Smith       aa  = a->a + ii[i];
152817ab2063SBarry Smith       sum = y[i];
1529f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153017ab2063SBarry Smith       z[i] = sum;
153117ab2063SBarry Smith     }
153202ab625aSSatish Balay #endif
1533f15663dcSBarry Smith   }
1534dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1535f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15361ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15372e8a6d31SBarry Smith   if (zz != yy) {
15381ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15392e8a6d31SBarry Smith   }
15408154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15416b375ea7SVictor Minden   /*
1542918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1543918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1544918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15456b375ea7SVictor Minden   */
1546918e98c3SVictor Minden #endif
15473a40ed3dSBarry Smith   PetscFunctionReturn(0);
154817ab2063SBarry Smith }
154917ab2063SBarry Smith 
155017ab2063SBarry Smith /*
155117ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
155217ab2063SBarry Smith */
15534a2ae208SSatish Balay #undef __FUNCT__
15544a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1555dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
155617ab2063SBarry Smith {
1557416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15586849ba73SBarry Smith   PetscErrorCode ierr;
1559d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
156017ab2063SBarry Smith 
15613a40ed3dSBarry Smith   PetscFunctionBegin;
156209f38230SBarry Smith   if (!a->diag) {
156309f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
15643bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
156509f38230SBarry Smith   }
1566d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
156709f38230SBarry Smith     a->diag[i] = a->i[i+1];
1568bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1569bfeeae90SHong Zhang       if (a->j[j] == i) {
157009f38230SBarry Smith         a->diag[i] = j;
157117ab2063SBarry Smith         break;
157217ab2063SBarry Smith       }
157317ab2063SBarry Smith     }
157417ab2063SBarry Smith   }
15753a40ed3dSBarry Smith   PetscFunctionReturn(0);
157617ab2063SBarry Smith }
157717ab2063SBarry Smith 
1578be5855fcSBarry Smith /*
1579be5855fcSBarry Smith      Checks for missing diagonals
1580be5855fcSBarry Smith */
15814a2ae208SSatish Balay #undef __FUNCT__
15824a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1583ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1584be5855fcSBarry Smith {
1585be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
158697f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1587be5855fcSBarry Smith 
1588be5855fcSBarry Smith   PetscFunctionBegin;
158909f38230SBarry Smith   *missing = PETSC_FALSE;
1590d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
159109f38230SBarry Smith     *missing = PETSC_TRUE;
159209f38230SBarry Smith     if (d) *d = 0;
1593358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
159409f38230SBarry Smith   } else {
1595f1e2ffcdSBarry Smith     diag = a->diag;
1596d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1597bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
159809f38230SBarry Smith         *missing = PETSC_TRUE;
159909f38230SBarry Smith         if (d) *d = i;
160009f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1601358d2f5dSShri Abhyankar         break;
160209f38230SBarry Smith       }
1603be5855fcSBarry Smith     }
1604be5855fcSBarry Smith   }
1605be5855fcSBarry Smith   PetscFunctionReturn(0);
1606be5855fcSBarry Smith }
1607be5855fcSBarry Smith 
160871f1c65dSBarry Smith #undef __FUNCT__
160971f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16107087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
161171f1c65dSBarry Smith {
161271f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
161371f1c65dSBarry Smith   PetscErrorCode ierr;
1614d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
161554f21887SBarry Smith   MatScalar      *v = a->a;
161654f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
161771f1c65dSBarry Smith 
161871f1c65dSBarry Smith   PetscFunctionBegin;
161971f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
162071f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
162171f1c65dSBarry Smith   diag = a->diag;
162271f1c65dSBarry Smith   if (!a->idiag) {
162371f1c65dSBarry Smith     ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
16243bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
162571f1c65dSBarry Smith     v    = a->a;
162671f1c65dSBarry Smith   }
162771f1c65dSBarry Smith   mdiag = a->mdiag;
162871f1c65dSBarry Smith   idiag = a->idiag;
162971f1c65dSBarry Smith 
1630028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
163171f1c65dSBarry Smith     for (i=0; i<m; i++) {
163271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1633e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
163471f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
163571f1c65dSBarry Smith     }
163671f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
163771f1c65dSBarry Smith   } else {
163871f1c65dSBarry Smith     for (i=0; i<m; i++) {
163971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
164071f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
164171f1c65dSBarry Smith     }
1642dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
164371f1c65dSBarry Smith   }
164471f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
164571f1c65dSBarry Smith   PetscFunctionReturn(0);
164671f1c65dSBarry Smith }
164771f1c65dSBarry Smith 
1648c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16494a2ae208SSatish Balay #undef __FUNCT__
165041f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
165141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
165217ab2063SBarry Smith {
1653416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1654e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1655e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
165654f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1657dfbe8321SBarry Smith   PetscErrorCode    ierr;
1658d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
165997f1f81fSBarry Smith   const PetscInt    *idx,*diag;
166017ab2063SBarry Smith 
16613a40ed3dSBarry Smith   PetscFunctionBegin;
1662b965ef7fSBarry Smith   its = its*lits;
166391723122SBarry Smith 
166471f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
166571f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
166671f1c65dSBarry Smith   a->fshift = fshift;
166771f1c65dSBarry Smith   a->omega  = omega;
1668ed480e8bSBarry Smith 
166971f1c65dSBarry Smith   diag  = a->diag;
167071f1c65dSBarry Smith   t     = a->ssor_work;
1671ed480e8bSBarry Smith   idiag = a->idiag;
167271f1c65dSBarry Smith   mdiag = a->mdiag;
1673ed480e8bSBarry Smith 
16741ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16753649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1676ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
167717ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
167817ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1679ed480e8bSBarry Smith     bs = b;
168017ab2063SBarry Smith     for (i=0; i<m; i++) {
168171f1c65dSBarry Smith       d   = fshift + mdiag[i];
1682416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1683ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1684ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
168517ab2063SBarry Smith       sum = b[i]*d/omega;
1686003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
168717ab2063SBarry Smith       x[i] = sum;
168817ab2063SBarry Smith     }
16891ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16903649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1691efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16923a40ed3dSBarry Smith     PetscFunctionReturn(0);
169317ab2063SBarry Smith   }
1694c783ea89SBarry Smith 
16952205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16962205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
169717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1698887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
169917ab2063SBarry Smith 
170017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
170117ab2063SBarry Smith 
1702887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
170317ab2063SBarry Smith     */
170417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
170517ab2063SBarry Smith 
170617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
170717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1708416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1709ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1710ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
171117ab2063SBarry Smith       sum = b[i];
1712e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1713ed480e8bSBarry Smith       x[i] = sum*idiag[i];
171417ab2063SBarry Smith     }
171517ab2063SBarry Smith 
171617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1717416022c9SBarry Smith     v = a->a;
17182205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
171917ab2063SBarry Smith 
172017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1721ed480e8bSBarry Smith     ts   = t;
1722416022c9SBarry Smith     diag = a->diag;
172317ab2063SBarry Smith     for (i=0; i<m; i++) {
1724416022c9SBarry Smith       n   = diag[i] - a->i[i];
1725ed480e8bSBarry Smith       idx = a->j + a->i[i];
1726ed480e8bSBarry Smith       v   = a->a + a->i[i];
172717ab2063SBarry Smith       sum = t[i];
1728003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1729ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1730733d66baSBarry Smith       /*  x = x + t */
1731733d66baSBarry Smith       x[i] += t[i];
173217ab2063SBarry Smith     }
173317ab2063SBarry Smith 
1734dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17351ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17363649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17373a40ed3dSBarry Smith     PetscFunctionReturn(0);
173817ab2063SBarry Smith   }
173917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
174017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
174117ab2063SBarry Smith       for (i=0; i<m; i++) {
1742416022c9SBarry Smith         n   = diag[i] - a->i[i];
1743ed480e8bSBarry Smith         idx = a->j + a->i[i];
1744ed480e8bSBarry Smith         v   = a->a + a->i[i];
174517ab2063SBarry Smith         sum = b[i];
1746e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17475c99c7daSBarry Smith         t[i] = sum;
1748ed480e8bSBarry Smith         x[i] = sum*idiag[i];
174917ab2063SBarry Smith       }
17505c99c7daSBarry Smith       xb   = t;
1751efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17523a40ed3dSBarry Smith     } else xb = b;
175317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
175417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1755416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1756ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1757ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
175817ab2063SBarry Smith         sum = xb[i];
1759e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17605c99c7daSBarry Smith         if (xb == b) {
1761ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17625c99c7daSBarry Smith         } else {
1763b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
176417ab2063SBarry Smith         }
17655c99c7daSBarry Smith       }
1766b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
176717ab2063SBarry Smith     }
176817ab2063SBarry Smith     its--;
176917ab2063SBarry Smith   }
177017ab2063SBarry Smith   while (its--) {
177117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
177217ab2063SBarry Smith       for (i=0; i<m; i++) {
1773b19a5dc2SMark Adams         /* lower */
1774b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1775ed480e8bSBarry Smith         idx = a->j + a->i[i];
1776ed480e8bSBarry Smith         v   = a->a + a->i[i];
177717ab2063SBarry Smith         sum = b[i];
1778e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1779b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1780b19a5dc2SMark Adams         /* upper */
1781b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1782b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1783b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1784b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1785b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
178617ab2063SBarry Smith       }
1787b19a5dc2SMark Adams       xb   = t;
17889f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1789b19a5dc2SMark Adams     } else xb = b;
179017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
179117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1792b19a5dc2SMark Adams         sum = xb[i];
1793b19a5dc2SMark Adams         if (xb == b) {
1794b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1795416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1796ed480e8bSBarry Smith           idx = a->j + a->i[i];
1797ed480e8bSBarry Smith           v   = a->a + a->i[i];
1798e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1799ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1800b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1801b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1802b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1803b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1804b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1805b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
180617ab2063SBarry Smith         }
1807b19a5dc2SMark Adams       }
1808b19a5dc2SMark Adams       if (xb == b) {
18099f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1810b19a5dc2SMark Adams       } else {
1811b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1812b19a5dc2SMark Adams       }
181317ab2063SBarry Smith     }
181417ab2063SBarry Smith   }
18151ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18163649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1817365a8a9eSBarry Smith   PetscFunctionReturn(0);
181817ab2063SBarry Smith }
181917ab2063SBarry Smith 
18202af78befSBarry Smith 
18214a2ae208SSatish Balay #undef __FUNCT__
18224a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1823dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
182417ab2063SBarry Smith {
1825416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18264e220ebcSLois Curfman McInnes 
18273a40ed3dSBarry Smith   PetscFunctionBegin;
18284e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18294e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18304e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18314e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18324e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18338e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18347adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1835d5f3da31SBarry Smith   if (A->factortype) {
18364e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18374e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18384e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18394e220ebcSLois Curfman McInnes   } else {
18404e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18414e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18424e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18434e220ebcSLois Curfman McInnes   }
18443a40ed3dSBarry Smith   PetscFunctionReturn(0);
184517ab2063SBarry Smith }
184617ab2063SBarry Smith 
18474a2ae208SSatish Balay #undef __FUNCT__
18484a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18492b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
185017ab2063SBarry Smith {
1851416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18523b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18536849ba73SBarry Smith   PetscErrorCode    ierr;
185497b48c8fSBarry Smith   const PetscScalar *xx;
185597b48c8fSBarry Smith   PetscScalar       *bb;
1856ace3abfcSBarry Smith   PetscBool         missing;
185717ab2063SBarry Smith 
18583a40ed3dSBarry Smith   PetscFunctionBegin;
185997b48c8fSBarry Smith   if (x && b) {
186097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
186197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
186297b48c8fSBarry Smith     for (i=0; i<N; i++) {
186397b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
186497b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
186597b48c8fSBarry Smith     }
186697b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
186797b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
186897b48c8fSBarry Smith   }
186997b48c8fSBarry Smith 
1870a9817697SBarry Smith   if (a->keepnonzeropattern) {
1871f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1872e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1873bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1874f1e2ffcdSBarry Smith     }
1875f4df32b1SMatthew Knepley     if (diag != 0.0) {
187609f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1877e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1878f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1879f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1880f1e2ffcdSBarry Smith       }
1881f1e2ffcdSBarry Smith     }
188288e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1883f1e2ffcdSBarry Smith   } else {
1884f4df32b1SMatthew Knepley     if (diag != 0.0) {
188517ab2063SBarry Smith       for (i=0; i<N; i++) {
1886e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18877ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1888416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1889f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1890bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18917ae801bdSBarry Smith         } else { /* in case row was completely empty */
1892f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
189317ab2063SBarry Smith         }
189417ab2063SBarry Smith       }
18953a40ed3dSBarry Smith     } else {
189617ab2063SBarry Smith       for (i=0; i<N; i++) {
1897e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1898416022c9SBarry Smith         a->ilen[rows[i]] = 0;
189917ab2063SBarry Smith       }
190017ab2063SBarry Smith     }
190188e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1902f1e2ffcdSBarry Smith   }
190343a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19043a40ed3dSBarry Smith   PetscFunctionReturn(0);
190517ab2063SBarry Smith }
190617ab2063SBarry Smith 
19074a2ae208SSatish Balay #undef __FUNCT__
19086e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19096e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19106e169961SBarry Smith {
19116e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19126e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19136e169961SBarry Smith   PetscErrorCode    ierr;
19142b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19156e169961SBarry Smith   const PetscScalar *xx;
19166e169961SBarry Smith   PetscScalar       *bb;
19176e169961SBarry Smith 
19186e169961SBarry Smith   PetscFunctionBegin;
19196e169961SBarry Smith   if (x && b) {
19206e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19216e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19222b40b63fSBarry Smith     vecs = PETSC_TRUE;
19236e169961SBarry Smith   }
19246e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
19256e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
19266e169961SBarry Smith   for (i=0; i<N; i++) {
19276e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19286e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19292205254eSKarl Rupp 
19306e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19316e169961SBarry Smith   }
19326e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19336e169961SBarry Smith     if (!zeroed[i]) {
19346e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19356e169961SBarry Smith         if (zeroed[a->j[j]]) {
19362b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19376e169961SBarry Smith           a->a[j] = 0.0;
19386e169961SBarry Smith         }
19396e169961SBarry Smith       }
19402b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19416e169961SBarry Smith   }
19426e169961SBarry Smith   if (x && b) {
19436e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19446e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19456e169961SBarry Smith   }
19466e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19476e169961SBarry Smith   if (diag != 0.0) {
19486e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19496e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19506e169961SBarry Smith     for (i=0; i<N; i++) {
19516e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19526e169961SBarry Smith     }
19536e169961SBarry Smith   }
19546e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19556e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19566e169961SBarry Smith   PetscFunctionReturn(0);
19576e169961SBarry Smith }
19586e169961SBarry Smith 
19596e169961SBarry Smith #undef __FUNCT__
19604a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1961a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
196217ab2063SBarry Smith {
1963416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
196497f1f81fSBarry Smith   PetscInt   *itmp;
196517ab2063SBarry Smith 
19663a40ed3dSBarry Smith   PetscFunctionBegin;
1967e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
196817ab2063SBarry Smith 
1969416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1970bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
197117ab2063SBarry Smith   if (idx) {
1972bfeeae90SHong Zhang     itmp = a->j + a->i[row];
197326fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
197417ab2063SBarry Smith     else *idx = 0;
197517ab2063SBarry Smith   }
19763a40ed3dSBarry Smith   PetscFunctionReturn(0);
197717ab2063SBarry Smith }
197817ab2063SBarry Smith 
1979bfeeae90SHong Zhang /* remove this function? */
19804a2ae208SSatish Balay #undef __FUNCT__
19814a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1982a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
198317ab2063SBarry Smith {
19843a40ed3dSBarry Smith   PetscFunctionBegin;
19853a40ed3dSBarry Smith   PetscFunctionReturn(0);
198617ab2063SBarry Smith }
198717ab2063SBarry Smith 
19884a2ae208SSatish Balay #undef __FUNCT__
19894a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1990dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
199117ab2063SBarry Smith {
1992416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
199354f21887SBarry Smith   MatScalar      *v  = a->a;
199436db0b34SBarry Smith   PetscReal      sum = 0.0;
19956849ba73SBarry Smith   PetscErrorCode ierr;
199697f1f81fSBarry Smith   PetscInt       i,j;
199717ab2063SBarry Smith 
19983a40ed3dSBarry Smith   PetscFunctionBegin;
199917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2000416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
200136db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
200217ab2063SBarry Smith     }
20038f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20043a40ed3dSBarry Smith   } else if (type == NORM_1) {
200536db0b34SBarry Smith     PetscReal *tmp;
200697f1f81fSBarry Smith     PetscInt  *jj = a->j;
2007d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
2008d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
2009064f8208SBarry Smith     *nrm = 0.0;
2010416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2011bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
201217ab2063SBarry Smith     }
2013d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2014064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
201517ab2063SBarry Smith     }
2016606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20173a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2018064f8208SBarry Smith     *nrm = 0.0;
2019d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2020bfeeae90SHong Zhang       v   = a->a + a->i[j];
202117ab2063SBarry Smith       sum = 0.0;
2022416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2023cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
202417ab2063SBarry Smith       }
2025064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
202617ab2063SBarry Smith     }
2027f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20283a40ed3dSBarry Smith   PetscFunctionReturn(0);
202917ab2063SBarry Smith }
203017ab2063SBarry Smith 
20314e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20324e938277SHong Zhang #undef __FUNCT__
20334e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20344e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20354e938277SHong Zhang {
20364e938277SHong Zhang   PetscErrorCode ierr;
20374e938277SHong Zhang   PetscInt       i,j,anzj;
20384e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20394e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20404e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20414e938277SHong Zhang 
20424e938277SHong Zhang   PetscFunctionBegin;
20434e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20444e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
20454e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
20464e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
20474e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
20484e938277SHong Zhang 
20494e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20504e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
205126fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20524e938277SHong Zhang   /* Form ati for csr format of A^T. */
205326fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20544e938277SHong Zhang 
20554e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20564e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20574e938277SHong Zhang 
20584e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20594e938277SHong Zhang   for (i=0;i<am;i++) {
20604e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20614e938277SHong Zhang     for (j=0;j<anzj;j++) {
20624e938277SHong Zhang       atj[atfill[*aj]] = i;
20634e938277SHong Zhang       atfill[*aj++]   += 1;
20644e938277SHong Zhang     }
20654e938277SHong Zhang   }
20664e938277SHong Zhang 
20674e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20684e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2069ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20702205254eSKarl Rupp 
2071a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2072a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2073a2f3521dSMark F. Adams 
20744e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20754e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20764e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20774e938277SHong Zhang   b->nonew   = 0;
20784e938277SHong Zhang   PetscFunctionReturn(0);
20794e938277SHong Zhang }
20804e938277SHong Zhang 
20814a2ae208SSatish Balay #undef __FUNCT__
20824a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2083fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
208417ab2063SBarry Smith {
2085416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2086416022c9SBarry Smith   Mat            C;
20876849ba73SBarry Smith   PetscErrorCode ierr;
2088d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
208954f21887SBarry Smith   MatScalar      *array = a->a;
209017ab2063SBarry Smith 
20913a40ed3dSBarry Smith   PetscFunctionBegin;
2092e32f2f54SBarry 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");
2093fc4dec0aSBarry Smith 
2094fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
2095d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
2096d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
2097bfeeae90SHong Zhang 
2098bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2099ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2100d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2101a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21027adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2103ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2104606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2105a541d17aSBarry Smith   } else {
2106a541d17aSBarry Smith     C = *B;
2107a541d17aSBarry Smith   }
2108a541d17aSBarry Smith 
210917ab2063SBarry Smith   for (i=0; i<m; i++) {
211017ab2063SBarry Smith     len    = ai[i+1]-ai[i];
211187d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2112b9b97703SBarry Smith     array += len;
2113b9b97703SBarry Smith     aj    += len;
211417ab2063SBarry Smith   }
21156d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21166d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
211717ab2063SBarry Smith 
2118815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2119416022c9SBarry Smith     *B = C;
212017ab2063SBarry Smith   } else {
2121eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
212217ab2063SBarry Smith   }
21233a40ed3dSBarry Smith   PetscFunctionReturn(0);
212417ab2063SBarry Smith }
212517ab2063SBarry Smith 
2126cd0d46ebSvictorle #undef __FUNCT__
21275fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21287087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2129cd0d46ebSvictorle {
2130cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
213154f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
213254f21887SBarry Smith   MatScalar      *va,*vb;
21336849ba73SBarry Smith   PetscErrorCode ierr;
213497f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2135cd0d46ebSvictorle 
2136cd0d46ebSvictorle   PetscFunctionBegin;
2137cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2138cd0d46ebSvictorle 
2139cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2140cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21415485867bSBarry Smith   if (ma!=nb || na!=mb) {
21425485867bSBarry Smith     *f = PETSC_FALSE;
21435485867bSBarry Smith     PetscFunctionReturn(0);
21445485867bSBarry Smith   }
2145cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2146cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2147cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
214897f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
214997f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2150cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2151cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2152cd0d46ebSvictorle 
2153cd0d46ebSvictorle   *f = PETSC_TRUE;
2154cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2155cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
215697f1f81fSBarry Smith       PetscInt    idc,idr;
21575485867bSBarry Smith       PetscScalar vc,vr;
2158cd0d46ebSvictorle       /* column/row index/value */
21595485867bSBarry Smith       idc = adx[aptr[i]];
21605485867bSBarry Smith       idr = bdx[bptr[idc]];
21615485867bSBarry Smith       vc  = va[aptr[i]];
21625485867bSBarry Smith       vr  = vb[bptr[idc]];
21635485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21645485867bSBarry Smith         *f = PETSC_FALSE;
21655485867bSBarry Smith         goto done;
2166cd0d46ebSvictorle       } else {
21675485867bSBarry Smith         aptr[i]++;
21685485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2169cd0d46ebSvictorle       }
2170cd0d46ebSvictorle     }
2171cd0d46ebSvictorle   }
2172cd0d46ebSvictorle done:
2173cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21743aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2175cd0d46ebSvictorle   PetscFunctionReturn(0);
2176cd0d46ebSvictorle }
2177cd0d46ebSvictorle 
21781cbb95d3SBarry Smith #undef __FUNCT__
21791cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21807087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21811cbb95d3SBarry Smith {
21821cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
218354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
218454f21887SBarry Smith   MatScalar      *va,*vb;
21851cbb95d3SBarry Smith   PetscErrorCode ierr;
21861cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21871cbb95d3SBarry Smith 
21881cbb95d3SBarry Smith   PetscFunctionBegin;
21891cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21901cbb95d3SBarry Smith 
21911cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21921cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21931cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21941cbb95d3SBarry Smith     *f = PETSC_FALSE;
21951cbb95d3SBarry Smith     PetscFunctionReturn(0);
21961cbb95d3SBarry Smith   }
21971cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
21981cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
21991cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
22001cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
22011cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
22021cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22031cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22041cbb95d3SBarry Smith 
22051cbb95d3SBarry Smith   *f = PETSC_TRUE;
22061cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22071cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22081cbb95d3SBarry Smith       PetscInt    idc,idr;
22091cbb95d3SBarry Smith       PetscScalar vc,vr;
22101cbb95d3SBarry Smith       /* column/row index/value */
22111cbb95d3SBarry Smith       idc = adx[aptr[i]];
22121cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22131cbb95d3SBarry Smith       vc  = va[aptr[i]];
22141cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22151cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22161cbb95d3SBarry Smith         *f = PETSC_FALSE;
22171cbb95d3SBarry Smith         goto done;
22181cbb95d3SBarry Smith       } else {
22191cbb95d3SBarry Smith         aptr[i]++;
22201cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22211cbb95d3SBarry Smith       }
22221cbb95d3SBarry Smith     }
22231cbb95d3SBarry Smith   }
22241cbb95d3SBarry Smith done:
22251cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22261cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22271cbb95d3SBarry Smith   PetscFunctionReturn(0);
22281cbb95d3SBarry Smith }
22291cbb95d3SBarry Smith 
22309e29f15eSvictorle #undef __FUNCT__
22319e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2232ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22339e29f15eSvictorle {
2234dfbe8321SBarry Smith   PetscErrorCode ierr;
22356e111a19SKarl Rupp 
22369e29f15eSvictorle   PetscFunctionBegin;
22375485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22389e29f15eSvictorle   PetscFunctionReturn(0);
22399e29f15eSvictorle }
22409e29f15eSvictorle 
22414a2ae208SSatish Balay #undef __FUNCT__
22421cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2243ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22441cbb95d3SBarry Smith {
22451cbb95d3SBarry Smith   PetscErrorCode ierr;
22466e111a19SKarl Rupp 
22471cbb95d3SBarry Smith   PetscFunctionBegin;
22481cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22491cbb95d3SBarry Smith   PetscFunctionReturn(0);
22501cbb95d3SBarry Smith }
22511cbb95d3SBarry Smith 
22521cbb95d3SBarry Smith #undef __FUNCT__
22534a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2254dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
225517ab2063SBarry Smith {
2256416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
225754f21887SBarry Smith   PetscScalar    *l,*r,x;
225854f21887SBarry Smith   MatScalar      *v;
2259dfbe8321SBarry Smith   PetscErrorCode ierr;
2260d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
226117ab2063SBarry Smith 
22623a40ed3dSBarry Smith   PetscFunctionBegin;
226317ab2063SBarry Smith   if (ll) {
22643ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22653ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2266e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2267e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22681ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2269416022c9SBarry Smith     v    = a->a;
227017ab2063SBarry Smith     for (i=0; i<m; i++) {
227117ab2063SBarry Smith       x = l[i];
2272416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22732205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
227417ab2063SBarry Smith     }
22751ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2276efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
227717ab2063SBarry Smith   }
227817ab2063SBarry Smith   if (rr) {
2279e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2280e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22811ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2282416022c9SBarry Smith     v    = a->a; jj = a->j;
22832205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22841ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2285efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228617ab2063SBarry Smith   }
2287acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22883a40ed3dSBarry Smith   PetscFunctionReturn(0);
228917ab2063SBarry Smith }
229017ab2063SBarry Smith 
22914a2ae208SSatish Balay #undef __FUNCT__
22924a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
229397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
229417ab2063SBarry Smith {
2295db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
22966849ba73SBarry Smith   PetscErrorCode ierr;
2297d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
229897f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
22995d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23005d0c19d7SBarry Smith   PetscInt       nrows,ncols;
230197f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
230254f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2303416022c9SBarry Smith   Mat            C;
2304ace3abfcSBarry Smith   PetscBool      stride,sorted;
230517ab2063SBarry Smith 
23063a40ed3dSBarry Smith   PetscFunctionBegin;
230714ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2308e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
230914ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2310e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
231199141d43SSatish Balay 
231217ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2313b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2314b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
231517ab2063SBarry Smith 
2316fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2317251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2318fee21e36SBarry Smith   if (stride && step == 1) {
231902834360SBarry Smith     /* special case of contiguous rows */
23200e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
232102834360SBarry Smith     /* loop over new rows determining lens and starting points */
232202834360SBarry Smith     for (i=0; i<nrows; i++) {
2323bfeeae90SHong Zhang       kstart = ai[irow[i]];
2324a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
232502834360SBarry Smith       for (k=kstart; k<kend; k++) {
2326bfeeae90SHong Zhang         if (aj[k] >= first) {
232702834360SBarry Smith           starts[i] = k;
232802834360SBarry Smith           break;
232902834360SBarry Smith         }
233002834360SBarry Smith       }
2331a2744918SBarry Smith       sum = 0;
233202834360SBarry Smith       while (k < kend) {
2333bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2334a2744918SBarry Smith         sum++;
233502834360SBarry Smith       }
2336a2744918SBarry Smith       lens[i] = sum;
233702834360SBarry Smith     }
233802834360SBarry Smith     /* create submatrix */
2339cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
234097f1f81fSBarry Smith       PetscInt n_cols,n_rows;
234108480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2342e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2343d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
234408480c60SBarry Smith       C    = *B;
23453a40ed3dSBarry Smith     } else {
23463bef6203SJed Brown       PetscInt rbs,cbs;
2347ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2348f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23493bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23503bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23513bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23527adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2353ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
235408480c60SBarry Smith     }
2355db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2356db02288aSLois Curfman McInnes 
235702834360SBarry Smith     /* loop over rows inserting into submatrix */
2358db02288aSLois Curfman McInnes     a_new = c->a;
2359db02288aSLois Curfman McInnes     j_new = c->j;
2360db02288aSLois Curfman McInnes     i_new = c->i;
2361bfeeae90SHong Zhang 
236202834360SBarry Smith     for (i=0; i<nrows; i++) {
2363a2744918SBarry Smith       ii    = starts[i];
2364a2744918SBarry Smith       lensi = lens[i];
2365a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2366a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
236702834360SBarry Smith       }
236887828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2369a2744918SBarry Smith       a_new     += lensi;
2370a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2371a2744918SBarry Smith       c->ilen[i] = lensi;
237202834360SBarry Smith     }
23730e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23743a40ed3dSBarry Smith   } else {
237502834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23760e83c824SBarry Smith     ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
237797f1f81fSBarry Smith     ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
23780e83c824SBarry Smith     ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
23794dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23804dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23814dcab191SBarry 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);
23824dcab191SBarry Smith #endif
23834dcab191SBarry Smith       smap[icol[i]] = i+1;
23844dcab191SBarry Smith     }
23854dcab191SBarry Smith 
238602834360SBarry Smith     /* determine lens of each row */
238702834360SBarry Smith     for (i=0; i<nrows; i++) {
2388bfeeae90SHong Zhang       kstart  = ai[irow[i]];
238902834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
239002834360SBarry Smith       lens[i] = 0;
239102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2392bfeeae90SHong Zhang         if (smap[aj[k]]) {
239302834360SBarry Smith           lens[i]++;
239402834360SBarry Smith         }
239502834360SBarry Smith       }
239602834360SBarry Smith     }
239717ab2063SBarry Smith     /* Create and fill new matrix */
2398a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2399ace3abfcSBarry Smith       PetscBool equal;
24000f5bd95cSBarry Smith 
240199141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2402e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2403d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2404f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2405d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
240608480c60SBarry Smith       C    = *B;
24073a40ed3dSBarry Smith     } else {
24083bef6203SJed Brown       PetscInt rbs,cbs;
2409ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2410f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24113bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24123bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24133bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24147adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2415ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
241608480c60SBarry Smith     }
241799141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
241817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
241999141d43SSatish Balay       row      = irow[i];
2420bfeeae90SHong Zhang       kstart   = ai[row];
242199141d43SSatish Balay       kend     = kstart + a->ilen[row];
2422bfeeae90SHong Zhang       mat_i    = c->i[i];
242399141d43SSatish Balay       mat_j    = c->j + mat_i;
242499141d43SSatish Balay       mat_a    = c->a + mat_i;
242599141d43SSatish Balay       mat_ilen = c->ilen + i;
242617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2427bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2428ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
242999141d43SSatish Balay           *mat_a++ = a->a[k];
243099141d43SSatish Balay           (*mat_ilen)++;
243199141d43SSatish Balay 
243217ab2063SBarry Smith         }
243317ab2063SBarry Smith       }
243417ab2063SBarry Smith     }
243502834360SBarry Smith     /* Free work space */
243602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2437606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2438606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
243902834360SBarry Smith   }
24406d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24416d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244217ab2063SBarry Smith 
244317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2444416022c9SBarry Smith   *B   = C;
24453a40ed3dSBarry Smith   PetscFunctionReturn(0);
244617ab2063SBarry Smith }
244717ab2063SBarry Smith 
24481df811f5SHong Zhang #undef __FUNCT__
244982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2450fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
245182d44351SHong Zhang {
245282d44351SHong Zhang   PetscErrorCode ierr;
245382d44351SHong Zhang   Mat            B;
245482d44351SHong Zhang 
245582d44351SHong Zhang   PetscFunctionBegin;
2456c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
245782d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
245882d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2459a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
246082d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
246182d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
246282d44351SHong Zhang     *subMat = B;
2463c2d650bdSHong Zhang   } else {
2464c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2465c2d650bdSHong Zhang   }
246682d44351SHong Zhang   PetscFunctionReturn(0);
246782d44351SHong Zhang }
246882d44351SHong Zhang 
246982d44351SHong Zhang #undef __FUNCT__
24704a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24710481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2472a871dcd8SBarry Smith {
247363b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2474dfbe8321SBarry Smith   PetscErrorCode ierr;
247563b91edcSBarry Smith   Mat            outA;
2476ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
247763b91edcSBarry Smith 
24783a40ed3dSBarry Smith   PetscFunctionBegin;
2479e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24801df811f5SHong Zhang 
2481b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2482b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2483a871dcd8SBarry Smith 
248463b91edcSBarry Smith   outA             = inA;
2485d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24862205254eSKarl Rupp 
2487c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24886bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24892205254eSKarl Rupp 
2490c3122656SLisandro Dalcin   a->row = row;
24912205254eSKarl Rupp 
2492c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24936bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24942205254eSKarl Rupp 
2495c3122656SLisandro Dalcin   a->col = col;
249663b91edcSBarry Smith 
249736db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
24986bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
24994c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25003bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2501f0ec6fceSSatish Balay 
250294a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2503d0f46423SBarry Smith     ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
25043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
250594a9d846SBarry Smith   }
250663b91edcSBarry Smith 
2507f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2508137fb511SHong Zhang   if (row_identity && col_identity) {
2509ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2510137fb511SHong Zhang   } else {
2511719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2512137fb511SHong Zhang   }
25133a40ed3dSBarry Smith   PetscFunctionReturn(0);
2514a871dcd8SBarry Smith }
2515a871dcd8SBarry Smith 
25164a2ae208SSatish Balay #undef __FUNCT__
25174a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2518f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2519f0b747eeSBarry Smith {
2520f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2521f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2522efee365bSSatish Balay   PetscErrorCode ierr;
2523c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25243a40ed3dSBarry Smith 
25253a40ed3dSBarry Smith   PetscFunctionBegin;
2526c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25278b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2528efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2529acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25303a40ed3dSBarry Smith   PetscFunctionReturn(0);
2531f0b747eeSBarry Smith }
2532f0b747eeSBarry Smith 
25334a2ae208SSatish Balay #undef __FUNCT__
25344a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
253597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2536cddf8d76SBarry Smith {
2537dfbe8321SBarry Smith   PetscErrorCode ierr;
253897f1f81fSBarry Smith   PetscInt       i;
2539cddf8d76SBarry Smith 
25403a40ed3dSBarry Smith   PetscFunctionBegin;
2541cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2542b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2543cddf8d76SBarry Smith   }
2544cddf8d76SBarry Smith 
2545cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25466a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2547cddf8d76SBarry Smith   }
25483a40ed3dSBarry Smith   PetscFunctionReturn(0);
2549cddf8d76SBarry Smith }
2550cddf8d76SBarry Smith 
25514a2ae208SSatish Balay #undef __FUNCT__
25524a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
255397f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25544dcbc457SBarry Smith {
2555e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25566849ba73SBarry Smith   PetscErrorCode ierr;
25575d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25585d0c19d7SBarry Smith   const PetscInt *idx;
255997f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2560f1af5d2fSBarry Smith   PetscBT        table;
2561bbd702dbSSatish Balay 
25623a40ed3dSBarry Smith   PetscFunctionBegin;
2563d0f46423SBarry Smith   m  = A->rmap->n;
2564e4d965acSSatish Balay   ai = a->i;
2565bfeeae90SHong Zhang   aj = a->j;
25668a047759SSatish Balay 
2567e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
256806763907SSatish Balay 
256997f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
257053b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
257106763907SSatish Balay 
2572e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2573b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2574e4d965acSSatish Balay     isz  = 0;
25756831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2576e4d965acSSatish Balay 
2577e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25784dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2579b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2580e4d965acSSatish Balay 
2581dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2582e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25832205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25844dcbc457SBarry Smith     }
258506763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25866bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2587e4d965acSSatish Balay 
258804a348a9SBarry Smith     k = 0;
258904a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
259004a348a9SBarry Smith       n = isz;
259106763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2592e4d965acSSatish Balay         row   = nidx[k];
2593e4d965acSSatish Balay         start = ai[row];
2594e4d965acSSatish Balay         end   = ai[row+1];
259504a348a9SBarry Smith         for (l = start; l<end; l++) {
2596efb16452SHong Zhang           val = aj[l];
25972205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2598e4d965acSSatish Balay         }
2599e4d965acSSatish Balay       }
2600e4d965acSSatish Balay     }
260170b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2602e4d965acSSatish Balay   }
260394bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2604606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26053a40ed3dSBarry Smith   PetscFunctionReturn(0);
26064dcbc457SBarry Smith }
260717ab2063SBarry Smith 
26080513a670SBarry Smith /* -------------------------------------------------------------- */
26094a2ae208SSatish Balay #undef __FUNCT__
26104a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2611dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26120513a670SBarry Smith {
26130513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26146849ba73SBarry Smith   PetscErrorCode ierr;
26153b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26165d0c19d7SBarry Smith   const PetscInt *row,*col;
26175d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
261856cd22aeSBarry Smith   IS             icolp,irowp;
26190298fd71SBarry Smith   PetscInt       *cwork = NULL;
26200298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26210513a670SBarry Smith 
26223a40ed3dSBarry Smith   PetscFunctionBegin;
26234c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
262456cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26254c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
262656cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26270513a670SBarry Smith 
26280513a670SBarry Smith   /* determine lengths of permuted rows */
262997f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
26302205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2631ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2632f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2633a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26347adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2635ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2636606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26370513a670SBarry Smith 
263897f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
26390513a670SBarry Smith   for (i=0; i<m; i++) {
264032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26412205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2642cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
264332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26440513a670SBarry Smith   }
2645606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26462205254eSKarl Rupp 
26473c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26482205254eSKarl Rupp 
26490513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26500513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
265156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
265256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26536bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26546bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26553a40ed3dSBarry Smith   PetscFunctionReturn(0);
26560513a670SBarry Smith }
26570513a670SBarry Smith 
26584a2ae208SSatish Balay #undef __FUNCT__
26594a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2660dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2661cb5b572fSBarry Smith {
2662dfbe8321SBarry Smith   PetscErrorCode ierr;
2663cb5b572fSBarry Smith 
2664cb5b572fSBarry Smith   PetscFunctionBegin;
266533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
266633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2667be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2668be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2669be6bf707SBarry Smith 
2670700c5bfcSBarry 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");
2671d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2672cb5b572fSBarry Smith   } else {
2673cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2674cb5b572fSBarry Smith   }
2675cb5b572fSBarry Smith   PetscFunctionReturn(0);
2676cb5b572fSBarry Smith }
2677cb5b572fSBarry Smith 
26784a2ae208SSatish Balay #undef __FUNCT__
26794994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26804994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2681273d9f13SBarry Smith {
2682dfbe8321SBarry Smith   PetscErrorCode ierr;
2683273d9f13SBarry Smith 
2684273d9f13SBarry Smith   PetscFunctionBegin;
2685ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2686273d9f13SBarry Smith   PetscFunctionReturn(0);
2687273d9f13SBarry Smith }
2688273d9f13SBarry Smith 
26894a2ae208SSatish Balay #undef __FUNCT__
26908c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
26918c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26926c0721eeSBarry Smith {
26936c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26946e111a19SKarl Rupp 
26956c0721eeSBarry Smith   PetscFunctionBegin;
26966c0721eeSBarry Smith   *array = a->a;
26976c0721eeSBarry Smith   PetscFunctionReturn(0);
26986c0721eeSBarry Smith }
26996c0721eeSBarry Smith 
27004a2ae208SSatish Balay #undef __FUNCT__
27018c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27028c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27036c0721eeSBarry Smith {
27046c0721eeSBarry Smith   PetscFunctionBegin;
27056c0721eeSBarry Smith   PetscFunctionReturn(0);
27066c0721eeSBarry Smith }
2707273d9f13SBarry Smith 
27088229c054SShri Abhyankar /*
27098229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27108229c054SShri Abhyankar    have different nonzero structure.
27118229c054SShri Abhyankar */
2712ac90fabeSBarry Smith #undef __FUNCT__
27138229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27148229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2715ec7775f6SShri Abhyankar {
27168229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2717ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2718ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2719ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2720ec7775f6SShri Abhyankar 
2721ec7775f6SShri Abhyankar   PetscFunctionBegin;
2722ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2723ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27248af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27258af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27268af7cee1SJed Brown     nnz[i] = 0;
27278af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27288af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27298af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27308af7cee1SJed Brown       nnz[i]++;
27318af7cee1SJed Brown     }
27328af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2733ec7775f6SShri Abhyankar   }
2734ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2735ec7775f6SShri Abhyankar }
2736ec7775f6SShri Abhyankar 
2737ec7775f6SShri Abhyankar #undef __FUNCT__
2738ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2739f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2740ac90fabeSBarry Smith {
2741dfbe8321SBarry Smith   PetscErrorCode ierr;
274297f1f81fSBarry Smith   PetscInt       i;
2743ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2744c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2745ac90fabeSBarry Smith 
2746ac90fabeSBarry Smith   PetscFunctionBegin;
2747c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2748ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2749f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27508b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2751acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2752c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2753a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2754a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27556bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2756a30b2313SHong Zhang     }
2757a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27580298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2759a30b2313SHong Zhang       y->XtoY = X;
2760407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2761c537a176SHong Zhang     }
2762f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2763ba0e910bSBarry 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);
2764ac90fabeSBarry Smith   } else {
27658229c054SShri Abhyankar     Mat      B;
27668229c054SShri Abhyankar     PetscInt *nnz;
276716b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2768ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2769bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27704aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2771a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2772176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27738229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2774ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2775ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2776ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27778229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2778ac90fabeSBarry Smith   }
2779ac90fabeSBarry Smith   PetscFunctionReturn(0);
2780ac90fabeSBarry Smith }
2781ac90fabeSBarry Smith 
2782521d7252SBarry Smith #undef __FUNCT__
2783354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27847087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2785354c94deSBarry Smith {
2786354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2787354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2788354c94deSBarry Smith   PetscInt    i,nz;
2789354c94deSBarry Smith   PetscScalar *a;
2790354c94deSBarry Smith 
2791354c94deSBarry Smith   PetscFunctionBegin;
2792354c94deSBarry Smith   nz = aij->nz;
2793354c94deSBarry Smith   a  = aij->a;
27942205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2795354c94deSBarry Smith #else
2796354c94deSBarry Smith   PetscFunctionBegin;
2797354c94deSBarry Smith #endif
2798354c94deSBarry Smith   PetscFunctionReturn(0);
2799354c94deSBarry Smith }
2800354c94deSBarry Smith 
2801e34fafa9SBarry Smith #undef __FUNCT__
2802985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2803985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2804e34fafa9SBarry Smith {
2805e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2806e34fafa9SBarry Smith   PetscErrorCode ierr;
2807d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2808e34fafa9SBarry Smith   PetscReal      atmp;
2809985db425SBarry Smith   PetscScalar    *x;
2810e34fafa9SBarry Smith   MatScalar      *aa;
2811e34fafa9SBarry Smith 
2812e34fafa9SBarry Smith   PetscFunctionBegin;
2813e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2814e34fafa9SBarry Smith   aa = a->a;
2815e34fafa9SBarry Smith   ai = a->i;
2816e34fafa9SBarry Smith   aj = a->j;
2817e34fafa9SBarry Smith 
2818985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2819e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2820e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2821e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2822e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2823e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28249189402eSHong Zhang     x[i]  = 0.0;
2825e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2826985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2827985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2828985db425SBarry Smith       aa++; aj++;
2829985db425SBarry Smith     }
2830985db425SBarry Smith   }
2831985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2832985db425SBarry Smith   PetscFunctionReturn(0);
2833985db425SBarry Smith }
2834985db425SBarry Smith 
2835985db425SBarry Smith #undef __FUNCT__
2836985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2837985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2838985db425SBarry Smith {
2839985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2840985db425SBarry Smith   PetscErrorCode ierr;
2841d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2842985db425SBarry Smith   PetscScalar    *x;
2843985db425SBarry Smith   MatScalar      *aa;
2844985db425SBarry Smith 
2845985db425SBarry Smith   PetscFunctionBegin;
2846e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2847985db425SBarry Smith   aa = a->a;
2848985db425SBarry Smith   ai = a->i;
2849985db425SBarry Smith   aj = a->j;
2850985db425SBarry Smith 
2851985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2852985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2853985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2854e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2855985db425SBarry Smith   for (i=0; i<m; i++) {
2856985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2857d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2858985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2859985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2860985db425SBarry Smith       x[i] = 0.0;
2861985db425SBarry Smith       if (idx) {
2862985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2863985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2864985db425SBarry Smith           if (aj[j] > j) {
2865985db425SBarry Smith             idx[i] = j;
2866985db425SBarry Smith             break;
2867985db425SBarry Smith           }
2868985db425SBarry Smith         }
2869985db425SBarry Smith       }
2870985db425SBarry Smith     }
2871985db425SBarry Smith     for (j=0; j<ncols; j++) {
2872985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2873985db425SBarry Smith       aa++; aj++;
2874985db425SBarry Smith     }
2875985db425SBarry Smith   }
2876985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2877985db425SBarry Smith   PetscFunctionReturn(0);
2878985db425SBarry Smith }
2879985db425SBarry Smith 
2880985db425SBarry Smith #undef __FUNCT__
2881c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2882c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2883c87e5d42SMatthew Knepley {
2884c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2885c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2886c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2887c87e5d42SMatthew Knepley   PetscReal      atmp;
2888c87e5d42SMatthew Knepley   PetscScalar    *x;
2889c87e5d42SMatthew Knepley   MatScalar      *aa;
2890c87e5d42SMatthew Knepley 
2891c87e5d42SMatthew Knepley   PetscFunctionBegin;
2892e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2893c87e5d42SMatthew Knepley   aa = a->a;
2894c87e5d42SMatthew Knepley   ai = a->i;
2895c87e5d42SMatthew Knepley   aj = a->j;
2896c87e5d42SMatthew Knepley 
2897c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2898c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2899c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
29003bb78c5cSMatthew 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);
2901c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2902c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2903289a08f5SMatthew Knepley     if (ncols) {
2904289a08f5SMatthew Knepley       /* Get first nonzero */
2905289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2906289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29072205254eSKarl Rupp         if (atmp > 1.0e-12) {
29082205254eSKarl Rupp           x[i] = atmp;
29092205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29102205254eSKarl Rupp           break;
29112205254eSKarl Rupp         }
2912289a08f5SMatthew Knepley       }
291312431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2914289a08f5SMatthew Knepley     } else {
2915289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2916289a08f5SMatthew Knepley     }
2917c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2918c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2919289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2920c87e5d42SMatthew Knepley       aa++; aj++;
2921c87e5d42SMatthew Knepley     }
2922c87e5d42SMatthew Knepley   }
2923c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2924c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2925c87e5d42SMatthew Knepley }
2926c87e5d42SMatthew Knepley 
2927c87e5d42SMatthew Knepley #undef __FUNCT__
2928985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2929985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2930985db425SBarry Smith {
2931985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2932985db425SBarry Smith   PetscErrorCode ierr;
2933d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2934985db425SBarry Smith   PetscScalar    *x;
2935985db425SBarry Smith   MatScalar      *aa;
2936985db425SBarry Smith 
2937985db425SBarry Smith   PetscFunctionBegin;
2938e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2939985db425SBarry Smith   aa = a->a;
2940985db425SBarry Smith   ai = a->i;
2941985db425SBarry Smith   aj = a->j;
2942985db425SBarry Smith 
2943985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2944985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2945985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2946e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2947985db425SBarry Smith   for (i=0; i<m; i++) {
2948985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2949d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2950985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2951985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2952985db425SBarry Smith       x[i] = 0.0;
2953985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2954985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2955985db425SBarry Smith         for (j=0; j<ncols; j++) {
2956985db425SBarry Smith           if (aj[j] > j) {
2957985db425SBarry Smith             idx[i] = j;
2958985db425SBarry Smith             break;
2959985db425SBarry Smith           }
2960985db425SBarry Smith         }
2961985db425SBarry Smith       }
2962985db425SBarry Smith     }
2963985db425SBarry Smith     for (j=0; j<ncols; j++) {
2964985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2965985db425SBarry Smith       aa++; aj++;
2966e34fafa9SBarry Smith     }
2967e34fafa9SBarry Smith   }
2968e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2969e34fafa9SBarry Smith   PetscFunctionReturn(0);
2970e34fafa9SBarry Smith }
2971bbead8a2SBarry Smith 
2972bbead8a2SBarry Smith #include <petscblaslapack.h>
297306873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
2974bbead8a2SBarry Smith 
2975bbead8a2SBarry Smith #undef __FUNCT__
2976bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2977713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2978bbead8a2SBarry Smith {
2979bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2980bbead8a2SBarry Smith   PetscErrorCode ierr;
298134fc4b71SJed 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;
2982bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2983bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2984bbead8a2SBarry Smith 
2985bbead8a2SBarry Smith   PetscFunctionBegin;
29864a0d0026SBarry Smith   if (a->ibdiagvalid) {
29874a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29884a0d0026SBarry Smith     PetscFunctionReturn(0);
29894a0d0026SBarry Smith   }
2990bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2991bbead8a2SBarry Smith   if (!a->ibdiag) {
2992bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr);
29933bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2994bbead8a2SBarry Smith   }
2995bbead8a2SBarry Smith   diag = a->ibdiag;
2996bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2997bbead8a2SBarry Smith   /* factor and invert each block */
2998bbead8a2SBarry Smith   switch (bs) {
2999bbead8a2SBarry Smith   case 1:
3000bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3001bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3002bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3003bbead8a2SBarry Smith     }
3004bbead8a2SBarry Smith     break;
3005bbead8a2SBarry Smith   case 2:
3006bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3007bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3008bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
300996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
301096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3011bbead8a2SBarry Smith       diag += 4;
3012bbead8a2SBarry Smith     }
3013bbead8a2SBarry Smith     break;
3014bbead8a2SBarry Smith   case 3:
3015bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3016bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3017bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
301896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
301996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3020bbead8a2SBarry Smith       diag += 9;
3021bbead8a2SBarry Smith     }
3022bbead8a2SBarry Smith     break;
3023bbead8a2SBarry Smith   case 4:
3024bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3025bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3026bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
302796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
302896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3029bbead8a2SBarry Smith       diag += 16;
3030bbead8a2SBarry Smith     }
3031bbead8a2SBarry Smith     break;
3032bbead8a2SBarry Smith   case 5:
3033bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3034bbead8a2SBarry 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;
3035bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
303696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
303796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3038bbead8a2SBarry Smith       diag += 25;
3039bbead8a2SBarry Smith     }
3040bbead8a2SBarry Smith     break;
3041bbead8a2SBarry Smith   case 6:
3042bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3043bbead8a2SBarry 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;
3044bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
304596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
304696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3047bbead8a2SBarry Smith       diag += 36;
3048bbead8a2SBarry Smith     }
3049bbead8a2SBarry Smith     break;
3050bbead8a2SBarry Smith   case 7:
3051bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3052bbead8a2SBarry 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;
3053bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
305496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
305596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3056bbead8a2SBarry Smith       diag += 49;
3057bbead8a2SBarry Smith     }
3058bbead8a2SBarry Smith     break;
3059bbead8a2SBarry Smith   default:
3060bbead8a2SBarry Smith     ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr);
3061bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3062bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3063bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3064bbead8a2SBarry Smith       }
3065bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
306696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
306796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3068bbead8a2SBarry Smith       diag += bs2;
3069bbead8a2SBarry Smith     }
3070bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3071bbead8a2SBarry Smith   }
3072bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3073bbead8a2SBarry Smith   PetscFunctionReturn(0);
3074bbead8a2SBarry Smith }
3075bbead8a2SBarry Smith 
307673a71a0fSBarry Smith #undef __FUNCT__
307773a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
307873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
307973a71a0fSBarry Smith {
308073a71a0fSBarry Smith   PetscErrorCode ierr;
308173a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
308273a71a0fSBarry Smith   PetscScalar    a;
308373a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
308473a71a0fSBarry Smith 
308573a71a0fSBarry Smith   PetscFunctionBegin;
308673a71a0fSBarry Smith   if (!x->assembled) {
308773a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
308873a71a0fSBarry Smith     for (i=0; i<m; i++) {
308973a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
309073a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
309173a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
309273a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
309373a71a0fSBarry Smith       }
309473a71a0fSBarry Smith     }
309573a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
309673a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
309773a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
309873a71a0fSBarry Smith   PetscFunctionReturn(0);
309973a71a0fSBarry Smith }
310073a71a0fSBarry Smith 
3101682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31020a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3103cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3104cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3105cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
310697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31077c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31087c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3109db4efbfdSBarry Smith                                         0,
3110db4efbfdSBarry Smith                                         0,
3111db4efbfdSBarry Smith                                         0,
3112db4efbfdSBarry Smith                                 /* 10*/ 0,
3113cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3114cb5b572fSBarry Smith                                         0,
311541f059aeSBarry Smith                                         MatSOR_SeqAIJ,
311617ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
311797304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3118cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3119cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3120cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3121cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
312297304618SKris Buschelman                                 /* 20*/ 0,
3123cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3124cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3125cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3126d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3127db4efbfdSBarry Smith                                         0,
3128db4efbfdSBarry Smith                                         0,
3129db4efbfdSBarry Smith                                         0,
3130db4efbfdSBarry Smith                                         0,
31314994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3132db4efbfdSBarry Smith                                         0,
3133db4efbfdSBarry Smith                                         0,
31348c778c55SBarry Smith                                         0,
31358c778c55SBarry Smith                                         0,
3136d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3137cb5b572fSBarry Smith                                         0,
3138cb5b572fSBarry Smith                                         0,
3139cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3140cb5b572fSBarry Smith                                         0,
3141d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3142cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3143cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3144cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3145cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3146d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3147cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3148cb5b572fSBarry Smith                                         0,
314979299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31506e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
315173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31523b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31533b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31543b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3155a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
3156040ebd07SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3157b9617806SBarry Smith                                         0,
31580513a670SBarry Smith                                         0,
3159cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3160cda55fadSBarry Smith                                         0,
3161d519adbfSMatthew Knepley                                 /* 59*/ 0,
3162b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3163b9b97703SBarry Smith                                         MatView_SeqAIJ,
3164357abbc8SBarry Smith                                         0,
3165321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3166321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3167321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3168ee4f033dSBarry Smith                                         0,
3169ee4f033dSBarry Smith                                         0,
3170ee4f033dSBarry Smith                                         0,
3171d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3172c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3173ee4f033dSBarry Smith                                         0,
3174ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3175dcf5cc72SBarry Smith                                         0,
3176d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31773acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
317897304618SKris Buschelman                                         0,
317997304618SKris Buschelman                                         0,
318097304618SKris Buschelman                                         0,
31816ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
318297304618SKris Buschelman                                         0,
318397304618SKris Buschelman                                         0,
318497304618SKris Buschelman                                         0,
3185bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3186d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31871cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31886284ec50SHong Zhang                                         0,
31896284ec50SHong Zhang                                         0,
3190bc011b1eSHong Zhang                                         0,
3191d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
319226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
319326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
319465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31954a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
319665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31976fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31986fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31996fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32002121bac1SHong Zhang                                         0,
32012121bac1SHong Zhang                                 /* 99*/ 0,
3202609c6c4dSKris Buschelman                                         0,
3203609c6c4dSKris Buschelman                                         0,
320487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
320587d4246cSBarry Smith                                         0,
3206d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
320799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3208f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3209f5edf698SHong Zhang                                         0,
32102bebee5dSHong Zhang                                         0,
3211cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3212985db425SBarry Smith                                         0,
32132af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32142af78befSBarry Smith                                         0,
3215599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3216d519adbfSMatthew Knepley                                 /*114*/ 0,
3217599ef60dSHong Zhang                                         0,
32183c2a7987SHong Zhang                                         0,
3219fe97e370SBarry Smith                                         0,
3220fbdbba38SShri Abhyankar                                         0,
3221fbdbba38SShri Abhyankar                                 /*119*/ 0,
3222fbdbba38SShri Abhyankar                                         0,
3223fbdbba38SShri Abhyankar                                         0,
322482d44351SHong Zhang                                         0,
3225b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32260716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3227bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
322837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
322937868618SMatthew G Knepley                                         0,
323037868618SMatthew G Knepley                                         0,
32315df89d91SHong Zhang                                 /*129*/ 0,
323275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
323375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
323475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3235b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3236b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32372b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32382b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32392b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32403964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32413964eb88SJed Brown                                  /*139*/0,
32423964eb88SJed Brown                                         0
32439e29f15eSvictorle };
324417ab2063SBarry Smith 
32454a2ae208SSatish Balay #undef __FUNCT__
32464a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32477087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3248bef8e0ddSBarry Smith {
3249bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325097f1f81fSBarry Smith   PetscInt   i,nz,n;
3251bef8e0ddSBarry Smith 
3252bef8e0ddSBarry Smith   PetscFunctionBegin;
3253bef8e0ddSBarry Smith   nz = aij->maxnz;
3254d0f46423SBarry Smith   n  = mat->rmap->n;
3255bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3256bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3257bef8e0ddSBarry Smith   }
3258bef8e0ddSBarry Smith   aij->nz = nz;
3259bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3260bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3261bef8e0ddSBarry Smith   }
3262bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3263bef8e0ddSBarry Smith }
3264bef8e0ddSBarry Smith 
32654a2ae208SSatish Balay #undef __FUNCT__
32664a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3267bef8e0ddSBarry Smith /*@
3268bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3269bef8e0ddSBarry Smith        in the matrix.
3270bef8e0ddSBarry Smith 
3271bef8e0ddSBarry Smith   Input Parameters:
3272bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3273bef8e0ddSBarry Smith -  indices - the column indices
3274bef8e0ddSBarry Smith 
327515091d37SBarry Smith   Level: advanced
327615091d37SBarry Smith 
3277bef8e0ddSBarry Smith   Notes:
3278bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3279bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3280bef8e0ddSBarry Smith   of the MatSetValues() operation.
3281bef8e0ddSBarry Smith 
3282bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3283d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3284bef8e0ddSBarry Smith 
3285bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3286bef8e0ddSBarry Smith 
3287b9617806SBarry Smith     The indices should start with zero, not one.
3288b9617806SBarry Smith 
3289bef8e0ddSBarry Smith @*/
32907087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3291bef8e0ddSBarry Smith {
32924ac538c5SBarry Smith   PetscErrorCode ierr;
3293bef8e0ddSBarry Smith 
3294bef8e0ddSBarry Smith   PetscFunctionBegin;
32950700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32964482741eSBarry Smith   PetscValidPointer(indices,2);
32974ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3298bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3299bef8e0ddSBarry Smith }
3300bef8e0ddSBarry Smith 
3301be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3302be6bf707SBarry Smith 
33034a2ae208SSatish Balay #undef __FUNCT__
33044a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33057087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3306be6bf707SBarry Smith {
3307be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33086849ba73SBarry Smith   PetscErrorCode ierr;
3309d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3310be6bf707SBarry Smith 
3311be6bf707SBarry Smith   PetscFunctionBegin;
3312f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3313be6bf707SBarry Smith 
3314be6bf707SBarry Smith   /* allocate space for values if not already there */
3315be6bf707SBarry Smith   if (!aij->saved_values) {
331687828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33173bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3318be6bf707SBarry Smith   }
3319be6bf707SBarry Smith 
3320be6bf707SBarry Smith   /* copy values over */
332187828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3322be6bf707SBarry Smith   PetscFunctionReturn(0);
3323be6bf707SBarry Smith }
3324be6bf707SBarry Smith 
33254a2ae208SSatish Balay #undef __FUNCT__
3326b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3327be6bf707SBarry Smith /*@
3328be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3329be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3330be6bf707SBarry Smith        nonlinear portion.
3331be6bf707SBarry Smith 
3332be6bf707SBarry Smith    Collect on Mat
3333be6bf707SBarry Smith 
3334be6bf707SBarry Smith   Input Parameters:
33350e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3336be6bf707SBarry Smith 
333715091d37SBarry Smith   Level: advanced
333815091d37SBarry Smith 
3339be6bf707SBarry Smith   Common Usage, with SNESSolve():
3340be6bf707SBarry Smith $    Create Jacobian matrix
3341be6bf707SBarry Smith $    Set linear terms into matrix
3342be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3343be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3344be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3345512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3346be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3347be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3348be6bf707SBarry Smith $    In your Jacobian routine
3349be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3350be6bf707SBarry Smith $      Set nonlinear terms in matrix
3351be6bf707SBarry Smith 
3352be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3353be6bf707SBarry Smith $    // build linear portion of Jacobian
3354512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3355be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3356be6bf707SBarry Smith $    loop over nonlinear iterations
3357be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3358be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3359be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3360be6bf707SBarry Smith $       Solve linear system with Jacobian
3361be6bf707SBarry Smith $    endloop
3362be6bf707SBarry Smith 
3363be6bf707SBarry Smith   Notes:
3364be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3365512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3366be6bf707SBarry Smith     calling this routine.
3367be6bf707SBarry Smith 
33680c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33690c468ba9SBarry Smith     and does not allocated additional space.
33700c468ba9SBarry Smith 
3371be6bf707SBarry Smith .seealso: MatRetrieveValues()
3372be6bf707SBarry Smith 
3373be6bf707SBarry Smith @*/
33747087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3375be6bf707SBarry Smith {
33764ac538c5SBarry Smith   PetscErrorCode ierr;
3377be6bf707SBarry Smith 
3378be6bf707SBarry Smith   PetscFunctionBegin;
33790700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3380e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3381e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33824ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3383be6bf707SBarry Smith   PetscFunctionReturn(0);
3384be6bf707SBarry Smith }
3385be6bf707SBarry Smith 
33864a2ae208SSatish Balay #undef __FUNCT__
33874a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33887087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3389be6bf707SBarry Smith {
3390be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33916849ba73SBarry Smith   PetscErrorCode ierr;
3392d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3393be6bf707SBarry Smith 
3394be6bf707SBarry Smith   PetscFunctionBegin;
3395f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3396f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3397be6bf707SBarry Smith   /* copy values over */
339887828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3399be6bf707SBarry Smith   PetscFunctionReturn(0);
3400be6bf707SBarry Smith }
3401be6bf707SBarry Smith 
34024a2ae208SSatish Balay #undef __FUNCT__
34034a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3404be6bf707SBarry Smith /*@
3405be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3406be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3407be6bf707SBarry Smith        nonlinear portion.
3408be6bf707SBarry Smith 
3409be6bf707SBarry Smith    Collect on Mat
3410be6bf707SBarry Smith 
3411be6bf707SBarry Smith   Input Parameters:
3412be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3413be6bf707SBarry Smith 
341415091d37SBarry Smith   Level: advanced
341515091d37SBarry Smith 
3416be6bf707SBarry Smith .seealso: MatStoreValues()
3417be6bf707SBarry Smith 
3418be6bf707SBarry Smith @*/
34197087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3420be6bf707SBarry Smith {
34214ac538c5SBarry Smith   PetscErrorCode ierr;
3422be6bf707SBarry Smith 
3423be6bf707SBarry Smith   PetscFunctionBegin;
34240700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3425e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3426e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34274ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3428be6bf707SBarry Smith   PetscFunctionReturn(0);
3429be6bf707SBarry Smith }
3430be6bf707SBarry Smith 
3431f83d6046SBarry Smith 
3432be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34334a2ae208SSatish Balay #undef __FUNCT__
34344a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
343517ab2063SBarry Smith /*@C
3436682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34370d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34386e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
343951c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34402bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344117ab2063SBarry Smith 
3442db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3443db81eaa0SLois Curfman McInnes 
344417ab2063SBarry Smith    Input Parameters:
3445db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
344617ab2063SBarry Smith .  m - number of rows
344717ab2063SBarry Smith .  n - number of columns
344817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
344951c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34500298fd71SBarry Smith          (possibly different for each row) or NULL
345117ab2063SBarry Smith 
345217ab2063SBarry Smith    Output Parameter:
3453416022c9SBarry Smith .  A - the matrix
345417ab2063SBarry Smith 
3455175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3456ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3457175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3458175b88e8SBarry Smith 
3459b259b22eSLois Curfman McInnes    Notes:
346049a6f317SBarry Smith    If nnz is given then nz is ignored
346149a6f317SBarry Smith 
346217ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346317ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34640002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
346544cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
346617ab2063SBarry Smith 
346717ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34680298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34693d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34706da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347117ab2063SBarry Smith 
3472682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34734fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3474682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34756c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34766c7ebb05SLois Curfman McInnes 
34776c7ebb05SLois Curfman McInnes    Options Database Keys:
3478698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34799db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348017ab2063SBarry Smith 
3481027ccd11SLois Curfman McInnes    Level: intermediate
3482027ccd11SLois Curfman McInnes 
348369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348436db0b34SBarry Smith 
348517ab2063SBarry Smith @*/
34867087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
348717ab2063SBarry Smith {
3488dfbe8321SBarry Smith   PetscErrorCode ierr;
34896945ee14SBarry Smith 
34903a40ed3dSBarry Smith   PetscFunctionBegin;
3491f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3492117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3493c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3494d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3495273d9f13SBarry Smith   PetscFunctionReturn(0);
3496273d9f13SBarry Smith }
3497273d9f13SBarry Smith 
34984a2ae208SSatish Balay #undef __FUNCT__
34994a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3500273d9f13SBarry Smith /*@C
3501273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3502273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3503273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3504273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3505273d9f13SBarry Smith 
3506273d9f13SBarry Smith    Collective on MPI_Comm
3507273d9f13SBarry Smith 
3508273d9f13SBarry Smith    Input Parameters:
3509117016b1SBarry Smith +  B - The matrix-free
3510273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3511273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35120298fd71SBarry Smith          (possibly different for each row) or NULL
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith    Notes:
351549a6f317SBarry Smith      If nnz is given then nz is ignored
351649a6f317SBarry Smith 
3517273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3518273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3519273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3520273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3521273d9f13SBarry Smith 
3522273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35230298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3524273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3525273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3526273d9f13SBarry Smith 
3527aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3528aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3529aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3530aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3531aa95bbe8SBarry Smith 
3532a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3533a96a251dSBarry Smith    entries or columns indices
3534a96a251dSBarry Smith 
3535273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3536273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3537273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3538273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3539273d9f13SBarry Smith 
3540273d9f13SBarry Smith    Options Database Keys:
3541698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3542698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3543273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3544273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3545273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3546273d9f13SBarry Smith 
3547273d9f13SBarry Smith    Level: intermediate
3548273d9f13SBarry Smith 
354969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3550273d9f13SBarry Smith 
3551273d9f13SBarry Smith @*/
35527087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3553273d9f13SBarry Smith {
35544ac538c5SBarry Smith   PetscErrorCode ierr;
3555a23d5eceSKris Buschelman 
3556a23d5eceSKris Buschelman   PetscFunctionBegin;
35576ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35586ba663aaSJed Brown   PetscValidType(B,1);
35594ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3560a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3561a23d5eceSKris Buschelman }
3562a23d5eceSKris Buschelman 
3563a23d5eceSKris Buschelman #undef __FUNCT__
3564a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35657087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3566a23d5eceSKris Buschelman {
3567273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35682576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35696849ba73SBarry Smith   PetscErrorCode ierr;
357097f1f81fSBarry Smith   PetscInt       i;
3571273d9f13SBarry Smith 
3572273d9f13SBarry Smith   PetscFunctionBegin;
35732576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3574a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3575c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3576c461c341SBarry Smith     nz             = 0;
3577c461c341SBarry Smith   }
3578c461c341SBarry Smith 
357926283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358026283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3581899cda47SBarry Smith 
3582435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3583e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3584b73539f3SBarry Smith   if (nnz) {
3585d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3586e32f2f54SBarry 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]);
3587e32f2f54SBarry 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);
3588b73539f3SBarry Smith     }
3589b73539f3SBarry Smith   }
3590b73539f3SBarry Smith 
3591273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35922205254eSKarl Rupp 
3593273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3594273d9f13SBarry Smith 
3595ab93d7beSBarry Smith   if (!skipallocation) {
35962ee49352SLisandro Dalcin     if (!b->imax) {
3597d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
35983bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35992ee49352SLisandro Dalcin     }
3600273d9f13SBarry Smith     if (!nnz) {
3601435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3602c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3603d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3604d0f46423SBarry Smith       nz = nz*B->rmap->n;
3605273d9f13SBarry Smith     } else {
3606273d9f13SBarry Smith       nz = 0;
3607d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3608273d9f13SBarry Smith     }
3609ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36102205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3611ab93d7beSBarry Smith 
3612273d9f13SBarry Smith     /* allocate the matrix space */
36132ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3614d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
36153bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3616bfeeae90SHong Zhang     b->i[0] = 0;
3617d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36185da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36195da197adSKris Buschelman     }
3620273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3621e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3622e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3623b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3624b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3625b31eba2aSShri Abhyankar #endif
3626c461c341SBarry Smith   } else {
3627e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3628e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3629c461c341SBarry Smith   }
3630273d9f13SBarry Smith 
3631273d9f13SBarry Smith   b->nz               = 0;
3632273d9f13SBarry Smith   b->maxnz            = nz;
3633273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36342205254eSKarl Rupp   if (realalloc) {
36352205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36362205254eSKarl Rupp   }
3637273d9f13SBarry Smith   PetscFunctionReturn(0);
3638273d9f13SBarry Smith }
3639273d9f13SBarry Smith 
3640a1661176SMatthew Knepley #undef  __FUNCT__
3641a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364258d36128SBarry Smith /*@
3643a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3644a1661176SMatthew Knepley 
3645a1661176SMatthew Knepley    Input Parameters:
3646a1661176SMatthew Knepley +  B - the matrix
3647a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3648a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3649a1661176SMatthew Knepley -  v - optional values in the matrix
3650a1661176SMatthew Knepley 
3651a1661176SMatthew Knepley    Level: developer
3652a1661176SMatthew Knepley 
365358d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365458d36128SBarry Smith 
3655a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3656a1661176SMatthew Knepley 
3657a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3658a1661176SMatthew Knepley @*/
3659a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3660a1661176SMatthew Knepley {
3661a1661176SMatthew Knepley   PetscErrorCode ierr;
3662a1661176SMatthew Knepley 
3663a1661176SMatthew Knepley   PetscFunctionBegin;
36640700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36656ba663aaSJed Brown   PetscValidType(B,1);
36664ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3667a1661176SMatthew Knepley   PetscFunctionReturn(0);
3668a1661176SMatthew Knepley }
3669a1661176SMatthew Knepley 
3670a1661176SMatthew Knepley #undef  __FUNCT__
3671a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36727087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3673a1661176SMatthew Knepley {
3674a1661176SMatthew Knepley   PetscInt       i;
3675a1661176SMatthew Knepley   PetscInt       m,n;
3676a1661176SMatthew Knepley   PetscInt       nz;
3677a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3678a1661176SMatthew Knepley   PetscScalar    *values;
3679a1661176SMatthew Knepley   PetscErrorCode ierr;
3680a1661176SMatthew Knepley 
3681a1661176SMatthew Knepley   PetscFunctionBegin;
368265e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3683779a8d59SSatish Balay 
3684779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3685779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3686779a8d59SSatish Balay 
3687779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3688a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3689a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3690b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3691a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369265e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3693a1661176SMatthew Knepley     nnz[i] = nz;
3694a1661176SMatthew Knepley   }
3695a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3696a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3697a1661176SMatthew Knepley 
3698a1661176SMatthew Knepley   if (v) {
3699a1661176SMatthew Knepley     values = (PetscScalar*) v;
3700a1661176SMatthew Knepley   } else {
37010e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3702a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3703a1661176SMatthew Knepley   }
3704a1661176SMatthew Knepley 
3705a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3706b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3707b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3708a1661176SMatthew Knepley   }
3709a1661176SMatthew Knepley 
3710a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3711a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3712a1661176SMatthew Knepley 
3713a1661176SMatthew Knepley   if (!v) {
3714a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3715a1661176SMatthew Knepley   }
37167827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3717a1661176SMatthew Knepley   PetscFunctionReturn(0);
3718a1661176SMatthew Knepley }
3719a1661176SMatthew Knepley 
3720c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372106873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3722170fe5c8SBarry Smith 
3723170fe5c8SBarry Smith #undef __FUNCT__
3724170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3725170fe5c8SBarry Smith /*
3726170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3727170fe5c8SBarry Smith 
3728170fe5c8SBarry Smith                n                       p                          p
3729170fe5c8SBarry Smith         (              )       (              )         (                  )
3730170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3731170fe5c8SBarry Smith         (              )       (              )         (                  )
3732170fe5c8SBarry Smith 
3733170fe5c8SBarry Smith */
3734170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3735170fe5c8SBarry Smith {
3736170fe5c8SBarry Smith   PetscErrorCode    ierr;
3737170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3738170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3739170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37401de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3741170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3742170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3743170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3744170fe5c8SBarry Smith 
3745170fe5c8SBarry Smith   PetscFunctionBegin;
3746d0f46423SBarry Smith   m    = A->rmap->n;
3747d0f46423SBarry Smith   n    = A->cmap->n;
3748d0f46423SBarry Smith   p    = B->cmap->n;
3749170fe5c8SBarry Smith   a    = sub_a->v;
3750170fe5c8SBarry Smith   b    = sub_b->a;
3751170fe5c8SBarry Smith   c    = sub_c->v;
3752170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3753170fe5c8SBarry Smith 
3754170fe5c8SBarry Smith   ii  = sub_b->i;
3755170fe5c8SBarry Smith   idx = sub_b->j;
3756170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3757170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3758170fe5c8SBarry Smith     while (q-->0) {
3759170fe5c8SBarry Smith       c_q = c + m*(*idx);
3760170fe5c8SBarry Smith       a_q = a + m*i;
3761854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3762170fe5c8SBarry Smith       idx++;
3763170fe5c8SBarry Smith       b++;
3764170fe5c8SBarry Smith     }
3765170fe5c8SBarry Smith   }
3766170fe5c8SBarry Smith   PetscFunctionReturn(0);
3767170fe5c8SBarry Smith }
3768170fe5c8SBarry Smith 
3769170fe5c8SBarry Smith #undef __FUNCT__
3770170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3771170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3772170fe5c8SBarry Smith {
3773170fe5c8SBarry Smith   PetscErrorCode ierr;
3774d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3775170fe5c8SBarry Smith   Mat            Cmat;
3776170fe5c8SBarry Smith 
3777170fe5c8SBarry Smith   PetscFunctionBegin;
3778e32f2f54SBarry 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);
3779ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3780170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3781a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3782170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37830298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3784d73949e8SHong Zhang 
3785d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37862205254eSKarl Rupp 
3787170fe5c8SBarry Smith   *C = Cmat;
3788170fe5c8SBarry Smith   PetscFunctionReturn(0);
3789170fe5c8SBarry Smith }
3790170fe5c8SBarry Smith 
3791170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3792170fe5c8SBarry Smith #undef __FUNCT__
3793170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3794170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3795170fe5c8SBarry Smith {
3796170fe5c8SBarry Smith   PetscErrorCode ierr;
3797170fe5c8SBarry Smith 
3798170fe5c8SBarry Smith   PetscFunctionBegin;
3799170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38003ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3801170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38023ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3803170fe5c8SBarry Smith   }
38043ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3805170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38063ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3807170fe5c8SBarry Smith   PetscFunctionReturn(0);
3808170fe5c8SBarry Smith }
3809170fe5c8SBarry Smith 
3810170fe5c8SBarry Smith 
38110bad9183SKris Buschelman /*MC
3812fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38130bad9183SKris Buschelman    based on compressed sparse row format.
38140bad9183SKris Buschelman 
38150bad9183SKris Buschelman    Options Database Keys:
38160bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38170bad9183SKris Buschelman 
38180bad9183SKris Buschelman   Level: beginner
38190bad9183SKris Buschelman 
3820f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38210bad9183SKris Buschelman M*/
38220bad9183SKris Buschelman 
3823ccd284c7SBarry Smith /*MC
3824ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3825ccd284c7SBarry Smith 
3826ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3827ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3828ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3829ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3830ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3831ccd284c7SBarry Smith 
3832ccd284c7SBarry Smith    Options Database Keys:
3833ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3834ccd284c7SBarry Smith 
3835ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3836ccd284c7SBarry Smith    enough exist.
3837ccd284c7SBarry Smith 
3838ccd284c7SBarry Smith   Level: beginner
3839ccd284c7SBarry Smith 
3840ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3841ccd284c7SBarry Smith M*/
3842ccd284c7SBarry Smith 
3843ccd284c7SBarry Smith /*MC
3844ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3845ccd284c7SBarry Smith 
3846ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3847ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3848ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3849ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3850ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3851ccd284c7SBarry Smith 
3852ccd284c7SBarry Smith    Options Database Keys:
3853ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3854ccd284c7SBarry Smith 
3855ccd284c7SBarry Smith   Level: beginner
3856ccd284c7SBarry Smith 
3857ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3858ccd284c7SBarry Smith M*/
3859ccd284c7SBarry Smith 
3860b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3862b5e56a35SBarry Smith #endif
3863ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38648cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3865af1023dbSSatish Balay #endif
38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38678cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38697087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3870611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3872611f576cSBarry Smith #endif
3873611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38748cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3875611f576cSBarry Smith #endif
3876f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3878f3c0ef26SHong Zhang #endif
3879eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3881eb3b5408SSatish Balay #endif
3882586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38838cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3884586621ddSJed Brown #endif
3885719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3887719d5645SBarry Smith #endif
3888b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38898cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38907087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38917087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3892b3866ffcSBarry Smith #endif
389317f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
389517f1a0eaSHong Zhang #endif
389617667f90SBarry Smith 
3897c0c8ee5eSDmitry Karpeev 
38988c778c55SBarry Smith #undef __FUNCT__
38998c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39008c778c55SBarry Smith /*@C
39018c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39028c778c55SBarry Smith 
39038c778c55SBarry Smith    Not Collective
39048c778c55SBarry Smith 
39058c778c55SBarry Smith    Input Parameter:
39068c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39078c778c55SBarry Smith 
39088c778c55SBarry Smith    Output Parameter:
39098c778c55SBarry Smith .   array - pointer to the data
39108c778c55SBarry Smith 
39118c778c55SBarry Smith    Level: intermediate
39128c778c55SBarry Smith 
3913774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39148c778c55SBarry Smith @*/
39158c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39168c778c55SBarry Smith {
39178c778c55SBarry Smith   PetscErrorCode ierr;
39188c778c55SBarry Smith 
39198c778c55SBarry Smith   PetscFunctionBegin;
39208c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39218c778c55SBarry Smith   PetscFunctionReturn(0);
39228c778c55SBarry Smith }
39238c778c55SBarry Smith 
39248c778c55SBarry Smith #undef __FUNCT__
39258c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39268c778c55SBarry Smith /*@C
39278c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39288c778c55SBarry Smith 
39298c778c55SBarry Smith    Not Collective
39308c778c55SBarry Smith 
39318c778c55SBarry Smith    Input Parameters:
39328c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39338c778c55SBarry Smith .  array - pointer to the data
39348c778c55SBarry Smith 
39358c778c55SBarry Smith    Level: intermediate
39368c778c55SBarry Smith 
3937774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39388c778c55SBarry Smith @*/
39398c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39408c778c55SBarry Smith {
39418c778c55SBarry Smith   PetscErrorCode ierr;
39428c778c55SBarry Smith 
39438c778c55SBarry Smith   PetscFunctionBegin;
39448c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39458c778c55SBarry Smith   PetscFunctionReturn(0);
39468c778c55SBarry Smith }
39478c778c55SBarry Smith 
39484a2ae208SSatish Balay #undef __FUNCT__
39494a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39508cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3951273d9f13SBarry Smith {
3952273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3953dfbe8321SBarry Smith   PetscErrorCode ierr;
395438baddfdSBarry Smith   PetscMPIInt    size;
3955273d9f13SBarry Smith 
3956273d9f13SBarry Smith   PetscFunctionBegin;
3957ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3958e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3959273d9f13SBarry Smith 
396038f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39612205254eSKarl Rupp 
3962b0a32e0cSBarry Smith   B->data = (void*)b;
39632205254eSKarl Rupp 
3964549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39652205254eSKarl Rupp 
3966416022c9SBarry Smith   b->row                = 0;
3967416022c9SBarry Smith   b->col                = 0;
396882bf6240SBarry Smith   b->icol               = 0;
3969b810aeb4SBarry Smith   b->reallocs           = 0;
397036db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3971f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3972416022c9SBarry Smith   b->nonew              = 0;
3973416022c9SBarry Smith   b->diag               = 0;
3974416022c9SBarry Smith   b->solve_work         = 0;
39752a1b7f2aSHong Zhang   B->spptr              = 0;
3976be6bf707SBarry Smith   b->saved_values       = 0;
3977d7f994e1SBarry Smith   b->idiag              = 0;
397871f1c65dSBarry Smith   b->mdiag              = 0;
397971f1c65dSBarry Smith   b->ssor_work          = 0;
398071f1c65dSBarry Smith   b->omega              = 1.0;
398171f1c65dSBarry Smith   b->fshift             = 0.0;
398271f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3983bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3984a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3985a30b2313SHong Zhang   b->xtoy               = 0;
3986a30b2313SHong Zhang   b->XtoY               = 0;
398788e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
398817ab2063SBarry Smith 
398935d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3990bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3991bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39928c778c55SBarry Smith 
3993b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3994bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3997b3866ffcSBarry Smith #endif
3998b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3999bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4000b5e56a35SBarry Smith #endif
4001ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4002bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4003719d5645SBarry Smith #endif
4004611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4005bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4006611f576cSBarry Smith #endif
4007f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4008bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4009f3c0ef26SHong Zhang #endif
4010611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4011bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4012611f576cSBarry Smith #endif
4013eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4014bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4015eb3b5408SSatish Balay #endif
4016586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4017bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4018586621ddSJed Brown #endif
4019719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4020bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4021719d5645SBarry Smith #endif
402217f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4023bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402417f1a0eaSHong Zhang #endif
402517f1a0eaSHong Zhang 
4026bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4027bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40444108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
404517667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40463a40ed3dSBarry Smith   PetscFunctionReturn(0);
404717ab2063SBarry Smith }
404817ab2063SBarry Smith 
40494a2ae208SSatish Balay #undef __FUNCT__
4050b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4051b24902e0SBarry Smith /*
4052b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4053b24902e0SBarry Smith */
4054ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
405517ab2063SBarry Smith {
4056416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40576849ba73SBarry Smith   PetscErrorCode ierr;
4058d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
405917ab2063SBarry Smith 
40603a40ed3dSBarry Smith   PetscFunctionBegin;
4061273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4062273d9f13SBarry Smith 
4063d5f3da31SBarry Smith   C->factortype = A->factortype;
4064416022c9SBarry Smith   c->row        = 0;
4065416022c9SBarry Smith   c->col        = 0;
406682bf6240SBarry Smith   c->icol       = 0;
40676ad4291fSHong Zhang   c->reallocs   = 0;
406817ab2063SBarry Smith 
40696ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407017ab2063SBarry Smith 
4071aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4072aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4073eec197d1SBarry Smith 
407433b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40753bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
407617ab2063SBarry Smith   for (i=0; i<m; i++) {
4077416022c9SBarry Smith     c->imax[i] = a->imax[i];
4078416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
407917ab2063SBarry Smith   }
408017ab2063SBarry Smith 
408117ab2063SBarry Smith   /* allocate the matrix space */
4082f77e22a1SHong Zhang   if (mallocmatspace) {
4083a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40843bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40852205254eSKarl Rupp 
4086f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40872205254eSKarl Rupp 
408897f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
408917ab2063SBarry Smith     if (m > 0) {
409097f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4091be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4092bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4093be6bf707SBarry Smith       } else {
4094bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
409517ab2063SBarry Smith       }
409608480c60SBarry Smith     }
4097f77e22a1SHong Zhang   }
409817ab2063SBarry Smith 
40996ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4100416022c9SBarry Smith   c->roworiented       = a->roworiented;
4101416022c9SBarry Smith   c->nonew             = a->nonew;
4102416022c9SBarry Smith   if (a->diag) {
410397f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410517ab2063SBarry Smith     for (i=0; i<m; i++) {
4106416022c9SBarry Smith       c->diag[i] = a->diag[i];
410717ab2063SBarry Smith     }
41083a40ed3dSBarry Smith   } else c->diag = 0;
41092205254eSKarl Rupp 
41106ad4291fSHong Zhang   c->solve_work         = 0;
41116ad4291fSHong Zhang   c->saved_values       = 0;
41126ad4291fSHong Zhang   c->idiag              = 0;
411371f1c65dSBarry Smith   c->ssor_work          = 0;
4114a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4115e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4116e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41176ad4291fSHong Zhang   c->xtoy               = 0;
41186ad4291fSHong Zhang   c->XtoY               = 0;
41196ad4291fSHong Zhang 
4120893ad86cSHong Zhang   c->rmax         = a->rmax;
4121416022c9SBarry Smith   c->nz           = a->nz;
41228ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4123273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4124754ec7b1SSatish Balay 
41256ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41266ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4127cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4128cd6b891eSBarry Smith   if (a->compressedrow.use) {
41296ad4291fSHong Zhang     i    = a->compressedrow.nrows;
41300e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
41316ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41326ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413327ea64f8SHong Zhang   } else {
413427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41350298fd71SBarry Smith     c->compressedrow.i      = NULL;
41360298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41376ad4291fSHong Zhang   }
413888e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41394846f1f5SKris Buschelman 
41402205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4141140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41423a40ed3dSBarry Smith   PetscFunctionReturn(0);
414317ab2063SBarry Smith }
414417ab2063SBarry Smith 
41454a2ae208SSatish Balay #undef __FUNCT__
4146b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4147b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4148b24902e0SBarry Smith {
4149b24902e0SBarry Smith   PetscErrorCode ierr;
4150b24902e0SBarry Smith 
4151b24902e0SBarry Smith   PetscFunctionBegin;
4152ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41534b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4154a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4155a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4156f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4157b24902e0SBarry Smith   PetscFunctionReturn(0);
4158b24902e0SBarry Smith }
4159b24902e0SBarry Smith 
4160b24902e0SBarry Smith #undef __FUNCT__
41614a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4162112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4163fbdbba38SShri Abhyankar {
4164fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4165fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4166fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4167fbdbba38SShri Abhyankar   int            fd;
4168fbdbba38SShri Abhyankar   PetscMPIInt    size;
4169fbdbba38SShri Abhyankar   MPI_Comm       comm;
4170bbead8a2SBarry Smith   PetscInt       bs = 1;
4171fbdbba38SShri Abhyankar 
4172fbdbba38SShri Abhyankar   PetscFunctionBegin;
4173fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4174fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4175fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4176bbead8a2SBarry Smith 
41770298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41780298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4179bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41801814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4181bbead8a2SBarry Smith 
4182fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4183fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4184fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4185fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4186fbdbba38SShri Abhyankar 
4187bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4188fbdbba38SShri Abhyankar 
4189fbdbba38SShri Abhyankar   /* read in row lengths */
4190fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4191fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4192fbdbba38SShri Abhyankar 
4193fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4194fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4195fbdbba38SShri 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);
4196fbdbba38SShri Abhyankar 
4197fbdbba38SShri Abhyankar   /* set global size if not set already*/
4198f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4199fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4200aabbc4fbSShri Abhyankar   } else {
4201fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4202fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42034c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42044c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42054c5b953cSHong Zhang     }
4206f501eaabSShri 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);
4207aabbc4fbSShri Abhyankar   }
4208fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4209fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4210fbdbba38SShri Abhyankar 
4211fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4212fbdbba38SShri Abhyankar 
4213fbdbba38SShri Abhyankar   /* read in nonzero values */
4214fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4215fbdbba38SShri Abhyankar 
4216fbdbba38SShri Abhyankar   /* set matrix "i" values */
4217fbdbba38SShri Abhyankar   a->i[0] = 0;
4218fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4219fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4220fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4221fbdbba38SShri Abhyankar   }
4222fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4223fbdbba38SShri Abhyankar 
4224fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4225fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4226fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4227fbdbba38SShri Abhyankar }
4228fbdbba38SShri Abhyankar 
4229fbdbba38SShri Abhyankar #undef __FUNCT__
4230b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4231ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42327264ac53SSatish Balay {
42337264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4234dfbe8321SBarry Smith   PetscErrorCode ierr;
4235eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4236eeffb40dSHong Zhang   PetscInt k;
4237eeffb40dSHong Zhang #endif
42387264ac53SSatish Balay 
42393a40ed3dSBarry Smith   PetscFunctionBegin;
4240bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4241d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4242ca44d042SBarry Smith     *flg = PETSC_FALSE;
4243ca44d042SBarry Smith     PetscFunctionReturn(0);
4244bcd2baecSBarry Smith   }
42457264ac53SSatish Balay 
42467264ac53SSatish Balay   /* if the a->i are the same */
4247d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4248abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42497264ac53SSatish Balay 
42507264ac53SSatish Balay   /* if a->j are the same */
425197f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4252abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4253bcd2baecSBarry Smith 
4254bcd2baecSBarry Smith   /* if a->a are the same */
4255eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4256eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4257eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4258eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42593a40ed3dSBarry Smith       PetscFunctionReturn(0);
4260eeffb40dSHong Zhang     }
4261eeffb40dSHong Zhang   }
4262eeffb40dSHong Zhang #else
4263eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4264eeffb40dSHong Zhang #endif
4265eeffb40dSHong Zhang   PetscFunctionReturn(0);
42667264ac53SSatish Balay }
426736db0b34SBarry Smith 
42684a2ae208SSatish Balay #undef __FUNCT__
42694a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
427005869f15SSatish Balay /*@
427136db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427236db0b34SBarry Smith               provided by the user.
427336db0b34SBarry Smith 
4274c75a6043SHong Zhang       Collective on MPI_Comm
427536db0b34SBarry Smith 
427636db0b34SBarry Smith    Input Parameters:
427736db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
427836db0b34SBarry Smith .   m - number of rows
427936db0b34SBarry Smith .   n - number of columns
428036db0b34SBarry Smith .   i - row indices
428136db0b34SBarry Smith .   j - column indices
428236db0b34SBarry Smith -   a - matrix values
428336db0b34SBarry Smith 
428436db0b34SBarry Smith    Output Parameter:
428536db0b34SBarry Smith .   mat - the matrix
428636db0b34SBarry Smith 
428736db0b34SBarry Smith    Level: intermediate
428836db0b34SBarry Smith 
428936db0b34SBarry Smith    Notes:
42900551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4291292fb18eSBarry Smith     once the matrix is destroyed and not before
429236db0b34SBarry Smith 
429336db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429436db0b34SBarry Smith 
4295bfeeae90SHong Zhang        The i and j indices are 0 based
429636db0b34SBarry Smith 
4297a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4298a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4299a4552177SSatish Balay     as shown:
4300a4552177SSatish Balay 
4301a4552177SSatish Balay         1 0 0
4302a4552177SSatish Balay         2 0 3
4303a4552177SSatish Balay         4 5 6
4304a4552177SSatish Balay 
4305a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43069985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4307a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4308a4552177SSatish Balay 
43099985e31cSBarry Smith 
431069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
431136db0b34SBarry Smith 
431236db0b34SBarry Smith @*/
43137087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431436db0b34SBarry Smith {
4315dfbe8321SBarry Smith   PetscErrorCode ierr;
4316cbcfb4deSHong Zhang   PetscInt       ii;
431736db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4318cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4319cbcfb4deSHong Zhang   PetscInt jj;
4320cbcfb4deSHong Zhang #endif
432136db0b34SBarry Smith 
432236db0b34SBarry Smith   PetscFunctionBegin;
4323f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4324f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4325f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4326a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4327ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4328ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4329ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4330ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4331ab93d7beSBarry Smith 
433236db0b34SBarry Smith   aij->i            = i;
433336db0b34SBarry Smith   aij->j            = j;
433436db0b34SBarry Smith   aij->a            = a;
433536db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
433636db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4337e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4338e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
433936db0b34SBarry Smith 
434036db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
434136db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43422515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4343e32f2f54SBarry 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]);
43449985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4345e32f2f54SBarry 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);
4346e32f2f54SBarry 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);
43479985e31cSBarry Smith     }
434836db0b34SBarry Smith #endif
434936db0b34SBarry Smith   }
43502515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435136db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4352e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4353e32f2f54SBarry 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]);
435436db0b34SBarry Smith   }
435536db0b34SBarry Smith #endif
435636db0b34SBarry Smith 
4357b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4358b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
435936db0b34SBarry Smith   PetscFunctionReturn(0);
436036db0b34SBarry Smith }
43618a0b0e6bSVictor Minden #undef __FUNCT__
43628a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436380ef6e79SMatthew G Knepley /*@C
4364d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43658a0b0e6bSVictor Minden               provided by the user.
43668a0b0e6bSVictor Minden 
43678a0b0e6bSVictor Minden       Collective on MPI_Comm
43688a0b0e6bSVictor Minden 
43698a0b0e6bSVictor Minden    Input Parameters:
43708a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43718a0b0e6bSVictor Minden .   m   - number of rows
43728a0b0e6bSVictor Minden .   n   - number of columns
43738a0b0e6bSVictor Minden .   i   - row indices
43748a0b0e6bSVictor Minden .   j   - column indices
43751230e6d1SVictor Minden .   a   - matrix values
43761230e6d1SVictor Minden .   nz  - number of nonzeros
43771230e6d1SVictor Minden -   idx - 0 or 1 based
43788a0b0e6bSVictor Minden 
43798a0b0e6bSVictor Minden    Output Parameter:
43808a0b0e6bSVictor Minden .   mat - the matrix
43818a0b0e6bSVictor Minden 
43828a0b0e6bSVictor Minden    Level: intermediate
43838a0b0e6bSVictor Minden 
43848a0b0e6bSVictor Minden    Notes:
43858a0b0e6bSVictor Minden        The i and j indices are 0 based
43868a0b0e6bSVictor Minden 
43878a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43888a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43898a0b0e6bSVictor Minden     as shown:
43908a0b0e6bSVictor Minden 
43918a0b0e6bSVictor Minden         1 0 0
43928a0b0e6bSVictor Minden         2 0 3
43938a0b0e6bSVictor Minden         4 5 6
43948a0b0e6bSVictor Minden 
43958a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43968a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43978a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43988a0b0e6bSVictor Minden 
43998a0b0e6bSVictor Minden 
440069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44018a0b0e6bSVictor Minden 
44028a0b0e6bSVictor Minden @*/
44031230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44048a0b0e6bSVictor Minden {
44058a0b0e6bSVictor Minden   PetscErrorCode ierr;
4406d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44078a0b0e6bSVictor Minden 
44088a0b0e6bSVictor Minden 
44098a0b0e6bSVictor Minden   PetscFunctionBegin;
4410d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44111230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44121230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44131230e6d1SVictor Minden     nnz[i[ii]] += 1;
44141230e6d1SVictor Minden   }
44158a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44168a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4417a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
44188a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44191230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44201230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44211230e6d1SVictor Minden     if (idx) {
44221230e6d1SVictor Minden       row = i[ii] - 1;
44231230e6d1SVictor Minden       col = j[ii] - 1;
44241230e6d1SVictor Minden     } else {
44251230e6d1SVictor Minden       row = i[ii];
44261230e6d1SVictor Minden       col = j[ii];
44278a0b0e6bSVictor Minden     }
44281230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44298a0b0e6bSVictor Minden   }
44308a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44318a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4432d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44338a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44348a0b0e6bSVictor Minden }
443536db0b34SBarry Smith 
4436cc8ba8e1SBarry Smith #undef __FUNCT__
4437ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4438dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4439cc8ba8e1SBarry Smith {
4440dfbe8321SBarry Smith   PetscErrorCode ierr;
4441cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444236db0b34SBarry Smith 
4443cc8ba8e1SBarry Smith   PetscFunctionBegin;
44448ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4445cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4446cc8ba8e1SBarry Smith     a->coloring = coloring;
444712c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
444897f1f81fSBarry Smith     PetscInt        i,*larray;
444912c595b3SBarry Smith     ISColoring      ocoloring;
445008b6dcc0SBarry Smith     ISColoringValue *colors;
445112c595b3SBarry Smith 
445212c595b3SBarry Smith     /* set coloring for diagonal portion */
44530e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44542205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44550298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44560e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44572205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
445812c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4459d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446012c595b3SBarry Smith     a->coloring = ocoloring;
446112c595b3SBarry Smith   }
4462cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4463cc8ba8e1SBarry Smith }
4464cc8ba8e1SBarry Smith 
4465ee4f033dSBarry Smith #undef __FUNCT__
4466ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446797f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4468ee4f033dSBarry Smith {
4469ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4470d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447154f21887SBarry Smith   MatScalar       *v      = a->a;
447254f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447308b6dcc0SBarry Smith   ISColoringValue *color;
4474ee4f033dSBarry Smith 
4475ee4f033dSBarry Smith   PetscFunctionBegin;
4476e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4477ee4f033dSBarry Smith   color = a->coloring->colors;
4478ee4f033dSBarry Smith   /* loop over rows */
4479ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4480ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4481ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44822205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4483ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4484cc8ba8e1SBarry Smith   }
4485cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4486cc8ba8e1SBarry Smith }
448736db0b34SBarry Smith 
4488acf2f550SJed Brown #undef __FUNCT__
4489acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4490acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4491acf2f550SJed Brown {
4492acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4493acf2f550SJed Brown   PetscErrorCode ierr;
4494acf2f550SJed Brown 
4495acf2f550SJed Brown   PetscFunctionBegin;
4496acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4497acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
44982205254eSKarl Rupp 
4499acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4500acf2f550SJed Brown   PetscFunctionReturn(0);
4501acf2f550SJed Brown }
4502acf2f550SJed Brown 
450381824310SBarry Smith /*
450481824310SBarry Smith     Special version for direct calls from Fortran
450581824310SBarry Smith */
4506b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
450781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
450881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
450981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451181824310SBarry Smith #endif
451281824310SBarry Smith 
451381824310SBarry Smith /* Change these macros so can be used in void function */
451481824310SBarry Smith #undef CHKERRQ
4515ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
451681824310SBarry Smith #undef SETERRQ2
4517e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45184994cf47SJed Brown #undef SETERRQ3
45194994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452081824310SBarry Smith 
452181824310SBarry Smith #undef __FUNCT__
452281824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45238cc058d9SJed 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)
452481824310SBarry Smith {
452581824310SBarry Smith   Mat            A  = *AA;
452681824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
452781824310SBarry Smith   InsertMode     is = *isis;
452881824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
452981824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453081824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453181824310SBarry Smith   PetscErrorCode ierr;
453281824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453354f21887SBarry Smith   MatScalar      *ap,value,*aa;
4534ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4535ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
453681824310SBarry Smith 
453781824310SBarry Smith   PetscFunctionBegin;
45384994cf47SJed Brown   MatCheckPreallocated(A,1);
453981824310SBarry Smith   imax  = a->imax;
454081824310SBarry Smith   ai    = a->i;
454181824310SBarry Smith   ailen = a->ilen;
454281824310SBarry Smith   aj    = a->j;
454381824310SBarry Smith   aa    = a->a;
454481824310SBarry Smith 
454581824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
454681824310SBarry Smith     row = im[k];
454781824310SBarry Smith     if (row < 0) continue;
454881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4549ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455081824310SBarry Smith #endif
455181824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455281824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455381824310SBarry Smith     low  = 0;
455481824310SBarry Smith     high = nrow;
455581824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
455681824310SBarry Smith       if (in[l] < 0) continue;
455781824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4558ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
455981824310SBarry Smith #endif
456081824310SBarry Smith       col = in[l];
45612205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45622205254eSKarl Rupp       else value = v[k + l*m];
45632205254eSKarl Rupp 
456481824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456581824310SBarry Smith 
45662205254eSKarl Rupp       if (col <= lastcol) low = 0;
45672205254eSKarl Rupp       else high = nrow;
456881824310SBarry Smith       lastcol = col;
456981824310SBarry Smith       while (high-low > 5) {
457081824310SBarry Smith         t = (low+high)/2;
457181824310SBarry Smith         if (rp[t] > col) high = t;
457281824310SBarry Smith         else             low  = t;
457381824310SBarry Smith       }
457481824310SBarry Smith       for (i=low; i<high; i++) {
457581824310SBarry Smith         if (rp[i] > col) break;
457681824310SBarry Smith         if (rp[i] == col) {
457781824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
457881824310SBarry Smith           else                  ap[i] = value;
457981824310SBarry Smith           goto noinsert;
458081824310SBarry Smith         }
458181824310SBarry Smith       }
458281824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458381824310SBarry Smith       if (nonew == 1) goto noinsert;
4584ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4585fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
458681824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
458781824310SBarry Smith       /* shift up all the later entries in this row */
458881824310SBarry Smith       for (ii=N; ii>=i; ii--) {
458981824310SBarry Smith         rp[ii+1] = rp[ii];
459081824310SBarry Smith         ap[ii+1] = ap[ii];
459181824310SBarry Smith       }
459281824310SBarry Smith       rp[i] = col;
459381824310SBarry Smith       ap[i] = value;
459481824310SBarry Smith noinsert:;
459581824310SBarry Smith       low = i + 1;
459681824310SBarry Smith     }
459781824310SBarry Smith     ailen[row] = nrow;
459881824310SBarry Smith   }
459981824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460081824310SBarry Smith   PetscFunctionReturnVoid();
460181824310SBarry Smith }
46029f7953f8SBarry Smith 
460362298a1eSBarry Smith 
4604