xref: /petsc/src/mat/impls/aij/seq/aij.c (revision f86b9fba6afbb510b5a4e5909e38406c0861ad7a)
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);
296625f6d37SHong 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,
3156*f86b9fbaSHong Zhang                                 /* 54*/ 0,
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,
3242*f86b9fbaSHong Zhang                                         0,
3243*f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32449e29f15eSvictorle };
324517ab2063SBarry Smith 
32464a2ae208SSatish Balay #undef __FUNCT__
32474a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32487087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3249bef8e0ddSBarry Smith {
3250bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325197f1f81fSBarry Smith   PetscInt   i,nz,n;
3252bef8e0ddSBarry Smith 
3253bef8e0ddSBarry Smith   PetscFunctionBegin;
3254bef8e0ddSBarry Smith   nz = aij->maxnz;
3255d0f46423SBarry Smith   n  = mat->rmap->n;
3256bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3257bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3258bef8e0ddSBarry Smith   }
3259bef8e0ddSBarry Smith   aij->nz = nz;
3260bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3261bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3262bef8e0ddSBarry Smith   }
3263bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3264bef8e0ddSBarry Smith }
3265bef8e0ddSBarry Smith 
32664a2ae208SSatish Balay #undef __FUNCT__
32674a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3268bef8e0ddSBarry Smith /*@
3269bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3270bef8e0ddSBarry Smith        in the matrix.
3271bef8e0ddSBarry Smith 
3272bef8e0ddSBarry Smith   Input Parameters:
3273bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3274bef8e0ddSBarry Smith -  indices - the column indices
3275bef8e0ddSBarry Smith 
327615091d37SBarry Smith   Level: advanced
327715091d37SBarry Smith 
3278bef8e0ddSBarry Smith   Notes:
3279bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3280bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3281bef8e0ddSBarry Smith   of the MatSetValues() operation.
3282bef8e0ddSBarry Smith 
3283bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3284d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3285bef8e0ddSBarry Smith 
3286bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3287bef8e0ddSBarry Smith 
3288b9617806SBarry Smith     The indices should start with zero, not one.
3289b9617806SBarry Smith 
3290bef8e0ddSBarry Smith @*/
32917087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3292bef8e0ddSBarry Smith {
32934ac538c5SBarry Smith   PetscErrorCode ierr;
3294bef8e0ddSBarry Smith 
3295bef8e0ddSBarry Smith   PetscFunctionBegin;
32960700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32974482741eSBarry Smith   PetscValidPointer(indices,2);
32984ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3299bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3300bef8e0ddSBarry Smith }
3301bef8e0ddSBarry Smith 
3302be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3303be6bf707SBarry Smith 
33044a2ae208SSatish Balay #undef __FUNCT__
33054a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33067087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3307be6bf707SBarry Smith {
3308be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33096849ba73SBarry Smith   PetscErrorCode ierr;
3310d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3311be6bf707SBarry Smith 
3312be6bf707SBarry Smith   PetscFunctionBegin;
3313f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3314be6bf707SBarry Smith 
3315be6bf707SBarry Smith   /* allocate space for values if not already there */
3316be6bf707SBarry Smith   if (!aij->saved_values) {
331787828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33183bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3319be6bf707SBarry Smith   }
3320be6bf707SBarry Smith 
3321be6bf707SBarry Smith   /* copy values over */
332287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3323be6bf707SBarry Smith   PetscFunctionReturn(0);
3324be6bf707SBarry Smith }
3325be6bf707SBarry Smith 
33264a2ae208SSatish Balay #undef __FUNCT__
3327b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3328be6bf707SBarry Smith /*@
3329be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3330be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3331be6bf707SBarry Smith        nonlinear portion.
3332be6bf707SBarry Smith 
3333be6bf707SBarry Smith    Collect on Mat
3334be6bf707SBarry Smith 
3335be6bf707SBarry Smith   Input Parameters:
33360e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3337be6bf707SBarry Smith 
333815091d37SBarry Smith   Level: advanced
333915091d37SBarry Smith 
3340be6bf707SBarry Smith   Common Usage, with SNESSolve():
3341be6bf707SBarry Smith $    Create Jacobian matrix
3342be6bf707SBarry Smith $    Set linear terms into matrix
3343be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3344be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3345be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3346512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3347be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3348be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3349be6bf707SBarry Smith $    In your Jacobian routine
3350be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3351be6bf707SBarry Smith $      Set nonlinear terms in matrix
3352be6bf707SBarry Smith 
3353be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3354be6bf707SBarry Smith $    // build linear portion of Jacobian
3355512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3356be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3357be6bf707SBarry Smith $    loop over nonlinear iterations
3358be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3359be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3360be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3361be6bf707SBarry Smith $       Solve linear system with Jacobian
3362be6bf707SBarry Smith $    endloop
3363be6bf707SBarry Smith 
3364be6bf707SBarry Smith   Notes:
3365be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3366512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3367be6bf707SBarry Smith     calling this routine.
3368be6bf707SBarry Smith 
33690c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33700c468ba9SBarry Smith     and does not allocated additional space.
33710c468ba9SBarry Smith 
3372be6bf707SBarry Smith .seealso: MatRetrieveValues()
3373be6bf707SBarry Smith 
3374be6bf707SBarry Smith @*/
33757087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3376be6bf707SBarry Smith {
33774ac538c5SBarry Smith   PetscErrorCode ierr;
3378be6bf707SBarry Smith 
3379be6bf707SBarry Smith   PetscFunctionBegin;
33800700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3381e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3382e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33834ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3384be6bf707SBarry Smith   PetscFunctionReturn(0);
3385be6bf707SBarry Smith }
3386be6bf707SBarry Smith 
33874a2ae208SSatish Balay #undef __FUNCT__
33884a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33897087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3390be6bf707SBarry Smith {
3391be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33926849ba73SBarry Smith   PetscErrorCode ierr;
3393d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3394be6bf707SBarry Smith 
3395be6bf707SBarry Smith   PetscFunctionBegin;
3396f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3397f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3398be6bf707SBarry Smith   /* copy values over */
339987828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3400be6bf707SBarry Smith   PetscFunctionReturn(0);
3401be6bf707SBarry Smith }
3402be6bf707SBarry Smith 
34034a2ae208SSatish Balay #undef __FUNCT__
34044a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3405be6bf707SBarry Smith /*@
3406be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3407be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3408be6bf707SBarry Smith        nonlinear portion.
3409be6bf707SBarry Smith 
3410be6bf707SBarry Smith    Collect on Mat
3411be6bf707SBarry Smith 
3412be6bf707SBarry Smith   Input Parameters:
3413be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3414be6bf707SBarry Smith 
341515091d37SBarry Smith   Level: advanced
341615091d37SBarry Smith 
3417be6bf707SBarry Smith .seealso: MatStoreValues()
3418be6bf707SBarry Smith 
3419be6bf707SBarry Smith @*/
34207087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3421be6bf707SBarry Smith {
34224ac538c5SBarry Smith   PetscErrorCode ierr;
3423be6bf707SBarry Smith 
3424be6bf707SBarry Smith   PetscFunctionBegin;
34250700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3426e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3427e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34284ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3429be6bf707SBarry Smith   PetscFunctionReturn(0);
3430be6bf707SBarry Smith }
3431be6bf707SBarry Smith 
3432f83d6046SBarry Smith 
3433be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34344a2ae208SSatish Balay #undef __FUNCT__
34354a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
343617ab2063SBarry Smith /*@C
3437682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34380d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34396e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
344051c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34412bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344217ab2063SBarry Smith 
3443db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3444db81eaa0SLois Curfman McInnes 
344517ab2063SBarry Smith    Input Parameters:
3446db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
344717ab2063SBarry Smith .  m - number of rows
344817ab2063SBarry Smith .  n - number of columns
344917ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
345051c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34510298fd71SBarry Smith          (possibly different for each row) or NULL
345217ab2063SBarry Smith 
345317ab2063SBarry Smith    Output Parameter:
3454416022c9SBarry Smith .  A - the matrix
345517ab2063SBarry Smith 
3456175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3457ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3458175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3459175b88e8SBarry Smith 
3460b259b22eSLois Curfman McInnes    Notes:
346149a6f317SBarry Smith    If nnz is given then nz is ignored
346249a6f317SBarry Smith 
346317ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346417ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34650002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
346644cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
346717ab2063SBarry Smith 
346817ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34690298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34703d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34716da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347217ab2063SBarry Smith 
3473682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34744fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3475682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34766c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34776c7ebb05SLois Curfman McInnes 
34786c7ebb05SLois Curfman McInnes    Options Database Keys:
3479698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34809db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348117ab2063SBarry Smith 
3482027ccd11SLois Curfman McInnes    Level: intermediate
3483027ccd11SLois Curfman McInnes 
348469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348536db0b34SBarry Smith 
348617ab2063SBarry Smith @*/
34877087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
348817ab2063SBarry Smith {
3489dfbe8321SBarry Smith   PetscErrorCode ierr;
34906945ee14SBarry Smith 
34913a40ed3dSBarry Smith   PetscFunctionBegin;
3492f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3493117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3494c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3495d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3496273d9f13SBarry Smith   PetscFunctionReturn(0);
3497273d9f13SBarry Smith }
3498273d9f13SBarry Smith 
34994a2ae208SSatish Balay #undef __FUNCT__
35004a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3501273d9f13SBarry Smith /*@C
3502273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3503273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3504273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3505273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3506273d9f13SBarry Smith 
3507273d9f13SBarry Smith    Collective on MPI_Comm
3508273d9f13SBarry Smith 
3509273d9f13SBarry Smith    Input Parameters:
3510117016b1SBarry Smith +  B - The matrix-free
3511273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3512273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35130298fd71SBarry Smith          (possibly different for each row) or NULL
3514273d9f13SBarry Smith 
3515273d9f13SBarry Smith    Notes:
351649a6f317SBarry Smith      If nnz is given then nz is ignored
351749a6f317SBarry Smith 
3518273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3519273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3520273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3521273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3522273d9f13SBarry Smith 
3523273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35240298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3525273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3526273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3527273d9f13SBarry Smith 
3528aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3529aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3530aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3531aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3532aa95bbe8SBarry Smith 
3533a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3534a96a251dSBarry Smith    entries or columns indices
3535a96a251dSBarry Smith 
3536273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3537273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3538273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3539273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3540273d9f13SBarry Smith 
3541273d9f13SBarry Smith    Options Database Keys:
3542698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3543698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3544273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3545273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3546273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3547273d9f13SBarry Smith 
3548273d9f13SBarry Smith    Level: intermediate
3549273d9f13SBarry Smith 
355069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3551273d9f13SBarry Smith 
3552273d9f13SBarry Smith @*/
35537087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3554273d9f13SBarry Smith {
35554ac538c5SBarry Smith   PetscErrorCode ierr;
3556a23d5eceSKris Buschelman 
3557a23d5eceSKris Buschelman   PetscFunctionBegin;
35586ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35596ba663aaSJed Brown   PetscValidType(B,1);
35604ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3561a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3562a23d5eceSKris Buschelman }
3563a23d5eceSKris Buschelman 
3564a23d5eceSKris Buschelman #undef __FUNCT__
3565a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35667087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3567a23d5eceSKris Buschelman {
3568273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35692576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35706849ba73SBarry Smith   PetscErrorCode ierr;
357197f1f81fSBarry Smith   PetscInt       i;
3572273d9f13SBarry Smith 
3573273d9f13SBarry Smith   PetscFunctionBegin;
35742576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3575a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3576c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3577c461c341SBarry Smith     nz             = 0;
3578c461c341SBarry Smith   }
3579c461c341SBarry Smith 
358026283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358126283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3582899cda47SBarry Smith 
3583435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3584e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3585b73539f3SBarry Smith   if (nnz) {
3586d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3587e32f2f54SBarry 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]);
3588e32f2f54SBarry 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);
3589b73539f3SBarry Smith     }
3590b73539f3SBarry Smith   }
3591b73539f3SBarry Smith 
3592273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35932205254eSKarl Rupp 
3594273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3595273d9f13SBarry Smith 
3596ab93d7beSBarry Smith   if (!skipallocation) {
35972ee49352SLisandro Dalcin     if (!b->imax) {
3598d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
35993bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36002ee49352SLisandro Dalcin     }
3601273d9f13SBarry Smith     if (!nnz) {
3602435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3603c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3604d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3605d0f46423SBarry Smith       nz = nz*B->rmap->n;
3606273d9f13SBarry Smith     } else {
3607273d9f13SBarry Smith       nz = 0;
3608d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3609273d9f13SBarry Smith     }
3610ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36112205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3612ab93d7beSBarry Smith 
3613273d9f13SBarry Smith     /* allocate the matrix space */
36142ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3615d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
36163bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3617bfeeae90SHong Zhang     b->i[0] = 0;
3618d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36195da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36205da197adSKris Buschelman     }
3621273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3622e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3623e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3624b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3625b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3626b31eba2aSShri Abhyankar #endif
3627c461c341SBarry Smith   } else {
3628e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3629e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3630c461c341SBarry Smith   }
3631273d9f13SBarry Smith 
3632273d9f13SBarry Smith   b->nz               = 0;
3633273d9f13SBarry Smith   b->maxnz            = nz;
3634273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36352205254eSKarl Rupp   if (realalloc) {
36362205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36372205254eSKarl Rupp   }
3638273d9f13SBarry Smith   PetscFunctionReturn(0);
3639273d9f13SBarry Smith }
3640273d9f13SBarry Smith 
3641a1661176SMatthew Knepley #undef  __FUNCT__
3642a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364358d36128SBarry Smith /*@
3644a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3645a1661176SMatthew Knepley 
3646a1661176SMatthew Knepley    Input Parameters:
3647a1661176SMatthew Knepley +  B - the matrix
3648a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3649a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3650a1661176SMatthew Knepley -  v - optional values in the matrix
3651a1661176SMatthew Knepley 
3652a1661176SMatthew Knepley    Level: developer
3653a1661176SMatthew Knepley 
365458d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365558d36128SBarry Smith 
3656a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3657a1661176SMatthew Knepley 
3658a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3659a1661176SMatthew Knepley @*/
3660a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3661a1661176SMatthew Knepley {
3662a1661176SMatthew Knepley   PetscErrorCode ierr;
3663a1661176SMatthew Knepley 
3664a1661176SMatthew Knepley   PetscFunctionBegin;
36650700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36666ba663aaSJed Brown   PetscValidType(B,1);
36674ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3668a1661176SMatthew Knepley   PetscFunctionReturn(0);
3669a1661176SMatthew Knepley }
3670a1661176SMatthew Knepley 
3671a1661176SMatthew Knepley #undef  __FUNCT__
3672a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36737087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3674a1661176SMatthew Knepley {
3675a1661176SMatthew Knepley   PetscInt       i;
3676a1661176SMatthew Knepley   PetscInt       m,n;
3677a1661176SMatthew Knepley   PetscInt       nz;
3678a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3679a1661176SMatthew Knepley   PetscScalar    *values;
3680a1661176SMatthew Knepley   PetscErrorCode ierr;
3681a1661176SMatthew Knepley 
3682a1661176SMatthew Knepley   PetscFunctionBegin;
368365e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3684779a8d59SSatish Balay 
3685779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3686779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3687779a8d59SSatish Balay 
3688779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3689a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3690a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3691b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3692a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369365e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3694a1661176SMatthew Knepley     nnz[i] = nz;
3695a1661176SMatthew Knepley   }
3696a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3697a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3698a1661176SMatthew Knepley 
3699a1661176SMatthew Knepley   if (v) {
3700a1661176SMatthew Knepley     values = (PetscScalar*) v;
3701a1661176SMatthew Knepley   } else {
37020e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3703a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3704a1661176SMatthew Knepley   }
3705a1661176SMatthew Knepley 
3706a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3707b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3708b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3709a1661176SMatthew Knepley   }
3710a1661176SMatthew Knepley 
3711a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3712a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3713a1661176SMatthew Knepley 
3714a1661176SMatthew Knepley   if (!v) {
3715a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3716a1661176SMatthew Knepley   }
37177827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3718a1661176SMatthew Knepley   PetscFunctionReturn(0);
3719a1661176SMatthew Knepley }
3720a1661176SMatthew Knepley 
3721c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372206873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3723170fe5c8SBarry Smith 
3724170fe5c8SBarry Smith #undef __FUNCT__
3725170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3726170fe5c8SBarry Smith /*
3727170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3728170fe5c8SBarry Smith 
3729170fe5c8SBarry Smith                n                       p                          p
3730170fe5c8SBarry Smith         (              )       (              )         (                  )
3731170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3732170fe5c8SBarry Smith         (              )       (              )         (                  )
3733170fe5c8SBarry Smith 
3734170fe5c8SBarry Smith */
3735170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3736170fe5c8SBarry Smith {
3737170fe5c8SBarry Smith   PetscErrorCode    ierr;
3738170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3739170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3740170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37411de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3742170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3743170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3744170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3745170fe5c8SBarry Smith 
3746170fe5c8SBarry Smith   PetscFunctionBegin;
3747d0f46423SBarry Smith   m    = A->rmap->n;
3748d0f46423SBarry Smith   n    = A->cmap->n;
3749d0f46423SBarry Smith   p    = B->cmap->n;
3750170fe5c8SBarry Smith   a    = sub_a->v;
3751170fe5c8SBarry Smith   b    = sub_b->a;
3752170fe5c8SBarry Smith   c    = sub_c->v;
3753170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3754170fe5c8SBarry Smith 
3755170fe5c8SBarry Smith   ii  = sub_b->i;
3756170fe5c8SBarry Smith   idx = sub_b->j;
3757170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3758170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3759170fe5c8SBarry Smith     while (q-->0) {
3760170fe5c8SBarry Smith       c_q = c + m*(*idx);
3761170fe5c8SBarry Smith       a_q = a + m*i;
3762854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3763170fe5c8SBarry Smith       idx++;
3764170fe5c8SBarry Smith       b++;
3765170fe5c8SBarry Smith     }
3766170fe5c8SBarry Smith   }
3767170fe5c8SBarry Smith   PetscFunctionReturn(0);
3768170fe5c8SBarry Smith }
3769170fe5c8SBarry Smith 
3770170fe5c8SBarry Smith #undef __FUNCT__
3771170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3772170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3773170fe5c8SBarry Smith {
3774170fe5c8SBarry Smith   PetscErrorCode ierr;
3775d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3776170fe5c8SBarry Smith   Mat            Cmat;
3777170fe5c8SBarry Smith 
3778170fe5c8SBarry Smith   PetscFunctionBegin;
3779e32f2f54SBarry 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);
3780ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3781170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3782a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3783170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37840298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3785d73949e8SHong Zhang 
3786d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37872205254eSKarl Rupp 
3788170fe5c8SBarry Smith   *C = Cmat;
3789170fe5c8SBarry Smith   PetscFunctionReturn(0);
3790170fe5c8SBarry Smith }
3791170fe5c8SBarry Smith 
3792170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3793170fe5c8SBarry Smith #undef __FUNCT__
3794170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3795170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3796170fe5c8SBarry Smith {
3797170fe5c8SBarry Smith   PetscErrorCode ierr;
3798170fe5c8SBarry Smith 
3799170fe5c8SBarry Smith   PetscFunctionBegin;
3800170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38013ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3802170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38033ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3804170fe5c8SBarry Smith   }
38053ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3806170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38073ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3808170fe5c8SBarry Smith   PetscFunctionReturn(0);
3809170fe5c8SBarry Smith }
3810170fe5c8SBarry Smith 
3811170fe5c8SBarry Smith 
38120bad9183SKris Buschelman /*MC
3813fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38140bad9183SKris Buschelman    based on compressed sparse row format.
38150bad9183SKris Buschelman 
38160bad9183SKris Buschelman    Options Database Keys:
38170bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38180bad9183SKris Buschelman 
38190bad9183SKris Buschelman   Level: beginner
38200bad9183SKris Buschelman 
3821f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38220bad9183SKris Buschelman M*/
38230bad9183SKris Buschelman 
3824ccd284c7SBarry Smith /*MC
3825ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3826ccd284c7SBarry Smith 
3827ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3828ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3829ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3830ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3831ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3832ccd284c7SBarry Smith 
3833ccd284c7SBarry Smith    Options Database Keys:
3834ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3835ccd284c7SBarry Smith 
3836ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3837ccd284c7SBarry Smith    enough exist.
3838ccd284c7SBarry Smith 
3839ccd284c7SBarry Smith   Level: beginner
3840ccd284c7SBarry Smith 
3841ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3842ccd284c7SBarry Smith M*/
3843ccd284c7SBarry Smith 
3844ccd284c7SBarry Smith /*MC
3845ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3846ccd284c7SBarry Smith 
3847ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3848ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3849ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3850ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3851ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3852ccd284c7SBarry Smith 
3853ccd284c7SBarry Smith    Options Database Keys:
3854ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3855ccd284c7SBarry Smith 
3856ccd284c7SBarry Smith   Level: beginner
3857ccd284c7SBarry Smith 
3858ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3859ccd284c7SBarry Smith M*/
3860ccd284c7SBarry Smith 
3861b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38628cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3863b5e56a35SBarry Smith #endif
3864ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3866af1023dbSSatish Balay #endif
38678cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38707087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3871611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3873611f576cSBarry Smith #endif
3874611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3876611f576cSBarry Smith #endif
3877f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3879f3c0ef26SHong Zhang #endif
3880eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3882eb3b5408SSatish Balay #endif
3883586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3885586621ddSJed Brown #endif
3886719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38878cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3888719d5645SBarry Smith #endif
3889b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38908cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38917087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38927087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3893b3866ffcSBarry Smith #endif
389417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
389617f1a0eaSHong Zhang #endif
389717667f90SBarry Smith 
3898c0c8ee5eSDmitry Karpeev 
38998c778c55SBarry Smith #undef __FUNCT__
39008c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39018c778c55SBarry Smith /*@C
39028c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39038c778c55SBarry Smith 
39048c778c55SBarry Smith    Not Collective
39058c778c55SBarry Smith 
39068c778c55SBarry Smith    Input Parameter:
39078c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39088c778c55SBarry Smith 
39098c778c55SBarry Smith    Output Parameter:
39108c778c55SBarry Smith .   array - pointer to the data
39118c778c55SBarry Smith 
39128c778c55SBarry Smith    Level: intermediate
39138c778c55SBarry Smith 
3914774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39158c778c55SBarry Smith @*/
39168c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39178c778c55SBarry Smith {
39188c778c55SBarry Smith   PetscErrorCode ierr;
39198c778c55SBarry Smith 
39208c778c55SBarry Smith   PetscFunctionBegin;
39218c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39228c778c55SBarry Smith   PetscFunctionReturn(0);
39238c778c55SBarry Smith }
39248c778c55SBarry Smith 
39258c778c55SBarry Smith #undef __FUNCT__
39268c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39278c778c55SBarry Smith /*@C
39288c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39298c778c55SBarry Smith 
39308c778c55SBarry Smith    Not Collective
39318c778c55SBarry Smith 
39328c778c55SBarry Smith    Input Parameters:
39338c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39348c778c55SBarry Smith .  array - pointer to the data
39358c778c55SBarry Smith 
39368c778c55SBarry Smith    Level: intermediate
39378c778c55SBarry Smith 
3938774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39398c778c55SBarry Smith @*/
39408c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39418c778c55SBarry Smith {
39428c778c55SBarry Smith   PetscErrorCode ierr;
39438c778c55SBarry Smith 
39448c778c55SBarry Smith   PetscFunctionBegin;
39458c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39468c778c55SBarry Smith   PetscFunctionReturn(0);
39478c778c55SBarry Smith }
39488c778c55SBarry Smith 
39494a2ae208SSatish Balay #undef __FUNCT__
39504a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3952273d9f13SBarry Smith {
3953273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3954dfbe8321SBarry Smith   PetscErrorCode ierr;
395538baddfdSBarry Smith   PetscMPIInt    size;
3956273d9f13SBarry Smith 
3957273d9f13SBarry Smith   PetscFunctionBegin;
3958ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3959e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3960273d9f13SBarry Smith 
396138f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39622205254eSKarl Rupp 
3963b0a32e0cSBarry Smith   B->data = (void*)b;
39642205254eSKarl Rupp 
3965549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39662205254eSKarl Rupp 
3967416022c9SBarry Smith   b->row                = 0;
3968416022c9SBarry Smith   b->col                = 0;
396982bf6240SBarry Smith   b->icol               = 0;
3970b810aeb4SBarry Smith   b->reallocs           = 0;
397136db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3972f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3973416022c9SBarry Smith   b->nonew              = 0;
3974416022c9SBarry Smith   b->diag               = 0;
3975416022c9SBarry Smith   b->solve_work         = 0;
39762a1b7f2aSHong Zhang   B->spptr              = 0;
3977be6bf707SBarry Smith   b->saved_values       = 0;
3978d7f994e1SBarry Smith   b->idiag              = 0;
397971f1c65dSBarry Smith   b->mdiag              = 0;
398071f1c65dSBarry Smith   b->ssor_work          = 0;
398171f1c65dSBarry Smith   b->omega              = 1.0;
398271f1c65dSBarry Smith   b->fshift             = 0.0;
398371f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3984bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3985a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3986a30b2313SHong Zhang   b->xtoy               = 0;
3987a30b2313SHong Zhang   b->XtoY               = 0;
398888e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
398917ab2063SBarry Smith 
399035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3991bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3992bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39938c778c55SBarry Smith 
3994b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3997bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3998b3866ffcSBarry Smith #endif
3999b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4000bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4001b5e56a35SBarry Smith #endif
4002ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4003bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4004719d5645SBarry Smith #endif
4005611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4006bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4007611f576cSBarry Smith #endif
4008f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4009bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4010f3c0ef26SHong Zhang #endif
4011611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4012bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4013611f576cSBarry Smith #endif
4014eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4015bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4016eb3b5408SSatish Balay #endif
4017586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4018bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4019586621ddSJed Brown #endif
4020719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4021bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4022719d5645SBarry Smith #endif
402317f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4024bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402517f1a0eaSHong Zhang #endif
402617f1a0eaSHong Zhang 
4027bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40454108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
404617667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40473a40ed3dSBarry Smith   PetscFunctionReturn(0);
404817ab2063SBarry Smith }
404917ab2063SBarry Smith 
40504a2ae208SSatish Balay #undef __FUNCT__
4051b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4052b24902e0SBarry Smith /*
4053b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4054b24902e0SBarry Smith */
4055ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
405617ab2063SBarry Smith {
4057416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40586849ba73SBarry Smith   PetscErrorCode ierr;
4059d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
406017ab2063SBarry Smith 
40613a40ed3dSBarry Smith   PetscFunctionBegin;
4062273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4063273d9f13SBarry Smith 
4064d5f3da31SBarry Smith   C->factortype = A->factortype;
4065416022c9SBarry Smith   c->row        = 0;
4066416022c9SBarry Smith   c->col        = 0;
406782bf6240SBarry Smith   c->icol       = 0;
40686ad4291fSHong Zhang   c->reallocs   = 0;
406917ab2063SBarry Smith 
40706ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407117ab2063SBarry Smith 
4072aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4073aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4074eec197d1SBarry Smith 
407533b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40763bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
407717ab2063SBarry Smith   for (i=0; i<m; i++) {
4078416022c9SBarry Smith     c->imax[i] = a->imax[i];
4079416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
408017ab2063SBarry Smith   }
408117ab2063SBarry Smith 
408217ab2063SBarry Smith   /* allocate the matrix space */
4083f77e22a1SHong Zhang   if (mallocmatspace) {
4084a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40853bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40862205254eSKarl Rupp 
4087f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40882205254eSKarl Rupp 
408997f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409017ab2063SBarry Smith     if (m > 0) {
409197f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4092be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4093bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4094be6bf707SBarry Smith       } else {
4095bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
409617ab2063SBarry Smith       }
409708480c60SBarry Smith     }
4098f77e22a1SHong Zhang   }
409917ab2063SBarry Smith 
41006ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4101416022c9SBarry Smith   c->roworiented       = a->roworiented;
4102416022c9SBarry Smith   c->nonew             = a->nonew;
4103416022c9SBarry Smith   if (a->diag) {
410497f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41053bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410617ab2063SBarry Smith     for (i=0; i<m; i++) {
4107416022c9SBarry Smith       c->diag[i] = a->diag[i];
410817ab2063SBarry Smith     }
41093a40ed3dSBarry Smith   } else c->diag = 0;
41102205254eSKarl Rupp 
41116ad4291fSHong Zhang   c->solve_work         = 0;
41126ad4291fSHong Zhang   c->saved_values       = 0;
41136ad4291fSHong Zhang   c->idiag              = 0;
411471f1c65dSBarry Smith   c->ssor_work          = 0;
4115a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4116e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4117e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41186ad4291fSHong Zhang   c->xtoy               = 0;
41196ad4291fSHong Zhang   c->XtoY               = 0;
41206ad4291fSHong Zhang 
4121893ad86cSHong Zhang   c->rmax         = a->rmax;
4122416022c9SBarry Smith   c->nz           = a->nz;
41238ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4124273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4125754ec7b1SSatish Balay 
41266ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41276ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4128cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4129cd6b891eSBarry Smith   if (a->compressedrow.use) {
41306ad4291fSHong Zhang     i    = a->compressedrow.nrows;
41310e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
41326ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41336ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413427ea64f8SHong Zhang   } else {
413527ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41360298fd71SBarry Smith     c->compressedrow.i      = NULL;
41370298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41386ad4291fSHong Zhang   }
413988e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41404846f1f5SKris Buschelman 
41412205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4142140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41433a40ed3dSBarry Smith   PetscFunctionReturn(0);
414417ab2063SBarry Smith }
414517ab2063SBarry Smith 
41464a2ae208SSatish Balay #undef __FUNCT__
4147b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4148b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4149b24902e0SBarry Smith {
4150b24902e0SBarry Smith   PetscErrorCode ierr;
4151b24902e0SBarry Smith 
4152b24902e0SBarry Smith   PetscFunctionBegin;
4153ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41544b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4155a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4156a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4157f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4158b24902e0SBarry Smith   PetscFunctionReturn(0);
4159b24902e0SBarry Smith }
4160b24902e0SBarry Smith 
4161b24902e0SBarry Smith #undef __FUNCT__
41624a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4163112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4164fbdbba38SShri Abhyankar {
4165fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4166fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4167fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4168fbdbba38SShri Abhyankar   int            fd;
4169fbdbba38SShri Abhyankar   PetscMPIInt    size;
4170fbdbba38SShri Abhyankar   MPI_Comm       comm;
4171bbead8a2SBarry Smith   PetscInt       bs = 1;
4172fbdbba38SShri Abhyankar 
4173fbdbba38SShri Abhyankar   PetscFunctionBegin;
4174fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4175fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4176fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4177bbead8a2SBarry Smith 
41780298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41790298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4180bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41811814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4182bbead8a2SBarry Smith 
4183fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4184fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4185fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4186fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4187fbdbba38SShri Abhyankar 
4188bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4189fbdbba38SShri Abhyankar 
4190fbdbba38SShri Abhyankar   /* read in row lengths */
4191fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4192fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4193fbdbba38SShri Abhyankar 
4194fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4195fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4196fbdbba38SShri 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);
4197fbdbba38SShri Abhyankar 
4198fbdbba38SShri Abhyankar   /* set global size if not set already*/
4199f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4200fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4201aabbc4fbSShri Abhyankar   } else {
4202fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4203fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42044c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42054c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42064c5b953cSHong Zhang     }
4207f501eaabSShri 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);
4208aabbc4fbSShri Abhyankar   }
4209fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4210fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4211fbdbba38SShri Abhyankar 
4212fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4213fbdbba38SShri Abhyankar 
4214fbdbba38SShri Abhyankar   /* read in nonzero values */
4215fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4216fbdbba38SShri Abhyankar 
4217fbdbba38SShri Abhyankar   /* set matrix "i" values */
4218fbdbba38SShri Abhyankar   a->i[0] = 0;
4219fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4220fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4221fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4222fbdbba38SShri Abhyankar   }
4223fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4224fbdbba38SShri Abhyankar 
4225fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4226fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4227fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4228fbdbba38SShri Abhyankar }
4229fbdbba38SShri Abhyankar 
4230fbdbba38SShri Abhyankar #undef __FUNCT__
4231b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4232ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42337264ac53SSatish Balay {
42347264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4235dfbe8321SBarry Smith   PetscErrorCode ierr;
4236eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4237eeffb40dSHong Zhang   PetscInt k;
4238eeffb40dSHong Zhang #endif
42397264ac53SSatish Balay 
42403a40ed3dSBarry Smith   PetscFunctionBegin;
4241bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4242d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4243ca44d042SBarry Smith     *flg = PETSC_FALSE;
4244ca44d042SBarry Smith     PetscFunctionReturn(0);
4245bcd2baecSBarry Smith   }
42467264ac53SSatish Balay 
42477264ac53SSatish Balay   /* if the a->i are the same */
4248d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4249abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42507264ac53SSatish Balay 
42517264ac53SSatish Balay   /* if a->j are the same */
425297f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4253abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4254bcd2baecSBarry Smith 
4255bcd2baecSBarry Smith   /* if a->a are the same */
4256eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4257eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4258eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4259eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42603a40ed3dSBarry Smith       PetscFunctionReturn(0);
4261eeffb40dSHong Zhang     }
4262eeffb40dSHong Zhang   }
4263eeffb40dSHong Zhang #else
4264eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4265eeffb40dSHong Zhang #endif
4266eeffb40dSHong Zhang   PetscFunctionReturn(0);
42677264ac53SSatish Balay }
426836db0b34SBarry Smith 
42694a2ae208SSatish Balay #undef __FUNCT__
42704a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
427105869f15SSatish Balay /*@
427236db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427336db0b34SBarry Smith               provided by the user.
427436db0b34SBarry Smith 
4275c75a6043SHong Zhang       Collective on MPI_Comm
427636db0b34SBarry Smith 
427736db0b34SBarry Smith    Input Parameters:
427836db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
427936db0b34SBarry Smith .   m - number of rows
428036db0b34SBarry Smith .   n - number of columns
428136db0b34SBarry Smith .   i - row indices
428236db0b34SBarry Smith .   j - column indices
428336db0b34SBarry Smith -   a - matrix values
428436db0b34SBarry Smith 
428536db0b34SBarry Smith    Output Parameter:
428636db0b34SBarry Smith .   mat - the matrix
428736db0b34SBarry Smith 
428836db0b34SBarry Smith    Level: intermediate
428936db0b34SBarry Smith 
429036db0b34SBarry Smith    Notes:
42910551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4292292fb18eSBarry Smith     once the matrix is destroyed and not before
429336db0b34SBarry Smith 
429436db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429536db0b34SBarry Smith 
4296bfeeae90SHong Zhang        The i and j indices are 0 based
429736db0b34SBarry Smith 
4298a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4299a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4300a4552177SSatish Balay     as shown:
4301a4552177SSatish Balay 
4302a4552177SSatish Balay         1 0 0
4303a4552177SSatish Balay         2 0 3
4304a4552177SSatish Balay         4 5 6
4305a4552177SSatish Balay 
4306a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43079985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4308a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4309a4552177SSatish Balay 
43109985e31cSBarry Smith 
431169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
431236db0b34SBarry Smith 
431336db0b34SBarry Smith @*/
43147087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431536db0b34SBarry Smith {
4316dfbe8321SBarry Smith   PetscErrorCode ierr;
4317cbcfb4deSHong Zhang   PetscInt       ii;
431836db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4319cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4320cbcfb4deSHong Zhang   PetscInt jj;
4321cbcfb4deSHong Zhang #endif
432236db0b34SBarry Smith 
432336db0b34SBarry Smith   PetscFunctionBegin;
4324f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4325f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4326f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4327a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4328ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4329ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4330ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4331ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4332ab93d7beSBarry Smith 
433336db0b34SBarry Smith   aij->i            = i;
433436db0b34SBarry Smith   aij->j            = j;
433536db0b34SBarry Smith   aij->a            = a;
433636db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
433736db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4338e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4339e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
434036db0b34SBarry Smith 
434136db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
434236db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43432515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4344e32f2f54SBarry 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]);
43459985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
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 not sorted",jj-i[ii],j[jj],ii);
4347e32f2f54SBarry 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);
43489985e31cSBarry Smith     }
434936db0b34SBarry Smith #endif
435036db0b34SBarry Smith   }
43512515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435236db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4353e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4354e32f2f54SBarry 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]);
435536db0b34SBarry Smith   }
435636db0b34SBarry Smith #endif
435736db0b34SBarry Smith 
4358b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4359b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
436036db0b34SBarry Smith   PetscFunctionReturn(0);
436136db0b34SBarry Smith }
43628a0b0e6bSVictor Minden #undef __FUNCT__
43638a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436480ef6e79SMatthew G Knepley /*@C
4365d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43668a0b0e6bSVictor Minden               provided by the user.
43678a0b0e6bSVictor Minden 
43688a0b0e6bSVictor Minden       Collective on MPI_Comm
43698a0b0e6bSVictor Minden 
43708a0b0e6bSVictor Minden    Input Parameters:
43718a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43728a0b0e6bSVictor Minden .   m   - number of rows
43738a0b0e6bSVictor Minden .   n   - number of columns
43748a0b0e6bSVictor Minden .   i   - row indices
43758a0b0e6bSVictor Minden .   j   - column indices
43761230e6d1SVictor Minden .   a   - matrix values
43771230e6d1SVictor Minden .   nz  - number of nonzeros
43781230e6d1SVictor Minden -   idx - 0 or 1 based
43798a0b0e6bSVictor Minden 
43808a0b0e6bSVictor Minden    Output Parameter:
43818a0b0e6bSVictor Minden .   mat - the matrix
43828a0b0e6bSVictor Minden 
43838a0b0e6bSVictor Minden    Level: intermediate
43848a0b0e6bSVictor Minden 
43858a0b0e6bSVictor Minden    Notes:
43868a0b0e6bSVictor Minden        The i and j indices are 0 based
43878a0b0e6bSVictor Minden 
43888a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43898a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43908a0b0e6bSVictor Minden     as shown:
43918a0b0e6bSVictor Minden 
43928a0b0e6bSVictor Minden         1 0 0
43938a0b0e6bSVictor Minden         2 0 3
43948a0b0e6bSVictor Minden         4 5 6
43958a0b0e6bSVictor Minden 
43968a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43978a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43988a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43998a0b0e6bSVictor Minden 
44008a0b0e6bSVictor Minden 
440169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44028a0b0e6bSVictor Minden 
44038a0b0e6bSVictor Minden @*/
44041230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44058a0b0e6bSVictor Minden {
44068a0b0e6bSVictor Minden   PetscErrorCode ierr;
4407d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44088a0b0e6bSVictor Minden 
44098a0b0e6bSVictor Minden 
44108a0b0e6bSVictor Minden   PetscFunctionBegin;
4411d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44121230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44131230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44141230e6d1SVictor Minden     nnz[i[ii]] += 1;
44151230e6d1SVictor Minden   }
44168a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44178a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4418a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
44198a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44201230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44211230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44221230e6d1SVictor Minden     if (idx) {
44231230e6d1SVictor Minden       row = i[ii] - 1;
44241230e6d1SVictor Minden       col = j[ii] - 1;
44251230e6d1SVictor Minden     } else {
44261230e6d1SVictor Minden       row = i[ii];
44271230e6d1SVictor Minden       col = j[ii];
44288a0b0e6bSVictor Minden     }
44291230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44308a0b0e6bSVictor Minden   }
44318a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44328a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4433d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44348a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44358a0b0e6bSVictor Minden }
443636db0b34SBarry Smith 
4437cc8ba8e1SBarry Smith #undef __FUNCT__
4438ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4439dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4440cc8ba8e1SBarry Smith {
4441dfbe8321SBarry Smith   PetscErrorCode ierr;
4442cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444336db0b34SBarry Smith 
4444cc8ba8e1SBarry Smith   PetscFunctionBegin;
44458ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4446cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4447cc8ba8e1SBarry Smith     a->coloring = coloring;
444812c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
444997f1f81fSBarry Smith     PetscInt        i,*larray;
445012c595b3SBarry Smith     ISColoring      ocoloring;
445108b6dcc0SBarry Smith     ISColoringValue *colors;
445212c595b3SBarry Smith 
445312c595b3SBarry Smith     /* set coloring for diagonal portion */
44540e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44552205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44560298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44570e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44582205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
445912c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4460d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446112c595b3SBarry Smith     a->coloring = ocoloring;
446212c595b3SBarry Smith   }
4463cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4464cc8ba8e1SBarry Smith }
4465cc8ba8e1SBarry Smith 
4466ee4f033dSBarry Smith #undef __FUNCT__
4467ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446897f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4469ee4f033dSBarry Smith {
4470ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4471d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447254f21887SBarry Smith   MatScalar       *v      = a->a;
447354f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447408b6dcc0SBarry Smith   ISColoringValue *color;
4475ee4f033dSBarry Smith 
4476ee4f033dSBarry Smith   PetscFunctionBegin;
4477e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4478ee4f033dSBarry Smith   color = a->coloring->colors;
4479ee4f033dSBarry Smith   /* loop over rows */
4480ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4481ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4482ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44832205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4484ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4485cc8ba8e1SBarry Smith   }
4486cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4487cc8ba8e1SBarry Smith }
448836db0b34SBarry Smith 
4489acf2f550SJed Brown #undef __FUNCT__
4490acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4491acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4492acf2f550SJed Brown {
4493acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4494acf2f550SJed Brown   PetscErrorCode ierr;
4495acf2f550SJed Brown 
4496acf2f550SJed Brown   PetscFunctionBegin;
4497acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4498acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
44992205254eSKarl Rupp 
4500acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4501acf2f550SJed Brown   PetscFunctionReturn(0);
4502acf2f550SJed Brown }
4503acf2f550SJed Brown 
450481824310SBarry Smith /*
450581824310SBarry Smith     Special version for direct calls from Fortran
450681824310SBarry Smith */
4507b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
450881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
450981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
451081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451281824310SBarry Smith #endif
451381824310SBarry Smith 
451481824310SBarry Smith /* Change these macros so can be used in void function */
451581824310SBarry Smith #undef CHKERRQ
4516ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
451781824310SBarry Smith #undef SETERRQ2
4518e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45194994cf47SJed Brown #undef SETERRQ3
45204994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452181824310SBarry Smith 
452281824310SBarry Smith #undef __FUNCT__
452381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45248cc058d9SJed 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)
452581824310SBarry Smith {
452681824310SBarry Smith   Mat            A  = *AA;
452781824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
452881824310SBarry Smith   InsertMode     is = *isis;
452981824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
453081824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453181824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453281824310SBarry Smith   PetscErrorCode ierr;
453381824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453454f21887SBarry Smith   MatScalar      *ap,value,*aa;
4535ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4536ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
453781824310SBarry Smith 
453881824310SBarry Smith   PetscFunctionBegin;
45394994cf47SJed Brown   MatCheckPreallocated(A,1);
454081824310SBarry Smith   imax  = a->imax;
454181824310SBarry Smith   ai    = a->i;
454281824310SBarry Smith   ailen = a->ilen;
454381824310SBarry Smith   aj    = a->j;
454481824310SBarry Smith   aa    = a->a;
454581824310SBarry Smith 
454681824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
454781824310SBarry Smith     row = im[k];
454881824310SBarry Smith     if (row < 0) continue;
454981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4550ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455181824310SBarry Smith #endif
455281824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455381824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455481824310SBarry Smith     low  = 0;
455581824310SBarry Smith     high = nrow;
455681824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
455781824310SBarry Smith       if (in[l] < 0) continue;
455881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4559ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
456081824310SBarry Smith #endif
456181824310SBarry Smith       col = in[l];
45622205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45632205254eSKarl Rupp       else value = v[k + l*m];
45642205254eSKarl Rupp 
456581824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456681824310SBarry Smith 
45672205254eSKarl Rupp       if (col <= lastcol) low = 0;
45682205254eSKarl Rupp       else high = nrow;
456981824310SBarry Smith       lastcol = col;
457081824310SBarry Smith       while (high-low > 5) {
457181824310SBarry Smith         t = (low+high)/2;
457281824310SBarry Smith         if (rp[t] > col) high = t;
457381824310SBarry Smith         else             low  = t;
457481824310SBarry Smith       }
457581824310SBarry Smith       for (i=low; i<high; i++) {
457681824310SBarry Smith         if (rp[i] > col) break;
457781824310SBarry Smith         if (rp[i] == col) {
457881824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
457981824310SBarry Smith           else                  ap[i] = value;
458081824310SBarry Smith           goto noinsert;
458181824310SBarry Smith         }
458281824310SBarry Smith       }
458381824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458481824310SBarry Smith       if (nonew == 1) goto noinsert;
4585ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4586fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
458781824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
458881824310SBarry Smith       /* shift up all the later entries in this row */
458981824310SBarry Smith       for (ii=N; ii>=i; ii--) {
459081824310SBarry Smith         rp[ii+1] = rp[ii];
459181824310SBarry Smith         ap[ii+1] = ap[ii];
459281824310SBarry Smith       }
459381824310SBarry Smith       rp[i] = col;
459481824310SBarry Smith       ap[i] = value;
459581824310SBarry Smith noinsert:;
459681824310SBarry Smith       low = i + 1;
459781824310SBarry Smith     }
459881824310SBarry Smith     ailen[row] = nrow;
459981824310SBarry Smith   }
460081824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460181824310SBarry Smith   PetscFunctionReturnVoid();
460281824310SBarry Smith }
46039f7953f8SBarry Smith 
460462298a1eSBarry Smith 
4605