xref: /petsc/src/mat/impls/aij/seq/aij.c (revision dcca6d9d80ebd869fe6029bd05a3aa9faafef49e)
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   }
9157b083b7cSBarry Smith 
91617ab2063SBarry Smith   /* reset ilen and imax for each row */
9177b083b7cSBarry Smith   a->nonzerorowcnt = 0;
91817ab2063SBarry Smith   for (i=0; i<m; i++) {
91917ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9207b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
92117ab2063SBarry Smith   }
922bfeeae90SHong Zhang   a->nz = ai[m];
92365e19b50SBarry 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);
92417ab2063SBarry Smith 
92509f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
926d0f46423SBarry 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);
927ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
928ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9292205254eSKarl Rupp 
9308e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
931dd5f02e7SSatish Balay   a->reallocs         = 0;
9324e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
93336db0b34SBarry Smith   a->rmax             = rmax;
9344e220ebcSLois Curfman McInnes 
93511e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9362205254eSKarl Rupp 
93788e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
93871c2f376SKris Buschelman 
9394108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
94071f1c65dSBarry Smith 
941acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9423a40ed3dSBarry Smith   PetscFunctionReturn(0);
94317ab2063SBarry Smith }
94417ab2063SBarry Smith 
9454a2ae208SSatish Balay #undef __FUNCT__
94699cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
94799cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
94899cafbc1SBarry Smith {
94999cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
95099cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
95154f21887SBarry Smith   MatScalar      *aa = a->a;
952acf2f550SJed Brown   PetscErrorCode ierr;
95399cafbc1SBarry Smith 
95499cafbc1SBarry Smith   PetscFunctionBegin;
95599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
956acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
95799cafbc1SBarry Smith   PetscFunctionReturn(0);
95899cafbc1SBarry Smith }
95999cafbc1SBarry Smith 
96099cafbc1SBarry Smith #undef __FUNCT__
96199cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
96299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
96399cafbc1SBarry Smith {
96499cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96599cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
96654f21887SBarry Smith   MatScalar      *aa = a->a;
967acf2f550SJed Brown   PetscErrorCode ierr;
96899cafbc1SBarry Smith 
96999cafbc1SBarry Smith   PetscFunctionBegin;
97099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
971acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
97299cafbc1SBarry Smith   PetscFunctionReturn(0);
97399cafbc1SBarry Smith }
97499cafbc1SBarry Smith 
97578b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
97678b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
97778b84d54SShri Abhyankar {
97878b84d54SShri Abhyankar   PetscErrorCode ierr;
97978b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
98078b84d54SShri Abhyankar   PetscInt       n,start,end;
98178b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98278b84d54SShri Abhyankar 
98378b84d54SShri Abhyankar   start = trstarts[thread_id];
98478b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
98519baf141SJed Brown   n     = a->i[end] - a->i[start];
98619baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
98778b84d54SShri Abhyankar   return 0;
98878b84d54SShri Abhyankar }
98978b84d54SShri Abhyankar 
99078b84d54SShri Abhyankar #undef __FUNCT__
99178b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
99278b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
99378b84d54SShri Abhyankar {
99478b84d54SShri Abhyankar   PetscErrorCode ierr;
99578b84d54SShri Abhyankar 
99678b84d54SShri Abhyankar   PetscFunctionBegin;
997ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
998acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99978b84d54SShri Abhyankar   PetscFunctionReturn(0);
100078b84d54SShri Abhyankar }
100178b84d54SShri Abhyankar #else
100299cafbc1SBarry Smith #undef __FUNCT__
10034a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1004dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
100517ab2063SBarry Smith {
1006416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1007dfbe8321SBarry Smith   PetscErrorCode ierr;
10083a40ed3dSBarry Smith 
10093a40ed3dSBarry Smith   PetscFunctionBegin;
1010d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1011acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10123a40ed3dSBarry Smith   PetscFunctionReturn(0);
101317ab2063SBarry Smith }
101478b84d54SShri Abhyankar #endif
1015416022c9SBarry Smith 
10164a2ae208SSatish Balay #undef __FUNCT__
10174a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1018dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
101917ab2063SBarry Smith {
1020416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1021dfbe8321SBarry Smith   PetscErrorCode ierr;
1022d5d45c9bSBarry Smith 
10233a40ed3dSBarry Smith   PetscFunctionBegin;
1024aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1025d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
102617ab2063SBarry Smith #endif
1027e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10286bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10296bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
103005b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1031d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
103205b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
103371f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
103405b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10356bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
103605b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10376bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
103805b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10396bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1040cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10410b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1042a30b2313SHong Zhang 
10434108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1044bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1045901853e0SKris Buschelman 
1046dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10573a40ed3dSBarry Smith   PetscFunctionReturn(0);
105817ab2063SBarry Smith }
105917ab2063SBarry Smith 
10604a2ae208SSatish Balay #undef __FUNCT__
10614a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1062ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
106317ab2063SBarry Smith {
1064416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10654846f1f5SKris Buschelman   PetscErrorCode ierr;
10663a40ed3dSBarry Smith 
10673a40ed3dSBarry Smith   PetscFunctionBegin;
1068a65d3064SKris Buschelman   switch (op) {
1069a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10704e0d8c25SBarry Smith     a->roworiented = flg;
1071a65d3064SKris Buschelman     break;
1072a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1073a9817697SBarry Smith     a->keepnonzeropattern = flg;
1074a65d3064SKris Buschelman     break;
1075512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1076512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1077a65d3064SKris Buschelman     break;
1078a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10794e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1080a65d3064SKris Buschelman     break;
1081a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10824e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1083a65d3064SKris Buschelman     break;
108428b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
108528b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
108628b2fa4aSMatthew Knepley     break;
1087a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10884e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10890df259c2SBarry Smith     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;
12567b083b7cSBarry Smith   PetscInt          n,i;
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       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128078b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
128178b84d54SShri Abhyankar       y[*ridx++] = sum;
128278b84d54SShri Abhyankar     }
128378b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
128478b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
128578b84d54SShri Abhyankar   } else { /* do not use compressed row format */
128678b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
128778b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
128878b84d54SShri Abhyankar #else
1289ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
129078b84d54SShri Abhyankar #endif
129178b84d54SShri Abhyankar   }
12927b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
129378b84d54SShri Abhyankar   PetscFunctionReturn(0);
129478b84d54SShri Abhyankar }
129578b84d54SShri Abhyankar #else
12965c897100SBarry Smith #undef __FUNCT__
12974a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1298dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
129917ab2063SBarry Smith {
1300416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1301d9fead3dSBarry Smith   PetscScalar       *y;
130254f21887SBarry Smith   const PetscScalar *x;
130354f21887SBarry Smith   const MatScalar   *aa;
1304dfbe8321SBarry Smith   PetscErrorCode    ierr;
1305003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13060298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13077b083b7cSBarry Smith   PetscInt          n,i;
1308362ced78SSatish Balay   PetscScalar       sum;
1309ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
131017ab2063SBarry Smith 
1311b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
131297952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1313fee21e36SBarry Smith #endif
1314fee21e36SBarry Smith 
13153a40ed3dSBarry Smith   PetscFunctionBegin;
13163649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13171ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
131897952fefSHong Zhang   aj   = a->j;
131997952fefSHong Zhang   aa   = a->a;
1320416022c9SBarry Smith   ii   = a->i;
13214eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
132297952fefSHong Zhang     m    = a->compressedrow.nrows;
132397952fefSHong Zhang     ii   = a->compressedrow.i;
132497952fefSHong Zhang     ridx = a->compressedrow.rindex;
132597952fefSHong Zhang     for (i=0; i<m; i++) {
132697952fefSHong Zhang       n           = ii[i+1] - ii[i];
132797952fefSHong Zhang       aj          = a->j + ii[i];
132897952fefSHong Zhang       aa          = a->a + ii[i];
132997952fefSHong Zhang       sum         = 0.0;
1330003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1331003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
133297952fefSHong Zhang       y[*ridx++] = sum;
133397952fefSHong Zhang     }
133497952fefSHong Zhang   } else { /* do not use compressed row format */
1335b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1336b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1337b05257ddSBarry Smith #else
133878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1339ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
134078b84d54SShri Abhyankar #else
134117ab2063SBarry Smith     for (i=0; i<m; i++) {
1342003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1343003131ecSBarry Smith       aj          = a->j + ii[i];
1344003131ecSBarry Smith       aa          = a->a + ii[i];
134517ab2063SBarry Smith       sum         = 0.0;
1346003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
134717ab2063SBarry Smith       y[i] = sum;
134817ab2063SBarry Smith     }
13498d195f9aSBarry Smith #endif
135078b84d54SShri Abhyankar #endif
1351b05257ddSBarry Smith   }
13527b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13533649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13553a40ed3dSBarry Smith   PetscFunctionReturn(0);
135617ab2063SBarry Smith }
135778b84d54SShri Abhyankar #endif
135817ab2063SBarry Smith 
1359b434eb95SMatthew G. Knepley #undef __FUNCT__
1360b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1361b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1362b434eb95SMatthew G. Knepley {
1363b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1364b434eb95SMatthew G. Knepley   PetscScalar       *y;
1365b434eb95SMatthew G. Knepley   const PetscScalar *x;
1366b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1367b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1368b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1369b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1370b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1371b434eb95SMatthew G. Knepley   PetscScalar       sum;
1372b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1373b434eb95SMatthew G. Knepley 
1374b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1375b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1376b434eb95SMatthew G. Knepley #endif
1377b434eb95SMatthew G. Knepley 
1378b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1379b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1380b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1381b434eb95SMatthew G. Knepley   aj   = a->j;
1382b434eb95SMatthew G. Knepley   aa   = a->a;
1383b434eb95SMatthew G. Knepley   ii   = a->i;
1384b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1385b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1386b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1387b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1388b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1389b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1390b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1391b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1392b434eb95SMatthew G. Knepley       sum         = 0.0;
1393b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1394b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1395b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1396b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1397b434eb95SMatthew G. Knepley     }
1398b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1399b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1400b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1401b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1402b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1403b434eb95SMatthew G. Knepley       sum         = 0.0;
1404b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1405b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1406b434eb95SMatthew G. Knepley       y[i] = sum;
1407b434eb95SMatthew G. Knepley     }
1408b434eb95SMatthew G. Knepley   }
1409b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1410b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1411b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1412b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1413b434eb95SMatthew G. Knepley }
1414b434eb95SMatthew G. Knepley 
1415b434eb95SMatthew G. Knepley #undef __FUNCT__
1416b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1417b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1418b434eb95SMatthew G. Knepley {
1419b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1420b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1421b434eb95SMatthew G. Knepley   const PetscScalar *x;
1422b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1423b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1424b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1425b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1426b434eb95SMatthew G. Knepley   PetscScalar       sum;
1427b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1428b434eb95SMatthew G. Knepley 
1429b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1430b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1431b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1432b434eb95SMatthew G. Knepley   if (zz != yy) {
1433b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1434b434eb95SMatthew G. Knepley   } else {
1435b434eb95SMatthew G. Knepley     z = y;
1436b434eb95SMatthew G. Knepley   }
1437b434eb95SMatthew G. Knepley 
1438b434eb95SMatthew G. Knepley   aj = a->j;
1439b434eb95SMatthew G. Knepley   aa = a->a;
1440b434eb95SMatthew G. Knepley   ii = a->i;
1441b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1442b434eb95SMatthew G. Knepley     if (zz != yy) {
1443b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1444b434eb95SMatthew G. Knepley     }
1445b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1446b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1447b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1448b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1449b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1450b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1451b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1452b434eb95SMatthew G. Knepley       sum = y[*ridx];
1453b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1454b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1455b434eb95SMatthew G. Knepley     }
1456b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1457b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1458b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1459b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1460b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1461b434eb95SMatthew G. Knepley       sum = y[i];
1462b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1463b434eb95SMatthew G. Knepley       z[i] = sum;
1464b434eb95SMatthew G. Knepley     }
1465b434eb95SMatthew G. Knepley   }
1466b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1467b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1468b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1469b434eb95SMatthew G. Knepley   if (zz != yy) {
1470b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1471b434eb95SMatthew G. Knepley   }
1472b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1473b434eb95SMatthew G. Knepley }
1474b434eb95SMatthew G. Knepley 
1475c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14764a2ae208SSatish Balay #undef __FUNCT__
14774a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1478dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
147917ab2063SBarry Smith {
1480416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1481f15663dcSBarry Smith   PetscScalar       *y,*z;
1482f15663dcSBarry Smith   const PetscScalar *x;
148354f21887SBarry Smith   const MatScalar   *aa;
1484dfbe8321SBarry Smith   PetscErrorCode    ierr;
1485d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14860298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1487362ced78SSatish Balay   PetscScalar       sum;
1488ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14899ea0dfa2SSatish Balay 
14903a40ed3dSBarry Smith   PetscFunctionBegin;
1491f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14921ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14932e8a6d31SBarry Smith   if (zz != yy) {
14941ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14952e8a6d31SBarry Smith   } else {
14962e8a6d31SBarry Smith     z = y;
14972e8a6d31SBarry Smith   }
1498bfeeae90SHong Zhang 
149997952fefSHong Zhang   aj = a->j;
150097952fefSHong Zhang   aa = a->a;
1501cddf8d76SBarry Smith   ii = a->i;
15024eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15034eb6d288SHong Zhang     if (zz != yy) {
15044eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15054eb6d288SHong Zhang     }
150697952fefSHong Zhang     m    = a->compressedrow.nrows;
150797952fefSHong Zhang     ii   = a->compressedrow.i;
150897952fefSHong Zhang     ridx = a->compressedrow.rindex;
150997952fefSHong Zhang     for (i=0; i<m; i++) {
151097952fefSHong Zhang       n   = ii[i+1] - ii[i];
151197952fefSHong Zhang       aj  = a->j + ii[i];
151297952fefSHong Zhang       aa  = a->a + ii[i];
151397952fefSHong Zhang       sum = y[*ridx];
1514f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
151597952fefSHong Zhang       z[*ridx++] = sum;
151697952fefSHong Zhang     }
151797952fefSHong Zhang   } else { /* do not use compressed row format */
1518f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1519f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1520f15663dcSBarry Smith #else
152117ab2063SBarry Smith     for (i=0; i<m; i++) {
1522f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1523f15663dcSBarry Smith       aj  = a->j + ii[i];
1524f15663dcSBarry Smith       aa  = a->a + ii[i];
152517ab2063SBarry Smith       sum = y[i];
1526f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152717ab2063SBarry Smith       z[i] = sum;
152817ab2063SBarry Smith     }
152902ab625aSSatish Balay #endif
1530f15663dcSBarry Smith   }
1531dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1532f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15331ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15342e8a6d31SBarry Smith   if (zz != yy) {
15351ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15362e8a6d31SBarry Smith   }
15378154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15386b375ea7SVictor Minden   /*
1539918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1540918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1541918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15426b375ea7SVictor Minden   */
1543918e98c3SVictor Minden #endif
15443a40ed3dSBarry Smith   PetscFunctionReturn(0);
154517ab2063SBarry Smith }
154617ab2063SBarry Smith 
154717ab2063SBarry Smith /*
154817ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
154917ab2063SBarry Smith */
15504a2ae208SSatish Balay #undef __FUNCT__
15514a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1552dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
155317ab2063SBarry Smith {
1554416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15556849ba73SBarry Smith   PetscErrorCode ierr;
1556d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
155717ab2063SBarry Smith 
15583a40ed3dSBarry Smith   PetscFunctionBegin;
155909f38230SBarry Smith   if (!a->diag) {
156009f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
15613bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
156209f38230SBarry Smith   }
1563d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
156409f38230SBarry Smith     a->diag[i] = a->i[i+1];
1565bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1566bfeeae90SHong Zhang       if (a->j[j] == i) {
156709f38230SBarry Smith         a->diag[i] = j;
156817ab2063SBarry Smith         break;
156917ab2063SBarry Smith       }
157017ab2063SBarry Smith     }
157117ab2063SBarry Smith   }
15723a40ed3dSBarry Smith   PetscFunctionReturn(0);
157317ab2063SBarry Smith }
157417ab2063SBarry Smith 
1575be5855fcSBarry Smith /*
1576be5855fcSBarry Smith      Checks for missing diagonals
1577be5855fcSBarry Smith */
15784a2ae208SSatish Balay #undef __FUNCT__
15794a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1580ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1581be5855fcSBarry Smith {
1582be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
158397f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1584be5855fcSBarry Smith 
1585be5855fcSBarry Smith   PetscFunctionBegin;
158609f38230SBarry Smith   *missing = PETSC_FALSE;
1587d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
158809f38230SBarry Smith     *missing = PETSC_TRUE;
158909f38230SBarry Smith     if (d) *d = 0;
1590358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
159109f38230SBarry Smith   } else {
1592f1e2ffcdSBarry Smith     diag = a->diag;
1593d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1594bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
159509f38230SBarry Smith         *missing = PETSC_TRUE;
159609f38230SBarry Smith         if (d) *d = i;
159709f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1598358d2f5dSShri Abhyankar         break;
159909f38230SBarry Smith       }
1600be5855fcSBarry Smith     }
1601be5855fcSBarry Smith   }
1602be5855fcSBarry Smith   PetscFunctionReturn(0);
1603be5855fcSBarry Smith }
1604be5855fcSBarry Smith 
160571f1c65dSBarry Smith #undef __FUNCT__
160671f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16077087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
160871f1c65dSBarry Smith {
160971f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
161071f1c65dSBarry Smith   PetscErrorCode ierr;
1611d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
161254f21887SBarry Smith   MatScalar      *v = a->a;
161354f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
161471f1c65dSBarry Smith 
161571f1c65dSBarry Smith   PetscFunctionBegin;
161671f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
161771f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
161871f1c65dSBarry Smith   diag = a->diag;
161971f1c65dSBarry Smith   if (!a->idiag) {
1620*dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
16213bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
162271f1c65dSBarry Smith     v    = a->a;
162371f1c65dSBarry Smith   }
162471f1c65dSBarry Smith   mdiag = a->mdiag;
162571f1c65dSBarry Smith   idiag = a->idiag;
162671f1c65dSBarry Smith 
1627028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
162871f1c65dSBarry Smith     for (i=0; i<m; i++) {
162971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1630e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
163171f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
163271f1c65dSBarry Smith     }
163371f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
163471f1c65dSBarry Smith   } else {
163571f1c65dSBarry Smith     for (i=0; i<m; i++) {
163671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
163771f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
163871f1c65dSBarry Smith     }
1639dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
164071f1c65dSBarry Smith   }
164171f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
164271f1c65dSBarry Smith   PetscFunctionReturn(0);
164371f1c65dSBarry Smith }
164471f1c65dSBarry Smith 
1645c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16464a2ae208SSatish Balay #undef __FUNCT__
164741f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
164841f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
164917ab2063SBarry Smith {
1650416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1651e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1652e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
165354f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1654dfbe8321SBarry Smith   PetscErrorCode    ierr;
1655d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
165697f1f81fSBarry Smith   const PetscInt    *idx,*diag;
165717ab2063SBarry Smith 
16583a40ed3dSBarry Smith   PetscFunctionBegin;
1659b965ef7fSBarry Smith   its = its*lits;
166091723122SBarry Smith 
166171f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
166271f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
166371f1c65dSBarry Smith   a->fshift = fshift;
166471f1c65dSBarry Smith   a->omega  = omega;
1665ed480e8bSBarry Smith 
166671f1c65dSBarry Smith   diag  = a->diag;
166771f1c65dSBarry Smith   t     = a->ssor_work;
1668ed480e8bSBarry Smith   idiag = a->idiag;
166971f1c65dSBarry Smith   mdiag = a->mdiag;
1670ed480e8bSBarry Smith 
16711ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16723649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1673ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
167417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
167517ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1676ed480e8bSBarry Smith     bs = b;
167717ab2063SBarry Smith     for (i=0; i<m; i++) {
167871f1c65dSBarry Smith       d   = fshift + mdiag[i];
1679416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1680ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1681ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
168217ab2063SBarry Smith       sum = b[i]*d/omega;
1683003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
168417ab2063SBarry Smith       x[i] = sum;
168517ab2063SBarry Smith     }
16861ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16873649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1688efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16893a40ed3dSBarry Smith     PetscFunctionReturn(0);
169017ab2063SBarry Smith   }
1691c783ea89SBarry Smith 
16922205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16932205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
169417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1695887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
169617ab2063SBarry Smith 
169717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
169817ab2063SBarry Smith 
1699887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
170017ab2063SBarry Smith     */
170117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
170217ab2063SBarry Smith 
170317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
170417ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1705416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1706ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1707ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
170817ab2063SBarry Smith       sum = b[i];
1709e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1710ed480e8bSBarry Smith       x[i] = sum*idiag[i];
171117ab2063SBarry Smith     }
171217ab2063SBarry Smith 
171317ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1714416022c9SBarry Smith     v = a->a;
17152205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
171617ab2063SBarry Smith 
171717ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1718ed480e8bSBarry Smith     ts   = t;
1719416022c9SBarry Smith     diag = a->diag;
172017ab2063SBarry Smith     for (i=0; i<m; i++) {
1721416022c9SBarry Smith       n   = diag[i] - a->i[i];
1722ed480e8bSBarry Smith       idx = a->j + a->i[i];
1723ed480e8bSBarry Smith       v   = a->a + a->i[i];
172417ab2063SBarry Smith       sum = t[i];
1725003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1726ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1727733d66baSBarry Smith       /*  x = x + t */
1728733d66baSBarry Smith       x[i] += t[i];
172917ab2063SBarry Smith     }
173017ab2063SBarry Smith 
1731dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17321ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17333649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17343a40ed3dSBarry Smith     PetscFunctionReturn(0);
173517ab2063SBarry Smith   }
173617ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
173717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
173817ab2063SBarry Smith       for (i=0; i<m; i++) {
1739416022c9SBarry Smith         n   = diag[i] - a->i[i];
1740ed480e8bSBarry Smith         idx = a->j + a->i[i];
1741ed480e8bSBarry Smith         v   = a->a + a->i[i];
174217ab2063SBarry Smith         sum = b[i];
1743e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17445c99c7daSBarry Smith         t[i] = sum;
1745ed480e8bSBarry Smith         x[i] = sum*idiag[i];
174617ab2063SBarry Smith       }
17475c99c7daSBarry Smith       xb   = t;
1748efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17493a40ed3dSBarry Smith     } else xb = b;
175017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
175117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1752416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1753ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1754ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
175517ab2063SBarry Smith         sum = xb[i];
1756e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17575c99c7daSBarry Smith         if (xb == b) {
1758ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17595c99c7daSBarry Smith         } else {
1760b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
176117ab2063SBarry Smith         }
17625c99c7daSBarry Smith       }
1763b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
176417ab2063SBarry Smith     }
176517ab2063SBarry Smith     its--;
176617ab2063SBarry Smith   }
176717ab2063SBarry Smith   while (its--) {
176817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
176917ab2063SBarry Smith       for (i=0; i<m; i++) {
1770b19a5dc2SMark Adams         /* lower */
1771b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1772ed480e8bSBarry Smith         idx = a->j + a->i[i];
1773ed480e8bSBarry Smith         v   = a->a + a->i[i];
177417ab2063SBarry Smith         sum = b[i];
1775e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1776b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1777b19a5dc2SMark Adams         /* upper */
1778b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1779b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1780b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1781b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1782b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
178317ab2063SBarry Smith       }
1784b19a5dc2SMark Adams       xb   = t;
17859f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1786b19a5dc2SMark Adams     } else xb = b;
178717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
178817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1789b19a5dc2SMark Adams         sum = xb[i];
1790b19a5dc2SMark Adams         if (xb == b) {
1791b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1792416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1793ed480e8bSBarry Smith           idx = a->j + a->i[i];
1794ed480e8bSBarry Smith           v   = a->a + a->i[i];
1795e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1796ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1797b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1798b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1799b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1800b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1801b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1802b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
180317ab2063SBarry Smith         }
1804b19a5dc2SMark Adams       }
1805b19a5dc2SMark Adams       if (xb == b) {
18069f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1807b19a5dc2SMark Adams       } else {
1808b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1809b19a5dc2SMark Adams       }
181017ab2063SBarry Smith     }
181117ab2063SBarry Smith   }
18121ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18133649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1814365a8a9eSBarry Smith   PetscFunctionReturn(0);
181517ab2063SBarry Smith }
181617ab2063SBarry Smith 
18172af78befSBarry Smith 
18184a2ae208SSatish Balay #undef __FUNCT__
18194a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1820dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
182117ab2063SBarry Smith {
1822416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18234e220ebcSLois Curfman McInnes 
18243a40ed3dSBarry Smith   PetscFunctionBegin;
18254e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18264e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18274e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18284e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18294e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18308e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18317adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1832d5f3da31SBarry Smith   if (A->factortype) {
18334e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18344e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18354e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18364e220ebcSLois Curfman McInnes   } else {
18374e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18384e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18394e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18404e220ebcSLois Curfman McInnes   }
18413a40ed3dSBarry Smith   PetscFunctionReturn(0);
184217ab2063SBarry Smith }
184317ab2063SBarry Smith 
18444a2ae208SSatish Balay #undef __FUNCT__
18454a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18462b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
184717ab2063SBarry Smith {
1848416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18493b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18506849ba73SBarry Smith   PetscErrorCode    ierr;
185197b48c8fSBarry Smith   const PetscScalar *xx;
185297b48c8fSBarry Smith   PetscScalar       *bb;
1853ace3abfcSBarry Smith   PetscBool         missing;
185417ab2063SBarry Smith 
18553a40ed3dSBarry Smith   PetscFunctionBegin;
185697b48c8fSBarry Smith   if (x && b) {
185797b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
185897b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
185997b48c8fSBarry Smith     for (i=0; i<N; i++) {
186097b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
186197b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
186297b48c8fSBarry Smith     }
186397b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
186497b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
186597b48c8fSBarry Smith   }
186697b48c8fSBarry Smith 
1867a9817697SBarry Smith   if (a->keepnonzeropattern) {
1868f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1869e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1870bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1871f1e2ffcdSBarry Smith     }
1872f4df32b1SMatthew Knepley     if (diag != 0.0) {
187309f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1874e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1875f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1876f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1877f1e2ffcdSBarry Smith       }
1878f1e2ffcdSBarry Smith     }
187988e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1880f1e2ffcdSBarry Smith   } else {
1881f4df32b1SMatthew Knepley     if (diag != 0.0) {
188217ab2063SBarry Smith       for (i=0; i<N; i++) {
1883e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18847ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1885416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1886f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1887bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18887ae801bdSBarry Smith         } else { /* in case row was completely empty */
1889f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
189017ab2063SBarry Smith         }
189117ab2063SBarry Smith       }
18923a40ed3dSBarry Smith     } else {
189317ab2063SBarry Smith       for (i=0; i<N; i++) {
1894e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1895416022c9SBarry Smith         a->ilen[rows[i]] = 0;
189617ab2063SBarry Smith       }
189717ab2063SBarry Smith     }
189888e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1899f1e2ffcdSBarry Smith   }
190043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19013a40ed3dSBarry Smith   PetscFunctionReturn(0);
190217ab2063SBarry Smith }
190317ab2063SBarry Smith 
19044a2ae208SSatish Balay #undef __FUNCT__
19056e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19066e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19076e169961SBarry Smith {
19086e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19096e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19106e169961SBarry Smith   PetscErrorCode    ierr;
19112b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19126e169961SBarry Smith   const PetscScalar *xx;
19136e169961SBarry Smith   PetscScalar       *bb;
19146e169961SBarry Smith 
19156e169961SBarry Smith   PetscFunctionBegin;
19166e169961SBarry Smith   if (x && b) {
19176e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19186e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19192b40b63fSBarry Smith     vecs = PETSC_TRUE;
19206e169961SBarry Smith   }
19216e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
19226e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
19236e169961SBarry Smith   for (i=0; i<N; i++) {
19246e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19256e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19262205254eSKarl Rupp 
19276e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19286e169961SBarry Smith   }
19296e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19306e169961SBarry Smith     if (!zeroed[i]) {
19316e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19326e169961SBarry Smith         if (zeroed[a->j[j]]) {
19332b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19346e169961SBarry Smith           a->a[j] = 0.0;
19356e169961SBarry Smith         }
19366e169961SBarry Smith       }
19372b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19386e169961SBarry Smith   }
19396e169961SBarry Smith   if (x && b) {
19406e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19416e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19426e169961SBarry Smith   }
19436e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19446e169961SBarry Smith   if (diag != 0.0) {
19456e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19466e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19476e169961SBarry Smith     for (i=0; i<N; i++) {
19486e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19496e169961SBarry Smith     }
19506e169961SBarry Smith   }
19516e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19526e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19536e169961SBarry Smith   PetscFunctionReturn(0);
19546e169961SBarry Smith }
19556e169961SBarry Smith 
19566e169961SBarry Smith #undef __FUNCT__
19574a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1958a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
195917ab2063SBarry Smith {
1960416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
196197f1f81fSBarry Smith   PetscInt   *itmp;
196217ab2063SBarry Smith 
19633a40ed3dSBarry Smith   PetscFunctionBegin;
1964e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
196517ab2063SBarry Smith 
1966416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1967bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
196817ab2063SBarry Smith   if (idx) {
1969bfeeae90SHong Zhang     itmp = a->j + a->i[row];
197026fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
197117ab2063SBarry Smith     else *idx = 0;
197217ab2063SBarry Smith   }
19733a40ed3dSBarry Smith   PetscFunctionReturn(0);
197417ab2063SBarry Smith }
197517ab2063SBarry Smith 
1976bfeeae90SHong Zhang /* remove this function? */
19774a2ae208SSatish Balay #undef __FUNCT__
19784a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1979a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
198017ab2063SBarry Smith {
19813a40ed3dSBarry Smith   PetscFunctionBegin;
19823a40ed3dSBarry Smith   PetscFunctionReturn(0);
198317ab2063SBarry Smith }
198417ab2063SBarry Smith 
19854a2ae208SSatish Balay #undef __FUNCT__
19864a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1987dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
198817ab2063SBarry Smith {
1989416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
199054f21887SBarry Smith   MatScalar      *v  = a->a;
199136db0b34SBarry Smith   PetscReal      sum = 0.0;
19926849ba73SBarry Smith   PetscErrorCode ierr;
199397f1f81fSBarry Smith   PetscInt       i,j;
199417ab2063SBarry Smith 
19953a40ed3dSBarry Smith   PetscFunctionBegin;
199617ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1997416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
199836db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
199917ab2063SBarry Smith     }
20008f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20013a40ed3dSBarry Smith   } else if (type == NORM_1) {
200236db0b34SBarry Smith     PetscReal *tmp;
200397f1f81fSBarry Smith     PetscInt  *jj = a->j;
2004d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
2005d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
2006064f8208SBarry Smith     *nrm = 0.0;
2007416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2008bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
200917ab2063SBarry Smith     }
2010d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2011064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
201217ab2063SBarry Smith     }
2013606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20143a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2015064f8208SBarry Smith     *nrm = 0.0;
2016d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2017bfeeae90SHong Zhang       v   = a->a + a->i[j];
201817ab2063SBarry Smith       sum = 0.0;
2019416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2020cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
202117ab2063SBarry Smith       }
2022064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
202317ab2063SBarry Smith     }
2024f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20253a40ed3dSBarry Smith   PetscFunctionReturn(0);
202617ab2063SBarry Smith }
202717ab2063SBarry Smith 
20284e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20294e938277SHong Zhang #undef __FUNCT__
20304e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20314e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20324e938277SHong Zhang {
20334e938277SHong Zhang   PetscErrorCode ierr;
20344e938277SHong Zhang   PetscInt       i,j,anzj;
20354e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20364e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20374e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20384e938277SHong Zhang 
20394e938277SHong Zhang   PetscFunctionBegin;
20404e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20414e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
20424e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
20434e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
20444e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
20454e938277SHong Zhang 
20464e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20474e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
204826fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20494e938277SHong Zhang   /* Form ati for csr format of A^T. */
205026fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20514e938277SHong Zhang 
20524e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20534e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20544e938277SHong Zhang 
20554e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20564e938277SHong Zhang   for (i=0;i<am;i++) {
20574e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20584e938277SHong Zhang     for (j=0;j<anzj;j++) {
20594e938277SHong Zhang       atj[atfill[*aj]] = i;
20604e938277SHong Zhang       atfill[*aj++]   += 1;
20614e938277SHong Zhang     }
20624e938277SHong Zhang   }
20634e938277SHong Zhang 
20644e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20654e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2066ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20672205254eSKarl Rupp 
2068a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2069a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2070a2f3521dSMark F. Adams 
20714e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20724e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20734e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20744e938277SHong Zhang   b->nonew   = 0;
20754e938277SHong Zhang   PetscFunctionReturn(0);
20764e938277SHong Zhang }
20774e938277SHong Zhang 
20784a2ae208SSatish Balay #undef __FUNCT__
20794a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2080fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
208117ab2063SBarry Smith {
2082416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2083416022c9SBarry Smith   Mat            C;
20846849ba73SBarry Smith   PetscErrorCode ierr;
2085d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
208654f21887SBarry Smith   MatScalar      *array = a->a;
208717ab2063SBarry Smith 
20883a40ed3dSBarry Smith   PetscFunctionBegin;
2089e32f2f54SBarry 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");
2090fc4dec0aSBarry Smith 
2091fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
2092d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
2093d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
2094bfeeae90SHong Zhang 
2095bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2096ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2097d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2098a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
20997adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2100ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2101606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2102a541d17aSBarry Smith   } else {
2103a541d17aSBarry Smith     C = *B;
2104a541d17aSBarry Smith   }
2105a541d17aSBarry Smith 
210617ab2063SBarry Smith   for (i=0; i<m; i++) {
210717ab2063SBarry Smith     len    = ai[i+1]-ai[i];
210887d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2109b9b97703SBarry Smith     array += len;
2110b9b97703SBarry Smith     aj    += len;
211117ab2063SBarry Smith   }
21126d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21136d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
211417ab2063SBarry Smith 
2115815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2116416022c9SBarry Smith     *B = C;
211717ab2063SBarry Smith   } else {
2118eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
211917ab2063SBarry Smith   }
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
212117ab2063SBarry Smith }
212217ab2063SBarry Smith 
2123cd0d46ebSvictorle #undef __FUNCT__
21245fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21257087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2126cd0d46ebSvictorle {
2127cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
212854f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
212954f21887SBarry Smith   MatScalar      *va,*vb;
21306849ba73SBarry Smith   PetscErrorCode ierr;
213197f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2132cd0d46ebSvictorle 
2133cd0d46ebSvictorle   PetscFunctionBegin;
2134cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2135cd0d46ebSvictorle 
2136cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2137cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21385485867bSBarry Smith   if (ma!=nb || na!=mb) {
21395485867bSBarry Smith     *f = PETSC_FALSE;
21405485867bSBarry Smith     PetscFunctionReturn(0);
21415485867bSBarry Smith   }
2142cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2143cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2144cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
214597f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
214697f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2147cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2148cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2149cd0d46ebSvictorle 
2150cd0d46ebSvictorle   *f = PETSC_TRUE;
2151cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2152cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
215397f1f81fSBarry Smith       PetscInt    idc,idr;
21545485867bSBarry Smith       PetscScalar vc,vr;
2155cd0d46ebSvictorle       /* column/row index/value */
21565485867bSBarry Smith       idc = adx[aptr[i]];
21575485867bSBarry Smith       idr = bdx[bptr[idc]];
21585485867bSBarry Smith       vc  = va[aptr[i]];
21595485867bSBarry Smith       vr  = vb[bptr[idc]];
21605485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21615485867bSBarry Smith         *f = PETSC_FALSE;
21625485867bSBarry Smith         goto done;
2163cd0d46ebSvictorle       } else {
21645485867bSBarry Smith         aptr[i]++;
21655485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2166cd0d46ebSvictorle       }
2167cd0d46ebSvictorle     }
2168cd0d46ebSvictorle   }
2169cd0d46ebSvictorle done:
2170cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21713aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2172cd0d46ebSvictorle   PetscFunctionReturn(0);
2173cd0d46ebSvictorle }
2174cd0d46ebSvictorle 
21751cbb95d3SBarry Smith #undef __FUNCT__
21761cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21777087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21781cbb95d3SBarry Smith {
21791cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
218054f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
218154f21887SBarry Smith   MatScalar      *va,*vb;
21821cbb95d3SBarry Smith   PetscErrorCode ierr;
21831cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21841cbb95d3SBarry Smith 
21851cbb95d3SBarry Smith   PetscFunctionBegin;
21861cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21871cbb95d3SBarry Smith 
21881cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21891cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21901cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21911cbb95d3SBarry Smith     *f = PETSC_FALSE;
21921cbb95d3SBarry Smith     PetscFunctionReturn(0);
21931cbb95d3SBarry Smith   }
21941cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
21951cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
21961cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
21971cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
21981cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
21991cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22001cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22011cbb95d3SBarry Smith 
22021cbb95d3SBarry Smith   *f = PETSC_TRUE;
22031cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22041cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22051cbb95d3SBarry Smith       PetscInt    idc,idr;
22061cbb95d3SBarry Smith       PetscScalar vc,vr;
22071cbb95d3SBarry Smith       /* column/row index/value */
22081cbb95d3SBarry Smith       idc = adx[aptr[i]];
22091cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22101cbb95d3SBarry Smith       vc  = va[aptr[i]];
22111cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22121cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22131cbb95d3SBarry Smith         *f = PETSC_FALSE;
22141cbb95d3SBarry Smith         goto done;
22151cbb95d3SBarry Smith       } else {
22161cbb95d3SBarry Smith         aptr[i]++;
22171cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22181cbb95d3SBarry Smith       }
22191cbb95d3SBarry Smith     }
22201cbb95d3SBarry Smith   }
22211cbb95d3SBarry Smith done:
22221cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22231cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22241cbb95d3SBarry Smith   PetscFunctionReturn(0);
22251cbb95d3SBarry Smith }
22261cbb95d3SBarry Smith 
22279e29f15eSvictorle #undef __FUNCT__
22289e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2229ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22309e29f15eSvictorle {
2231dfbe8321SBarry Smith   PetscErrorCode ierr;
22326e111a19SKarl Rupp 
22339e29f15eSvictorle   PetscFunctionBegin;
22345485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22359e29f15eSvictorle   PetscFunctionReturn(0);
22369e29f15eSvictorle }
22379e29f15eSvictorle 
22384a2ae208SSatish Balay #undef __FUNCT__
22391cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2240ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22411cbb95d3SBarry Smith {
22421cbb95d3SBarry Smith   PetscErrorCode ierr;
22436e111a19SKarl Rupp 
22441cbb95d3SBarry Smith   PetscFunctionBegin;
22451cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22461cbb95d3SBarry Smith   PetscFunctionReturn(0);
22471cbb95d3SBarry Smith }
22481cbb95d3SBarry Smith 
22491cbb95d3SBarry Smith #undef __FUNCT__
22504a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2251dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
225217ab2063SBarry Smith {
2253416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
225454f21887SBarry Smith   PetscScalar    *l,*r,x;
225554f21887SBarry Smith   MatScalar      *v;
2256dfbe8321SBarry Smith   PetscErrorCode ierr;
2257d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
225817ab2063SBarry Smith 
22593a40ed3dSBarry Smith   PetscFunctionBegin;
226017ab2063SBarry Smith   if (ll) {
22613ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22623ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2263e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2264e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22651ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2266416022c9SBarry Smith     v    = a->a;
226717ab2063SBarry Smith     for (i=0; i<m; i++) {
226817ab2063SBarry Smith       x = l[i];
2269416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22702205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
227117ab2063SBarry Smith     }
22721ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2273efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
227417ab2063SBarry Smith   }
227517ab2063SBarry Smith   if (rr) {
2276e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2277e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22781ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2279416022c9SBarry Smith     v    = a->a; jj = a->j;
22802205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22811ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2282efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228317ab2063SBarry Smith   }
2284acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22853a40ed3dSBarry Smith   PetscFunctionReturn(0);
228617ab2063SBarry Smith }
228717ab2063SBarry Smith 
22884a2ae208SSatish Balay #undef __FUNCT__
22894a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
229097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
229117ab2063SBarry Smith {
2292db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
22936849ba73SBarry Smith   PetscErrorCode ierr;
2294d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
229597f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
22965d0c19d7SBarry Smith   const PetscInt *irow,*icol;
22975d0c19d7SBarry Smith   PetscInt       nrows,ncols;
229897f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
229954f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2300416022c9SBarry Smith   Mat            C;
2301ace3abfcSBarry Smith   PetscBool      stride,sorted;
230217ab2063SBarry Smith 
23033a40ed3dSBarry Smith   PetscFunctionBegin;
230414ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2305e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
230614ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2307e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
230899141d43SSatish Balay 
230917ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2310b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2311b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
231217ab2063SBarry Smith 
2313fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2314251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2315fee21e36SBarry Smith   if (stride && step == 1) {
231602834360SBarry Smith     /* special case of contiguous rows */
2317*dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
231802834360SBarry Smith     /* loop over new rows determining lens and starting points */
231902834360SBarry Smith     for (i=0; i<nrows; i++) {
2320bfeeae90SHong Zhang       kstart = ai[irow[i]];
2321a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
232202834360SBarry Smith       for (k=kstart; k<kend; k++) {
2323bfeeae90SHong Zhang         if (aj[k] >= first) {
232402834360SBarry Smith           starts[i] = k;
232502834360SBarry Smith           break;
232602834360SBarry Smith         }
232702834360SBarry Smith       }
2328a2744918SBarry Smith       sum = 0;
232902834360SBarry Smith       while (k < kend) {
2330bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2331a2744918SBarry Smith         sum++;
233202834360SBarry Smith       }
2333a2744918SBarry Smith       lens[i] = sum;
233402834360SBarry Smith     }
233502834360SBarry Smith     /* create submatrix */
2336cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
233797f1f81fSBarry Smith       PetscInt n_cols,n_rows;
233808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2339e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2340d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
234108480c60SBarry Smith       C    = *B;
23423a40ed3dSBarry Smith     } else {
23433bef6203SJed Brown       PetscInt rbs,cbs;
2344ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2345f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23463bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23473bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23483bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23497adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2350ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
235108480c60SBarry Smith     }
2352db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2353db02288aSLois Curfman McInnes 
235402834360SBarry Smith     /* loop over rows inserting into submatrix */
2355db02288aSLois Curfman McInnes     a_new = c->a;
2356db02288aSLois Curfman McInnes     j_new = c->j;
2357db02288aSLois Curfman McInnes     i_new = c->i;
2358bfeeae90SHong Zhang 
235902834360SBarry Smith     for (i=0; i<nrows; i++) {
2360a2744918SBarry Smith       ii    = starts[i];
2361a2744918SBarry Smith       lensi = lens[i];
2362a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2363a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
236402834360SBarry Smith       }
236587828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2366a2744918SBarry Smith       a_new     += lensi;
2367a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2368a2744918SBarry Smith       c->ilen[i] = lensi;
236902834360SBarry Smith     }
23700e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23713a40ed3dSBarry Smith   } else {
237202834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23730e83c824SBarry Smith     ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
237497f1f81fSBarry Smith     ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
23750e83c824SBarry Smith     ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
23764dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23774dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23784dcab191SBarry 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);
23794dcab191SBarry Smith #endif
23804dcab191SBarry Smith       smap[icol[i]] = i+1;
23814dcab191SBarry Smith     }
23824dcab191SBarry Smith 
238302834360SBarry Smith     /* determine lens of each row */
238402834360SBarry Smith     for (i=0; i<nrows; i++) {
2385bfeeae90SHong Zhang       kstart  = ai[irow[i]];
238602834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
238702834360SBarry Smith       lens[i] = 0;
238802834360SBarry Smith       for (k=kstart; k<kend; k++) {
2389bfeeae90SHong Zhang         if (smap[aj[k]]) {
239002834360SBarry Smith           lens[i]++;
239102834360SBarry Smith         }
239202834360SBarry Smith       }
239302834360SBarry Smith     }
239417ab2063SBarry Smith     /* Create and fill new matrix */
2395a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2396ace3abfcSBarry Smith       PetscBool equal;
23970f5bd95cSBarry Smith 
239899141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2399e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2400d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2401f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2402d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
240308480c60SBarry Smith       C    = *B;
24043a40ed3dSBarry Smith     } else {
24053bef6203SJed Brown       PetscInt rbs,cbs;
2406ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2407f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24083bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24093bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24103bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24117adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2412ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
241308480c60SBarry Smith     }
241499141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
241517ab2063SBarry Smith     for (i=0; i<nrows; i++) {
241699141d43SSatish Balay       row      = irow[i];
2417bfeeae90SHong Zhang       kstart   = ai[row];
241899141d43SSatish Balay       kend     = kstart + a->ilen[row];
2419bfeeae90SHong Zhang       mat_i    = c->i[i];
242099141d43SSatish Balay       mat_j    = c->j + mat_i;
242199141d43SSatish Balay       mat_a    = c->a + mat_i;
242299141d43SSatish Balay       mat_ilen = c->ilen + i;
242317ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2424bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2425ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
242699141d43SSatish Balay           *mat_a++ = a->a[k];
242799141d43SSatish Balay           (*mat_ilen)++;
242899141d43SSatish Balay 
242917ab2063SBarry Smith         }
243017ab2063SBarry Smith       }
243117ab2063SBarry Smith     }
243202834360SBarry Smith     /* Free work space */
243302834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2434606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2435606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
243602834360SBarry Smith   }
24376d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24386d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
243917ab2063SBarry Smith 
244017ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2441416022c9SBarry Smith   *B   = C;
24423a40ed3dSBarry Smith   PetscFunctionReturn(0);
244317ab2063SBarry Smith }
244417ab2063SBarry Smith 
24451df811f5SHong Zhang #undef __FUNCT__
244682d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2447fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
244882d44351SHong Zhang {
244982d44351SHong Zhang   PetscErrorCode ierr;
245082d44351SHong Zhang   Mat            B;
245182d44351SHong Zhang 
245282d44351SHong Zhang   PetscFunctionBegin;
2453c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
245482d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
245582d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2456a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
245782d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
245882d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
245982d44351SHong Zhang     *subMat = B;
2460c2d650bdSHong Zhang   } else {
2461c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2462c2d650bdSHong Zhang   }
246382d44351SHong Zhang   PetscFunctionReturn(0);
246482d44351SHong Zhang }
246582d44351SHong Zhang 
246682d44351SHong Zhang #undef __FUNCT__
24674a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24680481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2469a871dcd8SBarry Smith {
247063b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2471dfbe8321SBarry Smith   PetscErrorCode ierr;
247263b91edcSBarry Smith   Mat            outA;
2473ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
247463b91edcSBarry Smith 
24753a40ed3dSBarry Smith   PetscFunctionBegin;
2476e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24771df811f5SHong Zhang 
2478b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2479b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2480a871dcd8SBarry Smith 
248163b91edcSBarry Smith   outA             = inA;
2482d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24832205254eSKarl Rupp 
2484c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24856bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24862205254eSKarl Rupp 
2487c3122656SLisandro Dalcin   a->row = row;
24882205254eSKarl Rupp 
2489c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24906bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24912205254eSKarl Rupp 
2492c3122656SLisandro Dalcin   a->col = col;
249363b91edcSBarry Smith 
249436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
24956bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
24964c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
24973bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2498f0ec6fceSSatish Balay 
249994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2500d0f46423SBarry Smith     ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
25013bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
250294a9d846SBarry Smith   }
250363b91edcSBarry Smith 
2504f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2505137fb511SHong Zhang   if (row_identity && col_identity) {
2506ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2507137fb511SHong Zhang   } else {
2508719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2509137fb511SHong Zhang   }
25103a40ed3dSBarry Smith   PetscFunctionReturn(0);
2511a871dcd8SBarry Smith }
2512a871dcd8SBarry Smith 
25134a2ae208SSatish Balay #undef __FUNCT__
25144a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2515f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2516f0b747eeSBarry Smith {
2517f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2518f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2519efee365bSSatish Balay   PetscErrorCode ierr;
2520c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25213a40ed3dSBarry Smith 
25223a40ed3dSBarry Smith   PetscFunctionBegin;
2523c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25248b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2525efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2526acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25273a40ed3dSBarry Smith   PetscFunctionReturn(0);
2528f0b747eeSBarry Smith }
2529f0b747eeSBarry Smith 
25304a2ae208SSatish Balay #undef __FUNCT__
25314a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
253297f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2533cddf8d76SBarry Smith {
2534dfbe8321SBarry Smith   PetscErrorCode ierr;
253597f1f81fSBarry Smith   PetscInt       i;
2536cddf8d76SBarry Smith 
25373a40ed3dSBarry Smith   PetscFunctionBegin;
2538cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2539b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2540cddf8d76SBarry Smith   }
2541cddf8d76SBarry Smith 
2542cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25436a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2544cddf8d76SBarry Smith   }
25453a40ed3dSBarry Smith   PetscFunctionReturn(0);
2546cddf8d76SBarry Smith }
2547cddf8d76SBarry Smith 
25484a2ae208SSatish Balay #undef __FUNCT__
25494a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
255097f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25514dcbc457SBarry Smith {
2552e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25536849ba73SBarry Smith   PetscErrorCode ierr;
25545d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25555d0c19d7SBarry Smith   const PetscInt *idx;
255697f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2557f1af5d2fSBarry Smith   PetscBT        table;
2558bbd702dbSSatish Balay 
25593a40ed3dSBarry Smith   PetscFunctionBegin;
2560d0f46423SBarry Smith   m  = A->rmap->n;
2561e4d965acSSatish Balay   ai = a->i;
2562bfeeae90SHong Zhang   aj = a->j;
25638a047759SSatish Balay 
2564e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
256506763907SSatish Balay 
256697f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
256753b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
256806763907SSatish Balay 
2569e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2570b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2571e4d965acSSatish Balay     isz  = 0;
25726831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2573e4d965acSSatish Balay 
2574e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25754dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2576b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2577e4d965acSSatish Balay 
2578dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2579e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25802205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25814dcbc457SBarry Smith     }
258206763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25836bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2584e4d965acSSatish Balay 
258504a348a9SBarry Smith     k = 0;
258604a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
258704a348a9SBarry Smith       n = isz;
258806763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2589e4d965acSSatish Balay         row   = nidx[k];
2590e4d965acSSatish Balay         start = ai[row];
2591e4d965acSSatish Balay         end   = ai[row+1];
259204a348a9SBarry Smith         for (l = start; l<end; l++) {
2593efb16452SHong Zhang           val = aj[l];
25942205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2595e4d965acSSatish Balay         }
2596e4d965acSSatish Balay       }
2597e4d965acSSatish Balay     }
259870b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2599e4d965acSSatish Balay   }
260094bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2601606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26023a40ed3dSBarry Smith   PetscFunctionReturn(0);
26034dcbc457SBarry Smith }
260417ab2063SBarry Smith 
26050513a670SBarry Smith /* -------------------------------------------------------------- */
26064a2ae208SSatish Balay #undef __FUNCT__
26074a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2608dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26090513a670SBarry Smith {
26100513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26116849ba73SBarry Smith   PetscErrorCode ierr;
26123b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26135d0c19d7SBarry Smith   const PetscInt *row,*col;
26145d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
261556cd22aeSBarry Smith   IS             icolp,irowp;
26160298fd71SBarry Smith   PetscInt       *cwork = NULL;
26170298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26180513a670SBarry Smith 
26193a40ed3dSBarry Smith   PetscFunctionBegin;
26204c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
262156cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26224c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
262356cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26240513a670SBarry Smith 
26250513a670SBarry Smith   /* determine lengths of permuted rows */
262697f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
26272205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2628ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2629f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2630a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26317adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2632ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2633606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26340513a670SBarry Smith 
263597f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
26360513a670SBarry Smith   for (i=0; i<m; i++) {
263732ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26382205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2639cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
264032ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26410513a670SBarry Smith   }
2642606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26432205254eSKarl Rupp 
26443c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26452205254eSKarl Rupp 
26460513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26470513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
264856cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
264956cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26506bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26516bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26523a40ed3dSBarry Smith   PetscFunctionReturn(0);
26530513a670SBarry Smith }
26540513a670SBarry Smith 
26554a2ae208SSatish Balay #undef __FUNCT__
26564a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2657dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2658cb5b572fSBarry Smith {
2659dfbe8321SBarry Smith   PetscErrorCode ierr;
2660cb5b572fSBarry Smith 
2661cb5b572fSBarry Smith   PetscFunctionBegin;
266233f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
266333f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2664be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2665be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2666be6bf707SBarry Smith 
2667700c5bfcSBarry 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");
2668d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2669cb5b572fSBarry Smith   } else {
2670cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2671cb5b572fSBarry Smith   }
2672cb5b572fSBarry Smith   PetscFunctionReturn(0);
2673cb5b572fSBarry Smith }
2674cb5b572fSBarry Smith 
26754a2ae208SSatish Balay #undef __FUNCT__
26764994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26774994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2678273d9f13SBarry Smith {
2679dfbe8321SBarry Smith   PetscErrorCode ierr;
2680273d9f13SBarry Smith 
2681273d9f13SBarry Smith   PetscFunctionBegin;
2682ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2683273d9f13SBarry Smith   PetscFunctionReturn(0);
2684273d9f13SBarry Smith }
2685273d9f13SBarry Smith 
26864a2ae208SSatish Balay #undef __FUNCT__
26878c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
26888c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26896c0721eeSBarry Smith {
26906c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26916e111a19SKarl Rupp 
26926c0721eeSBarry Smith   PetscFunctionBegin;
26936c0721eeSBarry Smith   *array = a->a;
26946c0721eeSBarry Smith   PetscFunctionReturn(0);
26956c0721eeSBarry Smith }
26966c0721eeSBarry Smith 
26974a2ae208SSatish Balay #undef __FUNCT__
26988c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
26998c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27006c0721eeSBarry Smith {
27016c0721eeSBarry Smith   PetscFunctionBegin;
27026c0721eeSBarry Smith   PetscFunctionReturn(0);
27036c0721eeSBarry Smith }
2704273d9f13SBarry Smith 
27058229c054SShri Abhyankar /*
27068229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27078229c054SShri Abhyankar    have different nonzero structure.
27088229c054SShri Abhyankar */
2709ac90fabeSBarry Smith #undef __FUNCT__
27108229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27118229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2712ec7775f6SShri Abhyankar {
27138229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2714ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2715ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2716ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2717ec7775f6SShri Abhyankar 
2718ec7775f6SShri Abhyankar   PetscFunctionBegin;
2719ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2720ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27218af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27228af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27238af7cee1SJed Brown     nnz[i] = 0;
27248af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27258af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27268af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27278af7cee1SJed Brown       nnz[i]++;
27288af7cee1SJed Brown     }
27298af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2730ec7775f6SShri Abhyankar   }
2731ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2732ec7775f6SShri Abhyankar }
2733ec7775f6SShri Abhyankar 
2734ec7775f6SShri Abhyankar #undef __FUNCT__
2735ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2736f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2737ac90fabeSBarry Smith {
2738dfbe8321SBarry Smith   PetscErrorCode ierr;
273997f1f81fSBarry Smith   PetscInt       i;
2740ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2741c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2742ac90fabeSBarry Smith 
2743ac90fabeSBarry Smith   PetscFunctionBegin;
2744c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2745ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2746f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27478b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2748acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2749c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2750a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2751a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27526bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2753a30b2313SHong Zhang     }
2754a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27550298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2756a30b2313SHong Zhang       y->XtoY = X;
2757407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2758c537a176SHong Zhang     }
2759f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2760ba0e910bSBarry 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);
2761ac90fabeSBarry Smith   } else {
27628229c054SShri Abhyankar     Mat      B;
27638229c054SShri Abhyankar     PetscInt *nnz;
276416b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
2765ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2766bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27674aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2768a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2769176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27708229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2771ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2772ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2773ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27748229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2775ac90fabeSBarry Smith   }
2776ac90fabeSBarry Smith   PetscFunctionReturn(0);
2777ac90fabeSBarry Smith }
2778ac90fabeSBarry Smith 
2779521d7252SBarry Smith #undef __FUNCT__
2780354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27817087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2782354c94deSBarry Smith {
2783354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2784354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2785354c94deSBarry Smith   PetscInt    i,nz;
2786354c94deSBarry Smith   PetscScalar *a;
2787354c94deSBarry Smith 
2788354c94deSBarry Smith   PetscFunctionBegin;
2789354c94deSBarry Smith   nz = aij->nz;
2790354c94deSBarry Smith   a  = aij->a;
27912205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2792354c94deSBarry Smith #else
2793354c94deSBarry Smith   PetscFunctionBegin;
2794354c94deSBarry Smith #endif
2795354c94deSBarry Smith   PetscFunctionReturn(0);
2796354c94deSBarry Smith }
2797354c94deSBarry Smith 
2798e34fafa9SBarry Smith #undef __FUNCT__
2799985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2800985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2801e34fafa9SBarry Smith {
2802e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2803e34fafa9SBarry Smith   PetscErrorCode ierr;
2804d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2805e34fafa9SBarry Smith   PetscReal      atmp;
2806985db425SBarry Smith   PetscScalar    *x;
2807e34fafa9SBarry Smith   MatScalar      *aa;
2808e34fafa9SBarry Smith 
2809e34fafa9SBarry Smith   PetscFunctionBegin;
2810e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2811e34fafa9SBarry Smith   aa = a->a;
2812e34fafa9SBarry Smith   ai = a->i;
2813e34fafa9SBarry Smith   aj = a->j;
2814e34fafa9SBarry Smith 
2815985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2816e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2817e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2818e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2819e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2820e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28219189402eSHong Zhang     x[i]  = 0.0;
2822e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2823985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2824985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2825985db425SBarry Smith       aa++; aj++;
2826985db425SBarry Smith     }
2827985db425SBarry Smith   }
2828985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2829985db425SBarry Smith   PetscFunctionReturn(0);
2830985db425SBarry Smith }
2831985db425SBarry Smith 
2832985db425SBarry Smith #undef __FUNCT__
2833985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2834985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2835985db425SBarry Smith {
2836985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2837985db425SBarry Smith   PetscErrorCode ierr;
2838d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2839985db425SBarry Smith   PetscScalar    *x;
2840985db425SBarry Smith   MatScalar      *aa;
2841985db425SBarry Smith 
2842985db425SBarry Smith   PetscFunctionBegin;
2843e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2844985db425SBarry Smith   aa = a->a;
2845985db425SBarry Smith   ai = a->i;
2846985db425SBarry Smith   aj = a->j;
2847985db425SBarry Smith 
2848985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2849985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2850985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2851e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2852985db425SBarry Smith   for (i=0; i<m; i++) {
2853985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2854d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2855985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2856985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2857985db425SBarry Smith       x[i] = 0.0;
2858985db425SBarry Smith       if (idx) {
2859985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2860985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2861985db425SBarry Smith           if (aj[j] > j) {
2862985db425SBarry Smith             idx[i] = j;
2863985db425SBarry Smith             break;
2864985db425SBarry Smith           }
2865985db425SBarry Smith         }
2866985db425SBarry Smith       }
2867985db425SBarry Smith     }
2868985db425SBarry Smith     for (j=0; j<ncols; j++) {
2869985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2870985db425SBarry Smith       aa++; aj++;
2871985db425SBarry Smith     }
2872985db425SBarry Smith   }
2873985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2874985db425SBarry Smith   PetscFunctionReturn(0);
2875985db425SBarry Smith }
2876985db425SBarry Smith 
2877985db425SBarry Smith #undef __FUNCT__
2878c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2879c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2880c87e5d42SMatthew Knepley {
2881c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2882c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2883c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2884c87e5d42SMatthew Knepley   PetscReal      atmp;
2885c87e5d42SMatthew Knepley   PetscScalar    *x;
2886c87e5d42SMatthew Knepley   MatScalar      *aa;
2887c87e5d42SMatthew Knepley 
2888c87e5d42SMatthew Knepley   PetscFunctionBegin;
2889e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2890c87e5d42SMatthew Knepley   aa = a->a;
2891c87e5d42SMatthew Knepley   ai = a->i;
2892c87e5d42SMatthew Knepley   aj = a->j;
2893c87e5d42SMatthew Knepley 
2894c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2895c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2896c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
28973bb78c5cSMatthew 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);
2898c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2899c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2900289a08f5SMatthew Knepley     if (ncols) {
2901289a08f5SMatthew Knepley       /* Get first nonzero */
2902289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2903289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29042205254eSKarl Rupp         if (atmp > 1.0e-12) {
29052205254eSKarl Rupp           x[i] = atmp;
29062205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29072205254eSKarl Rupp           break;
29082205254eSKarl Rupp         }
2909289a08f5SMatthew Knepley       }
291012431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2911289a08f5SMatthew Knepley     } else {
2912289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2913289a08f5SMatthew Knepley     }
2914c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2915c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2916289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2917c87e5d42SMatthew Knepley       aa++; aj++;
2918c87e5d42SMatthew Knepley     }
2919c87e5d42SMatthew Knepley   }
2920c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2921c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2922c87e5d42SMatthew Knepley }
2923c87e5d42SMatthew Knepley 
2924c87e5d42SMatthew Knepley #undef __FUNCT__
2925985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2926985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2927985db425SBarry Smith {
2928985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2929985db425SBarry Smith   PetscErrorCode ierr;
2930d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2931985db425SBarry Smith   PetscScalar    *x;
2932985db425SBarry Smith   MatScalar      *aa;
2933985db425SBarry Smith 
2934985db425SBarry Smith   PetscFunctionBegin;
2935e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936985db425SBarry Smith   aa = a->a;
2937985db425SBarry Smith   ai = a->i;
2938985db425SBarry Smith   aj = a->j;
2939985db425SBarry Smith 
2940985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2941985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2942985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2943e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2944985db425SBarry Smith   for (i=0; i<m; i++) {
2945985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2946d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2947985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2948985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2949985db425SBarry Smith       x[i] = 0.0;
2950985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2951985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2952985db425SBarry Smith         for (j=0; j<ncols; j++) {
2953985db425SBarry Smith           if (aj[j] > j) {
2954985db425SBarry Smith             idx[i] = j;
2955985db425SBarry Smith             break;
2956985db425SBarry Smith           }
2957985db425SBarry Smith         }
2958985db425SBarry Smith       }
2959985db425SBarry Smith     }
2960985db425SBarry Smith     for (j=0; j<ncols; j++) {
2961985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2962985db425SBarry Smith       aa++; aj++;
2963e34fafa9SBarry Smith     }
2964e34fafa9SBarry Smith   }
2965e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2966e34fafa9SBarry Smith   PetscFunctionReturn(0);
2967e34fafa9SBarry Smith }
2968bbead8a2SBarry Smith 
2969bbead8a2SBarry Smith #include <petscblaslapack.h>
297006873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
2971bbead8a2SBarry Smith 
2972bbead8a2SBarry Smith #undef __FUNCT__
2973bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2974713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2975bbead8a2SBarry Smith {
2976bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2977bbead8a2SBarry Smith   PetscErrorCode ierr;
297834fc4b71SJed 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;
2979bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2980bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2981bbead8a2SBarry Smith 
2982bbead8a2SBarry Smith   PetscFunctionBegin;
29834a0d0026SBarry Smith   if (a->ibdiagvalid) {
29844a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29854a0d0026SBarry Smith     PetscFunctionReturn(0);
29864a0d0026SBarry Smith   }
2987bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2988bbead8a2SBarry Smith   if (!a->ibdiag) {
2989bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr);
29903bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2991bbead8a2SBarry Smith   }
2992bbead8a2SBarry Smith   diag = a->ibdiag;
2993bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2994bbead8a2SBarry Smith   /* factor and invert each block */
2995bbead8a2SBarry Smith   switch (bs) {
2996bbead8a2SBarry Smith   case 1:
2997bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2998bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2999bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3000bbead8a2SBarry Smith     }
3001bbead8a2SBarry Smith     break;
3002bbead8a2SBarry Smith   case 2:
3003bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3004bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3005bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
300696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
300796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3008bbead8a2SBarry Smith       diag += 4;
3009bbead8a2SBarry Smith     }
3010bbead8a2SBarry Smith     break;
3011bbead8a2SBarry Smith   case 3:
3012bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3013bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3014bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
301596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
301696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3017bbead8a2SBarry Smith       diag += 9;
3018bbead8a2SBarry Smith     }
3019bbead8a2SBarry Smith     break;
3020bbead8a2SBarry Smith   case 4:
3021bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3022bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3023bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
302496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
302596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3026bbead8a2SBarry Smith       diag += 16;
3027bbead8a2SBarry Smith     }
3028bbead8a2SBarry Smith     break;
3029bbead8a2SBarry Smith   case 5:
3030bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3031bbead8a2SBarry 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;
3032bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
303396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
303496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3035bbead8a2SBarry Smith       diag += 25;
3036bbead8a2SBarry Smith     }
3037bbead8a2SBarry Smith     break;
3038bbead8a2SBarry Smith   case 6:
3039bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3040bbead8a2SBarry 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;
3041bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
304296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
304396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3044bbead8a2SBarry Smith       diag += 36;
3045bbead8a2SBarry Smith     }
3046bbead8a2SBarry Smith     break;
3047bbead8a2SBarry Smith   case 7:
3048bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3049bbead8a2SBarry 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;
3050bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
305196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
305296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3053bbead8a2SBarry Smith       diag += 49;
3054bbead8a2SBarry Smith     }
3055bbead8a2SBarry Smith     break;
3056bbead8a2SBarry Smith   default:
3057*dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3058bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3059bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3060bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3061bbead8a2SBarry Smith       }
3062bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
306396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
306496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3065bbead8a2SBarry Smith       diag += bs2;
3066bbead8a2SBarry Smith     }
3067bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3068bbead8a2SBarry Smith   }
3069bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3070bbead8a2SBarry Smith   PetscFunctionReturn(0);
3071bbead8a2SBarry Smith }
3072bbead8a2SBarry Smith 
307373a71a0fSBarry Smith #undef __FUNCT__
307473a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
307573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
307673a71a0fSBarry Smith {
307773a71a0fSBarry Smith   PetscErrorCode ierr;
307873a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
307973a71a0fSBarry Smith   PetscScalar    a;
308073a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
308173a71a0fSBarry Smith 
308273a71a0fSBarry Smith   PetscFunctionBegin;
308373a71a0fSBarry Smith   if (!x->assembled) {
308473a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
308573a71a0fSBarry Smith     for (i=0; i<m; i++) {
308673a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
308773a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
308873a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
308973a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
309073a71a0fSBarry Smith       }
309173a71a0fSBarry Smith     }
309273a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
309373a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
309473a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
309573a71a0fSBarry Smith   PetscFunctionReturn(0);
309673a71a0fSBarry Smith }
309773a71a0fSBarry Smith 
3098682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30990a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3100cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3101cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3102cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
310397304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31047c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31057c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3106db4efbfdSBarry Smith                                         0,
3107db4efbfdSBarry Smith                                         0,
3108db4efbfdSBarry Smith                                         0,
3109db4efbfdSBarry Smith                                 /* 10*/ 0,
3110cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3111cb5b572fSBarry Smith                                         0,
311241f059aeSBarry Smith                                         MatSOR_SeqAIJ,
311317ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
311497304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3115cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3116cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3117cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3118cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
311997304618SKris Buschelman                                 /* 20*/ 0,
3120cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3121cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3122cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3123d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3124db4efbfdSBarry Smith                                         0,
3125db4efbfdSBarry Smith                                         0,
3126db4efbfdSBarry Smith                                         0,
3127db4efbfdSBarry Smith                                         0,
31284994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3129db4efbfdSBarry Smith                                         0,
3130db4efbfdSBarry Smith                                         0,
31318c778c55SBarry Smith                                         0,
31328c778c55SBarry Smith                                         0,
3133d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3134cb5b572fSBarry Smith                                         0,
3135cb5b572fSBarry Smith                                         0,
3136cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3137cb5b572fSBarry Smith                                         0,
3138d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3139cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3140cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3141cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3142cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3143d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3144cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3145cb5b572fSBarry Smith                                         0,
314679299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31476e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
314873a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31493b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31503b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31513b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3152a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
315393dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3154b9617806SBarry Smith                                         0,
31550513a670SBarry Smith                                         0,
3156cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3157cda55fadSBarry Smith                                         0,
3158d519adbfSMatthew Knepley                                 /* 59*/ 0,
3159b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3160b9b97703SBarry Smith                                         MatView_SeqAIJ,
3161357abbc8SBarry Smith                                         0,
3162321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3163321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3164321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3165ee4f033dSBarry Smith                                         0,
3166ee4f033dSBarry Smith                                         0,
3167ee4f033dSBarry Smith                                         0,
3168d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3169c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3170ee4f033dSBarry Smith                                         0,
3171ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3172dcf5cc72SBarry Smith                                         0,
3173d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31743acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
317597304618SKris Buschelman                                         0,
317697304618SKris Buschelman                                         0,
317797304618SKris Buschelman                                         0,
31786ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
317997304618SKris Buschelman                                         0,
318097304618SKris Buschelman                                         0,
318197304618SKris Buschelman                                         0,
3182bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3183d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31841cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31856284ec50SHong Zhang                                         0,
31866284ec50SHong Zhang                                         0,
3187bc011b1eSHong Zhang                                         0,
3188d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
318926be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
319026be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
319165e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31924a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
319365e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31946fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31956fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31966fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31972121bac1SHong Zhang                                         0,
31982121bac1SHong Zhang                                 /* 99*/ 0,
3199609c6c4dSKris Buschelman                                         0,
3200609c6c4dSKris Buschelman                                         0,
320187d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
320287d4246cSBarry Smith                                         0,
3203d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
320499cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3205f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3206f5edf698SHong Zhang                                         0,
32072bebee5dSHong Zhang                                         0,
3208cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3209985db425SBarry Smith                                         0,
32102af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32112af78befSBarry Smith                                         0,
3212599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3213d519adbfSMatthew Knepley                                 /*114*/ 0,
3214599ef60dSHong Zhang                                         0,
32153c2a7987SHong Zhang                                         0,
3216fe97e370SBarry Smith                                         0,
3217fbdbba38SShri Abhyankar                                         0,
3218fbdbba38SShri Abhyankar                                 /*119*/ 0,
3219fbdbba38SShri Abhyankar                                         0,
3220fbdbba38SShri Abhyankar                                         0,
322182d44351SHong Zhang                                         0,
3222b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32230716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3224bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
322537868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
322637868618SMatthew G Knepley                                         0,
322737868618SMatthew G Knepley                                         0,
32285df89d91SHong Zhang                                 /*129*/ 0,
322975648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
323075648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
323175648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3232b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3233b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32342b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32352b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32362b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32373964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32383964eb88SJed Brown                                  /*139*/0,
3239f9426fe0SMark Adams                                         0,
32401919a2e2SJed Brown                                         0,
3241f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32429e29f15eSvictorle };
324317ab2063SBarry Smith 
32444a2ae208SSatish Balay #undef __FUNCT__
32454a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32467087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3247bef8e0ddSBarry Smith {
3248bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
324997f1f81fSBarry Smith   PetscInt   i,nz,n;
3250bef8e0ddSBarry Smith 
3251bef8e0ddSBarry Smith   PetscFunctionBegin;
3252bef8e0ddSBarry Smith   nz = aij->maxnz;
3253d0f46423SBarry Smith   n  = mat->rmap->n;
3254bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3255bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3256bef8e0ddSBarry Smith   }
3257bef8e0ddSBarry Smith   aij->nz = nz;
3258bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3259bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3260bef8e0ddSBarry Smith   }
3261bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3262bef8e0ddSBarry Smith }
3263bef8e0ddSBarry Smith 
32644a2ae208SSatish Balay #undef __FUNCT__
32654a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3266bef8e0ddSBarry Smith /*@
3267bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3268bef8e0ddSBarry Smith        in the matrix.
3269bef8e0ddSBarry Smith 
3270bef8e0ddSBarry Smith   Input Parameters:
3271bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3272bef8e0ddSBarry Smith -  indices - the column indices
3273bef8e0ddSBarry Smith 
327415091d37SBarry Smith   Level: advanced
327515091d37SBarry Smith 
3276bef8e0ddSBarry Smith   Notes:
3277bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3278bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3279bef8e0ddSBarry Smith   of the MatSetValues() operation.
3280bef8e0ddSBarry Smith 
3281bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3282d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3283bef8e0ddSBarry Smith 
3284bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3285bef8e0ddSBarry Smith 
3286b9617806SBarry Smith     The indices should start with zero, not one.
3287b9617806SBarry Smith 
3288bef8e0ddSBarry Smith @*/
32897087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3290bef8e0ddSBarry Smith {
32914ac538c5SBarry Smith   PetscErrorCode ierr;
3292bef8e0ddSBarry Smith 
3293bef8e0ddSBarry Smith   PetscFunctionBegin;
32940700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32954482741eSBarry Smith   PetscValidPointer(indices,2);
32964ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3297bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3298bef8e0ddSBarry Smith }
3299bef8e0ddSBarry Smith 
3300be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3301be6bf707SBarry Smith 
33024a2ae208SSatish Balay #undef __FUNCT__
33034a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33047087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3305be6bf707SBarry Smith {
3306be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33076849ba73SBarry Smith   PetscErrorCode ierr;
3308d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3309be6bf707SBarry Smith 
3310be6bf707SBarry Smith   PetscFunctionBegin;
3311f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3312be6bf707SBarry Smith 
3313be6bf707SBarry Smith   /* allocate space for values if not already there */
3314be6bf707SBarry Smith   if (!aij->saved_values) {
331587828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
33163bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3317be6bf707SBarry Smith   }
3318be6bf707SBarry Smith 
3319be6bf707SBarry Smith   /* copy values over */
332087828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3321be6bf707SBarry Smith   PetscFunctionReturn(0);
3322be6bf707SBarry Smith }
3323be6bf707SBarry Smith 
33244a2ae208SSatish Balay #undef __FUNCT__
3325b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3326be6bf707SBarry Smith /*@
3327be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3328be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3329be6bf707SBarry Smith        nonlinear portion.
3330be6bf707SBarry Smith 
3331be6bf707SBarry Smith    Collect on Mat
3332be6bf707SBarry Smith 
3333be6bf707SBarry Smith   Input Parameters:
33340e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3335be6bf707SBarry Smith 
333615091d37SBarry Smith   Level: advanced
333715091d37SBarry Smith 
3338be6bf707SBarry Smith   Common Usage, with SNESSolve():
3339be6bf707SBarry Smith $    Create Jacobian matrix
3340be6bf707SBarry Smith $    Set linear terms into matrix
3341be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3342be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3343be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3344512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3345be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3346be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3347be6bf707SBarry Smith $    In your Jacobian routine
3348be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3349be6bf707SBarry Smith $      Set nonlinear terms in matrix
3350be6bf707SBarry Smith 
3351be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3352be6bf707SBarry Smith $    // build linear portion of Jacobian
3353512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3354be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3355be6bf707SBarry Smith $    loop over nonlinear iterations
3356be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3357be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3358be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3359be6bf707SBarry Smith $       Solve linear system with Jacobian
3360be6bf707SBarry Smith $    endloop
3361be6bf707SBarry Smith 
3362be6bf707SBarry Smith   Notes:
3363be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3364512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3365be6bf707SBarry Smith     calling this routine.
3366be6bf707SBarry Smith 
33670c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33680c468ba9SBarry Smith     and does not allocated additional space.
33690c468ba9SBarry Smith 
3370be6bf707SBarry Smith .seealso: MatRetrieveValues()
3371be6bf707SBarry Smith 
3372be6bf707SBarry Smith @*/
33737087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3374be6bf707SBarry Smith {
33754ac538c5SBarry Smith   PetscErrorCode ierr;
3376be6bf707SBarry Smith 
3377be6bf707SBarry Smith   PetscFunctionBegin;
33780700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3379e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3380e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33814ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3382be6bf707SBarry Smith   PetscFunctionReturn(0);
3383be6bf707SBarry Smith }
3384be6bf707SBarry Smith 
33854a2ae208SSatish Balay #undef __FUNCT__
33864a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33877087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3388be6bf707SBarry Smith {
3389be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33906849ba73SBarry Smith   PetscErrorCode ierr;
3391d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3392be6bf707SBarry Smith 
3393be6bf707SBarry Smith   PetscFunctionBegin;
3394f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3395f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3396be6bf707SBarry Smith   /* copy values over */
339787828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3398be6bf707SBarry Smith   PetscFunctionReturn(0);
3399be6bf707SBarry Smith }
3400be6bf707SBarry Smith 
34014a2ae208SSatish Balay #undef __FUNCT__
34024a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3403be6bf707SBarry Smith /*@
3404be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3405be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3406be6bf707SBarry Smith        nonlinear portion.
3407be6bf707SBarry Smith 
3408be6bf707SBarry Smith    Collect on Mat
3409be6bf707SBarry Smith 
3410be6bf707SBarry Smith   Input Parameters:
3411be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3412be6bf707SBarry Smith 
341315091d37SBarry Smith   Level: advanced
341415091d37SBarry Smith 
3415be6bf707SBarry Smith .seealso: MatStoreValues()
3416be6bf707SBarry Smith 
3417be6bf707SBarry Smith @*/
34187087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3419be6bf707SBarry Smith {
34204ac538c5SBarry Smith   PetscErrorCode ierr;
3421be6bf707SBarry Smith 
3422be6bf707SBarry Smith   PetscFunctionBegin;
34230700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3424e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3425e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34264ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3427be6bf707SBarry Smith   PetscFunctionReturn(0);
3428be6bf707SBarry Smith }
3429be6bf707SBarry Smith 
3430f83d6046SBarry Smith 
3431be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34324a2ae208SSatish Balay #undef __FUNCT__
34334a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
343417ab2063SBarry Smith /*@C
3435682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34360d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34376e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
343851c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34392bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
344017ab2063SBarry Smith 
3441db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3442db81eaa0SLois Curfman McInnes 
344317ab2063SBarry Smith    Input Parameters:
3444db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
344517ab2063SBarry Smith .  m - number of rows
344617ab2063SBarry Smith .  n - number of columns
344717ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
344851c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34490298fd71SBarry Smith          (possibly different for each row) or NULL
345017ab2063SBarry Smith 
345117ab2063SBarry Smith    Output Parameter:
3452416022c9SBarry Smith .  A - the matrix
345317ab2063SBarry Smith 
3454175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3455ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3456175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3457175b88e8SBarry Smith 
3458b259b22eSLois Curfman McInnes    Notes:
345949a6f317SBarry Smith    If nnz is given then nz is ignored
346049a6f317SBarry Smith 
346117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
346217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34630002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
346444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
346517ab2063SBarry Smith 
346617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34670298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34683d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34696da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
347017ab2063SBarry Smith 
3471682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34724fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3473682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34746c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34756c7ebb05SLois Curfman McInnes 
34766c7ebb05SLois Curfman McInnes    Options Database Keys:
3477698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34789db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
347917ab2063SBarry Smith 
3480027ccd11SLois Curfman McInnes    Level: intermediate
3481027ccd11SLois Curfman McInnes 
348269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
348336db0b34SBarry Smith 
348417ab2063SBarry Smith @*/
34857087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
348617ab2063SBarry Smith {
3487dfbe8321SBarry Smith   PetscErrorCode ierr;
34886945ee14SBarry Smith 
34893a40ed3dSBarry Smith   PetscFunctionBegin;
3490f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3491117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3492c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3493d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3494273d9f13SBarry Smith   PetscFunctionReturn(0);
3495273d9f13SBarry Smith }
3496273d9f13SBarry Smith 
34974a2ae208SSatish Balay #undef __FUNCT__
34984a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3499273d9f13SBarry Smith /*@C
3500273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3501273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3502273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3503273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3504273d9f13SBarry Smith 
3505273d9f13SBarry Smith    Collective on MPI_Comm
3506273d9f13SBarry Smith 
3507273d9f13SBarry Smith    Input Parameters:
3508117016b1SBarry Smith +  B - The matrix-free
3509273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3510273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35110298fd71SBarry Smith          (possibly different for each row) or NULL
3512273d9f13SBarry Smith 
3513273d9f13SBarry Smith    Notes:
351449a6f317SBarry Smith      If nnz is given then nz is ignored
351549a6f317SBarry Smith 
3516273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3517273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3518273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3519273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3520273d9f13SBarry Smith 
3521273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35220298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3523273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3524273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3525273d9f13SBarry Smith 
3526aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3527aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3528aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3529aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3530aa95bbe8SBarry Smith 
3531a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3532a96a251dSBarry Smith    entries or columns indices
3533a96a251dSBarry Smith 
3534273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3535273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3536273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3537273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3538273d9f13SBarry Smith 
3539273d9f13SBarry Smith    Options Database Keys:
3540698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3541698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3542273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3543273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3544273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3545273d9f13SBarry Smith 
3546273d9f13SBarry Smith    Level: intermediate
3547273d9f13SBarry Smith 
354869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3549273d9f13SBarry Smith 
3550273d9f13SBarry Smith @*/
35517087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3552273d9f13SBarry Smith {
35534ac538c5SBarry Smith   PetscErrorCode ierr;
3554a23d5eceSKris Buschelman 
3555a23d5eceSKris Buschelman   PetscFunctionBegin;
35566ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35576ba663aaSJed Brown   PetscValidType(B,1);
35584ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3559a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3560a23d5eceSKris Buschelman }
3561a23d5eceSKris Buschelman 
3562a23d5eceSKris Buschelman #undef __FUNCT__
3563a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35647087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3565a23d5eceSKris Buschelman {
3566273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35672576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35686849ba73SBarry Smith   PetscErrorCode ierr;
356997f1f81fSBarry Smith   PetscInt       i;
3570273d9f13SBarry Smith 
3571273d9f13SBarry Smith   PetscFunctionBegin;
35722576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3573a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3574c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3575c461c341SBarry Smith     nz             = 0;
3576c461c341SBarry Smith   }
3577c461c341SBarry Smith 
357826283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
357926283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3580899cda47SBarry Smith 
3581435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3582e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3583b73539f3SBarry Smith   if (nnz) {
3584d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3585e32f2f54SBarry 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]);
3586e32f2f54SBarry 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);
3587b73539f3SBarry Smith     }
3588b73539f3SBarry Smith   }
3589b73539f3SBarry Smith 
3590273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35912205254eSKarl Rupp 
3592273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3593273d9f13SBarry Smith 
3594ab93d7beSBarry Smith   if (!skipallocation) {
35952ee49352SLisandro Dalcin     if (!b->imax) {
3596*dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35973bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35982ee49352SLisandro Dalcin     }
3599273d9f13SBarry Smith     if (!nnz) {
3600435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3601c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3602d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3603d0f46423SBarry Smith       nz = nz*B->rmap->n;
3604273d9f13SBarry Smith     } else {
3605273d9f13SBarry Smith       nz = 0;
3606d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3607273d9f13SBarry Smith     }
3608ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36092205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3610ab93d7beSBarry Smith 
3611273d9f13SBarry Smith     /* allocate the matrix space */
36122ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3613*dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
36143bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3615bfeeae90SHong Zhang     b->i[0] = 0;
3616d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36175da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36185da197adSKris Buschelman     }
3619273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3620e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3621e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3622b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3623b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3624b31eba2aSShri Abhyankar #endif
3625c461c341SBarry Smith   } else {
3626e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3627e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3628c461c341SBarry Smith   }
3629273d9f13SBarry Smith 
3630273d9f13SBarry Smith   b->nz               = 0;
3631273d9f13SBarry Smith   b->maxnz            = nz;
3632273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36332205254eSKarl Rupp   if (realalloc) {
36342205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36352205254eSKarl Rupp   }
3636273d9f13SBarry Smith   PetscFunctionReturn(0);
3637273d9f13SBarry Smith }
3638273d9f13SBarry Smith 
3639a1661176SMatthew Knepley #undef  __FUNCT__
3640a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
364158d36128SBarry Smith /*@
3642a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3643a1661176SMatthew Knepley 
3644a1661176SMatthew Knepley    Input Parameters:
3645a1661176SMatthew Knepley +  B - the matrix
3646a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3647a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3648a1661176SMatthew Knepley -  v - optional values in the matrix
3649a1661176SMatthew Knepley 
3650a1661176SMatthew Knepley    Level: developer
3651a1661176SMatthew Knepley 
365258d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
365358d36128SBarry Smith 
3654a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3655a1661176SMatthew Knepley 
3656a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3657a1661176SMatthew Knepley @*/
3658a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3659a1661176SMatthew Knepley {
3660a1661176SMatthew Knepley   PetscErrorCode ierr;
3661a1661176SMatthew Knepley 
3662a1661176SMatthew Knepley   PetscFunctionBegin;
36630700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36646ba663aaSJed Brown   PetscValidType(B,1);
36654ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3666a1661176SMatthew Knepley   PetscFunctionReturn(0);
3667a1661176SMatthew Knepley }
3668a1661176SMatthew Knepley 
3669a1661176SMatthew Knepley #undef  __FUNCT__
3670a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36717087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3672a1661176SMatthew Knepley {
3673a1661176SMatthew Knepley   PetscInt       i;
3674a1661176SMatthew Knepley   PetscInt       m,n;
3675a1661176SMatthew Knepley   PetscInt       nz;
3676a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3677a1661176SMatthew Knepley   PetscScalar    *values;
3678a1661176SMatthew Knepley   PetscErrorCode ierr;
3679a1661176SMatthew Knepley 
3680a1661176SMatthew Knepley   PetscFunctionBegin;
368165e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3682779a8d59SSatish Balay 
3683779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3684779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3685779a8d59SSatish Balay 
3686779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3687a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
3688a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3689b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3690a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
369165e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3692a1661176SMatthew Knepley     nnz[i] = nz;
3693a1661176SMatthew Knepley   }
3694a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3695a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3696a1661176SMatthew Knepley 
3697a1661176SMatthew Knepley   if (v) {
3698a1661176SMatthew Knepley     values = (PetscScalar*) v;
3699a1661176SMatthew Knepley   } else {
37000e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
3701a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
3702a1661176SMatthew Knepley   }
3703a1661176SMatthew Knepley 
3704a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3705b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3706b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3707a1661176SMatthew Knepley   }
3708a1661176SMatthew Knepley 
3709a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3710a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3711a1661176SMatthew Knepley 
3712a1661176SMatthew Knepley   if (!v) {
3713a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3714a1661176SMatthew Knepley   }
37157827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3716a1661176SMatthew Knepley   PetscFunctionReturn(0);
3717a1661176SMatthew Knepley }
3718a1661176SMatthew Knepley 
3719c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
372006873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3721170fe5c8SBarry Smith 
3722170fe5c8SBarry Smith #undef __FUNCT__
3723170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3724170fe5c8SBarry Smith /*
3725170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3726170fe5c8SBarry Smith 
3727170fe5c8SBarry Smith                n                       p                          p
3728170fe5c8SBarry Smith         (              )       (              )         (                  )
3729170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3730170fe5c8SBarry Smith         (              )       (              )         (                  )
3731170fe5c8SBarry Smith 
3732170fe5c8SBarry Smith */
3733170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3734170fe5c8SBarry Smith {
3735170fe5c8SBarry Smith   PetscErrorCode    ierr;
3736170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3737170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3738170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37391de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3740170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3741170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3742170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3743170fe5c8SBarry Smith 
3744170fe5c8SBarry Smith   PetscFunctionBegin;
3745d0f46423SBarry Smith   m    = A->rmap->n;
3746d0f46423SBarry Smith   n    = A->cmap->n;
3747d0f46423SBarry Smith   p    = B->cmap->n;
3748170fe5c8SBarry Smith   a    = sub_a->v;
3749170fe5c8SBarry Smith   b    = sub_b->a;
3750170fe5c8SBarry Smith   c    = sub_c->v;
3751170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3752170fe5c8SBarry Smith 
3753170fe5c8SBarry Smith   ii  = sub_b->i;
3754170fe5c8SBarry Smith   idx = sub_b->j;
3755170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3756170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3757170fe5c8SBarry Smith     while (q-->0) {
3758170fe5c8SBarry Smith       c_q = c + m*(*idx);
3759170fe5c8SBarry Smith       a_q = a + m*i;
3760854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3761170fe5c8SBarry Smith       idx++;
3762170fe5c8SBarry Smith       b++;
3763170fe5c8SBarry Smith     }
3764170fe5c8SBarry Smith   }
3765170fe5c8SBarry Smith   PetscFunctionReturn(0);
3766170fe5c8SBarry Smith }
3767170fe5c8SBarry Smith 
3768170fe5c8SBarry Smith #undef __FUNCT__
3769170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3770170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3771170fe5c8SBarry Smith {
3772170fe5c8SBarry Smith   PetscErrorCode ierr;
3773d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3774170fe5c8SBarry Smith   Mat            Cmat;
3775170fe5c8SBarry Smith 
3776170fe5c8SBarry Smith   PetscFunctionBegin;
3777e32f2f54SBarry 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);
3778ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3779170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3780a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3781170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37820298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3783d73949e8SHong Zhang 
3784d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37852205254eSKarl Rupp 
3786170fe5c8SBarry Smith   *C = Cmat;
3787170fe5c8SBarry Smith   PetscFunctionReturn(0);
3788170fe5c8SBarry Smith }
3789170fe5c8SBarry Smith 
3790170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3791170fe5c8SBarry Smith #undef __FUNCT__
3792170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3793170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3794170fe5c8SBarry Smith {
3795170fe5c8SBarry Smith   PetscErrorCode ierr;
3796170fe5c8SBarry Smith 
3797170fe5c8SBarry Smith   PetscFunctionBegin;
3798170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37993ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3800170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38013ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3802170fe5c8SBarry Smith   }
38033ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3804170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38053ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3806170fe5c8SBarry Smith   PetscFunctionReturn(0);
3807170fe5c8SBarry Smith }
3808170fe5c8SBarry Smith 
3809170fe5c8SBarry Smith 
38100bad9183SKris Buschelman /*MC
3811fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38120bad9183SKris Buschelman    based on compressed sparse row format.
38130bad9183SKris Buschelman 
38140bad9183SKris Buschelman    Options Database Keys:
38150bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38160bad9183SKris Buschelman 
38170bad9183SKris Buschelman   Level: beginner
38180bad9183SKris Buschelman 
3819f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38200bad9183SKris Buschelman M*/
38210bad9183SKris Buschelman 
3822ccd284c7SBarry Smith /*MC
3823ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3824ccd284c7SBarry Smith 
3825ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3826ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3827ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3828ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3829ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3830ccd284c7SBarry Smith 
3831ccd284c7SBarry Smith    Options Database Keys:
3832ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3833ccd284c7SBarry Smith 
3834ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3835ccd284c7SBarry Smith    enough exist.
3836ccd284c7SBarry Smith 
3837ccd284c7SBarry Smith   Level: beginner
3838ccd284c7SBarry Smith 
3839ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3840ccd284c7SBarry Smith M*/
3841ccd284c7SBarry Smith 
3842ccd284c7SBarry Smith /*MC
3843ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3844ccd284c7SBarry Smith 
3845ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3846ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3847ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3848ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3849ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3850ccd284c7SBarry Smith 
3851ccd284c7SBarry Smith    Options Database Keys:
3852ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3853ccd284c7SBarry Smith 
3854ccd284c7SBarry Smith   Level: beginner
3855ccd284c7SBarry Smith 
3856ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3857ccd284c7SBarry Smith M*/
3858ccd284c7SBarry Smith 
3859b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38608cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3861b5e56a35SBarry Smith #endif
3862ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38638cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3864af1023dbSSatish Balay #endif
38658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38678cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38687087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3869611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38708cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3871611f576cSBarry Smith #endif
3872611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3874611f576cSBarry Smith #endif
3875f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3877f3c0ef26SHong Zhang #endif
3878eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3880eb3b5408SSatish Balay #endif
3881586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3883586621ddSJed Brown #endif
3884719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3886719d5645SBarry Smith #endif
3887b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38897087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38907087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3891b3866ffcSBarry Smith #endif
389217f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
389417f1a0eaSHong Zhang #endif
389517667f90SBarry Smith 
3896c0c8ee5eSDmitry Karpeev 
38978c778c55SBarry Smith #undef __FUNCT__
38988c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
38998c778c55SBarry Smith /*@C
39008c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39018c778c55SBarry Smith 
39028c778c55SBarry Smith    Not Collective
39038c778c55SBarry Smith 
39048c778c55SBarry Smith    Input Parameter:
39058c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39068c778c55SBarry Smith 
39078c778c55SBarry Smith    Output Parameter:
39088c778c55SBarry Smith .   array - pointer to the data
39098c778c55SBarry Smith 
39108c778c55SBarry Smith    Level: intermediate
39118c778c55SBarry Smith 
3912774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39138c778c55SBarry Smith @*/
39148c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39158c778c55SBarry Smith {
39168c778c55SBarry Smith   PetscErrorCode ierr;
39178c778c55SBarry Smith 
39188c778c55SBarry Smith   PetscFunctionBegin;
39198c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39208c778c55SBarry Smith   PetscFunctionReturn(0);
39218c778c55SBarry Smith }
39228c778c55SBarry Smith 
39238c778c55SBarry Smith #undef __FUNCT__
39248c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39258c778c55SBarry Smith /*@C
39268c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39278c778c55SBarry Smith 
39288c778c55SBarry Smith    Not Collective
39298c778c55SBarry Smith 
39308c778c55SBarry Smith    Input Parameters:
39318c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39328c778c55SBarry Smith .  array - pointer to the data
39338c778c55SBarry Smith 
39348c778c55SBarry Smith    Level: intermediate
39358c778c55SBarry Smith 
3936774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39378c778c55SBarry Smith @*/
39388c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39398c778c55SBarry Smith {
39408c778c55SBarry Smith   PetscErrorCode ierr;
39418c778c55SBarry Smith 
39428c778c55SBarry Smith   PetscFunctionBegin;
39438c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39448c778c55SBarry Smith   PetscFunctionReturn(0);
39458c778c55SBarry Smith }
39468c778c55SBarry Smith 
39474a2ae208SSatish Balay #undef __FUNCT__
39484a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39498cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3950273d9f13SBarry Smith {
3951273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3952dfbe8321SBarry Smith   PetscErrorCode ierr;
395338baddfdSBarry Smith   PetscMPIInt    size;
3954273d9f13SBarry Smith 
3955273d9f13SBarry Smith   PetscFunctionBegin;
3956ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3957e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3958273d9f13SBarry Smith 
395938f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39602205254eSKarl Rupp 
3961b0a32e0cSBarry Smith   B->data = (void*)b;
39622205254eSKarl Rupp 
3963549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39642205254eSKarl Rupp 
3965416022c9SBarry Smith   b->row                = 0;
3966416022c9SBarry Smith   b->col                = 0;
396782bf6240SBarry Smith   b->icol               = 0;
3968b810aeb4SBarry Smith   b->reallocs           = 0;
396936db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3970f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3971416022c9SBarry Smith   b->nonew              = 0;
3972416022c9SBarry Smith   b->diag               = 0;
3973416022c9SBarry Smith   b->solve_work         = 0;
39742a1b7f2aSHong Zhang   B->spptr              = 0;
3975be6bf707SBarry Smith   b->saved_values       = 0;
3976d7f994e1SBarry Smith   b->idiag              = 0;
397771f1c65dSBarry Smith   b->mdiag              = 0;
397871f1c65dSBarry Smith   b->ssor_work          = 0;
397971f1c65dSBarry Smith   b->omega              = 1.0;
398071f1c65dSBarry Smith   b->fshift             = 0.0;
398171f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3982bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3983a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3984a30b2313SHong Zhang   b->xtoy               = 0;
3985a30b2313SHong Zhang   b->XtoY               = 0;
398688e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
398717ab2063SBarry Smith 
398835d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3989bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3990bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39918c778c55SBarry Smith 
3992b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3993bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3994bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3996b3866ffcSBarry Smith #endif
3997b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3998bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3999b5e56a35SBarry Smith #endif
4000ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4001bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4002719d5645SBarry Smith #endif
4003611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4004bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4005611f576cSBarry Smith #endif
4006f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4008f3c0ef26SHong Zhang #endif
4009611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4010bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4011611f576cSBarry Smith #endif
4012eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4013bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4014eb3b5408SSatish Balay #endif
4015586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4016bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4017586621ddSJed Brown #endif
4018719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4020719d5645SBarry Smith #endif
402117f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4022bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
402317f1a0eaSHong Zhang #endif
402417f1a0eaSHong Zhang 
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4026bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4027bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40434108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
404417667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40453a40ed3dSBarry Smith   PetscFunctionReturn(0);
404617ab2063SBarry Smith }
404717ab2063SBarry Smith 
40484a2ae208SSatish Balay #undef __FUNCT__
4049b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4050b24902e0SBarry Smith /*
4051b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4052b24902e0SBarry Smith */
4053ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
405417ab2063SBarry Smith {
4055416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40566849ba73SBarry Smith   PetscErrorCode ierr;
4057d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
405817ab2063SBarry Smith 
40593a40ed3dSBarry Smith   PetscFunctionBegin;
4060273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4061273d9f13SBarry Smith 
4062d5f3da31SBarry Smith   C->factortype = A->factortype;
4063416022c9SBarry Smith   c->row        = 0;
4064416022c9SBarry Smith   c->col        = 0;
406582bf6240SBarry Smith   c->icol       = 0;
40666ad4291fSHong Zhang   c->reallocs   = 0;
406717ab2063SBarry Smith 
40686ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
406917ab2063SBarry Smith 
4070aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4071aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4072eec197d1SBarry Smith 
4073*dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40743bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
407517ab2063SBarry Smith   for (i=0; i<m; i++) {
4076416022c9SBarry Smith     c->imax[i] = a->imax[i];
4077416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
407817ab2063SBarry Smith   }
407917ab2063SBarry Smith 
408017ab2063SBarry Smith   /* allocate the matrix space */
4081f77e22a1SHong Zhang   if (mallocmatspace) {
4082*dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40833bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40842205254eSKarl Rupp 
4085f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40862205254eSKarl Rupp 
408797f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
408817ab2063SBarry Smith     if (m > 0) {
408997f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4090be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4091bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4092be6bf707SBarry Smith       } else {
4093bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
409417ab2063SBarry Smith       }
409508480c60SBarry Smith     }
4096f77e22a1SHong Zhang   }
409717ab2063SBarry Smith 
40986ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4099416022c9SBarry Smith   c->roworiented       = a->roworiented;
4100416022c9SBarry Smith   c->nonew             = a->nonew;
4101416022c9SBarry Smith   if (a->diag) {
410297f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
41033bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410417ab2063SBarry Smith     for (i=0; i<m; i++) {
4105416022c9SBarry Smith       c->diag[i] = a->diag[i];
410617ab2063SBarry Smith     }
41073a40ed3dSBarry Smith   } else c->diag = 0;
41082205254eSKarl Rupp 
41096ad4291fSHong Zhang   c->solve_work         = 0;
41106ad4291fSHong Zhang   c->saved_values       = 0;
41116ad4291fSHong Zhang   c->idiag              = 0;
411271f1c65dSBarry Smith   c->ssor_work          = 0;
4113a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4114e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4115e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41166ad4291fSHong Zhang   c->xtoy               = 0;
41176ad4291fSHong Zhang   c->XtoY               = 0;
41186ad4291fSHong Zhang 
4119893ad86cSHong Zhang   c->rmax         = a->rmax;
4120416022c9SBarry Smith   c->nz           = a->nz;
41218ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4122273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4123754ec7b1SSatish Balay 
41246ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41256ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4126cd6b891eSBarry Smith   if (a->compressedrow.use) {
41276ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4128*dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
41296ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41306ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
413127ea64f8SHong Zhang   } else {
413227ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41330298fd71SBarry Smith     c->compressedrow.i      = NULL;
41340298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41356ad4291fSHong Zhang   }
413688e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41374846f1f5SKris Buschelman 
41382205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4139140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41403a40ed3dSBarry Smith   PetscFunctionReturn(0);
414117ab2063SBarry Smith }
414217ab2063SBarry Smith 
41434a2ae208SSatish Balay #undef __FUNCT__
4144b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4145b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4146b24902e0SBarry Smith {
4147b24902e0SBarry Smith   PetscErrorCode ierr;
4148b24902e0SBarry Smith 
4149b24902e0SBarry Smith   PetscFunctionBegin;
4150ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41514b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4152a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4153a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4154f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4155b24902e0SBarry Smith   PetscFunctionReturn(0);
4156b24902e0SBarry Smith }
4157b24902e0SBarry Smith 
4158b24902e0SBarry Smith #undef __FUNCT__
41594a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4160112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4161fbdbba38SShri Abhyankar {
4162fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4163fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4164fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4165fbdbba38SShri Abhyankar   int            fd;
4166fbdbba38SShri Abhyankar   PetscMPIInt    size;
4167fbdbba38SShri Abhyankar   MPI_Comm       comm;
4168bbead8a2SBarry Smith   PetscInt       bs = 1;
4169fbdbba38SShri Abhyankar 
4170fbdbba38SShri Abhyankar   PetscFunctionBegin;
4171fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4172fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4173fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4174bbead8a2SBarry Smith 
41750298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41760298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4177bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41781814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4179bbead8a2SBarry Smith 
4180fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4181fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4182fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4183fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4184fbdbba38SShri Abhyankar 
4185bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4186fbdbba38SShri Abhyankar 
4187fbdbba38SShri Abhyankar   /* read in row lengths */
4188fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4189fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4190fbdbba38SShri Abhyankar 
4191fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4192fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4193fbdbba38SShri 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);
4194fbdbba38SShri Abhyankar 
4195fbdbba38SShri Abhyankar   /* set global size if not set already*/
4196f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4197fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4198aabbc4fbSShri Abhyankar   } else {
4199fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4200fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42014c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42024c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42034c5b953cSHong Zhang     }
4204f501eaabSShri 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);
4205aabbc4fbSShri Abhyankar   }
4206fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4207fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4208fbdbba38SShri Abhyankar 
4209fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4210fbdbba38SShri Abhyankar 
4211fbdbba38SShri Abhyankar   /* read in nonzero values */
4212fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4213fbdbba38SShri Abhyankar 
4214fbdbba38SShri Abhyankar   /* set matrix "i" values */
4215fbdbba38SShri Abhyankar   a->i[0] = 0;
4216fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4217fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4218fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4219fbdbba38SShri Abhyankar   }
4220fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4221fbdbba38SShri Abhyankar 
4222fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4223fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4224fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4225fbdbba38SShri Abhyankar }
4226fbdbba38SShri Abhyankar 
4227fbdbba38SShri Abhyankar #undef __FUNCT__
4228b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4229ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42307264ac53SSatish Balay {
42317264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4232dfbe8321SBarry Smith   PetscErrorCode ierr;
4233eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4234eeffb40dSHong Zhang   PetscInt k;
4235eeffb40dSHong Zhang #endif
42367264ac53SSatish Balay 
42373a40ed3dSBarry Smith   PetscFunctionBegin;
4238bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4239d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4240ca44d042SBarry Smith     *flg = PETSC_FALSE;
4241ca44d042SBarry Smith     PetscFunctionReturn(0);
4242bcd2baecSBarry Smith   }
42437264ac53SSatish Balay 
42447264ac53SSatish Balay   /* if the a->i are the same */
4245d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4246abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42477264ac53SSatish Balay 
42487264ac53SSatish Balay   /* if a->j are the same */
424997f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4250abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4251bcd2baecSBarry Smith 
4252bcd2baecSBarry Smith   /* if a->a are the same */
4253eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4254eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4255eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4256eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42573a40ed3dSBarry Smith       PetscFunctionReturn(0);
4258eeffb40dSHong Zhang     }
4259eeffb40dSHong Zhang   }
4260eeffb40dSHong Zhang #else
4261eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4262eeffb40dSHong Zhang #endif
4263eeffb40dSHong Zhang   PetscFunctionReturn(0);
42647264ac53SSatish Balay }
426536db0b34SBarry Smith 
42664a2ae208SSatish Balay #undef __FUNCT__
42674a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
426805869f15SSatish Balay /*@
426936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
427036db0b34SBarry Smith               provided by the user.
427136db0b34SBarry Smith 
4272c75a6043SHong Zhang       Collective on MPI_Comm
427336db0b34SBarry Smith 
427436db0b34SBarry Smith    Input Parameters:
427536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
427636db0b34SBarry Smith .   m - number of rows
427736db0b34SBarry Smith .   n - number of columns
427836db0b34SBarry Smith .   i - row indices
427936db0b34SBarry Smith .   j - column indices
428036db0b34SBarry Smith -   a - matrix values
428136db0b34SBarry Smith 
428236db0b34SBarry Smith    Output Parameter:
428336db0b34SBarry Smith .   mat - the matrix
428436db0b34SBarry Smith 
428536db0b34SBarry Smith    Level: intermediate
428636db0b34SBarry Smith 
428736db0b34SBarry Smith    Notes:
42880551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4289292fb18eSBarry Smith     once the matrix is destroyed and not before
429036db0b34SBarry Smith 
429136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
429236db0b34SBarry Smith 
4293bfeeae90SHong Zhang        The i and j indices are 0 based
429436db0b34SBarry Smith 
4295a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4296a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4297a4552177SSatish Balay     as shown:
4298a4552177SSatish Balay 
4299a4552177SSatish Balay         1 0 0
4300a4552177SSatish Balay         2 0 3
4301a4552177SSatish Balay         4 5 6
4302a4552177SSatish Balay 
4303a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43049985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4305a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4306a4552177SSatish Balay 
43079985e31cSBarry Smith 
430869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
430936db0b34SBarry Smith 
431036db0b34SBarry Smith @*/
43117087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
431236db0b34SBarry Smith {
4313dfbe8321SBarry Smith   PetscErrorCode ierr;
4314cbcfb4deSHong Zhang   PetscInt       ii;
431536db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4316cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4317cbcfb4deSHong Zhang   PetscInt jj;
4318cbcfb4deSHong Zhang #endif
431936db0b34SBarry Smith 
432036db0b34SBarry Smith   PetscFunctionBegin;
4321f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4322f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4323f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4324a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4325ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4326ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4327ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4328*dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4329ab93d7beSBarry Smith 
433036db0b34SBarry Smith   aij->i            = i;
433136db0b34SBarry Smith   aij->j            = j;
433236db0b34SBarry Smith   aij->a            = a;
433336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
433436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4335e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4336e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
433736db0b34SBarry Smith 
433836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
433936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43402515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4341e32f2f54SBarry 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]);
43429985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4343e32f2f54SBarry 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);
4344e32f2f54SBarry 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);
43459985e31cSBarry Smith     }
434636db0b34SBarry Smith #endif
434736db0b34SBarry Smith   }
43482515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
434936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4350e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4351e32f2f54SBarry 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]);
435236db0b34SBarry Smith   }
435336db0b34SBarry Smith #endif
435436db0b34SBarry Smith 
4355b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4356b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
435736db0b34SBarry Smith   PetscFunctionReturn(0);
435836db0b34SBarry Smith }
43598a0b0e6bSVictor Minden #undef __FUNCT__
43608a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
436180ef6e79SMatthew G Knepley /*@C
4362d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43638a0b0e6bSVictor Minden               provided by the user.
43648a0b0e6bSVictor Minden 
43658a0b0e6bSVictor Minden       Collective on MPI_Comm
43668a0b0e6bSVictor Minden 
43678a0b0e6bSVictor Minden    Input Parameters:
43688a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43698a0b0e6bSVictor Minden .   m   - number of rows
43708a0b0e6bSVictor Minden .   n   - number of columns
43718a0b0e6bSVictor Minden .   i   - row indices
43728a0b0e6bSVictor Minden .   j   - column indices
43731230e6d1SVictor Minden .   a   - matrix values
43741230e6d1SVictor Minden .   nz  - number of nonzeros
43751230e6d1SVictor Minden -   idx - 0 or 1 based
43768a0b0e6bSVictor Minden 
43778a0b0e6bSVictor Minden    Output Parameter:
43788a0b0e6bSVictor Minden .   mat - the matrix
43798a0b0e6bSVictor Minden 
43808a0b0e6bSVictor Minden    Level: intermediate
43818a0b0e6bSVictor Minden 
43828a0b0e6bSVictor Minden    Notes:
43838a0b0e6bSVictor Minden        The i and j indices are 0 based
43848a0b0e6bSVictor Minden 
43858a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43868a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43878a0b0e6bSVictor Minden     as shown:
43888a0b0e6bSVictor Minden 
43898a0b0e6bSVictor Minden         1 0 0
43908a0b0e6bSVictor Minden         2 0 3
43918a0b0e6bSVictor Minden         4 5 6
43928a0b0e6bSVictor Minden 
43938a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43948a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43958a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43968a0b0e6bSVictor Minden 
43978a0b0e6bSVictor Minden 
439869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43998a0b0e6bSVictor Minden 
44008a0b0e6bSVictor Minden @*/
44011230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44028a0b0e6bSVictor Minden {
44038a0b0e6bSVictor Minden   PetscErrorCode ierr;
4404d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44058a0b0e6bSVictor Minden 
44068a0b0e6bSVictor Minden 
44078a0b0e6bSVictor Minden   PetscFunctionBegin;
4408d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
44091230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
44101230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4411c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
44121230e6d1SVictor Minden   }
44138a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44148a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
44158a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44161230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44171230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44181230e6d1SVictor Minden     if (idx) {
44191230e6d1SVictor Minden       row = i[ii] - 1;
44201230e6d1SVictor Minden       col = j[ii] - 1;
44211230e6d1SVictor Minden     } else {
44221230e6d1SVictor Minden       row = i[ii];
44231230e6d1SVictor Minden       col = j[ii];
44248a0b0e6bSVictor Minden     }
44251230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44268a0b0e6bSVictor Minden   }
44278a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44288a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4429d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44308a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44318a0b0e6bSVictor Minden }
443236db0b34SBarry Smith 
4433cc8ba8e1SBarry Smith #undef __FUNCT__
4434ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4435dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4436cc8ba8e1SBarry Smith {
4437dfbe8321SBarry Smith   PetscErrorCode ierr;
4438cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
443936db0b34SBarry Smith 
4440cc8ba8e1SBarry Smith   PetscFunctionBegin;
44418ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4442cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4443cc8ba8e1SBarry Smith     a->coloring = coloring;
444412c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
444597f1f81fSBarry Smith     PetscInt        i,*larray;
444612c595b3SBarry Smith     ISColoring      ocoloring;
444708b6dcc0SBarry Smith     ISColoringValue *colors;
444812c595b3SBarry Smith 
444912c595b3SBarry Smith     /* set coloring for diagonal portion */
44500e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
44512205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44520298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
44530e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
44542205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
445512c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4456d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
445712c595b3SBarry Smith     a->coloring = ocoloring;
445812c595b3SBarry Smith   }
4459cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4460cc8ba8e1SBarry Smith }
4461cc8ba8e1SBarry Smith 
4462ee4f033dSBarry Smith #undef __FUNCT__
4463ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
446497f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4465ee4f033dSBarry Smith {
4466ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4467d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
446854f21887SBarry Smith   MatScalar       *v      = a->a;
446954f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
447008b6dcc0SBarry Smith   ISColoringValue *color;
4471ee4f033dSBarry Smith 
4472ee4f033dSBarry Smith   PetscFunctionBegin;
4473e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4474ee4f033dSBarry Smith   color = a->coloring->colors;
4475ee4f033dSBarry Smith   /* loop over rows */
4476ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4477ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4478ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44792205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4480ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4481cc8ba8e1SBarry Smith   }
4482cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4483cc8ba8e1SBarry Smith }
448436db0b34SBarry Smith 
4485acf2f550SJed Brown #undef __FUNCT__
4486acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4487acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4488acf2f550SJed Brown {
4489acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4490acf2f550SJed Brown   PetscErrorCode ierr;
4491acf2f550SJed Brown 
4492acf2f550SJed Brown   PetscFunctionBegin;
4493acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4494acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
44952205254eSKarl Rupp 
4496acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4497acf2f550SJed Brown   PetscFunctionReturn(0);
4498acf2f550SJed Brown }
4499acf2f550SJed Brown 
450081824310SBarry Smith /*
450181824310SBarry Smith     Special version for direct calls from Fortran
450281824310SBarry Smith */
4503b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
450481824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
450581824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
450681824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
450781824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
450881824310SBarry Smith #endif
450981824310SBarry Smith 
451081824310SBarry Smith /* Change these macros so can be used in void function */
451181824310SBarry Smith #undef CHKERRQ
4512ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
451381824310SBarry Smith #undef SETERRQ2
4514e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45154994cf47SJed Brown #undef SETERRQ3
45164994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
451781824310SBarry Smith 
451881824310SBarry Smith #undef __FUNCT__
451981824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45208cc058d9SJed 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)
452181824310SBarry Smith {
452281824310SBarry Smith   Mat            A  = *AA;
452381824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
452481824310SBarry Smith   InsertMode     is = *isis;
452581824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
452681824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
452781824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
452881824310SBarry Smith   PetscErrorCode ierr;
452981824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
453054f21887SBarry Smith   MatScalar      *ap,value,*aa;
4531ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4532ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
453381824310SBarry Smith 
453481824310SBarry Smith   PetscFunctionBegin;
45354994cf47SJed Brown   MatCheckPreallocated(A,1);
453681824310SBarry Smith   imax  = a->imax;
453781824310SBarry Smith   ai    = a->i;
453881824310SBarry Smith   ailen = a->ilen;
453981824310SBarry Smith   aj    = a->j;
454081824310SBarry Smith   aa    = a->a;
454181824310SBarry Smith 
454281824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
454381824310SBarry Smith     row = im[k];
454481824310SBarry Smith     if (row < 0) continue;
454581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4546ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
454781824310SBarry Smith #endif
454881824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
454981824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
455081824310SBarry Smith     low  = 0;
455181824310SBarry Smith     high = nrow;
455281824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
455381824310SBarry Smith       if (in[l] < 0) continue;
455481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4555ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
455681824310SBarry Smith #endif
455781824310SBarry Smith       col = in[l];
45582205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45592205254eSKarl Rupp       else value = v[k + l*m];
45602205254eSKarl Rupp 
456181824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
456281824310SBarry Smith 
45632205254eSKarl Rupp       if (col <= lastcol) low = 0;
45642205254eSKarl Rupp       else high = nrow;
456581824310SBarry Smith       lastcol = col;
456681824310SBarry Smith       while (high-low > 5) {
456781824310SBarry Smith         t = (low+high)/2;
456881824310SBarry Smith         if (rp[t] > col) high = t;
456981824310SBarry Smith         else             low  = t;
457081824310SBarry Smith       }
457181824310SBarry Smith       for (i=low; i<high; i++) {
457281824310SBarry Smith         if (rp[i] > col) break;
457381824310SBarry Smith         if (rp[i] == col) {
457481824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
457581824310SBarry Smith           else                  ap[i] = value;
457681824310SBarry Smith           goto noinsert;
457781824310SBarry Smith         }
457881824310SBarry Smith       }
457981824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
458081824310SBarry Smith       if (nonew == 1) goto noinsert;
4581ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4582fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
458381824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
458481824310SBarry Smith       /* shift up all the later entries in this row */
458581824310SBarry Smith       for (ii=N; ii>=i; ii--) {
458681824310SBarry Smith         rp[ii+1] = rp[ii];
458781824310SBarry Smith         ap[ii+1] = ap[ii];
458881824310SBarry Smith       }
458981824310SBarry Smith       rp[i] = col;
459081824310SBarry Smith       ap[i] = value;
459181824310SBarry Smith noinsert:;
459281824310SBarry Smith       low = i + 1;
459381824310SBarry Smith     }
459481824310SBarry Smith     ailen[row] = nrow;
459581824310SBarry Smith   }
459681824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
459781824310SBarry Smith   PetscFunctionReturnVoid();
459881824310SBarry Smith }
45999f7953f8SBarry Smith 
460062298a1eSBarry Smith 
4601