xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 1919a2e27368ed52b6c8261d193f4ca7e8c0f256)
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,
315693dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3157b9617806SBarry Smith                                         0,
31580513a670SBarry Smith                                         0,
3159cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3160cda55fadSBarry Smith                                         0,
3161d519adbfSMatthew Knepley                                 /* 59*/ 0,
3162b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3163b9b97703SBarry Smith                                         MatView_SeqAIJ,
3164357abbc8SBarry Smith                                         0,
3165321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3166321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3167321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3168ee4f033dSBarry Smith                                         0,
3169ee4f033dSBarry Smith                                         0,
3170ee4f033dSBarry Smith                                         0,
3171d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3172c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3173ee4f033dSBarry Smith                                         0,
3174ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3175dcf5cc72SBarry Smith                                         0,
3176d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31773acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
317897304618SKris Buschelman                                         0,
317997304618SKris Buschelman                                         0,
318097304618SKris Buschelman                                         0,
31816ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
318297304618SKris Buschelman                                         0,
318397304618SKris Buschelman                                         0,
318497304618SKris Buschelman                                         0,
3185bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3186d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31871cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31886284ec50SHong Zhang                                         0,
31896284ec50SHong Zhang                                         0,
3190bc011b1eSHong Zhang                                         0,
3191d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
319226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
319326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
319465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31954a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
319665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31976fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31986fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31996fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32002121bac1SHong Zhang                                         0,
32012121bac1SHong Zhang                                 /* 99*/ 0,
3202609c6c4dSKris Buschelman                                         0,
3203609c6c4dSKris Buschelman                                         0,
320487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
320587d4246cSBarry Smith                                         0,
3206d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
320799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3208f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3209f5edf698SHong Zhang                                         0,
32102bebee5dSHong Zhang                                         0,
3211cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3212985db425SBarry Smith                                         0,
32132af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32142af78befSBarry Smith                                         0,
3215599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3216d519adbfSMatthew Knepley                                 /*114*/ 0,
3217599ef60dSHong Zhang                                         0,
32183c2a7987SHong Zhang                                         0,
3219fe97e370SBarry Smith                                         0,
3220fbdbba38SShri Abhyankar                                         0,
3221fbdbba38SShri Abhyankar                                 /*119*/ 0,
3222fbdbba38SShri Abhyankar                                         0,
3223fbdbba38SShri Abhyankar                                         0,
322482d44351SHong Zhang                                         0,
3225b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32260716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3227bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
322837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
322937868618SMatthew G Knepley                                         0,
323037868618SMatthew G Knepley                                         0,
32315df89d91SHong Zhang                                 /*129*/ 0,
323275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
323375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
323475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3235b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3236b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32372b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32382b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32392b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32403964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32413964eb88SJed Brown                                  /*139*/0,
3242f86b9fbaSHong Zhang                                         0,
3243*1919a2e2SJed Brown                                         0,
3244f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32459e29f15eSvictorle };
324617ab2063SBarry Smith 
32474a2ae208SSatish Balay #undef __FUNCT__
32484a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32497087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3250bef8e0ddSBarry Smith {
3251bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
325297f1f81fSBarry Smith   PetscInt   i,nz,n;
3253bef8e0ddSBarry Smith 
3254bef8e0ddSBarry Smith   PetscFunctionBegin;
3255bef8e0ddSBarry Smith   nz = aij->maxnz;
3256d0f46423SBarry Smith   n  = mat->rmap->n;
3257bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3258bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3259bef8e0ddSBarry Smith   }
3260bef8e0ddSBarry Smith   aij->nz = nz;
3261bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3262bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3263bef8e0ddSBarry Smith   }
3264bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3265bef8e0ddSBarry Smith }
3266bef8e0ddSBarry Smith 
32674a2ae208SSatish Balay #undef __FUNCT__
32684a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3269bef8e0ddSBarry Smith /*@
3270bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3271bef8e0ddSBarry Smith        in the matrix.
3272bef8e0ddSBarry Smith 
3273bef8e0ddSBarry Smith   Input Parameters:
3274bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3275bef8e0ddSBarry Smith -  indices - the column indices
3276bef8e0ddSBarry Smith 
327715091d37SBarry Smith   Level: advanced
327815091d37SBarry Smith 
3279bef8e0ddSBarry Smith   Notes:
3280bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3281bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3282bef8e0ddSBarry Smith   of the MatSetValues() operation.
3283bef8e0ddSBarry Smith 
3284bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3285d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3286bef8e0ddSBarry Smith 
3287bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3288bef8e0ddSBarry Smith 
3289b9617806SBarry Smith     The indices should start with zero, not one.
3290b9617806SBarry Smith 
3291bef8e0ddSBarry Smith @*/
32927087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3293bef8e0ddSBarry Smith {
32944ac538c5SBarry Smith   PetscErrorCode ierr;
3295bef8e0ddSBarry Smith 
3296bef8e0ddSBarry Smith   PetscFunctionBegin;
32970700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32984482741eSBarry Smith   PetscValidPointer(indices,2);
32994ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3300bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3301bef8e0ddSBarry Smith }
3302bef8e0ddSBarry Smith 
3303be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3304be6bf707SBarry Smith 
33054a2ae208SSatish Balay #undef __FUNCT__
33064a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33077087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3308be6bf707SBarry Smith {
3309be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33106849ba73SBarry Smith   PetscErrorCode ierr;
3311d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3312be6bf707SBarry Smith 
3313be6bf707SBarry Smith   PetscFunctionBegin;
3314f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3315be6bf707SBarry Smith 
3316be6bf707SBarry Smith   /* allocate space for values if not already there */
3317be6bf707SBarry Smith   if (!aij->saved_values) {
331887828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33193bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3320be6bf707SBarry Smith   }
3321be6bf707SBarry Smith 
3322be6bf707SBarry Smith   /* copy values over */
332387828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3324be6bf707SBarry Smith   PetscFunctionReturn(0);
3325be6bf707SBarry Smith }
3326be6bf707SBarry Smith 
33274a2ae208SSatish Balay #undef __FUNCT__
3328b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3329be6bf707SBarry Smith /*@
3330be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3331be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3332be6bf707SBarry Smith        nonlinear portion.
3333be6bf707SBarry Smith 
3334be6bf707SBarry Smith    Collect on Mat
3335be6bf707SBarry Smith 
3336be6bf707SBarry Smith   Input Parameters:
33370e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3338be6bf707SBarry Smith 
333915091d37SBarry Smith   Level: advanced
334015091d37SBarry Smith 
3341be6bf707SBarry Smith   Common Usage, with SNESSolve():
3342be6bf707SBarry Smith $    Create Jacobian matrix
3343be6bf707SBarry Smith $    Set linear terms into matrix
3344be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3345be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3346be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3347512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3348be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3349be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3350be6bf707SBarry Smith $    In your Jacobian routine
3351be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3352be6bf707SBarry Smith $      Set nonlinear terms in matrix
3353be6bf707SBarry Smith 
3354be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3355be6bf707SBarry Smith $    // build linear portion of Jacobian
3356512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3357be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3358be6bf707SBarry Smith $    loop over nonlinear iterations
3359be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3360be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3361be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3362be6bf707SBarry Smith $       Solve linear system with Jacobian
3363be6bf707SBarry Smith $    endloop
3364be6bf707SBarry Smith 
3365be6bf707SBarry Smith   Notes:
3366be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3367512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3368be6bf707SBarry Smith     calling this routine.
3369be6bf707SBarry Smith 
33700c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33710c468ba9SBarry Smith     and does not allocated additional space.
33720c468ba9SBarry Smith 
3373be6bf707SBarry Smith .seealso: MatRetrieveValues()
3374be6bf707SBarry Smith 
3375be6bf707SBarry Smith @*/
33767087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3377be6bf707SBarry Smith {
33784ac538c5SBarry Smith   PetscErrorCode ierr;
3379be6bf707SBarry Smith 
3380be6bf707SBarry Smith   PetscFunctionBegin;
33810700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3382e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3383e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33844ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3385be6bf707SBarry Smith   PetscFunctionReturn(0);
3386be6bf707SBarry Smith }
3387be6bf707SBarry Smith 
33884a2ae208SSatish Balay #undef __FUNCT__
33894a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33907087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3391be6bf707SBarry Smith {
3392be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33936849ba73SBarry Smith   PetscErrorCode ierr;
3394d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3395be6bf707SBarry Smith 
3396be6bf707SBarry Smith   PetscFunctionBegin;
3397f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3398f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3399be6bf707SBarry Smith   /* copy values over */
340087828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3401be6bf707SBarry Smith   PetscFunctionReturn(0);
3402be6bf707SBarry Smith }
3403be6bf707SBarry Smith 
34044a2ae208SSatish Balay #undef __FUNCT__
34054a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3406be6bf707SBarry Smith /*@
3407be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3408be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3409be6bf707SBarry Smith        nonlinear portion.
3410be6bf707SBarry Smith 
3411be6bf707SBarry Smith    Collect on Mat
3412be6bf707SBarry Smith 
3413be6bf707SBarry Smith   Input Parameters:
3414be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3415be6bf707SBarry Smith 
341615091d37SBarry Smith   Level: advanced
341715091d37SBarry Smith 
3418be6bf707SBarry Smith .seealso: MatStoreValues()
3419be6bf707SBarry Smith 
3420be6bf707SBarry Smith @*/
34217087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3422be6bf707SBarry Smith {
34234ac538c5SBarry Smith   PetscErrorCode ierr;
3424be6bf707SBarry Smith 
3425be6bf707SBarry Smith   PetscFunctionBegin;
34260700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3427e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3428e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34294ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3430be6bf707SBarry Smith   PetscFunctionReturn(0);
3431be6bf707SBarry Smith }
3432be6bf707SBarry Smith 
3433f83d6046SBarry Smith 
3434be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34354a2ae208SSatish Balay #undef __FUNCT__
34364a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
343717ab2063SBarry Smith /*@C
3438682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34390d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34406e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
344151c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34422bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344317ab2063SBarry Smith 
3444db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3445db81eaa0SLois Curfman McInnes 
344617ab2063SBarry Smith    Input Parameters:
3447db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
344817ab2063SBarry Smith .  m - number of rows
344917ab2063SBarry Smith .  n - number of columns
345017ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
345151c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34520298fd71SBarry Smith          (possibly different for each row) or NULL
345317ab2063SBarry Smith 
345417ab2063SBarry Smith    Output Parameter:
3455416022c9SBarry Smith .  A - the matrix
345617ab2063SBarry Smith 
3457175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3458ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3459175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3460175b88e8SBarry Smith 
3461b259b22eSLois Curfman McInnes    Notes:
346249a6f317SBarry Smith    If nnz is given then nz is ignored
346349a6f317SBarry Smith 
346417ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346517ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34660002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
346744cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
346817ab2063SBarry Smith 
346917ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34700298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34713d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34726da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347317ab2063SBarry Smith 
3474682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34754fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3476682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34776c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34786c7ebb05SLois Curfman McInnes 
34796c7ebb05SLois Curfman McInnes    Options Database Keys:
3480698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34819db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
348217ab2063SBarry Smith 
3483027ccd11SLois Curfman McInnes    Level: intermediate
3484027ccd11SLois Curfman McInnes 
348569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348636db0b34SBarry Smith 
348717ab2063SBarry Smith @*/
34887087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
348917ab2063SBarry Smith {
3490dfbe8321SBarry Smith   PetscErrorCode ierr;
34916945ee14SBarry Smith 
34923a40ed3dSBarry Smith   PetscFunctionBegin;
3493f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3494117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3495c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3496d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3497273d9f13SBarry Smith   PetscFunctionReturn(0);
3498273d9f13SBarry Smith }
3499273d9f13SBarry Smith 
35004a2ae208SSatish Balay #undef __FUNCT__
35014a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3502273d9f13SBarry Smith /*@C
3503273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3504273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3505273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3506273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3507273d9f13SBarry Smith 
3508273d9f13SBarry Smith    Collective on MPI_Comm
3509273d9f13SBarry Smith 
3510273d9f13SBarry Smith    Input Parameters:
3511117016b1SBarry Smith +  B - The matrix-free
3512273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3513273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35140298fd71SBarry Smith          (possibly different for each row) or NULL
3515273d9f13SBarry Smith 
3516273d9f13SBarry Smith    Notes:
351749a6f317SBarry Smith      If nnz is given then nz is ignored
351849a6f317SBarry Smith 
3519273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3520273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3521273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3522273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3523273d9f13SBarry Smith 
3524273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35250298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3526273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3527273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3528273d9f13SBarry Smith 
3529aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3530aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3531aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3532aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3533aa95bbe8SBarry Smith 
3534a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3535a96a251dSBarry Smith    entries or columns indices
3536a96a251dSBarry Smith 
3537273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3538273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3539273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3540273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3541273d9f13SBarry Smith 
3542273d9f13SBarry Smith    Options Database Keys:
3543698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3544698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3545273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3546273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3547273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3548273d9f13SBarry Smith 
3549273d9f13SBarry Smith    Level: intermediate
3550273d9f13SBarry Smith 
355169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3552273d9f13SBarry Smith 
3553273d9f13SBarry Smith @*/
35547087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3555273d9f13SBarry Smith {
35564ac538c5SBarry Smith   PetscErrorCode ierr;
3557a23d5eceSKris Buschelman 
3558a23d5eceSKris Buschelman   PetscFunctionBegin;
35596ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35606ba663aaSJed Brown   PetscValidType(B,1);
35614ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3562a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3563a23d5eceSKris Buschelman }
3564a23d5eceSKris Buschelman 
3565a23d5eceSKris Buschelman #undef __FUNCT__
3566a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35677087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3568a23d5eceSKris Buschelman {
3569273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35702576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35716849ba73SBarry Smith   PetscErrorCode ierr;
357297f1f81fSBarry Smith   PetscInt       i;
3573273d9f13SBarry Smith 
3574273d9f13SBarry Smith   PetscFunctionBegin;
35752576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3576a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3577c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3578c461c341SBarry Smith     nz             = 0;
3579c461c341SBarry Smith   }
3580c461c341SBarry Smith 
358126283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
358226283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3583899cda47SBarry Smith 
3584435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3585e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3586b73539f3SBarry Smith   if (nnz) {
3587d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3588e32f2f54SBarry 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]);
3589e32f2f54SBarry 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);
3590b73539f3SBarry Smith     }
3591b73539f3SBarry Smith   }
3592b73539f3SBarry Smith 
3593273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35942205254eSKarl Rupp 
3595273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3596273d9f13SBarry Smith 
3597ab93d7beSBarry Smith   if (!skipallocation) {
35982ee49352SLisandro Dalcin     if (!b->imax) {
3599d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
36003bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36012ee49352SLisandro Dalcin     }
3602273d9f13SBarry Smith     if (!nnz) {
3603435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3604c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3605d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3606d0f46423SBarry Smith       nz = nz*B->rmap->n;
3607273d9f13SBarry Smith     } else {
3608273d9f13SBarry Smith       nz = 0;
3609d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3610273d9f13SBarry Smith     }
3611ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36122205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3613ab93d7beSBarry Smith 
3614273d9f13SBarry Smith     /* allocate the matrix space */
36152ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3616d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
36173bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3618bfeeae90SHong Zhang     b->i[0] = 0;
3619d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36205da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36215da197adSKris Buschelman     }
3622273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3623e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3624e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3625b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3626b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3627b31eba2aSShri Abhyankar #endif
3628c461c341SBarry Smith   } else {
3629e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3630e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3631c461c341SBarry Smith   }
3632273d9f13SBarry Smith 
3633273d9f13SBarry Smith   b->nz               = 0;
3634273d9f13SBarry Smith   b->maxnz            = nz;
3635273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36362205254eSKarl Rupp   if (realalloc) {
36372205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36382205254eSKarl Rupp   }
3639273d9f13SBarry Smith   PetscFunctionReturn(0);
3640273d9f13SBarry Smith }
3641273d9f13SBarry Smith 
3642a1661176SMatthew Knepley #undef  __FUNCT__
3643a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364458d36128SBarry Smith /*@
3645a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3646a1661176SMatthew Knepley 
3647a1661176SMatthew Knepley    Input Parameters:
3648a1661176SMatthew Knepley +  B - the matrix
3649a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3650a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3651a1661176SMatthew Knepley -  v - optional values in the matrix
3652a1661176SMatthew Knepley 
3653a1661176SMatthew Knepley    Level: developer
3654a1661176SMatthew Knepley 
365558d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365658d36128SBarry Smith 
3657a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3658a1661176SMatthew Knepley 
3659a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3660a1661176SMatthew Knepley @*/
3661a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3662a1661176SMatthew Knepley {
3663a1661176SMatthew Knepley   PetscErrorCode ierr;
3664a1661176SMatthew Knepley 
3665a1661176SMatthew Knepley   PetscFunctionBegin;
36660700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36676ba663aaSJed Brown   PetscValidType(B,1);
36684ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3669a1661176SMatthew Knepley   PetscFunctionReturn(0);
3670a1661176SMatthew Knepley }
3671a1661176SMatthew Knepley 
3672a1661176SMatthew Knepley #undef  __FUNCT__
3673a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36747087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3675a1661176SMatthew Knepley {
3676a1661176SMatthew Knepley   PetscInt       i;
3677a1661176SMatthew Knepley   PetscInt       m,n;
3678a1661176SMatthew Knepley   PetscInt       nz;
3679a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3680a1661176SMatthew Knepley   PetscScalar    *values;
3681a1661176SMatthew Knepley   PetscErrorCode ierr;
3682a1661176SMatthew Knepley 
3683a1661176SMatthew Knepley   PetscFunctionBegin;
368465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3685779a8d59SSatish Balay 
3686779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3687779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3688779a8d59SSatish Balay 
3689779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3690a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3691a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3692b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3693a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369465e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3695a1661176SMatthew Knepley     nnz[i] = nz;
3696a1661176SMatthew Knepley   }
3697a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3698a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3699a1661176SMatthew Knepley 
3700a1661176SMatthew Knepley   if (v) {
3701a1661176SMatthew Knepley     values = (PetscScalar*) v;
3702a1661176SMatthew Knepley   } else {
37030e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3704a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3705a1661176SMatthew Knepley   }
3706a1661176SMatthew Knepley 
3707a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3708b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3709b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3710a1661176SMatthew Knepley   }
3711a1661176SMatthew Knepley 
3712a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3713a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3714a1661176SMatthew Knepley 
3715a1661176SMatthew Knepley   if (!v) {
3716a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3717a1661176SMatthew Knepley   }
37187827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3719a1661176SMatthew Knepley   PetscFunctionReturn(0);
3720a1661176SMatthew Knepley }
3721a1661176SMatthew Knepley 
3722c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372306873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3724170fe5c8SBarry Smith 
3725170fe5c8SBarry Smith #undef __FUNCT__
3726170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3727170fe5c8SBarry Smith /*
3728170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3729170fe5c8SBarry Smith 
3730170fe5c8SBarry Smith                n                       p                          p
3731170fe5c8SBarry Smith         (              )       (              )         (                  )
3732170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3733170fe5c8SBarry Smith         (              )       (              )         (                  )
3734170fe5c8SBarry Smith 
3735170fe5c8SBarry Smith */
3736170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3737170fe5c8SBarry Smith {
3738170fe5c8SBarry Smith   PetscErrorCode    ierr;
3739170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3740170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3741170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37421de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3743170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3744170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3745170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3746170fe5c8SBarry Smith 
3747170fe5c8SBarry Smith   PetscFunctionBegin;
3748d0f46423SBarry Smith   m    = A->rmap->n;
3749d0f46423SBarry Smith   n    = A->cmap->n;
3750d0f46423SBarry Smith   p    = B->cmap->n;
3751170fe5c8SBarry Smith   a    = sub_a->v;
3752170fe5c8SBarry Smith   b    = sub_b->a;
3753170fe5c8SBarry Smith   c    = sub_c->v;
3754170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3755170fe5c8SBarry Smith 
3756170fe5c8SBarry Smith   ii  = sub_b->i;
3757170fe5c8SBarry Smith   idx = sub_b->j;
3758170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3759170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3760170fe5c8SBarry Smith     while (q-->0) {
3761170fe5c8SBarry Smith       c_q = c + m*(*idx);
3762170fe5c8SBarry Smith       a_q = a + m*i;
3763854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3764170fe5c8SBarry Smith       idx++;
3765170fe5c8SBarry Smith       b++;
3766170fe5c8SBarry Smith     }
3767170fe5c8SBarry Smith   }
3768170fe5c8SBarry Smith   PetscFunctionReturn(0);
3769170fe5c8SBarry Smith }
3770170fe5c8SBarry Smith 
3771170fe5c8SBarry Smith #undef __FUNCT__
3772170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3773170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3774170fe5c8SBarry Smith {
3775170fe5c8SBarry Smith   PetscErrorCode ierr;
3776d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3777170fe5c8SBarry Smith   Mat            Cmat;
3778170fe5c8SBarry Smith 
3779170fe5c8SBarry Smith   PetscFunctionBegin;
3780e32f2f54SBarry 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);
3781ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3782170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3783a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3784170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37850298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3786d73949e8SHong Zhang 
3787d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37882205254eSKarl Rupp 
3789170fe5c8SBarry Smith   *C = Cmat;
3790170fe5c8SBarry Smith   PetscFunctionReturn(0);
3791170fe5c8SBarry Smith }
3792170fe5c8SBarry Smith 
3793170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3794170fe5c8SBarry Smith #undef __FUNCT__
3795170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3796170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3797170fe5c8SBarry Smith {
3798170fe5c8SBarry Smith   PetscErrorCode ierr;
3799170fe5c8SBarry Smith 
3800170fe5c8SBarry Smith   PetscFunctionBegin;
3801170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38023ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3803170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38043ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3805170fe5c8SBarry Smith   }
38063ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3807170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38083ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3809170fe5c8SBarry Smith   PetscFunctionReturn(0);
3810170fe5c8SBarry Smith }
3811170fe5c8SBarry Smith 
3812170fe5c8SBarry Smith 
38130bad9183SKris Buschelman /*MC
3814fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38150bad9183SKris Buschelman    based on compressed sparse row format.
38160bad9183SKris Buschelman 
38170bad9183SKris Buschelman    Options Database Keys:
38180bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38190bad9183SKris Buschelman 
38200bad9183SKris Buschelman   Level: beginner
38210bad9183SKris Buschelman 
3822f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38230bad9183SKris Buschelman M*/
38240bad9183SKris Buschelman 
3825ccd284c7SBarry Smith /*MC
3826ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3827ccd284c7SBarry Smith 
3828ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3829ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3830ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3831ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3832ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3833ccd284c7SBarry Smith 
3834ccd284c7SBarry Smith    Options Database Keys:
3835ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3836ccd284c7SBarry Smith 
3837ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3838ccd284c7SBarry Smith    enough exist.
3839ccd284c7SBarry Smith 
3840ccd284c7SBarry Smith   Level: beginner
3841ccd284c7SBarry Smith 
3842ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3843ccd284c7SBarry Smith M*/
3844ccd284c7SBarry Smith 
3845ccd284c7SBarry Smith /*MC
3846ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3847ccd284c7SBarry Smith 
3848ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3849ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3850ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3851ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3852ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3853ccd284c7SBarry Smith 
3854ccd284c7SBarry Smith    Options Database Keys:
3855ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3856ccd284c7SBarry Smith 
3857ccd284c7SBarry Smith   Level: beginner
3858ccd284c7SBarry Smith 
3859ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3860ccd284c7SBarry Smith M*/
3861ccd284c7SBarry Smith 
3862b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38638cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3864b5e56a35SBarry Smith #endif
3865ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3867af1023dbSSatish Balay #endif
38688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38708cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38717087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3872611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3874611f576cSBarry Smith #endif
3875611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3877611f576cSBarry Smith #endif
3878f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3880f3c0ef26SHong Zhang #endif
3881eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3883eb3b5408SSatish Balay #endif
3884586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3886586621ddSJed Brown #endif
3887719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3889719d5645SBarry Smith #endif
3890b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38927087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38937087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3894b3866ffcSBarry Smith #endif
389517f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
389717f1a0eaSHong Zhang #endif
389817667f90SBarry Smith 
3899c0c8ee5eSDmitry Karpeev 
39008c778c55SBarry Smith #undef __FUNCT__
39018c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39028c778c55SBarry Smith /*@C
39038c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39048c778c55SBarry Smith 
39058c778c55SBarry Smith    Not Collective
39068c778c55SBarry Smith 
39078c778c55SBarry Smith    Input Parameter:
39088c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39098c778c55SBarry Smith 
39108c778c55SBarry Smith    Output Parameter:
39118c778c55SBarry Smith .   array - pointer to the data
39128c778c55SBarry Smith 
39138c778c55SBarry Smith    Level: intermediate
39148c778c55SBarry Smith 
3915774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39168c778c55SBarry Smith @*/
39178c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39188c778c55SBarry Smith {
39198c778c55SBarry Smith   PetscErrorCode ierr;
39208c778c55SBarry Smith 
39218c778c55SBarry Smith   PetscFunctionBegin;
39228c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39238c778c55SBarry Smith   PetscFunctionReturn(0);
39248c778c55SBarry Smith }
39258c778c55SBarry Smith 
39268c778c55SBarry Smith #undef __FUNCT__
39278c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39288c778c55SBarry Smith /*@C
39298c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39308c778c55SBarry Smith 
39318c778c55SBarry Smith    Not Collective
39328c778c55SBarry Smith 
39338c778c55SBarry Smith    Input Parameters:
39348c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39358c778c55SBarry Smith .  array - pointer to the data
39368c778c55SBarry Smith 
39378c778c55SBarry Smith    Level: intermediate
39388c778c55SBarry Smith 
3939774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39408c778c55SBarry Smith @*/
39418c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39428c778c55SBarry Smith {
39438c778c55SBarry Smith   PetscErrorCode ierr;
39448c778c55SBarry Smith 
39458c778c55SBarry Smith   PetscFunctionBegin;
39468c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39478c778c55SBarry Smith   PetscFunctionReturn(0);
39488c778c55SBarry Smith }
39498c778c55SBarry Smith 
39504a2ae208SSatish Balay #undef __FUNCT__
39514a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39528cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3953273d9f13SBarry Smith {
3954273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3955dfbe8321SBarry Smith   PetscErrorCode ierr;
395638baddfdSBarry Smith   PetscMPIInt    size;
3957273d9f13SBarry Smith 
3958273d9f13SBarry Smith   PetscFunctionBegin;
3959ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3960e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3961273d9f13SBarry Smith 
396238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39632205254eSKarl Rupp 
3964b0a32e0cSBarry Smith   B->data = (void*)b;
39652205254eSKarl Rupp 
3966549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39672205254eSKarl Rupp 
3968416022c9SBarry Smith   b->row                = 0;
3969416022c9SBarry Smith   b->col                = 0;
397082bf6240SBarry Smith   b->icol               = 0;
3971b810aeb4SBarry Smith   b->reallocs           = 0;
397236db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3973f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3974416022c9SBarry Smith   b->nonew              = 0;
3975416022c9SBarry Smith   b->diag               = 0;
3976416022c9SBarry Smith   b->solve_work         = 0;
39772a1b7f2aSHong Zhang   B->spptr              = 0;
3978be6bf707SBarry Smith   b->saved_values       = 0;
3979d7f994e1SBarry Smith   b->idiag              = 0;
398071f1c65dSBarry Smith   b->mdiag              = 0;
398171f1c65dSBarry Smith   b->ssor_work          = 0;
398271f1c65dSBarry Smith   b->omega              = 1.0;
398371f1c65dSBarry Smith   b->fshift             = 0.0;
398471f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3985bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3986a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3987a30b2313SHong Zhang   b->xtoy               = 0;
3988a30b2313SHong Zhang   b->XtoY               = 0;
398988e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
399017ab2063SBarry Smith 
399135d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3992bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3993bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39948c778c55SBarry Smith 
3995b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3997bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3998bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3999b3866ffcSBarry Smith #endif
4000b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4001bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4002b5e56a35SBarry Smith #endif
4003ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4004bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4005719d5645SBarry Smith #endif
4006611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4008611f576cSBarry Smith #endif
4009f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4010bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4011f3c0ef26SHong Zhang #endif
4012611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4013bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4014611f576cSBarry Smith #endif
4015eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4016bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4017eb3b5408SSatish Balay #endif
4018586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4020586621ddSJed Brown #endif
4021719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4022bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4023719d5645SBarry Smith #endif
402417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402617f1a0eaSHong Zhang #endif
402717f1a0eaSHong Zhang 
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40464108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
404717667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40483a40ed3dSBarry Smith   PetscFunctionReturn(0);
404917ab2063SBarry Smith }
405017ab2063SBarry Smith 
40514a2ae208SSatish Balay #undef __FUNCT__
4052b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4053b24902e0SBarry Smith /*
4054b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4055b24902e0SBarry Smith */
4056ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
405717ab2063SBarry Smith {
4058416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40596849ba73SBarry Smith   PetscErrorCode ierr;
4060d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
406117ab2063SBarry Smith 
40623a40ed3dSBarry Smith   PetscFunctionBegin;
4063273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4064273d9f13SBarry Smith 
4065d5f3da31SBarry Smith   C->factortype = A->factortype;
4066416022c9SBarry Smith   c->row        = 0;
4067416022c9SBarry Smith   c->col        = 0;
406882bf6240SBarry Smith   c->icol       = 0;
40696ad4291fSHong Zhang   c->reallocs   = 0;
407017ab2063SBarry Smith 
40716ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
407217ab2063SBarry Smith 
4073aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4074aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4075eec197d1SBarry Smith 
407633b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
40773bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
407817ab2063SBarry Smith   for (i=0; i<m; i++) {
4079416022c9SBarry Smith     c->imax[i] = a->imax[i];
4080416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
408117ab2063SBarry Smith   }
408217ab2063SBarry Smith 
408317ab2063SBarry Smith   /* allocate the matrix space */
4084f77e22a1SHong Zhang   if (mallocmatspace) {
4085a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
40863bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40872205254eSKarl Rupp 
4088f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40892205254eSKarl Rupp 
409097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409117ab2063SBarry Smith     if (m > 0) {
409297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4093be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4094bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4095be6bf707SBarry Smith       } else {
4096bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
409717ab2063SBarry Smith       }
409808480c60SBarry Smith     }
4099f77e22a1SHong Zhang   }
410017ab2063SBarry Smith 
41016ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4102416022c9SBarry Smith   c->roworiented       = a->roworiented;
4103416022c9SBarry Smith   c->nonew             = a->nonew;
4104416022c9SBarry Smith   if (a->diag) {
410597f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41063bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410717ab2063SBarry Smith     for (i=0; i<m; i++) {
4108416022c9SBarry Smith       c->diag[i] = a->diag[i];
410917ab2063SBarry Smith     }
41103a40ed3dSBarry Smith   } else c->diag = 0;
41112205254eSKarl Rupp 
41126ad4291fSHong Zhang   c->solve_work         = 0;
41136ad4291fSHong Zhang   c->saved_values       = 0;
41146ad4291fSHong Zhang   c->idiag              = 0;
411571f1c65dSBarry Smith   c->ssor_work          = 0;
4116a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4117e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4118e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41196ad4291fSHong Zhang   c->xtoy               = 0;
41206ad4291fSHong Zhang   c->XtoY               = 0;
41216ad4291fSHong Zhang 
4122893ad86cSHong Zhang   c->rmax         = a->rmax;
4123416022c9SBarry Smith   c->nz           = a->nz;
41248ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4125273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4126754ec7b1SSatish Balay 
41276ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41286ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4129cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4130cd6b891eSBarry Smith   if (a->compressedrow.use) {
41316ad4291fSHong Zhang     i    = a->compressedrow.nrows;
41320e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
41336ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41346ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413527ea64f8SHong Zhang   } else {
413627ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41370298fd71SBarry Smith     c->compressedrow.i      = NULL;
41380298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41396ad4291fSHong Zhang   }
414088e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41414846f1f5SKris Buschelman 
41422205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4143140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41443a40ed3dSBarry Smith   PetscFunctionReturn(0);
414517ab2063SBarry Smith }
414617ab2063SBarry Smith 
41474a2ae208SSatish Balay #undef __FUNCT__
4148b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4149b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4150b24902e0SBarry Smith {
4151b24902e0SBarry Smith   PetscErrorCode ierr;
4152b24902e0SBarry Smith 
4153b24902e0SBarry Smith   PetscFunctionBegin;
4154ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41554b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4156a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4157a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4158f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4159b24902e0SBarry Smith   PetscFunctionReturn(0);
4160b24902e0SBarry Smith }
4161b24902e0SBarry Smith 
4162b24902e0SBarry Smith #undef __FUNCT__
41634a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4164112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4165fbdbba38SShri Abhyankar {
4166fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4167fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4168fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4169fbdbba38SShri Abhyankar   int            fd;
4170fbdbba38SShri Abhyankar   PetscMPIInt    size;
4171fbdbba38SShri Abhyankar   MPI_Comm       comm;
4172bbead8a2SBarry Smith   PetscInt       bs = 1;
4173fbdbba38SShri Abhyankar 
4174fbdbba38SShri Abhyankar   PetscFunctionBegin;
4175fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4176fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4177fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4178bbead8a2SBarry Smith 
41790298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41800298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4181bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41821814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4183bbead8a2SBarry Smith 
4184fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4185fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4186fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4187fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4188fbdbba38SShri Abhyankar 
4189bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4190fbdbba38SShri Abhyankar 
4191fbdbba38SShri Abhyankar   /* read in row lengths */
4192fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4193fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4194fbdbba38SShri Abhyankar 
4195fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4196fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4197fbdbba38SShri 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);
4198fbdbba38SShri Abhyankar 
4199fbdbba38SShri Abhyankar   /* set global size if not set already*/
4200f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4201fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4202aabbc4fbSShri Abhyankar   } else {
4203fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4204fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42054c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42064c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42074c5b953cSHong Zhang     }
4208f501eaabSShri 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);
4209aabbc4fbSShri Abhyankar   }
4210fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4211fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4212fbdbba38SShri Abhyankar 
4213fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4214fbdbba38SShri Abhyankar 
4215fbdbba38SShri Abhyankar   /* read in nonzero values */
4216fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4217fbdbba38SShri Abhyankar 
4218fbdbba38SShri Abhyankar   /* set matrix "i" values */
4219fbdbba38SShri Abhyankar   a->i[0] = 0;
4220fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4221fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4222fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4223fbdbba38SShri Abhyankar   }
4224fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4225fbdbba38SShri Abhyankar 
4226fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4227fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4228fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4229fbdbba38SShri Abhyankar }
4230fbdbba38SShri Abhyankar 
4231fbdbba38SShri Abhyankar #undef __FUNCT__
4232b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4233ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42347264ac53SSatish Balay {
42357264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4236dfbe8321SBarry Smith   PetscErrorCode ierr;
4237eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4238eeffb40dSHong Zhang   PetscInt k;
4239eeffb40dSHong Zhang #endif
42407264ac53SSatish Balay 
42413a40ed3dSBarry Smith   PetscFunctionBegin;
4242bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4243d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4244ca44d042SBarry Smith     *flg = PETSC_FALSE;
4245ca44d042SBarry Smith     PetscFunctionReturn(0);
4246bcd2baecSBarry Smith   }
42477264ac53SSatish Balay 
42487264ac53SSatish Balay   /* if the a->i are the same */
4249d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4250abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42517264ac53SSatish Balay 
42527264ac53SSatish Balay   /* if a->j are the same */
425397f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4254abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4255bcd2baecSBarry Smith 
4256bcd2baecSBarry Smith   /* if a->a are the same */
4257eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4258eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4259eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4260eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42613a40ed3dSBarry Smith       PetscFunctionReturn(0);
4262eeffb40dSHong Zhang     }
4263eeffb40dSHong Zhang   }
4264eeffb40dSHong Zhang #else
4265eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4266eeffb40dSHong Zhang #endif
4267eeffb40dSHong Zhang   PetscFunctionReturn(0);
42687264ac53SSatish Balay }
426936db0b34SBarry Smith 
42704a2ae208SSatish Balay #undef __FUNCT__
42714a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
427205869f15SSatish Balay /*@
427336db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427436db0b34SBarry Smith               provided by the user.
427536db0b34SBarry Smith 
4276c75a6043SHong Zhang       Collective on MPI_Comm
427736db0b34SBarry Smith 
427836db0b34SBarry Smith    Input Parameters:
427936db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
428036db0b34SBarry Smith .   m - number of rows
428136db0b34SBarry Smith .   n - number of columns
428236db0b34SBarry Smith .   i - row indices
428336db0b34SBarry Smith .   j - column indices
428436db0b34SBarry Smith -   a - matrix values
428536db0b34SBarry Smith 
428636db0b34SBarry Smith    Output Parameter:
428736db0b34SBarry Smith .   mat - the matrix
428836db0b34SBarry Smith 
428936db0b34SBarry Smith    Level: intermediate
429036db0b34SBarry Smith 
429136db0b34SBarry Smith    Notes:
42920551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4293292fb18eSBarry Smith     once the matrix is destroyed and not before
429436db0b34SBarry Smith 
429536db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429636db0b34SBarry Smith 
4297bfeeae90SHong Zhang        The i and j indices are 0 based
429836db0b34SBarry Smith 
4299a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4300a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4301a4552177SSatish Balay     as shown:
4302a4552177SSatish Balay 
4303a4552177SSatish Balay         1 0 0
4304a4552177SSatish Balay         2 0 3
4305a4552177SSatish Balay         4 5 6
4306a4552177SSatish Balay 
4307a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43089985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4309a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4310a4552177SSatish Balay 
43119985e31cSBarry Smith 
431269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
431336db0b34SBarry Smith 
431436db0b34SBarry Smith @*/
43157087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431636db0b34SBarry Smith {
4317dfbe8321SBarry Smith   PetscErrorCode ierr;
4318cbcfb4deSHong Zhang   PetscInt       ii;
431936db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4320cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4321cbcfb4deSHong Zhang   PetscInt jj;
4322cbcfb4deSHong Zhang #endif
432336db0b34SBarry Smith 
432436db0b34SBarry Smith   PetscFunctionBegin;
4325f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4326f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4327f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4328a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4329ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4330ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4331ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4332ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4333ab93d7beSBarry Smith 
433436db0b34SBarry Smith   aij->i            = i;
433536db0b34SBarry Smith   aij->j            = j;
433636db0b34SBarry Smith   aij->a            = a;
433736db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
433836db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4339e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4340e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
434136db0b34SBarry Smith 
434236db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
434336db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43442515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4345e32f2f54SBarry 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]);
43469985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
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 not sorted",jj-i[ii],j[jj],ii);
4348e32f2f54SBarry 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);
43499985e31cSBarry Smith     }
435036db0b34SBarry Smith #endif
435136db0b34SBarry Smith   }
43522515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435336db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4354e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4355e32f2f54SBarry 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]);
435636db0b34SBarry Smith   }
435736db0b34SBarry Smith #endif
435836db0b34SBarry Smith 
4359b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4360b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
436136db0b34SBarry Smith   PetscFunctionReturn(0);
436236db0b34SBarry Smith }
43638a0b0e6bSVictor Minden #undef __FUNCT__
43648a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436580ef6e79SMatthew G Knepley /*@C
4366d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43678a0b0e6bSVictor Minden               provided by the user.
43688a0b0e6bSVictor Minden 
43698a0b0e6bSVictor Minden       Collective on MPI_Comm
43708a0b0e6bSVictor Minden 
43718a0b0e6bSVictor Minden    Input Parameters:
43728a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43738a0b0e6bSVictor Minden .   m   - number of rows
43748a0b0e6bSVictor Minden .   n   - number of columns
43758a0b0e6bSVictor Minden .   i   - row indices
43768a0b0e6bSVictor Minden .   j   - column indices
43771230e6d1SVictor Minden .   a   - matrix values
43781230e6d1SVictor Minden .   nz  - number of nonzeros
43791230e6d1SVictor Minden -   idx - 0 or 1 based
43808a0b0e6bSVictor Minden 
43818a0b0e6bSVictor Minden    Output Parameter:
43828a0b0e6bSVictor Minden .   mat - the matrix
43838a0b0e6bSVictor Minden 
43848a0b0e6bSVictor Minden    Level: intermediate
43858a0b0e6bSVictor Minden 
43868a0b0e6bSVictor Minden    Notes:
43878a0b0e6bSVictor Minden        The i and j indices are 0 based
43888a0b0e6bSVictor Minden 
43898a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43908a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43918a0b0e6bSVictor Minden     as shown:
43928a0b0e6bSVictor Minden 
43938a0b0e6bSVictor Minden         1 0 0
43948a0b0e6bSVictor Minden         2 0 3
43958a0b0e6bSVictor Minden         4 5 6
43968a0b0e6bSVictor Minden 
43978a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43988a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43998a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44008a0b0e6bSVictor Minden 
44018a0b0e6bSVictor Minden 
440269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44038a0b0e6bSVictor Minden 
44048a0b0e6bSVictor Minden @*/
44051230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44068a0b0e6bSVictor Minden {
44078a0b0e6bSVictor Minden   PetscErrorCode ierr;
4408d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44098a0b0e6bSVictor Minden 
44108a0b0e6bSVictor Minden 
44118a0b0e6bSVictor Minden   PetscFunctionBegin;
4412d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44131230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44141230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44151230e6d1SVictor Minden     nnz[i[ii]] += 1;
44161230e6d1SVictor Minden   }
44178a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44188a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4419a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
44208a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44211230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44221230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44231230e6d1SVictor Minden     if (idx) {
44241230e6d1SVictor Minden       row = i[ii] - 1;
44251230e6d1SVictor Minden       col = j[ii] - 1;
44261230e6d1SVictor Minden     } else {
44271230e6d1SVictor Minden       row = i[ii];
44281230e6d1SVictor Minden       col = j[ii];
44298a0b0e6bSVictor Minden     }
44301230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44318a0b0e6bSVictor Minden   }
44328a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44338a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4434d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44358a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44368a0b0e6bSVictor Minden }
443736db0b34SBarry Smith 
4438cc8ba8e1SBarry Smith #undef __FUNCT__
4439ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4440dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4441cc8ba8e1SBarry Smith {
4442dfbe8321SBarry Smith   PetscErrorCode ierr;
4443cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
444436db0b34SBarry Smith 
4445cc8ba8e1SBarry Smith   PetscFunctionBegin;
44468ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4447cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4448cc8ba8e1SBarry Smith     a->coloring = coloring;
444912c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
445097f1f81fSBarry Smith     PetscInt        i,*larray;
445112c595b3SBarry Smith     ISColoring      ocoloring;
445208b6dcc0SBarry Smith     ISColoringValue *colors;
445312c595b3SBarry Smith 
445412c595b3SBarry Smith     /* set coloring for diagonal portion */
44550e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44562205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44570298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44580e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44592205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
446012c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4461d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
446212c595b3SBarry Smith     a->coloring = ocoloring;
446312c595b3SBarry Smith   }
4464cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4465cc8ba8e1SBarry Smith }
4466cc8ba8e1SBarry Smith 
4467ee4f033dSBarry Smith #undef __FUNCT__
4468ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4470ee4f033dSBarry Smith {
4471ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4472d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
447354f21887SBarry Smith   MatScalar       *v      = a->a;
447454f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447508b6dcc0SBarry Smith   ISColoringValue *color;
4476ee4f033dSBarry Smith 
4477ee4f033dSBarry Smith   PetscFunctionBegin;
4478e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4479ee4f033dSBarry Smith   color = a->coloring->colors;
4480ee4f033dSBarry Smith   /* loop over rows */
4481ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4482ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4483ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44842205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4485ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4486cc8ba8e1SBarry Smith   }
4487cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4488cc8ba8e1SBarry Smith }
448936db0b34SBarry Smith 
4490acf2f550SJed Brown #undef __FUNCT__
4491acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4492acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4493acf2f550SJed Brown {
4494acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4495acf2f550SJed Brown   PetscErrorCode ierr;
4496acf2f550SJed Brown 
4497acf2f550SJed Brown   PetscFunctionBegin;
4498acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4499acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45002205254eSKarl Rupp 
4501acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4502acf2f550SJed Brown   PetscFunctionReturn(0);
4503acf2f550SJed Brown }
4504acf2f550SJed Brown 
450581824310SBarry Smith /*
450681824310SBarry Smith     Special version for direct calls from Fortran
450781824310SBarry Smith */
4508b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
450981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
451081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
451181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
451281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
451381824310SBarry Smith #endif
451481824310SBarry Smith 
451581824310SBarry Smith /* Change these macros so can be used in void function */
451681824310SBarry Smith #undef CHKERRQ
4517ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
451881824310SBarry Smith #undef SETERRQ2
4519e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45204994cf47SJed Brown #undef SETERRQ3
45214994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
452281824310SBarry Smith 
452381824310SBarry Smith #undef __FUNCT__
452481824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45258cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
452681824310SBarry Smith {
452781824310SBarry Smith   Mat            A  = *AA;
452881824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
452981824310SBarry Smith   InsertMode     is = *isis;
453081824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
453181824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
453281824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
453381824310SBarry Smith   PetscErrorCode ierr;
453481824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453554f21887SBarry Smith   MatScalar      *ap,value,*aa;
4536ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4537ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
453881824310SBarry Smith 
453981824310SBarry Smith   PetscFunctionBegin;
45404994cf47SJed Brown   MatCheckPreallocated(A,1);
454181824310SBarry Smith   imax  = a->imax;
454281824310SBarry Smith   ai    = a->i;
454381824310SBarry Smith   ailen = a->ilen;
454481824310SBarry Smith   aj    = a->j;
454581824310SBarry Smith   aa    = a->a;
454681824310SBarry Smith 
454781824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
454881824310SBarry Smith     row = im[k];
454981824310SBarry Smith     if (row < 0) continue;
455081824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4551ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
455281824310SBarry Smith #endif
455381824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
455481824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455581824310SBarry Smith     low  = 0;
455681824310SBarry Smith     high = nrow;
455781824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
455881824310SBarry Smith       if (in[l] < 0) continue;
455981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4560ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
456181824310SBarry Smith #endif
456281824310SBarry Smith       col = in[l];
45632205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45642205254eSKarl Rupp       else value = v[k + l*m];
45652205254eSKarl Rupp 
456681824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456781824310SBarry Smith 
45682205254eSKarl Rupp       if (col <= lastcol) low = 0;
45692205254eSKarl Rupp       else high = nrow;
457081824310SBarry Smith       lastcol = col;
457181824310SBarry Smith       while (high-low > 5) {
457281824310SBarry Smith         t = (low+high)/2;
457381824310SBarry Smith         if (rp[t] > col) high = t;
457481824310SBarry Smith         else             low  = t;
457581824310SBarry Smith       }
457681824310SBarry Smith       for (i=low; i<high; i++) {
457781824310SBarry Smith         if (rp[i] > col) break;
457881824310SBarry Smith         if (rp[i] == col) {
457981824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
458081824310SBarry Smith           else                  ap[i] = value;
458181824310SBarry Smith           goto noinsert;
458281824310SBarry Smith         }
458381824310SBarry Smith       }
458481824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458581824310SBarry Smith       if (nonew == 1) goto noinsert;
4586ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4587fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
458881824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
458981824310SBarry Smith       /* shift up all the later entries in this row */
459081824310SBarry Smith       for (ii=N; ii>=i; ii--) {
459181824310SBarry Smith         rp[ii+1] = rp[ii];
459281824310SBarry Smith         ap[ii+1] = ap[ii];
459381824310SBarry Smith       }
459481824310SBarry Smith       rp[i] = col;
459581824310SBarry Smith       ap[i] = value;
459681824310SBarry Smith noinsert:;
459781824310SBarry Smith       low = i + 1;
459881824310SBarry Smith     }
459981824310SBarry Smith     ailen[row] = nrow;
460081824310SBarry Smith   }
460181824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
460281824310SBarry Smith   PetscFunctionReturnVoid();
460381824310SBarry Smith }
46049f7953f8SBarry Smith 
460562298a1eSBarry Smith 
4606