xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 33d57670fcdbf57d9203d482728f549b81403a0e)
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   }
66785e854fSJed Brown   ierr = PetscMalloc1(cnt,&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);
120785e854fSJed Brown   ierr = PetscMalloc1((A->rmap->n-cnt),&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 */
190785e854fSJed Brown     ierr = PetscMalloc1((A->rmap->n+1),&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;
195785e854fSJed Brown       ierr = PetscMalloc1((nz+1),&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 {
2361795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
237785e854fSJed Brown     ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
238785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
2393b2fbd54SBarry Smith     jj   = a->j;
2403b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
241bfeeae90SHong Zhang       collengths[jj[i]]++;
2423b2fbd54SBarry Smith     }
2433b2fbd54SBarry Smith     cia[0] = oshift;
2443b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2453b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2463b2fbd54SBarry Smith     }
24797f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2483b2fbd54SBarry Smith     jj   = a->j;
249a93ec695SBarry Smith     for (row=0; row<m; row++) {
250a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
251a93ec695SBarry Smith       for (i=0; i<mr; i++) {
252bfeeae90SHong Zhang         col = *jj++;
2532205254eSKarl Rupp 
2543b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2553b2fbd54SBarry Smith       }
2563b2fbd54SBarry Smith     }
257606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2583b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2593b2fbd54SBarry Smith   }
2603a40ed3dSBarry Smith   PetscFunctionReturn(0);
2613b2fbd54SBarry Smith }
2623b2fbd54SBarry Smith 
2634a2ae208SSatish Balay #undef __FUNCT__
2644a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2651a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2663b2fbd54SBarry Smith {
267dfbe8321SBarry Smith   PetscErrorCode ierr;
268606d414cSSatish Balay 
2693a40ed3dSBarry Smith   PetscFunctionBegin;
2703a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2713b2fbd54SBarry Smith 
272606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
273606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2743a40ed3dSBarry Smith   PetscFunctionReturn(0);
2753b2fbd54SBarry Smith }
2763b2fbd54SBarry Smith 
2777cee066cSHong Zhang /*
2787cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
2797cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
280040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
2817cee066cSHong Zhang */
2827cee066cSHong Zhang #undef __FUNCT__
2837cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
2847cee066cSHong 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)
2857cee066cSHong Zhang {
2867cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2877cee066cSHong Zhang   PetscErrorCode ierr;
2887cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
2897cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
2907cee066cSHong Zhang   PetscInt       *cspidx;
2917cee066cSHong Zhang 
2927cee066cSHong Zhang   PetscFunctionBegin;
2937cee066cSHong Zhang   *nn = n;
2947cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
295625f6d37SHong Zhang 
2961795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
297785e854fSJed Brown   ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
298785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
299785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr);
3007cee066cSHong Zhang   jj   = a->j;
3017cee066cSHong Zhang   for (i=0; i<nz; i++) {
3027cee066cSHong Zhang     collengths[jj[i]]++;
3037cee066cSHong Zhang   }
3047cee066cSHong Zhang   cia[0] = oshift;
3057cee066cSHong Zhang   for (i=0; i<n; i++) {
3067cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3077cee066cSHong Zhang   }
3087cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3097cee066cSHong Zhang   jj   = a->j;
3107cee066cSHong Zhang   for (row=0; row<m; row++) {
3117cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3127cee066cSHong Zhang     for (i=0; i<mr; i++) {
3137cee066cSHong Zhang       col = *jj++;
3147cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3157cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3167cee066cSHong Zhang     }
3177cee066cSHong Zhang   }
3187cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3197cee066cSHong Zhang   *ia    = cia; *ja = cja;
3207cee066cSHong Zhang   *spidx = cspidx;
3217cee066cSHong Zhang   PetscFunctionReturn(0);
3227cee066cSHong Zhang }
3237cee066cSHong Zhang 
3247cee066cSHong Zhang #undef __FUNCT__
3257cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3267cee066cSHong 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)
3277cee066cSHong Zhang {
3287cee066cSHong Zhang   PetscErrorCode ierr;
3297cee066cSHong Zhang 
3307cee066cSHong Zhang   PetscFunctionBegin;
3315243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3327cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3337cee066cSHong Zhang   PetscFunctionReturn(0);
3347cee066cSHong Zhang }
3357cee066cSHong Zhang 
33687d4246cSBarry Smith #undef __FUNCT__
33787d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
33987d4246cSBarry Smith {
34087d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
34187d4246cSBarry Smith   PetscInt       *ai = a->i;
34287d4246cSBarry Smith   PetscErrorCode ierr;
34387d4246cSBarry Smith 
34487d4246cSBarry Smith   PetscFunctionBegin;
34587d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
34687d4246cSBarry Smith   PetscFunctionReturn(0);
34787d4246cSBarry Smith }
34887d4246cSBarry Smith 
3494a2ae208SSatish Balay #undef __FUNCT__
3504a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
35197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
35217ab2063SBarry Smith {
353416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
354e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
35597f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3566849ba73SBarry Smith   PetscErrorCode ierr;
357e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
35854f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
359ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
360ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
36117ab2063SBarry Smith 
3623a40ed3dSBarry Smith   PetscFunctionBegin;
36371fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
36417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
365416022c9SBarry Smith     row = im[k];
3665ef9f2a5SBarry Smith     if (row < 0) continue;
3672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
368e32f2f54SBarry 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);
3693b2fbd54SBarry Smith #endif
370bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
37117ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
372416022c9SBarry Smith     low  = 0;
373c71e6ed7SBarry Smith     high = nrow;
37417ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3755ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3762515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
377e32f2f54SBarry 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);
3783b2fbd54SBarry Smith #endif
379bfeeae90SHong Zhang       col = in[l];
38016371a99SBarry Smith       if (v) {
3814b0e389bSBarry Smith         if (roworiented) {
3825ef9f2a5SBarry Smith           value = v[l + k*n];
383bef8e0ddSBarry Smith         } else {
3844b0e389bSBarry Smith           value = v[k + l*m];
3854b0e389bSBarry Smith         }
38616371a99SBarry Smith       } else {
38775567043SBarry Smith         value = 0.;
38816371a99SBarry Smith       }
38933b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
39036db0b34SBarry Smith 
3912205254eSKarl Rupp       if (col <= lastcol) low = 0;
3922205254eSKarl Rupp       else high = nrow;
393e2ee6c50SBarry Smith       lastcol = col;
394416022c9SBarry Smith       while (high-low > 5) {
395416022c9SBarry Smith         t = (low+high)/2;
396416022c9SBarry Smith         if (rp[t] > col) high = t;
397416022c9SBarry Smith         else low = t;
39817ab2063SBarry Smith       }
399416022c9SBarry Smith       for (i=low; i<high; i++) {
40017ab2063SBarry Smith         if (rp[i] > col) break;
40117ab2063SBarry Smith         if (rp[i] == col) {
402416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
40317ab2063SBarry Smith           else ap[i] = value;
404e44c0bd4SBarry Smith           low = i + 1;
40517ab2063SBarry Smith           goto noinsert;
40617ab2063SBarry Smith         }
40717ab2063SBarry Smith       }
408abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
409c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
410e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
411fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
412c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
413416022c9SBarry Smith       /* shift up all the later entries in this row */
414416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
41517ab2063SBarry Smith         rp[ii+1] = rp[ii];
41617ab2063SBarry Smith         ap[ii+1] = ap[ii];
41717ab2063SBarry Smith       }
41817ab2063SBarry Smith       rp[i] = col;
41917ab2063SBarry Smith       ap[i] = value;
420416022c9SBarry Smith       low   = i + 1;
421e44c0bd4SBarry Smith noinsert:;
42217ab2063SBarry Smith     }
42317ab2063SBarry Smith     ailen[row] = nrow;
42417ab2063SBarry Smith   }
42588e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4263a40ed3dSBarry Smith   PetscFunctionReturn(0);
42717ab2063SBarry Smith }
42817ab2063SBarry Smith 
42981824310SBarry Smith 
4304a2ae208SSatish Balay #undef __FUNCT__
4314a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
432a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4337eb43aa7SLois Curfman McInnes {
4347eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
43597f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
43697f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
43754f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4387eb43aa7SLois Curfman McInnes 
4393a40ed3dSBarry Smith   PetscFunctionBegin;
4407eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4417eb43aa7SLois Curfman McInnes     row = im[k];
442e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
443e32f2f54SBarry 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);
444bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4457eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4467eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
447e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
448e32f2f54SBarry 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);
449bfeeae90SHong Zhang       col  = in[l];
4507eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4517eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4527eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4537eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4547eb43aa7SLois Curfman McInnes         else low = t;
4557eb43aa7SLois Curfman McInnes       }
4567eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4577eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4587eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
459b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4607eb43aa7SLois Curfman McInnes           goto finished;
4617eb43aa7SLois Curfman McInnes         }
4627eb43aa7SLois Curfman McInnes       }
46397e567efSBarry Smith       *v++ = 0.0;
4647eb43aa7SLois Curfman McInnes finished:;
4657eb43aa7SLois Curfman McInnes     }
4667eb43aa7SLois Curfman McInnes   }
4673a40ed3dSBarry Smith   PetscFunctionReturn(0);
4687eb43aa7SLois Curfman McInnes }
4697eb43aa7SLois Curfman McInnes 
47017ab2063SBarry Smith 
4714a2ae208SSatish Balay #undef __FUNCT__
4724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
473dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
47417ab2063SBarry Smith {
475416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4766849ba73SBarry Smith   PetscErrorCode ierr;
4776f69ff64SBarry Smith   PetscInt       i,*col_lens;
4786f69ff64SBarry Smith   int            fd;
479b37d52dbSMark F. Adams   FILE           *file;
48017ab2063SBarry Smith 
4813a40ed3dSBarry Smith   PetscFunctionBegin;
482b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
483785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
4842205254eSKarl Rupp 
4850700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
486d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
487d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
488416022c9SBarry Smith   col_lens[3] = a->nz;
489416022c9SBarry Smith 
490416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
491d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
492416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
49317ab2063SBarry Smith   }
494d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
495606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
496416022c9SBarry Smith 
497416022c9SBarry Smith   /* store column indices (zero start index) */
4986f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
499416022c9SBarry Smith 
500416022c9SBarry Smith   /* store nonzero values */
5016f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
502b37d52dbSMark F. Adams 
503b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
504b37d52dbSMark F. Adams   if (file) {
505*33d57670SJed Brown     fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs));
506b37d52dbSMark F. Adams   }
5073a40ed3dSBarry Smith   PetscFunctionReturn(0);
50817ab2063SBarry Smith }
509416022c9SBarry Smith 
51009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
511cd155464SBarry Smith 
5124a2ae208SSatish Balay #undef __FUNCT__
5134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
514dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
515416022c9SBarry Smith {
516416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
517dfbe8321SBarry Smith   PetscErrorCode    ierr;
51860e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
519e060cb09SBarry Smith   const char        *name;
520f3ef73ceSBarry Smith   PetscViewerFormat format;
52117ab2063SBarry Smith 
5223a40ed3dSBarry Smith   PetscFunctionBegin;
523b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
52471c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
52597f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
52660e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
527c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
528d00d2cf4SBarry Smith       nofinalvalue = 1;
529d00d2cf4SBarry Smith     }
530d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
531d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
53277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
533fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
534fbfe6fa7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
535fbfe6fa7SJed Brown #else
53677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
537fbfe6fa7SJed Brown #endif
538b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
53917ab2063SBarry Smith 
54017ab2063SBarry Smith     for (i=0; i<m; i++) {
54160e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
542aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
543a9bf72d8SJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
54417ab2063SBarry Smith #else
54560e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
54617ab2063SBarry Smith #endif
54717ab2063SBarry Smith       }
54817ab2063SBarry Smith     }
549d00d2cf4SBarry Smith     if (nofinalvalue) {
550c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
551c337ccceSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
552c337ccceSJed Brown #else
553d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
554c337ccceSJed Brown #endif
555d00d2cf4SBarry Smith     }
556317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
557fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
558d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
55968369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
560cd155464SBarry Smith     PetscFunctionReturn(0);
561fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
562d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
563dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
56444cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
56577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
56660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
567aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
56836db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
56960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57036db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
57160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57236db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
57360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
5746831982aSBarry Smith         }
57544cd7ae7SLois Curfman McInnes #else
57660e0710aSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
57744cd7ae7SLois Curfman McInnes #endif
57844cd7ae7SLois Curfman McInnes       }
579b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
58044cd7ae7SLois Curfman McInnes     }
581d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
582fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
58397f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
584d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
585dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
586785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
587496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
588496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
58960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
590496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
591aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
59236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
593496be53dSLois Curfman McInnes #else
594496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
595496be53dSLois Curfman McInnes #endif
596496be53dSLois Curfman McInnes         }
597496be53dSLois Curfman McInnes       }
598496be53dSLois Curfman McInnes     }
5992e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
60077431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6012e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6022205254eSKarl Rupp       if (i+4<m) {
6032205254eSKarl 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);
6042205254eSKarl Rupp       } else if (i+3<m) {
6052205254eSKarl 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);
6062205254eSKarl Rupp       } else if (i+2<m) {
6072205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6082205254eSKarl Rupp       } else if (i+1<m) {
6092205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6102205254eSKarl Rupp       } else if (i<m) {
6112205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6122205254eSKarl Rupp       } else {
6132205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6142205254eSKarl Rupp       }
615496be53dSLois Curfman McInnes     }
616b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
617606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
618496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
61960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
62077431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
621496be53dSLois Curfman McInnes       }
622b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
623496be53dSLois Curfman McInnes     }
624b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
625496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
62660e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
627496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
628aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
63060e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6316831982aSBarry Smith           }
632496be53dSLois Curfman McInnes #else
63360e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
634496be53dSLois Curfman McInnes #endif
635496be53dSLois Curfman McInnes         }
636496be53dSLois Curfman McInnes       }
637b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
638496be53dSLois Curfman McInnes     }
639d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
640fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
64197f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
64287828ca2SBarry Smith     PetscScalar value;
64368f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
64468f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
64568f1ed48SBarry Smith 
64668f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
64768f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
64868f1ed48SBarry Smith         realonly = PETSC_FALSE;
64968f1ed48SBarry Smith         break;
65068f1ed48SBarry Smith       }
65168f1ed48SBarry Smith     }
65268f1ed48SBarry Smith #endif
65302594712SBarry Smith 
654d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
655dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
65602594712SBarry Smith     for (i=0; i<m; i++) {
65702594712SBarry Smith       jcnt = 0;
658d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
659e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
66002594712SBarry Smith           value = a->a[cnt++];
661e24b481bSBarry Smith           jcnt++;
66202594712SBarry Smith         } else {
66302594712SBarry Smith           value = 0.0;
66402594712SBarry Smith         }
665aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66668f1ed48SBarry Smith         if (realonly) {
66760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
66868f1ed48SBarry Smith         } else {
66960e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
67068f1ed48SBarry Smith         }
67102594712SBarry Smith #else
67260e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
67302594712SBarry Smith #endif
67402594712SBarry Smith       }
675b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
67602594712SBarry Smith     }
677d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6783c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
679150b93efSMatthew G. Knepley     PetscInt fshift=1;
680d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
6813c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6823c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6833c215bfdSMatthew Knepley #else
6843c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6853c215bfdSMatthew Knepley #endif
686d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6873c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
68860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
6893c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6903c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
69160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6923c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
69360e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6943c215bfdSMatthew Knepley         } else {
69560e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
6963c215bfdSMatthew Knepley         }
6973c215bfdSMatthew Knepley #else
698150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
6993c215bfdSMatthew Knepley #endif
7003c215bfdSMatthew Knepley       }
7013c215bfdSMatthew Knepley     }
702d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7033a40ed3dSBarry Smith   } else {
704d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
705dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
706d5f3da31SBarry Smith     if (A->factortype) {
70716cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
70816cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
70916cd7e1dSShri Abhyankar         /* L part */
71060e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
71116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
71216cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
71360e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
71416cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7156712e2f1SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
71616cd7e1dSShri Abhyankar           } else {
71760e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
71816cd7e1dSShri Abhyankar           }
71916cd7e1dSShri Abhyankar #else
72060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
72116cd7e1dSShri Abhyankar #endif
72216cd7e1dSShri Abhyankar         }
72316cd7e1dSShri Abhyankar         /* diagonal */
72416cd7e1dSShri Abhyankar         j = a->diag[i];
72516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
72616cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
72760e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
72816cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
7296712e2f1SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr);
73016cd7e1dSShri Abhyankar         } else {
73160e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
73216cd7e1dSShri Abhyankar         }
73316cd7e1dSShri Abhyankar #else
73460e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
73516cd7e1dSShri Abhyankar #endif
73616cd7e1dSShri Abhyankar 
73716cd7e1dSShri Abhyankar         /* U part */
73860e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
73916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
74016cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
74160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
74216cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
74322ab088eSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
74416cd7e1dSShri Abhyankar           } else {
74560e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
74616cd7e1dSShri Abhyankar           }
74716cd7e1dSShri Abhyankar #else
74860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
74916cd7e1dSShri Abhyankar #endif
75016cd7e1dSShri Abhyankar         }
75116cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
75216cd7e1dSShri Abhyankar       }
75316cd7e1dSShri Abhyankar     } else {
75417ab2063SBarry Smith       for (i=0; i<m; i++) {
75577431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
75660e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
757aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
75836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
75960e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
76036db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
76160e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7623a40ed3dSBarry Smith           } else {
76360e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
76417ab2063SBarry Smith           }
76517ab2063SBarry Smith #else
76660e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
76717ab2063SBarry Smith #endif
76817ab2063SBarry Smith         }
769b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
77017ab2063SBarry Smith       }
77116cd7e1dSShri Abhyankar     }
772d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
77317ab2063SBarry Smith   }
774b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7753a40ed3dSBarry Smith   PetscFunctionReturn(0);
776416022c9SBarry Smith }
777416022c9SBarry Smith 
7789804daf3SBarry Smith #include <petscdraw.h>
7794a2ae208SSatish Balay #undef __FUNCT__
7804a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
781dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
782416022c9SBarry Smith {
783480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
784416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
785dfbe8321SBarry Smith   PetscErrorCode    ierr;
786d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
78736db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
788b0a32e0cSBarry Smith   PetscViewer       viewer;
789f3ef73ceSBarry Smith   PetscViewerFormat format;
790cddf8d76SBarry Smith 
7913a40ed3dSBarry Smith   PetscFunctionBegin;
792480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
793b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
79419bcc07fSBarry Smith 
795b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
796416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7970513a670SBarry Smith 
798fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7990513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
800b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
801416022c9SBarry Smith     for (i=0; i<m; i++) {
802cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
803bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
804bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
80536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
806b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
807cddf8d76SBarry Smith       }
808cddf8d76SBarry Smith     }
809b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
810cddf8d76SBarry Smith     for (i=0; i<m; i++) {
811cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
812bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
813bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
814cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
815b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
816cddf8d76SBarry Smith       }
817cddf8d76SBarry Smith     }
818b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
819cddf8d76SBarry Smith     for (i=0; i<m; i++) {
820cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
821bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
822bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
82336db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
824b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
825416022c9SBarry Smith       }
826416022c9SBarry Smith     }
8270513a670SBarry Smith   } else {
8280513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8290513a670SBarry Smith     /* first determine max of all nonzero values */
83097f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
831b0a32e0cSBarry Smith     PetscDraw popup;
83236db0b34SBarry Smith     PetscReal scale;
8330513a670SBarry Smith 
8340513a670SBarry Smith     for (i=0; i<nz; i++) {
8350513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8360513a670SBarry Smith     }
837b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
838b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8392205254eSKarl Rupp     if (popup) {
8402205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8412205254eSKarl Rupp     }
8420513a670SBarry Smith     count = 0;
8430513a670SBarry Smith     for (i=0; i<m; i++) {
8440513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
845bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
846bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
84797f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
848b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8490513a670SBarry Smith         count++;
8500513a670SBarry Smith       }
8510513a670SBarry Smith     }
8520513a670SBarry Smith   }
853480ef9eaSBarry Smith   PetscFunctionReturn(0);
854480ef9eaSBarry Smith }
855cddf8d76SBarry Smith 
8569804daf3SBarry Smith #include <petscdraw.h>
8574a2ae208SSatish Balay #undef __FUNCT__
8584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
859dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
860480ef9eaSBarry Smith {
861dfbe8321SBarry Smith   PetscErrorCode ierr;
862b0a32e0cSBarry Smith   PetscDraw      draw;
86336db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
864ace3abfcSBarry Smith   PetscBool      isnull;
865480ef9eaSBarry Smith 
866480ef9eaSBarry Smith   PetscFunctionBegin;
867b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
868b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
869480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
870480ef9eaSBarry Smith 
871480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
872d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
873480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
874b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
875b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8760298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8773a40ed3dSBarry Smith   PetscFunctionReturn(0);
878416022c9SBarry Smith }
879416022c9SBarry Smith 
8804a2ae208SSatish Balay #undef __FUNCT__
8814a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
882dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
883416022c9SBarry Smith {
884dfbe8321SBarry Smith   PetscErrorCode ierr;
885ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
886416022c9SBarry Smith 
8873a40ed3dSBarry Smith   PetscFunctionBegin;
888251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
889251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
890251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
891c45a1595SBarry Smith   if (iascii) {
8923a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8930f5bd95cSBarry Smith   } else if (isbinary) {
8943a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8950f5bd95cSBarry Smith   } else if (isdraw) {
8963a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
89711aeaf0aSBarry Smith   }
8984108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8993a40ed3dSBarry Smith   PetscFunctionReturn(0);
90017ab2063SBarry Smith }
90119bcc07fSBarry Smith 
9024a2ae208SSatish Balay #undef __FUNCT__
9034a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
904dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
90517ab2063SBarry Smith {
906416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9076849ba73SBarry Smith   PetscErrorCode ierr;
90897f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
909d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
91054f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9113447b6efSHong Zhang   PetscReal      ratio  = 0.6;
91217ab2063SBarry Smith 
9133a40ed3dSBarry Smith   PetscFunctionBegin;
9143a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
91517ab2063SBarry Smith 
91643ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
91717ab2063SBarry Smith   for (i=1; i<m; i++) {
918416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
91917ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
92094a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
92117ab2063SBarry Smith     if (fshift) {
922bfeeae90SHong Zhang       ip = aj + ai[i];
923bfeeae90SHong Zhang       ap = aa + ai[i];
92417ab2063SBarry Smith       N  = ailen[i];
92517ab2063SBarry Smith       for (j=0; j<N; j++) {
92617ab2063SBarry Smith         ip[j-fshift] = ip[j];
92717ab2063SBarry Smith         ap[j-fshift] = ap[j];
92817ab2063SBarry Smith       }
92917ab2063SBarry Smith     }
93017ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
93117ab2063SBarry Smith   }
93217ab2063SBarry Smith   if (m) {
93317ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
93417ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
93517ab2063SBarry Smith   }
9367b083b7cSBarry Smith 
93717ab2063SBarry Smith   /* reset ilen and imax for each row */
9387b083b7cSBarry Smith   a->nonzerorowcnt = 0;
93917ab2063SBarry Smith   for (i=0; i<m; i++) {
94017ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9417b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
94217ab2063SBarry Smith   }
943bfeeae90SHong Zhang   a->nz = ai[m];
94465e19b50SBarry 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);
94517ab2063SBarry Smith 
94609f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
947d0f46423SBarry 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);
948ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
949ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9502205254eSKarl Rupp 
9518e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
952dd5f02e7SSatish Balay   a->reallocs         = 0;
9536712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
95436db0b34SBarry Smith   a->rmax             = rmax;
9554e220ebcSLois Curfman McInnes 
95611e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9572205254eSKarl Rupp 
95888e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
95971c2f376SKris Buschelman 
9604108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
96171f1c65dSBarry Smith 
962acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9633a40ed3dSBarry Smith   PetscFunctionReturn(0);
96417ab2063SBarry Smith }
96517ab2063SBarry Smith 
9664a2ae208SSatish Balay #undef __FUNCT__
96799cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
96899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
96999cafbc1SBarry Smith {
97099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
97199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
97254f21887SBarry Smith   MatScalar      *aa = a->a;
973acf2f550SJed Brown   PetscErrorCode ierr;
97499cafbc1SBarry Smith 
97599cafbc1SBarry Smith   PetscFunctionBegin;
97699cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
977acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
97899cafbc1SBarry Smith   PetscFunctionReturn(0);
97999cafbc1SBarry Smith }
98099cafbc1SBarry Smith 
98199cafbc1SBarry Smith #undef __FUNCT__
98299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
98399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
98499cafbc1SBarry Smith {
98599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
98754f21887SBarry Smith   MatScalar      *aa = a->a;
988acf2f550SJed Brown   PetscErrorCode ierr;
98999cafbc1SBarry Smith 
99099cafbc1SBarry Smith   PetscFunctionBegin;
99199cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
992acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99399cafbc1SBarry Smith   PetscFunctionReturn(0);
99499cafbc1SBarry Smith }
99599cafbc1SBarry Smith 
99678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
99778b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
99878b84d54SShri Abhyankar {
99978b84d54SShri Abhyankar   PetscErrorCode ierr;
100078b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
100178b84d54SShri Abhyankar   PetscInt       n,start,end;
100278b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
100378b84d54SShri Abhyankar 
100478b84d54SShri Abhyankar   start = trstarts[thread_id];
100578b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
100619baf141SJed Brown   n     = a->i[end] - a->i[start];
100719baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
100878b84d54SShri Abhyankar   return 0;
100978b84d54SShri Abhyankar }
101078b84d54SShri Abhyankar 
101178b84d54SShri Abhyankar #undef __FUNCT__
101278b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
101378b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
101478b84d54SShri Abhyankar {
101578b84d54SShri Abhyankar   PetscErrorCode ierr;
101678b84d54SShri Abhyankar 
101778b84d54SShri Abhyankar   PetscFunctionBegin;
1018ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1019acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
102078b84d54SShri Abhyankar   PetscFunctionReturn(0);
102178b84d54SShri Abhyankar }
102278b84d54SShri Abhyankar #else
102399cafbc1SBarry Smith #undef __FUNCT__
10244a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1025dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
102617ab2063SBarry Smith {
1027416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1028dfbe8321SBarry Smith   PetscErrorCode ierr;
10293a40ed3dSBarry Smith 
10303a40ed3dSBarry Smith   PetscFunctionBegin;
1031d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1032acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10333a40ed3dSBarry Smith   PetscFunctionReturn(0);
103417ab2063SBarry Smith }
103578b84d54SShri Abhyankar #endif
1036416022c9SBarry Smith 
10374a2ae208SSatish Balay #undef __FUNCT__
10384a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1039dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
104017ab2063SBarry Smith {
1041416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1042dfbe8321SBarry Smith   PetscErrorCode ierr;
1043d5d45c9bSBarry Smith 
10443a40ed3dSBarry Smith   PetscFunctionBegin;
1045aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1046d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
104717ab2063SBarry Smith #endif
1048e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10496bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10506bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
105105b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1052d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
105305b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
105471f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
105505b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10566bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
105705b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10586bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
105905b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10606bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1061cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10620b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1063a30b2313SHong Zhang 
10644108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1065bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1066901853e0SKris Buschelman 
1067dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1069bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1070bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1071bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1072bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1073bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1074bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1075bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1076bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1077bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10783a40ed3dSBarry Smith   PetscFunctionReturn(0);
107917ab2063SBarry Smith }
108017ab2063SBarry Smith 
10814a2ae208SSatish Balay #undef __FUNCT__
10824a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1083ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
108417ab2063SBarry Smith {
1085416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10864846f1f5SKris Buschelman   PetscErrorCode ierr;
10873a40ed3dSBarry Smith 
10883a40ed3dSBarry Smith   PetscFunctionBegin;
1089a65d3064SKris Buschelman   switch (op) {
1090a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10914e0d8c25SBarry Smith     a->roworiented = flg;
1092a65d3064SKris Buschelman     break;
1093a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1094a9817697SBarry Smith     a->keepnonzeropattern = flg;
1095a65d3064SKris Buschelman     break;
1096512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1097512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1098a65d3064SKris Buschelman     break;
1099a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11004e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1101a65d3064SKris Buschelman     break;
1102a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11034e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1104a65d3064SKris Buschelman     break;
110528b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
110628b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
110728b2fa4aSMatthew Knepley     break;
1108a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11094e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11100df259c2SBarry Smith     break;
11113d472b54SHong Zhang   case MAT_SPD:
1112b1646e73SJed Brown   case MAT_SYMMETRIC:
1113b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1114b1646e73SJed Brown   case MAT_HERMITIAN:
1115b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11165021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11175021d80fSJed Brown     break;
11184e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1119a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1120a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1121290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1122a65d3064SKris Buschelman     break;
1123b87ac2d8SJed Brown   case MAT_USE_INODES:
1124b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1125b87ac2d8SJed Brown     break;
1126a65d3064SKris Buschelman   default:
1127e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1128a65d3064SKris Buschelman   }
11294108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11303a40ed3dSBarry Smith   PetscFunctionReturn(0);
113117ab2063SBarry Smith }
113217ab2063SBarry Smith 
11334a2ae208SSatish Balay #undef __FUNCT__
11344a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1135dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
113617ab2063SBarry Smith {
1137416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11386849ba73SBarry Smith   PetscErrorCode ierr;
1139d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
114035e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
114117ab2063SBarry Smith 
11423a40ed3dSBarry Smith   PetscFunctionBegin;
1143d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1144e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
114535e7444dSHong Zhang 
1146d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1147d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
114835e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11492c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
115035e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
115135e7444dSHong Zhang     PetscFunctionReturn(0);
115235e7444dSHong Zhang   }
115335e7444dSHong Zhang 
11542dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11551ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
115635e7444dSHong Zhang   for (i=0; i<n; i++) {
115735e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11582f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
115935e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
116035e7444dSHong Zhang       if (aj[j] == i) {
116135e7444dSHong Zhang         x[i] = aa[j];
116217ab2063SBarry Smith         break;
116317ab2063SBarry Smith       }
116417ab2063SBarry Smith     }
116517ab2063SBarry Smith   }
11661ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11673a40ed3dSBarry Smith   PetscFunctionReturn(0);
116817ab2063SBarry Smith }
116917ab2063SBarry Smith 
1170c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11714a2ae208SSatish Balay #undef __FUNCT__
11724a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1173dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
117417ab2063SBarry Smith {
1175416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11765c897100SBarry Smith   PetscScalar    *x,*y;
1177dfbe8321SBarry Smith   PetscErrorCode ierr;
1178d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11795c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1180a77337e4SBarry Smith   MatScalar         *v;
1181a77337e4SBarry Smith   PetscScalar       alpha;
11820298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11833447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1184ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11855c897100SBarry Smith #endif
118617ab2063SBarry Smith 
11873a40ed3dSBarry Smith   PetscFunctionBegin;
11882e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11891ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11901ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11915c897100SBarry Smith 
11925c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1193bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11945c897100SBarry Smith #else
11953447b6efSHong Zhang   if (usecprow) {
11963447b6efSHong Zhang     m    = cprow.nrows;
11973447b6efSHong Zhang     ii   = cprow.i;
11987b2bb3b9SHong Zhang     ridx = cprow.rindex;
11993447b6efSHong Zhang   } else {
12003447b6efSHong Zhang     ii = a->i;
12013447b6efSHong Zhang   }
120217ab2063SBarry Smith   for (i=0; i<m; i++) {
12033447b6efSHong Zhang     idx = a->j + ii[i];
12043447b6efSHong Zhang     v   = a->a + ii[i];
12053447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12063447b6efSHong Zhang     if (usecprow) {
12077b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12083447b6efSHong Zhang     } else {
120917ab2063SBarry Smith       alpha = x[i];
12103447b6efSHong Zhang     }
121104fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
121217ab2063SBarry Smith   }
12135c897100SBarry Smith #endif
1214dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
12151ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12161ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12173a40ed3dSBarry Smith   PetscFunctionReturn(0);
121817ab2063SBarry Smith }
121917ab2063SBarry Smith 
12204a2ae208SSatish Balay #undef __FUNCT__
12215c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1222dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12235c897100SBarry Smith {
1224dfbe8321SBarry Smith   PetscErrorCode ierr;
12255c897100SBarry Smith 
12265c897100SBarry Smith   PetscFunctionBegin;
1227170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12285c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12295c897100SBarry Smith   PetscFunctionReturn(0);
12305c897100SBarry Smith }
12315c897100SBarry Smith 
1232c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
123378b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
123478b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
123578b84d54SShri Abhyankar {
123678b84d54SShri Abhyankar   PetscErrorCode    ierr;
123778b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
123878b84d54SShri Abhyankar   PetscScalar       *y;
123978b84d54SShri Abhyankar   const PetscScalar *x;
124078b84d54SShri Abhyankar   const MatScalar   *aa;
124178b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
124278b84d54SShri Abhyankar   PetscInt          n,start,end,i;
124378b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
124478b84d54SShri Abhyankar   PetscScalar       sum;
124578b84d54SShri Abhyankar 
124678b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
124778b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
124878b84d54SShri Abhyankar   start = trstarts[thread_id];
124978b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
125078b84d54SShri Abhyankar   aj    = a->j;
125178b84d54SShri Abhyankar   aa    = a->a;
125278b84d54SShri Abhyankar   ai    = a->i;
125378b84d54SShri Abhyankar   for (i=start; i<end; i++) {
125478b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
125578b84d54SShri Abhyankar     aj  = a->j + ai[i];
125678b84d54SShri Abhyankar     aa  = a->a + ai[i];
125778b84d54SShri Abhyankar     sum = 0.0;
125878b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
125978b84d54SShri Abhyankar     y[i] = sum;
126078b84d54SShri Abhyankar   }
126178b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
126278b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
126378b84d54SShri Abhyankar   return 0;
126478b84d54SShri Abhyankar }
126578b84d54SShri Abhyankar 
126678b84d54SShri Abhyankar #undef __FUNCT__
126778b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
126878b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
126978b84d54SShri Abhyankar {
127078b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
127178b84d54SShri Abhyankar   PetscScalar       *y;
127278b84d54SShri Abhyankar   const PetscScalar *x;
127378b84d54SShri Abhyankar   const MatScalar   *aa;
127478b84d54SShri Abhyankar   PetscErrorCode    ierr;
127578b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12760298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12777b083b7cSBarry Smith   PetscInt          n,i;
127878b84d54SShri Abhyankar   PetscScalar       sum;
127978b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
128078b84d54SShri Abhyankar 
128178b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
128278b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
128378b84d54SShri Abhyankar #endif
128478b84d54SShri Abhyankar 
128578b84d54SShri Abhyankar   PetscFunctionBegin;
128678b84d54SShri Abhyankar   aj = a->j;
128778b84d54SShri Abhyankar   aa = a->a;
128878b84d54SShri Abhyankar   ii = a->i;
128978b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
129078b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
129178b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
129278b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
129378b84d54SShri Abhyankar     ii   = a->compressedrow.i;
129478b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
129578b84d54SShri Abhyankar     for (i=0; i<m; i++) {
129678b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
129778b84d54SShri Abhyankar       aj          = a->j + ii[i];
129878b84d54SShri Abhyankar       aa          = a->a + ii[i];
129978b84d54SShri Abhyankar       sum         = 0.0;
130078b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
130178b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
130278b84d54SShri Abhyankar       y[*ridx++] = sum;
130378b84d54SShri Abhyankar     }
130478b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
130578b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
130678b84d54SShri Abhyankar   } else { /* do not use compressed row format */
130778b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
130878b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
130978b84d54SShri Abhyankar #else
1310ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
131178b84d54SShri Abhyankar #endif
131278b84d54SShri Abhyankar   }
13137b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
131478b84d54SShri Abhyankar   PetscFunctionReturn(0);
131578b84d54SShri Abhyankar }
131678b84d54SShri Abhyankar #else
13175c897100SBarry Smith #undef __FUNCT__
13184a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1319dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
132017ab2063SBarry Smith {
1321416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1322d9fead3dSBarry Smith   PetscScalar       *y;
132354f21887SBarry Smith   const PetscScalar *x;
132454f21887SBarry Smith   const MatScalar   *aa;
1325dfbe8321SBarry Smith   PetscErrorCode    ierr;
1326003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13270298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13287b083b7cSBarry Smith   PetscInt          n,i;
1329362ced78SSatish Balay   PetscScalar       sum;
1330ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
133117ab2063SBarry Smith 
1332b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
133397952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1334fee21e36SBarry Smith #endif
1335fee21e36SBarry Smith 
13363a40ed3dSBarry Smith   PetscFunctionBegin;
13373649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13381ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
133997952fefSHong Zhang   aj   = a->j;
134097952fefSHong Zhang   aa   = a->a;
1341416022c9SBarry Smith   ii   = a->i;
13424eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
134397952fefSHong Zhang     m    = a->compressedrow.nrows;
134497952fefSHong Zhang     ii   = a->compressedrow.i;
134597952fefSHong Zhang     ridx = a->compressedrow.rindex;
134697952fefSHong Zhang     for (i=0; i<m; i++) {
134797952fefSHong Zhang       n           = ii[i+1] - ii[i];
134897952fefSHong Zhang       aj          = a->j + ii[i];
134997952fefSHong Zhang       aa          = a->a + ii[i];
135097952fefSHong Zhang       sum         = 0.0;
1351003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1352003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
135397952fefSHong Zhang       y[*ridx++] = sum;
135497952fefSHong Zhang     }
135597952fefSHong Zhang   } else { /* do not use compressed row format */
1356b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1357b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1358b05257ddSBarry Smith #else
135978b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1360ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
136178b84d54SShri Abhyankar #else
136217ab2063SBarry Smith     for (i=0; i<m; i++) {
1363003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1364003131ecSBarry Smith       aj          = a->j + ii[i];
1365003131ecSBarry Smith       aa          = a->a + ii[i];
136617ab2063SBarry Smith       sum         = 0.0;
1367003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
136817ab2063SBarry Smith       y[i] = sum;
136917ab2063SBarry Smith     }
13708d195f9aSBarry Smith #endif
137178b84d54SShri Abhyankar #endif
1372b05257ddSBarry Smith   }
13737b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13743649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13751ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13763a40ed3dSBarry Smith   PetscFunctionReturn(0);
137717ab2063SBarry Smith }
137878b84d54SShri Abhyankar #endif
137917ab2063SBarry Smith 
1380b434eb95SMatthew G. Knepley #undef __FUNCT__
1381b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1382b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1383b434eb95SMatthew G. Knepley {
1384b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1385b434eb95SMatthew G. Knepley   PetscScalar       *y;
1386b434eb95SMatthew G. Knepley   const PetscScalar *x;
1387b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1388b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1389b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1390b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1391b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1392b434eb95SMatthew G. Knepley   PetscScalar       sum;
1393b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1394b434eb95SMatthew G. Knepley 
1395b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1396b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1397b434eb95SMatthew G. Knepley #endif
1398b434eb95SMatthew G. Knepley 
1399b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1400b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1401b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1402b434eb95SMatthew G. Knepley   aj   = a->j;
1403b434eb95SMatthew G. Knepley   aa   = a->a;
1404b434eb95SMatthew G. Knepley   ii   = a->i;
1405b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1406b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1407b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1408b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1409b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1410b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1411b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1412b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1413b434eb95SMatthew G. Knepley       sum         = 0.0;
1414b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1415b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1416b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1417b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1418b434eb95SMatthew G. Knepley     }
1419b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1420b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1421b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1422b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1423b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1424b434eb95SMatthew G. Knepley       sum         = 0.0;
1425b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1426b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1427b434eb95SMatthew G. Knepley       y[i] = sum;
1428b434eb95SMatthew G. Knepley     }
1429b434eb95SMatthew G. Knepley   }
1430b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1431b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1432b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1433b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1434b434eb95SMatthew G. Knepley }
1435b434eb95SMatthew G. Knepley 
1436b434eb95SMatthew G. Knepley #undef __FUNCT__
1437b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1438b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1439b434eb95SMatthew G. Knepley {
1440b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1441b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1442b434eb95SMatthew G. Knepley   const PetscScalar *x;
1443b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1444b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1445b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1446b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1447b434eb95SMatthew G. Knepley   PetscScalar       sum;
1448b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1449b434eb95SMatthew G. Knepley 
1450b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1451b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1452b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1453b434eb95SMatthew G. Knepley   if (zz != yy) {
1454b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1455b434eb95SMatthew G. Knepley   } else {
1456b434eb95SMatthew G. Knepley     z = y;
1457b434eb95SMatthew G. Knepley   }
1458b434eb95SMatthew G. Knepley 
1459b434eb95SMatthew G. Knepley   aj = a->j;
1460b434eb95SMatthew G. Knepley   aa = a->a;
1461b434eb95SMatthew G. Knepley   ii = a->i;
1462b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1463b434eb95SMatthew G. Knepley     if (zz != yy) {
1464b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1465b434eb95SMatthew G. Knepley     }
1466b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1467b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1468b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1469b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1470b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1471b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1472b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1473b434eb95SMatthew G. Knepley       sum = y[*ridx];
1474b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1475b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1476b434eb95SMatthew G. Knepley     }
1477b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1478b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1479b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1480b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1481b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1482b434eb95SMatthew G. Knepley       sum = y[i];
1483b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1484b434eb95SMatthew G. Knepley       z[i] = sum;
1485b434eb95SMatthew G. Knepley     }
1486b434eb95SMatthew G. Knepley   }
1487b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1488b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1489b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1490b434eb95SMatthew G. Knepley   if (zz != yy) {
1491b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1492b434eb95SMatthew G. Knepley   }
1493b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1494b434eb95SMatthew G. Knepley }
1495b434eb95SMatthew G. Knepley 
1496c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14974a2ae208SSatish Balay #undef __FUNCT__
14984a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1499dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
150017ab2063SBarry Smith {
1501416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1502f15663dcSBarry Smith   PetscScalar       *y,*z;
1503f15663dcSBarry Smith   const PetscScalar *x;
150454f21887SBarry Smith   const MatScalar   *aa;
1505dfbe8321SBarry Smith   PetscErrorCode    ierr;
1506d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
15070298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1508362ced78SSatish Balay   PetscScalar       sum;
1509ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
15109ea0dfa2SSatish Balay 
15113a40ed3dSBarry Smith   PetscFunctionBegin;
1512f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15131ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15142e8a6d31SBarry Smith   if (zz != yy) {
15151ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15162e8a6d31SBarry Smith   } else {
15172e8a6d31SBarry Smith     z = y;
15182e8a6d31SBarry Smith   }
1519bfeeae90SHong Zhang 
152097952fefSHong Zhang   aj = a->j;
152197952fefSHong Zhang   aa = a->a;
1522cddf8d76SBarry Smith   ii = a->i;
15234eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15244eb6d288SHong Zhang     if (zz != yy) {
15254eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15264eb6d288SHong Zhang     }
152797952fefSHong Zhang     m    = a->compressedrow.nrows;
152897952fefSHong Zhang     ii   = a->compressedrow.i;
152997952fefSHong Zhang     ridx = a->compressedrow.rindex;
153097952fefSHong Zhang     for (i=0; i<m; i++) {
153197952fefSHong Zhang       n   = ii[i+1] - ii[i];
153297952fefSHong Zhang       aj  = a->j + ii[i];
153397952fefSHong Zhang       aa  = a->a + ii[i];
153497952fefSHong Zhang       sum = y[*ridx];
1535f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153697952fefSHong Zhang       z[*ridx++] = sum;
153797952fefSHong Zhang     }
153897952fefSHong Zhang   } else { /* do not use compressed row format */
1539f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1540f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1541f15663dcSBarry Smith #else
154217ab2063SBarry Smith     for (i=0; i<m; i++) {
1543f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1544f15663dcSBarry Smith       aj  = a->j + ii[i];
1545f15663dcSBarry Smith       aa  = a->a + ii[i];
154617ab2063SBarry Smith       sum = y[i];
1547f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
154817ab2063SBarry Smith       z[i] = sum;
154917ab2063SBarry Smith     }
155002ab625aSSatish Balay #endif
1551f15663dcSBarry Smith   }
1552dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1553f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15552e8a6d31SBarry Smith   if (zz != yy) {
15561ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15572e8a6d31SBarry Smith   }
15588154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15596b375ea7SVictor Minden   /*
1560918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1561918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1562918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15636b375ea7SVictor Minden   */
1564918e98c3SVictor Minden #endif
15653a40ed3dSBarry Smith   PetscFunctionReturn(0);
156617ab2063SBarry Smith }
156717ab2063SBarry Smith 
156817ab2063SBarry Smith /*
156917ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
157017ab2063SBarry Smith */
15714a2ae208SSatish Balay #undef __FUNCT__
15724a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1573dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
157417ab2063SBarry Smith {
1575416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15766849ba73SBarry Smith   PetscErrorCode ierr;
1577d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
157817ab2063SBarry Smith 
15793a40ed3dSBarry Smith   PetscFunctionBegin;
158009f38230SBarry Smith   if (!a->diag) {
1581785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
15823bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
158309f38230SBarry Smith   }
1584d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
158509f38230SBarry Smith     a->diag[i] = a->i[i+1];
1586bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1587bfeeae90SHong Zhang       if (a->j[j] == i) {
158809f38230SBarry Smith         a->diag[i] = j;
158917ab2063SBarry Smith         break;
159017ab2063SBarry Smith       }
159117ab2063SBarry Smith     }
159217ab2063SBarry Smith   }
15933a40ed3dSBarry Smith   PetscFunctionReturn(0);
159417ab2063SBarry Smith }
159517ab2063SBarry Smith 
1596be5855fcSBarry Smith /*
1597be5855fcSBarry Smith      Checks for missing diagonals
1598be5855fcSBarry Smith */
15994a2ae208SSatish Balay #undef __FUNCT__
16004a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1601ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1602be5855fcSBarry Smith {
1603be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
160497f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1605be5855fcSBarry Smith 
1606be5855fcSBarry Smith   PetscFunctionBegin;
160709f38230SBarry Smith   *missing = PETSC_FALSE;
1608d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
160909f38230SBarry Smith     *missing = PETSC_TRUE;
161009f38230SBarry Smith     if (d) *d = 0;
1611358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
161209f38230SBarry Smith   } else {
1613f1e2ffcdSBarry Smith     diag = a->diag;
1614d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1615bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
161609f38230SBarry Smith         *missing = PETSC_TRUE;
161709f38230SBarry Smith         if (d) *d = i;
161809f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1619358d2f5dSShri Abhyankar         break;
162009f38230SBarry Smith       }
1621be5855fcSBarry Smith     }
1622be5855fcSBarry Smith   }
1623be5855fcSBarry Smith   PetscFunctionReturn(0);
1624be5855fcSBarry Smith }
1625be5855fcSBarry Smith 
162671f1c65dSBarry Smith #undef __FUNCT__
162771f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16287087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
162971f1c65dSBarry Smith {
163071f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
163171f1c65dSBarry Smith   PetscErrorCode ierr;
1632d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
163354f21887SBarry Smith   MatScalar      *v = a->a;
163454f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
163571f1c65dSBarry Smith 
163671f1c65dSBarry Smith   PetscFunctionBegin;
163771f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
163871f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
163971f1c65dSBarry Smith   diag = a->diag;
164071f1c65dSBarry Smith   if (!a->idiag) {
1641dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
16423bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
164371f1c65dSBarry Smith     v    = a->a;
164471f1c65dSBarry Smith   }
164571f1c65dSBarry Smith   mdiag = a->mdiag;
164671f1c65dSBarry Smith   idiag = a->idiag;
164771f1c65dSBarry Smith 
1648028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
164971f1c65dSBarry Smith     for (i=0; i<m; i++) {
165071f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1651e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
165271f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
165371f1c65dSBarry Smith     }
165471f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
165571f1c65dSBarry Smith   } else {
165671f1c65dSBarry Smith     for (i=0; i<m; i++) {
165771f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
165871f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
165971f1c65dSBarry Smith     }
1660dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
166171f1c65dSBarry Smith   }
166271f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
166371f1c65dSBarry Smith   PetscFunctionReturn(0);
166471f1c65dSBarry Smith }
166571f1c65dSBarry Smith 
1666c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16674a2ae208SSatish Balay #undef __FUNCT__
166841f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
166941f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
167017ab2063SBarry Smith {
1671416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1672e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1673e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
167454f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1675dfbe8321SBarry Smith   PetscErrorCode    ierr;
1676d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
167797f1f81fSBarry Smith   const PetscInt    *idx,*diag;
167817ab2063SBarry Smith 
16793a40ed3dSBarry Smith   PetscFunctionBegin;
1680b965ef7fSBarry Smith   its = its*lits;
168191723122SBarry Smith 
168271f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
168371f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
168471f1c65dSBarry Smith   a->fshift = fshift;
168571f1c65dSBarry Smith   a->omega  = omega;
1686ed480e8bSBarry Smith 
168771f1c65dSBarry Smith   diag  = a->diag;
168871f1c65dSBarry Smith   t     = a->ssor_work;
1689ed480e8bSBarry Smith   idiag = a->idiag;
169071f1c65dSBarry Smith   mdiag = a->mdiag;
1691ed480e8bSBarry Smith 
16921ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16933649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1694ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
169517ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
169617ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1697ed480e8bSBarry Smith     bs = b;
169817ab2063SBarry Smith     for (i=0; i<m; i++) {
169971f1c65dSBarry Smith       d   = fshift + mdiag[i];
1700416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1701ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1702ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
170317ab2063SBarry Smith       sum = b[i]*d/omega;
1704003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
170517ab2063SBarry Smith       x[i] = sum;
170617ab2063SBarry Smith     }
17071ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17083649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1709efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17103a40ed3dSBarry Smith     PetscFunctionReturn(0);
171117ab2063SBarry Smith   }
1712c783ea89SBarry Smith 
17132205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17142205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
171517ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1716887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
171717ab2063SBarry Smith 
171817ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
171917ab2063SBarry Smith 
1720887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
172117ab2063SBarry Smith     */
172217ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
172317ab2063SBarry Smith 
172417ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
172517ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1726416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1727ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1728ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
172917ab2063SBarry Smith       sum = b[i];
1730e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1731ed480e8bSBarry Smith       x[i] = sum*idiag[i];
173217ab2063SBarry Smith     }
173317ab2063SBarry Smith 
173417ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1735416022c9SBarry Smith     v = a->a;
17362205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
173717ab2063SBarry Smith 
173817ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1739ed480e8bSBarry Smith     ts   = t;
1740416022c9SBarry Smith     diag = a->diag;
174117ab2063SBarry Smith     for (i=0; i<m; i++) {
1742416022c9SBarry Smith       n   = diag[i] - a->i[i];
1743ed480e8bSBarry Smith       idx = a->j + a->i[i];
1744ed480e8bSBarry Smith       v   = a->a + a->i[i];
174517ab2063SBarry Smith       sum = t[i];
1746003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1747ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1748733d66baSBarry Smith       /*  x = x + t */
1749733d66baSBarry Smith       x[i] += t[i];
175017ab2063SBarry Smith     }
175117ab2063SBarry Smith 
1752dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17531ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17543649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17553a40ed3dSBarry Smith     PetscFunctionReturn(0);
175617ab2063SBarry Smith   }
175717ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
175817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
175917ab2063SBarry Smith       for (i=0; i<m; i++) {
1760416022c9SBarry Smith         n   = diag[i] - a->i[i];
1761ed480e8bSBarry Smith         idx = a->j + a->i[i];
1762ed480e8bSBarry Smith         v   = a->a + a->i[i];
176317ab2063SBarry Smith         sum = b[i];
1764e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17655c99c7daSBarry Smith         t[i] = sum;
1766ed480e8bSBarry Smith         x[i] = sum*idiag[i];
176717ab2063SBarry Smith       }
17685c99c7daSBarry Smith       xb   = t;
1769efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17703a40ed3dSBarry Smith     } else xb = b;
177117ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
177217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1773416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1774ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1775ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
177617ab2063SBarry Smith         sum = xb[i];
1777e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17785c99c7daSBarry Smith         if (xb == b) {
1779ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17805c99c7daSBarry Smith         } else {
1781b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
178217ab2063SBarry Smith         }
17835c99c7daSBarry Smith       }
1784b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
178517ab2063SBarry Smith     }
178617ab2063SBarry Smith     its--;
178717ab2063SBarry Smith   }
178817ab2063SBarry Smith   while (its--) {
178917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
179017ab2063SBarry Smith       for (i=0; i<m; i++) {
1791b19a5dc2SMark Adams         /* lower */
1792b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1793ed480e8bSBarry Smith         idx = a->j + a->i[i];
1794ed480e8bSBarry Smith         v   = a->a + a->i[i];
179517ab2063SBarry Smith         sum = b[i];
1796e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1797b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1798b19a5dc2SMark Adams         /* upper */
1799b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1800b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1801b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1802b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1803b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
180417ab2063SBarry Smith       }
1805b19a5dc2SMark Adams       xb   = t;
18069f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1807b19a5dc2SMark Adams     } else xb = b;
180817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
180917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1810b19a5dc2SMark Adams         sum = xb[i];
1811b19a5dc2SMark Adams         if (xb == b) {
1812b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1813416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1814ed480e8bSBarry Smith           idx = a->j + a->i[i];
1815ed480e8bSBarry Smith           v   = a->a + a->i[i];
1816e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1817ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1818b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1819b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1820b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1821b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1822b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1823b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
182417ab2063SBarry Smith         }
1825b19a5dc2SMark Adams       }
1826b19a5dc2SMark Adams       if (xb == b) {
18279f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1828b19a5dc2SMark Adams       } else {
1829b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1830b19a5dc2SMark Adams       }
183117ab2063SBarry Smith     }
183217ab2063SBarry Smith   }
18331ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18343649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1835365a8a9eSBarry Smith   PetscFunctionReturn(0);
183617ab2063SBarry Smith }
183717ab2063SBarry Smith 
18382af78befSBarry Smith 
18394a2ae208SSatish Balay #undef __FUNCT__
18404a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1841dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
184217ab2063SBarry Smith {
1843416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18444e220ebcSLois Curfman McInnes 
18453a40ed3dSBarry Smith   PetscFunctionBegin;
18464e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18474e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18484e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18494e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18504e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18518e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18527adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1853d5f3da31SBarry Smith   if (A->factortype) {
18544e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18554e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18564e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18574e220ebcSLois Curfman McInnes   } else {
18584e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18594e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18604e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18614e220ebcSLois Curfman McInnes   }
18623a40ed3dSBarry Smith   PetscFunctionReturn(0);
186317ab2063SBarry Smith }
186417ab2063SBarry Smith 
18654a2ae208SSatish Balay #undef __FUNCT__
18664a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18672b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
186817ab2063SBarry Smith {
1869416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18703b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18716849ba73SBarry Smith   PetscErrorCode    ierr;
187297b48c8fSBarry Smith   const PetscScalar *xx;
187397b48c8fSBarry Smith   PetscScalar       *bb;
1874ace3abfcSBarry Smith   PetscBool         missing;
187517ab2063SBarry Smith 
18763a40ed3dSBarry Smith   PetscFunctionBegin;
187797b48c8fSBarry Smith   if (x && b) {
187897b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
187997b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
188097b48c8fSBarry Smith     for (i=0; i<N; i++) {
188197b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
188297b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
188397b48c8fSBarry Smith     }
188497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
188597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
188697b48c8fSBarry Smith   }
188797b48c8fSBarry Smith 
1888a9817697SBarry Smith   if (a->keepnonzeropattern) {
1889f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1890e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1891bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1892f1e2ffcdSBarry Smith     }
1893f4df32b1SMatthew Knepley     if (diag != 0.0) {
189409f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1895e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1896f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1897f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1898f1e2ffcdSBarry Smith       }
1899f1e2ffcdSBarry Smith     }
190088e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1901f1e2ffcdSBarry Smith   } else {
1902f4df32b1SMatthew Knepley     if (diag != 0.0) {
190317ab2063SBarry Smith       for (i=0; i<N; i++) {
1904e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19057ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1906416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1907f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1908bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
19097ae801bdSBarry Smith         } else { /* in case row was completely empty */
1910f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
191117ab2063SBarry Smith         }
191217ab2063SBarry Smith       }
19133a40ed3dSBarry Smith     } else {
191417ab2063SBarry Smith       for (i=0; i<N; i++) {
1915e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1916416022c9SBarry Smith         a->ilen[rows[i]] = 0;
191717ab2063SBarry Smith       }
191817ab2063SBarry Smith     }
191988e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1920f1e2ffcdSBarry Smith   }
192143a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19223a40ed3dSBarry Smith   PetscFunctionReturn(0);
192317ab2063SBarry Smith }
192417ab2063SBarry Smith 
19254a2ae208SSatish Balay #undef __FUNCT__
19266e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19276e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19286e169961SBarry Smith {
19296e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19306e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19316e169961SBarry Smith   PetscErrorCode    ierr;
19322b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19336e169961SBarry Smith   const PetscScalar *xx;
19346e169961SBarry Smith   PetscScalar       *bb;
19356e169961SBarry Smith 
19366e169961SBarry Smith   PetscFunctionBegin;
19376e169961SBarry Smith   if (x && b) {
19386e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19396e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19402b40b63fSBarry Smith     vecs = PETSC_TRUE;
19416e169961SBarry Smith   }
19421795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
19436e169961SBarry Smith   for (i=0; i<N; i++) {
19446e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19456e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19462205254eSKarl Rupp 
19476e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19486e169961SBarry Smith   }
19496e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19506e169961SBarry Smith     if (!zeroed[i]) {
19516e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19526e169961SBarry Smith         if (zeroed[a->j[j]]) {
19532b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19546e169961SBarry Smith           a->a[j] = 0.0;
19556e169961SBarry Smith         }
19566e169961SBarry Smith       }
19572b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19586e169961SBarry Smith   }
19596e169961SBarry Smith   if (x && b) {
19606e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19616e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19626e169961SBarry Smith   }
19636e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19646e169961SBarry Smith   if (diag != 0.0) {
19656e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19666e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19676e169961SBarry Smith     for (i=0; i<N; i++) {
19686e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19696e169961SBarry Smith     }
19706e169961SBarry Smith   }
19716e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19726e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19736e169961SBarry Smith   PetscFunctionReturn(0);
19746e169961SBarry Smith }
19756e169961SBarry Smith 
19766e169961SBarry Smith #undef __FUNCT__
19774a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1978a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
197917ab2063SBarry Smith {
1980416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
198197f1f81fSBarry Smith   PetscInt   *itmp;
198217ab2063SBarry Smith 
19833a40ed3dSBarry Smith   PetscFunctionBegin;
1984e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
198517ab2063SBarry Smith 
1986416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1987bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
198817ab2063SBarry Smith   if (idx) {
1989bfeeae90SHong Zhang     itmp = a->j + a->i[row];
199026fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
199117ab2063SBarry Smith     else *idx = 0;
199217ab2063SBarry Smith   }
19933a40ed3dSBarry Smith   PetscFunctionReturn(0);
199417ab2063SBarry Smith }
199517ab2063SBarry Smith 
1996bfeeae90SHong Zhang /* remove this function? */
19974a2ae208SSatish Balay #undef __FUNCT__
19984a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1999a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
200017ab2063SBarry Smith {
20013a40ed3dSBarry Smith   PetscFunctionBegin;
20023a40ed3dSBarry Smith   PetscFunctionReturn(0);
200317ab2063SBarry Smith }
200417ab2063SBarry Smith 
20054a2ae208SSatish Balay #undef __FUNCT__
20064a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
2007dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
200817ab2063SBarry Smith {
2009416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
201054f21887SBarry Smith   MatScalar      *v  = a->a;
201136db0b34SBarry Smith   PetscReal      sum = 0.0;
20126849ba73SBarry Smith   PetscErrorCode ierr;
201397f1f81fSBarry Smith   PetscInt       i,j;
201417ab2063SBarry Smith 
20153a40ed3dSBarry Smith   PetscFunctionBegin;
201617ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2017416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
201836db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
201917ab2063SBarry Smith     }
20208f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20213a40ed3dSBarry Smith   } else if (type == NORM_1) {
202236db0b34SBarry Smith     PetscReal *tmp;
202397f1f81fSBarry Smith     PetscInt  *jj = a->j;
20241795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2025064f8208SBarry Smith     *nrm = 0.0;
2026416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2027bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
202817ab2063SBarry Smith     }
2029d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2030064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
203117ab2063SBarry Smith     }
2032606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20333a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2034064f8208SBarry Smith     *nrm = 0.0;
2035d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2036bfeeae90SHong Zhang       v   = a->a + a->i[j];
203717ab2063SBarry Smith       sum = 0.0;
2038416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2039cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
204017ab2063SBarry Smith       }
2041064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
204217ab2063SBarry Smith     }
2043f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20443a40ed3dSBarry Smith   PetscFunctionReturn(0);
204517ab2063SBarry Smith }
204617ab2063SBarry Smith 
20474e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20484e938277SHong Zhang #undef __FUNCT__
20494e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20504e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20514e938277SHong Zhang {
20524e938277SHong Zhang   PetscErrorCode ierr;
20534e938277SHong Zhang   PetscInt       i,j,anzj;
20544e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20554e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20564e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20574e938277SHong Zhang 
20584e938277SHong Zhang   PetscFunctionBegin;
20594e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20601795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2061785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2062785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
20634e938277SHong Zhang 
20644e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20654e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
206626fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20674e938277SHong Zhang   /* Form ati for csr format of A^T. */
206826fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20694e938277SHong Zhang 
20704e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20714e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20724e938277SHong Zhang 
20734e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20744e938277SHong Zhang   for (i=0;i<am;i++) {
20754e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20764e938277SHong Zhang     for (j=0;j<anzj;j++) {
20774e938277SHong Zhang       atj[atfill[*aj]] = i;
20784e938277SHong Zhang       atfill[*aj++]   += 1;
20794e938277SHong Zhang     }
20804e938277SHong Zhang   }
20814e938277SHong Zhang 
20824e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20834e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2084ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
2085*33d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
2086a2f3521dSMark F. Adams 
20874e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20884e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20894e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20904e938277SHong Zhang   b->nonew   = 0;
20914e938277SHong Zhang   PetscFunctionReturn(0);
20924e938277SHong Zhang }
20934e938277SHong Zhang 
20944a2ae208SSatish Balay #undef __FUNCT__
20954a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2096fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
209717ab2063SBarry Smith {
2098416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2099416022c9SBarry Smith   Mat            C;
21006849ba73SBarry Smith   PetscErrorCode ierr;
2101d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
210254f21887SBarry Smith   MatScalar      *array = a->a;
210317ab2063SBarry Smith 
21043a40ed3dSBarry Smith   PetscFunctionBegin;
2105e32f2f54SBarry 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");
2106fc4dec0aSBarry Smith 
2107fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
21081795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2109bfeeae90SHong Zhang 
2110bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2111ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2112d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2113*33d57670SJed Brown     ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
21147adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2115ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2116606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2117a541d17aSBarry Smith   } else {
2118a541d17aSBarry Smith     C = *B;
2119a541d17aSBarry Smith   }
2120a541d17aSBarry Smith 
212117ab2063SBarry Smith   for (i=0; i<m; i++) {
212217ab2063SBarry Smith     len    = ai[i+1]-ai[i];
212387d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2124b9b97703SBarry Smith     array += len;
2125b9b97703SBarry Smith     aj    += len;
212617ab2063SBarry Smith   }
21276d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21286d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
212917ab2063SBarry Smith 
2130815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2131416022c9SBarry Smith     *B = C;
213217ab2063SBarry Smith   } else {
2133eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
213417ab2063SBarry Smith   }
21353a40ed3dSBarry Smith   PetscFunctionReturn(0);
213617ab2063SBarry Smith }
213717ab2063SBarry Smith 
2138cd0d46ebSvictorle #undef __FUNCT__
21395fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21407087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2141cd0d46ebSvictorle {
2142cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
214354f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
214454f21887SBarry Smith   MatScalar      *va,*vb;
21456849ba73SBarry Smith   PetscErrorCode ierr;
214697f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2147cd0d46ebSvictorle 
2148cd0d46ebSvictorle   PetscFunctionBegin;
2149cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2150cd0d46ebSvictorle 
2151cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2152cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21535485867bSBarry Smith   if (ma!=nb || na!=mb) {
21545485867bSBarry Smith     *f = PETSC_FALSE;
21555485867bSBarry Smith     PetscFunctionReturn(0);
21565485867bSBarry Smith   }
2157cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2158cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2159cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2160785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2161785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2162cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2163cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2164cd0d46ebSvictorle 
2165cd0d46ebSvictorle   *f = PETSC_TRUE;
2166cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2167cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
216897f1f81fSBarry Smith       PetscInt    idc,idr;
21695485867bSBarry Smith       PetscScalar vc,vr;
2170cd0d46ebSvictorle       /* column/row index/value */
21715485867bSBarry Smith       idc = adx[aptr[i]];
21725485867bSBarry Smith       idr = bdx[bptr[idc]];
21735485867bSBarry Smith       vc  = va[aptr[i]];
21745485867bSBarry Smith       vr  = vb[bptr[idc]];
21755485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21765485867bSBarry Smith         *f = PETSC_FALSE;
21775485867bSBarry Smith         goto done;
2178cd0d46ebSvictorle       } else {
21795485867bSBarry Smith         aptr[i]++;
21805485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2181cd0d46ebSvictorle       }
2182cd0d46ebSvictorle     }
2183cd0d46ebSvictorle   }
2184cd0d46ebSvictorle done:
2185cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21863aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2187cd0d46ebSvictorle   PetscFunctionReturn(0);
2188cd0d46ebSvictorle }
2189cd0d46ebSvictorle 
21901cbb95d3SBarry Smith #undef __FUNCT__
21911cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21927087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21931cbb95d3SBarry Smith {
21941cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
219554f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
219654f21887SBarry Smith   MatScalar      *va,*vb;
21971cbb95d3SBarry Smith   PetscErrorCode ierr;
21981cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21991cbb95d3SBarry Smith 
22001cbb95d3SBarry Smith   PetscFunctionBegin;
22011cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
22021cbb95d3SBarry Smith 
22031cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
22041cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22051cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
22061cbb95d3SBarry Smith     *f = PETSC_FALSE;
22071cbb95d3SBarry Smith     PetscFunctionReturn(0);
22081cbb95d3SBarry Smith   }
22091cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22101cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22111cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2212785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2213785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
22141cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22151cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22161cbb95d3SBarry Smith 
22171cbb95d3SBarry Smith   *f = PETSC_TRUE;
22181cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22191cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22201cbb95d3SBarry Smith       PetscInt    idc,idr;
22211cbb95d3SBarry Smith       PetscScalar vc,vr;
22221cbb95d3SBarry Smith       /* column/row index/value */
22231cbb95d3SBarry Smith       idc = adx[aptr[i]];
22241cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22251cbb95d3SBarry Smith       vc  = va[aptr[i]];
22261cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22271cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22281cbb95d3SBarry Smith         *f = PETSC_FALSE;
22291cbb95d3SBarry Smith         goto done;
22301cbb95d3SBarry Smith       } else {
22311cbb95d3SBarry Smith         aptr[i]++;
22321cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22331cbb95d3SBarry Smith       }
22341cbb95d3SBarry Smith     }
22351cbb95d3SBarry Smith   }
22361cbb95d3SBarry Smith done:
22371cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22381cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22391cbb95d3SBarry Smith   PetscFunctionReturn(0);
22401cbb95d3SBarry Smith }
22411cbb95d3SBarry Smith 
22429e29f15eSvictorle #undef __FUNCT__
22439e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2244ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22459e29f15eSvictorle {
2246dfbe8321SBarry Smith   PetscErrorCode ierr;
22476e111a19SKarl Rupp 
22489e29f15eSvictorle   PetscFunctionBegin;
22495485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22509e29f15eSvictorle   PetscFunctionReturn(0);
22519e29f15eSvictorle }
22529e29f15eSvictorle 
22534a2ae208SSatish Balay #undef __FUNCT__
22541cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2255ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22561cbb95d3SBarry Smith {
22571cbb95d3SBarry Smith   PetscErrorCode ierr;
22586e111a19SKarl Rupp 
22591cbb95d3SBarry Smith   PetscFunctionBegin;
22601cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22611cbb95d3SBarry Smith   PetscFunctionReturn(0);
22621cbb95d3SBarry Smith }
22631cbb95d3SBarry Smith 
22641cbb95d3SBarry Smith #undef __FUNCT__
22654a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2266dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
226717ab2063SBarry Smith {
2268416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226954f21887SBarry Smith   PetscScalar    *l,*r,x;
227054f21887SBarry Smith   MatScalar      *v;
2271dfbe8321SBarry Smith   PetscErrorCode ierr;
2272d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
227317ab2063SBarry Smith 
22743a40ed3dSBarry Smith   PetscFunctionBegin;
227517ab2063SBarry Smith   if (ll) {
22763ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22773ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2278e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2279e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22801ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2281416022c9SBarry Smith     v    = a->a;
228217ab2063SBarry Smith     for (i=0; i<m; i++) {
228317ab2063SBarry Smith       x = l[i];
2284416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22852205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
228617ab2063SBarry Smith     }
22871ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2288efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228917ab2063SBarry Smith   }
229017ab2063SBarry Smith   if (rr) {
2291e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2292e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22931ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2294416022c9SBarry Smith     v    = a->a; jj = a->j;
22952205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22961ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2297efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
229817ab2063SBarry Smith   }
2299acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
23003a40ed3dSBarry Smith   PetscFunctionReturn(0);
230117ab2063SBarry Smith }
230217ab2063SBarry Smith 
23034a2ae208SSatish Balay #undef __FUNCT__
23044a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
230597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
230617ab2063SBarry Smith {
2307db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23086849ba73SBarry Smith   PetscErrorCode ierr;
2309d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
231097f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23115d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23125d0c19d7SBarry Smith   PetscInt       nrows,ncols;
231397f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
231454f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2315416022c9SBarry Smith   Mat            C;
2316ace3abfcSBarry Smith   PetscBool      stride,sorted;
231717ab2063SBarry Smith 
23183a40ed3dSBarry Smith   PetscFunctionBegin;
231914ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2320e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
232114ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2322e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
232399141d43SSatish Balay 
232417ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2325b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2326b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
232717ab2063SBarry Smith 
2328fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2329251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2330fee21e36SBarry Smith   if (stride && step == 1) {
233102834360SBarry Smith     /* special case of contiguous rows */
2332dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
233302834360SBarry Smith     /* loop over new rows determining lens and starting points */
233402834360SBarry Smith     for (i=0; i<nrows; i++) {
2335bfeeae90SHong Zhang       kstart = ai[irow[i]];
2336a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
233702834360SBarry Smith       for (k=kstart; k<kend; k++) {
2338bfeeae90SHong Zhang         if (aj[k] >= first) {
233902834360SBarry Smith           starts[i] = k;
234002834360SBarry Smith           break;
234102834360SBarry Smith         }
234202834360SBarry Smith       }
2343a2744918SBarry Smith       sum = 0;
234402834360SBarry Smith       while (k < kend) {
2345bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2346a2744918SBarry Smith         sum++;
234702834360SBarry Smith       }
2348a2744918SBarry Smith       lens[i] = sum;
234902834360SBarry Smith     }
235002834360SBarry Smith     /* create submatrix */
2351cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
235297f1f81fSBarry Smith       PetscInt n_cols,n_rows;
235308480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2354e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2355d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
235608480c60SBarry Smith       C    = *B;
23573a40ed3dSBarry Smith     } else {
23583bef6203SJed Brown       PetscInt rbs,cbs;
2359ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2360f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23613bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23623bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23633bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23647adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2365ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
236608480c60SBarry Smith     }
2367db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2368db02288aSLois Curfman McInnes 
236902834360SBarry Smith     /* loop over rows inserting into submatrix */
2370db02288aSLois Curfman McInnes     a_new = c->a;
2371db02288aSLois Curfman McInnes     j_new = c->j;
2372db02288aSLois Curfman McInnes     i_new = c->i;
2373bfeeae90SHong Zhang 
237402834360SBarry Smith     for (i=0; i<nrows; i++) {
2375a2744918SBarry Smith       ii    = starts[i];
2376a2744918SBarry Smith       lensi = lens[i];
2377a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2378a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
237902834360SBarry Smith       }
238087828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2381a2744918SBarry Smith       a_new     += lensi;
2382a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2383a2744918SBarry Smith       c->ilen[i] = lensi;
238402834360SBarry Smith     }
23850e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23863a40ed3dSBarry Smith   } else {
238702834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23881795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2389785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
23904dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23914dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23924dcab191SBarry 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);
23934dcab191SBarry Smith #endif
23944dcab191SBarry Smith       smap[icol[i]] = i+1;
23954dcab191SBarry Smith     }
23964dcab191SBarry Smith 
239702834360SBarry Smith     /* determine lens of each row */
239802834360SBarry Smith     for (i=0; i<nrows; i++) {
2399bfeeae90SHong Zhang       kstart  = ai[irow[i]];
240002834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
240102834360SBarry Smith       lens[i] = 0;
240202834360SBarry Smith       for (k=kstart; k<kend; k++) {
2403bfeeae90SHong Zhang         if (smap[aj[k]]) {
240402834360SBarry Smith           lens[i]++;
240502834360SBarry Smith         }
240602834360SBarry Smith       }
240702834360SBarry Smith     }
240817ab2063SBarry Smith     /* Create and fill new matrix */
2409a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2410ace3abfcSBarry Smith       PetscBool equal;
24110f5bd95cSBarry Smith 
241299141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2413e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2414d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2415f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2416d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
241708480c60SBarry Smith       C    = *B;
24183a40ed3dSBarry Smith     } else {
24193bef6203SJed Brown       PetscInt rbs,cbs;
2420ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2421f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24223bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24233bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24243bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24257adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2426ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
242708480c60SBarry Smith     }
242899141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
242917ab2063SBarry Smith     for (i=0; i<nrows; i++) {
243099141d43SSatish Balay       row      = irow[i];
2431bfeeae90SHong Zhang       kstart   = ai[row];
243299141d43SSatish Balay       kend     = kstart + a->ilen[row];
2433bfeeae90SHong Zhang       mat_i    = c->i[i];
243499141d43SSatish Balay       mat_j    = c->j + mat_i;
243599141d43SSatish Balay       mat_a    = c->a + mat_i;
243699141d43SSatish Balay       mat_ilen = c->ilen + i;
243717ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2438bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2439ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
244099141d43SSatish Balay           *mat_a++ = a->a[k];
244199141d43SSatish Balay           (*mat_ilen)++;
244299141d43SSatish Balay 
244317ab2063SBarry Smith         }
244417ab2063SBarry Smith       }
244517ab2063SBarry Smith     }
244602834360SBarry Smith     /* Free work space */
244702834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2448606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2449606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
245002834360SBarry Smith   }
24516d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24526d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
245317ab2063SBarry Smith 
245417ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2455416022c9SBarry Smith   *B   = C;
24563a40ed3dSBarry Smith   PetscFunctionReturn(0);
245717ab2063SBarry Smith }
245817ab2063SBarry Smith 
24591df811f5SHong Zhang #undef __FUNCT__
246082d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2461fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
246282d44351SHong Zhang {
246382d44351SHong Zhang   PetscErrorCode ierr;
246482d44351SHong Zhang   Mat            B;
246582d44351SHong Zhang 
246682d44351SHong Zhang   PetscFunctionBegin;
2467c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
246882d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
246982d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2470*33d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
247182d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
247282d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
247382d44351SHong Zhang     *subMat = B;
2474c2d650bdSHong Zhang   } else {
2475c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2476c2d650bdSHong Zhang   }
247782d44351SHong Zhang   PetscFunctionReturn(0);
247882d44351SHong Zhang }
247982d44351SHong Zhang 
248082d44351SHong Zhang #undef __FUNCT__
24814a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24820481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2483a871dcd8SBarry Smith {
248463b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2485dfbe8321SBarry Smith   PetscErrorCode ierr;
248663b91edcSBarry Smith   Mat            outA;
2487ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
248863b91edcSBarry Smith 
24893a40ed3dSBarry Smith   PetscFunctionBegin;
2490e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24911df811f5SHong Zhang 
2492b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2493b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2494a871dcd8SBarry Smith 
249563b91edcSBarry Smith   outA             = inA;
2496d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24972205254eSKarl Rupp 
2498c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24996bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
25002205254eSKarl Rupp 
2501c3122656SLisandro Dalcin   a->row = row;
25022205254eSKarl Rupp 
2503c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
25046bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
25052205254eSKarl Rupp 
2506c3122656SLisandro Dalcin   a->col = col;
250763b91edcSBarry Smith 
250836db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
25096bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
25104c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25113bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2512f0ec6fceSSatish Balay 
251394a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2514785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
25153bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
251694a9d846SBarry Smith   }
251763b91edcSBarry Smith 
2518f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2519137fb511SHong Zhang   if (row_identity && col_identity) {
2520ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2521137fb511SHong Zhang   } else {
2522719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2523137fb511SHong Zhang   }
25243a40ed3dSBarry Smith   PetscFunctionReturn(0);
2525a871dcd8SBarry Smith }
2526a871dcd8SBarry Smith 
25274a2ae208SSatish Balay #undef __FUNCT__
25284a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2529f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2530f0b747eeSBarry Smith {
2531f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2532f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2533efee365bSSatish Balay   PetscErrorCode ierr;
2534c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25353a40ed3dSBarry Smith 
25363a40ed3dSBarry Smith   PetscFunctionBegin;
2537c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25388b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2539efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2540acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25413a40ed3dSBarry Smith   PetscFunctionReturn(0);
2542f0b747eeSBarry Smith }
2543f0b747eeSBarry Smith 
25444a2ae208SSatish Balay #undef __FUNCT__
25454a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
254697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2547cddf8d76SBarry Smith {
2548dfbe8321SBarry Smith   PetscErrorCode ierr;
254997f1f81fSBarry Smith   PetscInt       i;
2550cddf8d76SBarry Smith 
25513a40ed3dSBarry Smith   PetscFunctionBegin;
2552cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2553785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2554cddf8d76SBarry Smith   }
2555cddf8d76SBarry Smith 
2556cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25576a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2558cddf8d76SBarry Smith   }
25593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2560cddf8d76SBarry Smith }
2561cddf8d76SBarry Smith 
25624a2ae208SSatish Balay #undef __FUNCT__
25634a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
256497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25654dcbc457SBarry Smith {
2566e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25676849ba73SBarry Smith   PetscErrorCode ierr;
25685d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25695d0c19d7SBarry Smith   const PetscInt *idx;
257097f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2571f1af5d2fSBarry Smith   PetscBT        table;
2572bbd702dbSSatish Balay 
25733a40ed3dSBarry Smith   PetscFunctionBegin;
2574d0f46423SBarry Smith   m  = A->rmap->n;
2575e4d965acSSatish Balay   ai = a->i;
2576bfeeae90SHong Zhang   aj = a->j;
25778a047759SSatish Balay 
2578e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
257906763907SSatish Balay 
2580785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
258153b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
258206763907SSatish Balay 
2583e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2584b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2585e4d965acSSatish Balay     isz  = 0;
25866831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2587e4d965acSSatish Balay 
2588e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25894dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2590b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2591e4d965acSSatish Balay 
2592dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2593e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25942205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25954dcbc457SBarry Smith     }
259606763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25976bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2598e4d965acSSatish Balay 
259904a348a9SBarry Smith     k = 0;
260004a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
260104a348a9SBarry Smith       n = isz;
260206763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2603e4d965acSSatish Balay         row   = nidx[k];
2604e4d965acSSatish Balay         start = ai[row];
2605e4d965acSSatish Balay         end   = ai[row+1];
260604a348a9SBarry Smith         for (l = start; l<end; l++) {
2607efb16452SHong Zhang           val = aj[l];
26082205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2609e4d965acSSatish Balay         }
2610e4d965acSSatish Balay       }
2611e4d965acSSatish Balay     }
261270b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2613e4d965acSSatish Balay   }
261494bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2615606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26163a40ed3dSBarry Smith   PetscFunctionReturn(0);
26174dcbc457SBarry Smith }
261817ab2063SBarry Smith 
26190513a670SBarry Smith /* -------------------------------------------------------------- */
26204a2ae208SSatish Balay #undef __FUNCT__
26214a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2622dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26230513a670SBarry Smith {
26240513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26256849ba73SBarry Smith   PetscErrorCode ierr;
26263b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26275d0c19d7SBarry Smith   const PetscInt *row,*col;
26285d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
262956cd22aeSBarry Smith   IS             icolp,irowp;
26300298fd71SBarry Smith   PetscInt       *cwork = NULL;
26310298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26320513a670SBarry Smith 
26333a40ed3dSBarry Smith   PetscFunctionBegin;
26344c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
263556cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26364c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
263756cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26380513a670SBarry Smith 
26390513a670SBarry Smith   /* determine lengths of permuted rows */
2640785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
26412205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2642ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2643f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2644*33d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
26457adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2646ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2647606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26480513a670SBarry Smith 
2649785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26500513a670SBarry Smith   for (i=0; i<m; i++) {
265132ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26522205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2653cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
265432ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26550513a670SBarry Smith   }
2656606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26572205254eSKarl Rupp 
26583c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26592205254eSKarl Rupp 
26600513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26610513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
266256cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
266356cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26646bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26656bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26663a40ed3dSBarry Smith   PetscFunctionReturn(0);
26670513a670SBarry Smith }
26680513a670SBarry Smith 
26694a2ae208SSatish Balay #undef __FUNCT__
26704a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2671dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2672cb5b572fSBarry Smith {
2673dfbe8321SBarry Smith   PetscErrorCode ierr;
2674cb5b572fSBarry Smith 
2675cb5b572fSBarry Smith   PetscFunctionBegin;
267633f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
267733f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2678be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2679be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2680be6bf707SBarry Smith 
2681700c5bfcSBarry 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");
2682d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2683cb5b572fSBarry Smith   } else {
2684cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2685cb5b572fSBarry Smith   }
2686cb5b572fSBarry Smith   PetscFunctionReturn(0);
2687cb5b572fSBarry Smith }
2688cb5b572fSBarry Smith 
26894a2ae208SSatish Balay #undef __FUNCT__
26904994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26914994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2692273d9f13SBarry Smith {
2693dfbe8321SBarry Smith   PetscErrorCode ierr;
2694273d9f13SBarry Smith 
2695273d9f13SBarry Smith   PetscFunctionBegin;
2696ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2697273d9f13SBarry Smith   PetscFunctionReturn(0);
2698273d9f13SBarry Smith }
2699273d9f13SBarry Smith 
27004a2ae208SSatish Balay #undef __FUNCT__
27018c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
27028c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
27036c0721eeSBarry Smith {
27046c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
27056e111a19SKarl Rupp 
27066c0721eeSBarry Smith   PetscFunctionBegin;
27076c0721eeSBarry Smith   *array = a->a;
27086c0721eeSBarry Smith   PetscFunctionReturn(0);
27096c0721eeSBarry Smith }
27106c0721eeSBarry Smith 
27114a2ae208SSatish Balay #undef __FUNCT__
27128c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27138c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27146c0721eeSBarry Smith {
27156c0721eeSBarry Smith   PetscFunctionBegin;
27166c0721eeSBarry Smith   PetscFunctionReturn(0);
27176c0721eeSBarry Smith }
2718273d9f13SBarry Smith 
27198229c054SShri Abhyankar /*
27208229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27218229c054SShri Abhyankar    have different nonzero structure.
27228229c054SShri Abhyankar */
2723ac90fabeSBarry Smith #undef __FUNCT__
27248229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27258229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2726ec7775f6SShri Abhyankar {
27278229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2728ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2729ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2730ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2731ec7775f6SShri Abhyankar 
2732ec7775f6SShri Abhyankar   PetscFunctionBegin;
2733ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2734ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27358af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27368af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27378af7cee1SJed Brown     nnz[i] = 0;
27388af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27398af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27408af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27418af7cee1SJed Brown       nnz[i]++;
27428af7cee1SJed Brown     }
27438af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2744ec7775f6SShri Abhyankar   }
2745ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2746ec7775f6SShri Abhyankar }
2747ec7775f6SShri Abhyankar 
2748ec7775f6SShri Abhyankar #undef __FUNCT__
2749ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2750f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2751ac90fabeSBarry Smith {
2752dfbe8321SBarry Smith   PetscErrorCode ierr;
275397f1f81fSBarry Smith   PetscInt       i;
2754ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2755c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2756ac90fabeSBarry Smith 
2757ac90fabeSBarry Smith   PetscFunctionBegin;
2758c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2759ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2760f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27618b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2762acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2763c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2764a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2765a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27666bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2767a30b2313SHong Zhang     }
2768a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27690298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2770a30b2313SHong Zhang       y->XtoY = X;
2771407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2772c537a176SHong Zhang     }
2773f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
27746712e2f1SBarry 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);
2775ac90fabeSBarry Smith   } else {
27768229c054SShri Abhyankar     Mat      B;
27778229c054SShri Abhyankar     PetscInt *nnz;
2778785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2779ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2780bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27814aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2782*33d57670SJed Brown     ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr);
2783176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27848229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2785ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2786ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2787ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27888229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2789ac90fabeSBarry Smith   }
2790ac90fabeSBarry Smith   PetscFunctionReturn(0);
2791ac90fabeSBarry Smith }
2792ac90fabeSBarry Smith 
2793521d7252SBarry Smith #undef __FUNCT__
2794354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27957087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2796354c94deSBarry Smith {
2797354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2798354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2799354c94deSBarry Smith   PetscInt    i,nz;
2800354c94deSBarry Smith   PetscScalar *a;
2801354c94deSBarry Smith 
2802354c94deSBarry Smith   PetscFunctionBegin;
2803354c94deSBarry Smith   nz = aij->nz;
2804354c94deSBarry Smith   a  = aij->a;
28052205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2806354c94deSBarry Smith #else
2807354c94deSBarry Smith   PetscFunctionBegin;
2808354c94deSBarry Smith #endif
2809354c94deSBarry Smith   PetscFunctionReturn(0);
2810354c94deSBarry Smith }
2811354c94deSBarry Smith 
2812e34fafa9SBarry Smith #undef __FUNCT__
2813985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2814985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2815e34fafa9SBarry Smith {
2816e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2817e34fafa9SBarry Smith   PetscErrorCode ierr;
2818d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2819e34fafa9SBarry Smith   PetscReal      atmp;
2820985db425SBarry Smith   PetscScalar    *x;
2821e34fafa9SBarry Smith   MatScalar      *aa;
2822e34fafa9SBarry Smith 
2823e34fafa9SBarry Smith   PetscFunctionBegin;
2824e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2825e34fafa9SBarry Smith   aa = a->a;
2826e34fafa9SBarry Smith   ai = a->i;
2827e34fafa9SBarry Smith   aj = a->j;
2828e34fafa9SBarry Smith 
2829985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2830e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2831e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2832e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2833e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2834e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28359189402eSHong Zhang     x[i]  = 0.0;
2836e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2837985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2838985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2839985db425SBarry Smith       aa++; aj++;
2840985db425SBarry Smith     }
2841985db425SBarry Smith   }
2842985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2843985db425SBarry Smith   PetscFunctionReturn(0);
2844985db425SBarry Smith }
2845985db425SBarry Smith 
2846985db425SBarry Smith #undef __FUNCT__
2847985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2848985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2849985db425SBarry Smith {
2850985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2851985db425SBarry Smith   PetscErrorCode ierr;
2852d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2853985db425SBarry Smith   PetscScalar    *x;
2854985db425SBarry Smith   MatScalar      *aa;
2855985db425SBarry Smith 
2856985db425SBarry Smith   PetscFunctionBegin;
2857e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2858985db425SBarry Smith   aa = a->a;
2859985db425SBarry Smith   ai = a->i;
2860985db425SBarry Smith   aj = a->j;
2861985db425SBarry Smith 
2862985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2863985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2864985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2865e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2866985db425SBarry Smith   for (i=0; i<m; i++) {
2867985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2868d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2869985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2870985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2871985db425SBarry Smith       x[i] = 0.0;
2872985db425SBarry Smith       if (idx) {
2873985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2874985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2875985db425SBarry Smith           if (aj[j] > j) {
2876985db425SBarry Smith             idx[i] = j;
2877985db425SBarry Smith             break;
2878985db425SBarry Smith           }
2879985db425SBarry Smith         }
2880985db425SBarry Smith       }
2881985db425SBarry Smith     }
2882985db425SBarry Smith     for (j=0; j<ncols; j++) {
2883985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2884985db425SBarry Smith       aa++; aj++;
2885985db425SBarry Smith     }
2886985db425SBarry Smith   }
2887985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2888985db425SBarry Smith   PetscFunctionReturn(0);
2889985db425SBarry Smith }
2890985db425SBarry Smith 
2891985db425SBarry Smith #undef __FUNCT__
2892c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2893c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2894c87e5d42SMatthew Knepley {
2895c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2896c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2897c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2898c87e5d42SMatthew Knepley   PetscReal      atmp;
2899c87e5d42SMatthew Knepley   PetscScalar    *x;
2900c87e5d42SMatthew Knepley   MatScalar      *aa;
2901c87e5d42SMatthew Knepley 
2902c87e5d42SMatthew Knepley   PetscFunctionBegin;
2903e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2904c87e5d42SMatthew Knepley   aa = a->a;
2905c87e5d42SMatthew Knepley   ai = a->i;
2906c87e5d42SMatthew Knepley   aj = a->j;
2907c87e5d42SMatthew Knepley 
2908c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2909c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2910c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
291160e0710aSBarry Smith   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);
2912c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2913c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2914289a08f5SMatthew Knepley     if (ncols) {
2915289a08f5SMatthew Knepley       /* Get first nonzero */
2916289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2917289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29182205254eSKarl Rupp         if (atmp > 1.0e-12) {
29192205254eSKarl Rupp           x[i] = atmp;
29202205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29212205254eSKarl Rupp           break;
29222205254eSKarl Rupp         }
2923289a08f5SMatthew Knepley       }
292412431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2925289a08f5SMatthew Knepley     } else {
2926289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2927289a08f5SMatthew Knepley     }
2928c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2929c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2930289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2931c87e5d42SMatthew Knepley       aa++; aj++;
2932c87e5d42SMatthew Knepley     }
2933c87e5d42SMatthew Knepley   }
2934c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2935c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2936c87e5d42SMatthew Knepley }
2937c87e5d42SMatthew Knepley 
2938c87e5d42SMatthew Knepley #undef __FUNCT__
2939985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2940985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2941985db425SBarry Smith {
2942985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2943985db425SBarry Smith   PetscErrorCode ierr;
2944d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2945985db425SBarry Smith   PetscScalar    *x;
2946985db425SBarry Smith   MatScalar      *aa;
2947985db425SBarry Smith 
2948985db425SBarry Smith   PetscFunctionBegin;
2949e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2950985db425SBarry Smith   aa = a->a;
2951985db425SBarry Smith   ai = a->i;
2952985db425SBarry Smith   aj = a->j;
2953985db425SBarry Smith 
2954985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2955985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2956985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2957e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2958985db425SBarry Smith   for (i=0; i<m; i++) {
2959985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2960d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2961985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2962985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2963985db425SBarry Smith       x[i] = 0.0;
2964985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2965985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2966985db425SBarry Smith         for (j=0; j<ncols; j++) {
2967985db425SBarry Smith           if (aj[j] > j) {
2968985db425SBarry Smith             idx[i] = j;
2969985db425SBarry Smith             break;
2970985db425SBarry Smith           }
2971985db425SBarry Smith         }
2972985db425SBarry Smith       }
2973985db425SBarry Smith     }
2974985db425SBarry Smith     for (j=0; j<ncols; j++) {
2975985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2976985db425SBarry Smith       aa++; aj++;
2977e34fafa9SBarry Smith     }
2978e34fafa9SBarry Smith   }
2979e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2980e34fafa9SBarry Smith   PetscFunctionReturn(0);
2981e34fafa9SBarry Smith }
2982bbead8a2SBarry Smith 
2983bbead8a2SBarry Smith #include <petscblaslapack.h>
298406873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
2985bbead8a2SBarry Smith 
2986bbead8a2SBarry Smith #undef __FUNCT__
2987bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2988713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2989bbead8a2SBarry Smith {
2990bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2991bbead8a2SBarry Smith   PetscErrorCode ierr;
2992*33d57670SJed Brown   PetscInt       i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2993bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2994bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2995bbead8a2SBarry Smith 
2996bbead8a2SBarry Smith   PetscFunctionBegin;
29974a0d0026SBarry Smith   if (a->ibdiagvalid) {
29984a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29994a0d0026SBarry Smith     PetscFunctionReturn(0);
30004a0d0026SBarry Smith   }
3001bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3002bbead8a2SBarry Smith   if (!a->ibdiag) {
3003785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
30043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3005bbead8a2SBarry Smith   }
3006bbead8a2SBarry Smith   diag = a->ibdiag;
3007bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3008bbead8a2SBarry Smith   /* factor and invert each block */
3009bbead8a2SBarry Smith   switch (bs) {
3010bbead8a2SBarry Smith   case 1:
3011bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3012bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3013bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3014bbead8a2SBarry Smith     }
3015bbead8a2SBarry Smith     break;
3016bbead8a2SBarry Smith   case 2:
3017bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3018bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3019bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
302096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
302196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3022bbead8a2SBarry Smith       diag += 4;
3023bbead8a2SBarry Smith     }
3024bbead8a2SBarry Smith     break;
3025bbead8a2SBarry Smith   case 3:
3026bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3027bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3028bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
302996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
303096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3031bbead8a2SBarry Smith       diag += 9;
3032bbead8a2SBarry Smith     }
3033bbead8a2SBarry Smith     break;
3034bbead8a2SBarry Smith   case 4:
3035bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3036bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3037bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
303896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
303996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3040bbead8a2SBarry Smith       diag += 16;
3041bbead8a2SBarry Smith     }
3042bbead8a2SBarry Smith     break;
3043bbead8a2SBarry Smith   case 5:
3044bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3045bbead8a2SBarry 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;
3046bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
304796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
304896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3049bbead8a2SBarry Smith       diag += 25;
3050bbead8a2SBarry Smith     }
3051bbead8a2SBarry Smith     break;
3052bbead8a2SBarry Smith   case 6:
3053bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3054bbead8a2SBarry 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;
3055bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
305696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
305796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3058bbead8a2SBarry Smith       diag += 36;
3059bbead8a2SBarry Smith     }
3060bbead8a2SBarry Smith     break;
3061bbead8a2SBarry Smith   case 7:
3062bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3063bbead8a2SBarry 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;
3064bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
306596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
306696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3067bbead8a2SBarry Smith       diag += 49;
3068bbead8a2SBarry Smith     }
3069bbead8a2SBarry Smith     break;
3070bbead8a2SBarry Smith   default:
3071dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3072bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3073bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3074bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3075bbead8a2SBarry Smith       }
3076bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
307796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
307896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3079bbead8a2SBarry Smith       diag += bs2;
3080bbead8a2SBarry Smith     }
3081bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3082bbead8a2SBarry Smith   }
3083bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3084bbead8a2SBarry Smith   PetscFunctionReturn(0);
3085bbead8a2SBarry Smith }
3086bbead8a2SBarry Smith 
308773a71a0fSBarry Smith #undef __FUNCT__
308873a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
308973a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
309073a71a0fSBarry Smith {
309173a71a0fSBarry Smith   PetscErrorCode ierr;
309273a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
309373a71a0fSBarry Smith   PetscScalar    a;
309473a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
309573a71a0fSBarry Smith 
309673a71a0fSBarry Smith   PetscFunctionBegin;
309773a71a0fSBarry Smith   if (!x->assembled) {
309873a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
309973a71a0fSBarry Smith     for (i=0; i<m; i++) {
310073a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
310173a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
310273a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
310373a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
310473a71a0fSBarry Smith       }
310573a71a0fSBarry Smith     }
310673a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
310773a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
310873a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
310973a71a0fSBarry Smith   PetscFunctionReturn(0);
311073a71a0fSBarry Smith }
311173a71a0fSBarry Smith 
3112682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31130a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3114cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3115cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3116cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
311797304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31187c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31197c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3120db4efbfdSBarry Smith                                         0,
3121db4efbfdSBarry Smith                                         0,
3122db4efbfdSBarry Smith                                         0,
3123db4efbfdSBarry Smith                                 /* 10*/ 0,
3124cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3125cb5b572fSBarry Smith                                         0,
312641f059aeSBarry Smith                                         MatSOR_SeqAIJ,
312717ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
312897304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3129cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3130cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3131cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3132cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
313397304618SKris Buschelman                                 /* 20*/ 0,
3134cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3135cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3136cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3137d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3138db4efbfdSBarry Smith                                         0,
3139db4efbfdSBarry Smith                                         0,
3140db4efbfdSBarry Smith                                         0,
3141db4efbfdSBarry Smith                                         0,
31424994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3143db4efbfdSBarry Smith                                         0,
3144db4efbfdSBarry Smith                                         0,
31458c778c55SBarry Smith                                         0,
31468c778c55SBarry Smith                                         0,
3147d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3148cb5b572fSBarry Smith                                         0,
3149cb5b572fSBarry Smith                                         0,
3150cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3151cb5b572fSBarry Smith                                         0,
3152d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3153cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3154cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3155cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3156cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3157d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3158cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3159cb5b572fSBarry Smith                                         0,
316079299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31616e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
316273a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31633b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31643b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31653b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3166a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
316793dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3168b9617806SBarry Smith                                         0,
31690513a670SBarry Smith                                         0,
3170cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3171cda55fadSBarry Smith                                         0,
3172d519adbfSMatthew Knepley                                 /* 59*/ 0,
3173b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3174b9b97703SBarry Smith                                         MatView_SeqAIJ,
3175357abbc8SBarry Smith                                         0,
3176321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3177321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3178321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3179ee4f033dSBarry Smith                                         0,
3180ee4f033dSBarry Smith                                         0,
3181ee4f033dSBarry Smith                                         0,
3182d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3183c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3184ee4f033dSBarry Smith                                         0,
3185ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3186dcf5cc72SBarry Smith                                         0,
3187d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31883acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
318997304618SKris Buschelman                                         0,
319097304618SKris Buschelman                                         0,
319197304618SKris Buschelman                                         0,
31926ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
319397304618SKris Buschelman                                         0,
319497304618SKris Buschelman                                         0,
319597304618SKris Buschelman                                         0,
3196bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3197d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31981cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31996284ec50SHong Zhang                                         0,
32006284ec50SHong Zhang                                         0,
3201bc011b1eSHong Zhang                                         0,
3202d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
320326be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
320426be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
320565e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
32064a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
320765e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
32086fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
32096fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
32106fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32112121bac1SHong Zhang                                         0,
32122121bac1SHong Zhang                                 /* 99*/ 0,
3213609c6c4dSKris Buschelman                                         0,
3214609c6c4dSKris Buschelman                                         0,
321587d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
321687d4246cSBarry Smith                                         0,
3217d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
321899cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3219f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3220f5edf698SHong Zhang                                         0,
32212bebee5dSHong Zhang                                         0,
3222cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3223985db425SBarry Smith                                         0,
32242af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32252af78befSBarry Smith                                         0,
3226599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3227d519adbfSMatthew Knepley                                 /*114*/ 0,
3228599ef60dSHong Zhang                                         0,
32293c2a7987SHong Zhang                                         0,
3230fe97e370SBarry Smith                                         0,
3231fbdbba38SShri Abhyankar                                         0,
3232fbdbba38SShri Abhyankar                                 /*119*/ 0,
3233fbdbba38SShri Abhyankar                                         0,
3234fbdbba38SShri Abhyankar                                         0,
323582d44351SHong Zhang                                         0,
3236b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32370716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3238bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
323937868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
324037868618SMatthew G Knepley                                         0,
324137868618SMatthew G Knepley                                         0,
32425df89d91SHong Zhang                                 /*129*/ 0,
324375648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
324475648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
324575648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3246b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3247b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32482b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32492b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32502b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32513964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32523964eb88SJed Brown                                  /*139*/0,
3253f9426fe0SMark Adams                                         0,
32541919a2e2SJed Brown                                         0,
3255f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32569e29f15eSvictorle };
325717ab2063SBarry Smith 
32584a2ae208SSatish Balay #undef __FUNCT__
32594a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32607087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3261bef8e0ddSBarry Smith {
3262bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
326397f1f81fSBarry Smith   PetscInt   i,nz,n;
3264bef8e0ddSBarry Smith 
3265bef8e0ddSBarry Smith   PetscFunctionBegin;
3266bef8e0ddSBarry Smith   nz = aij->maxnz;
3267d0f46423SBarry Smith   n  = mat->rmap->n;
3268bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3269bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3270bef8e0ddSBarry Smith   }
3271bef8e0ddSBarry Smith   aij->nz = nz;
3272bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3273bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3274bef8e0ddSBarry Smith   }
3275bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3276bef8e0ddSBarry Smith }
3277bef8e0ddSBarry Smith 
32784a2ae208SSatish Balay #undef __FUNCT__
32794a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3280bef8e0ddSBarry Smith /*@
3281bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3282bef8e0ddSBarry Smith        in the matrix.
3283bef8e0ddSBarry Smith 
3284bef8e0ddSBarry Smith   Input Parameters:
3285bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3286bef8e0ddSBarry Smith -  indices - the column indices
3287bef8e0ddSBarry Smith 
328815091d37SBarry Smith   Level: advanced
328915091d37SBarry Smith 
3290bef8e0ddSBarry Smith   Notes:
3291bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3292bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3293bef8e0ddSBarry Smith   of the MatSetValues() operation.
3294bef8e0ddSBarry Smith 
3295bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3296d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3297bef8e0ddSBarry Smith 
3298bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3299bef8e0ddSBarry Smith 
3300b9617806SBarry Smith     The indices should start with zero, not one.
3301b9617806SBarry Smith 
3302bef8e0ddSBarry Smith @*/
33037087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3304bef8e0ddSBarry Smith {
33054ac538c5SBarry Smith   PetscErrorCode ierr;
3306bef8e0ddSBarry Smith 
3307bef8e0ddSBarry Smith   PetscFunctionBegin;
33080700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33094482741eSBarry Smith   PetscValidPointer(indices,2);
33104ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3311bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3312bef8e0ddSBarry Smith }
3313bef8e0ddSBarry Smith 
3314be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3315be6bf707SBarry Smith 
33164a2ae208SSatish Balay #undef __FUNCT__
33174a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33187087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3319be6bf707SBarry Smith {
3320be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33216849ba73SBarry Smith   PetscErrorCode ierr;
3322d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3323be6bf707SBarry Smith 
3324be6bf707SBarry Smith   PetscFunctionBegin;
3325f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3326be6bf707SBarry Smith 
3327be6bf707SBarry Smith   /* allocate space for values if not already there */
3328be6bf707SBarry Smith   if (!aij->saved_values) {
3329785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
33303bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3331be6bf707SBarry Smith   }
3332be6bf707SBarry Smith 
3333be6bf707SBarry Smith   /* copy values over */
333487828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3335be6bf707SBarry Smith   PetscFunctionReturn(0);
3336be6bf707SBarry Smith }
3337be6bf707SBarry Smith 
33384a2ae208SSatish Balay #undef __FUNCT__
3339b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3340be6bf707SBarry Smith /*@
3341be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3342be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3343be6bf707SBarry Smith        nonlinear portion.
3344be6bf707SBarry Smith 
3345be6bf707SBarry Smith    Collect on Mat
3346be6bf707SBarry Smith 
3347be6bf707SBarry Smith   Input Parameters:
33480e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3349be6bf707SBarry Smith 
335015091d37SBarry Smith   Level: advanced
335115091d37SBarry Smith 
3352be6bf707SBarry Smith   Common Usage, with SNESSolve():
3353be6bf707SBarry Smith $    Create Jacobian matrix
3354be6bf707SBarry Smith $    Set linear terms into matrix
3355be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3356be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3357be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3358512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3359be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3360be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3361be6bf707SBarry Smith $    In your Jacobian routine
3362be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3363be6bf707SBarry Smith $      Set nonlinear terms in matrix
3364be6bf707SBarry Smith 
3365be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3366be6bf707SBarry Smith $    // build linear portion of Jacobian
3367512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3368be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3369be6bf707SBarry Smith $    loop over nonlinear iterations
3370be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3371be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3372be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3373be6bf707SBarry Smith $       Solve linear system with Jacobian
3374be6bf707SBarry Smith $    endloop
3375be6bf707SBarry Smith 
3376be6bf707SBarry Smith   Notes:
3377be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3378512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3379be6bf707SBarry Smith     calling this routine.
3380be6bf707SBarry Smith 
33810c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33820c468ba9SBarry Smith     and does not allocated additional space.
33830c468ba9SBarry Smith 
3384be6bf707SBarry Smith .seealso: MatRetrieveValues()
3385be6bf707SBarry Smith 
3386be6bf707SBarry Smith @*/
33877087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3388be6bf707SBarry Smith {
33894ac538c5SBarry Smith   PetscErrorCode ierr;
3390be6bf707SBarry Smith 
3391be6bf707SBarry Smith   PetscFunctionBegin;
33920700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3393e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3394e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33954ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3396be6bf707SBarry Smith   PetscFunctionReturn(0);
3397be6bf707SBarry Smith }
3398be6bf707SBarry Smith 
33994a2ae208SSatish Balay #undef __FUNCT__
34004a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
34017087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3402be6bf707SBarry Smith {
3403be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
34046849ba73SBarry Smith   PetscErrorCode ierr;
3405d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3406be6bf707SBarry Smith 
3407be6bf707SBarry Smith   PetscFunctionBegin;
3408f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3409f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3410be6bf707SBarry Smith   /* copy values over */
341187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3412be6bf707SBarry Smith   PetscFunctionReturn(0);
3413be6bf707SBarry Smith }
3414be6bf707SBarry Smith 
34154a2ae208SSatish Balay #undef __FUNCT__
34164a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3417be6bf707SBarry Smith /*@
3418be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3419be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3420be6bf707SBarry Smith        nonlinear portion.
3421be6bf707SBarry Smith 
3422be6bf707SBarry Smith    Collect on Mat
3423be6bf707SBarry Smith 
3424be6bf707SBarry Smith   Input Parameters:
3425be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3426be6bf707SBarry Smith 
342715091d37SBarry Smith   Level: advanced
342815091d37SBarry Smith 
3429be6bf707SBarry Smith .seealso: MatStoreValues()
3430be6bf707SBarry Smith 
3431be6bf707SBarry Smith @*/
34327087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3433be6bf707SBarry Smith {
34344ac538c5SBarry Smith   PetscErrorCode ierr;
3435be6bf707SBarry Smith 
3436be6bf707SBarry Smith   PetscFunctionBegin;
34370700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3438e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3439e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34404ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3441be6bf707SBarry Smith   PetscFunctionReturn(0);
3442be6bf707SBarry Smith }
3443be6bf707SBarry Smith 
3444f83d6046SBarry Smith 
3445be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34464a2ae208SSatish Balay #undef __FUNCT__
34474a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
344817ab2063SBarry Smith /*@C
3449682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34500d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34516e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
345251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34532bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
345417ab2063SBarry Smith 
3455db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3456db81eaa0SLois Curfman McInnes 
345717ab2063SBarry Smith    Input Parameters:
3458db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
345917ab2063SBarry Smith .  m - number of rows
346017ab2063SBarry Smith .  n - number of columns
346117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
346251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34630298fd71SBarry Smith          (possibly different for each row) or NULL
346417ab2063SBarry Smith 
346517ab2063SBarry Smith    Output Parameter:
3466416022c9SBarry Smith .  A - the matrix
346717ab2063SBarry Smith 
3468175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3469ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3470175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3471175b88e8SBarry Smith 
3472b259b22eSLois Curfman McInnes    Notes:
347349a6f317SBarry Smith    If nnz is given then nz is ignored
347449a6f317SBarry Smith 
347517ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
347617ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34770002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
347844cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
347917ab2063SBarry Smith 
348017ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34810298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34823d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34836da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
348417ab2063SBarry Smith 
3485682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34864fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3487682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34886c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34896c7ebb05SLois Curfman McInnes 
34906c7ebb05SLois Curfman McInnes    Options Database Keys:
3491698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34929db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
349317ab2063SBarry Smith 
3494027ccd11SLois Curfman McInnes    Level: intermediate
3495027ccd11SLois Curfman McInnes 
349669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
349736db0b34SBarry Smith 
349817ab2063SBarry Smith @*/
34997087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
350017ab2063SBarry Smith {
3501dfbe8321SBarry Smith   PetscErrorCode ierr;
35026945ee14SBarry Smith 
35033a40ed3dSBarry Smith   PetscFunctionBegin;
3504f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3505117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3506c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3507d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3508273d9f13SBarry Smith   PetscFunctionReturn(0);
3509273d9f13SBarry Smith }
3510273d9f13SBarry Smith 
35114a2ae208SSatish Balay #undef __FUNCT__
35124a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3513273d9f13SBarry Smith /*@C
3514273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3515273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3516273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3517273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3518273d9f13SBarry Smith 
3519273d9f13SBarry Smith    Collective on MPI_Comm
3520273d9f13SBarry Smith 
3521273d9f13SBarry Smith    Input Parameters:
3522117016b1SBarry Smith +  B - The matrix-free
3523273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3524273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35250298fd71SBarry Smith          (possibly different for each row) or NULL
3526273d9f13SBarry Smith 
3527273d9f13SBarry Smith    Notes:
352849a6f317SBarry Smith      If nnz is given then nz is ignored
352949a6f317SBarry Smith 
3530273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3531273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3532273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3533273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3534273d9f13SBarry Smith 
3535273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35360298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3537273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3538273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3539273d9f13SBarry Smith 
3540aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3541aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3542aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3543aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3544aa95bbe8SBarry Smith 
3545a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3546a96a251dSBarry Smith    entries or columns indices
3547a96a251dSBarry Smith 
3548273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3549273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3550273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3551273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3552273d9f13SBarry Smith 
3553273d9f13SBarry Smith    Options Database Keys:
3554698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3555698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3556273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3557273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3558273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3559273d9f13SBarry Smith 
3560273d9f13SBarry Smith    Level: intermediate
3561273d9f13SBarry Smith 
356269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3563273d9f13SBarry Smith 
3564273d9f13SBarry Smith @*/
35657087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3566273d9f13SBarry Smith {
35674ac538c5SBarry Smith   PetscErrorCode ierr;
3568a23d5eceSKris Buschelman 
3569a23d5eceSKris Buschelman   PetscFunctionBegin;
35706ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35716ba663aaSJed Brown   PetscValidType(B,1);
35724ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3573a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3574a23d5eceSKris Buschelman }
3575a23d5eceSKris Buschelman 
3576a23d5eceSKris Buschelman #undef __FUNCT__
3577a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35787087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3579a23d5eceSKris Buschelman {
3580273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35812576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35826849ba73SBarry Smith   PetscErrorCode ierr;
358397f1f81fSBarry Smith   PetscInt       i;
3584273d9f13SBarry Smith 
3585273d9f13SBarry Smith   PetscFunctionBegin;
35862576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3587a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3588c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3589c461c341SBarry Smith     nz             = 0;
3590c461c341SBarry Smith   }
3591c461c341SBarry Smith 
359226283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
359326283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3594899cda47SBarry Smith 
3595435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
359660e0710aSBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz);
3597b73539f3SBarry Smith   if (nnz) {
3598d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
359960e0710aSBarry 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]);
360060e0710aSBarry 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);
3601b73539f3SBarry Smith     }
3602b73539f3SBarry Smith   }
3603b73539f3SBarry Smith 
3604273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
36052205254eSKarl Rupp 
3606273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3607273d9f13SBarry Smith 
3608ab93d7beSBarry Smith   if (!skipallocation) {
36092ee49352SLisandro Dalcin     if (!b->imax) {
3610dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
36113bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36122ee49352SLisandro Dalcin     }
3613273d9f13SBarry Smith     if (!nnz) {
3614435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3615c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3616d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3617d0f46423SBarry Smith       nz = nz*B->rmap->n;
3618273d9f13SBarry Smith     } else {
3619273d9f13SBarry Smith       nz = 0;
3620d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3621273d9f13SBarry Smith     }
3622ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36232205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3624ab93d7beSBarry Smith 
3625273d9f13SBarry Smith     /* allocate the matrix space */
36262ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3627dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
36283bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3629bfeeae90SHong Zhang     b->i[0] = 0;
3630d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36315da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36325da197adSKris Buschelman     }
3633273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3634e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3635e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3636b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3637b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3638b31eba2aSShri Abhyankar #endif
3639c461c341SBarry Smith   } else {
3640e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3641e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3642c461c341SBarry Smith   }
3643273d9f13SBarry Smith 
3644273d9f13SBarry Smith   b->nz               = 0;
3645273d9f13SBarry Smith   b->maxnz            = nz;
3646273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36472205254eSKarl Rupp   if (realalloc) {
36482205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36492205254eSKarl Rupp   }
3650273d9f13SBarry Smith   PetscFunctionReturn(0);
3651273d9f13SBarry Smith }
3652273d9f13SBarry Smith 
3653a1661176SMatthew Knepley #undef  __FUNCT__
3654a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
365558d36128SBarry Smith /*@
3656a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3657a1661176SMatthew Knepley 
3658a1661176SMatthew Knepley    Input Parameters:
3659a1661176SMatthew Knepley +  B - the matrix
3660a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3661a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3662a1661176SMatthew Knepley -  v - optional values in the matrix
3663a1661176SMatthew Knepley 
3664a1661176SMatthew Knepley    Level: developer
3665a1661176SMatthew Knepley 
366658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
366758d36128SBarry Smith 
3668a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3669a1661176SMatthew Knepley 
3670a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3671a1661176SMatthew Knepley @*/
3672a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3673a1661176SMatthew Knepley {
3674a1661176SMatthew Knepley   PetscErrorCode ierr;
3675a1661176SMatthew Knepley 
3676a1661176SMatthew Knepley   PetscFunctionBegin;
36770700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36786ba663aaSJed Brown   PetscValidType(B,1);
36794ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3680a1661176SMatthew Knepley   PetscFunctionReturn(0);
3681a1661176SMatthew Knepley }
3682a1661176SMatthew Knepley 
3683a1661176SMatthew Knepley #undef  __FUNCT__
3684a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36857087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3686a1661176SMatthew Knepley {
3687a1661176SMatthew Knepley   PetscInt       i;
3688a1661176SMatthew Knepley   PetscInt       m,n;
3689a1661176SMatthew Knepley   PetscInt       nz;
3690a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3691a1661176SMatthew Knepley   PetscScalar    *values;
3692a1661176SMatthew Knepley   PetscErrorCode ierr;
3693a1661176SMatthew Knepley 
3694a1661176SMatthew Knepley   PetscFunctionBegin;
369565e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3696779a8d59SSatish Balay 
3697779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3698779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3699779a8d59SSatish Balay 
3700779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3701785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3702a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3703b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3704a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
370565e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3706a1661176SMatthew Knepley     nnz[i] = nz;
3707a1661176SMatthew Knepley   }
3708a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3709a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3710a1661176SMatthew Knepley 
3711a1661176SMatthew Knepley   if (v) {
3712a1661176SMatthew Knepley     values = (PetscScalar*) v;
3713a1661176SMatthew Knepley   } else {
37141795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3715a1661176SMatthew Knepley   }
3716a1661176SMatthew Knepley 
3717a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3718b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3719b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3720a1661176SMatthew Knepley   }
3721a1661176SMatthew Knepley 
3722a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3723a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3724a1661176SMatthew Knepley 
3725a1661176SMatthew Knepley   if (!v) {
3726a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3727a1661176SMatthew Knepley   }
37287827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3729a1661176SMatthew Knepley   PetscFunctionReturn(0);
3730a1661176SMatthew Knepley }
3731a1661176SMatthew Knepley 
3732c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
373306873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3734170fe5c8SBarry Smith 
3735170fe5c8SBarry Smith #undef __FUNCT__
3736170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3737170fe5c8SBarry Smith /*
3738170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3739170fe5c8SBarry Smith 
3740170fe5c8SBarry Smith                n                       p                          p
3741170fe5c8SBarry Smith         (              )       (              )         (                  )
3742170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3743170fe5c8SBarry Smith         (              )       (              )         (                  )
3744170fe5c8SBarry Smith 
3745170fe5c8SBarry Smith */
3746170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3747170fe5c8SBarry Smith {
3748170fe5c8SBarry Smith   PetscErrorCode    ierr;
3749170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3750170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3751170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37521de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3753170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3754170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3755170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3756170fe5c8SBarry Smith 
3757170fe5c8SBarry Smith   PetscFunctionBegin;
3758d0f46423SBarry Smith   m    = A->rmap->n;
3759d0f46423SBarry Smith   n    = A->cmap->n;
3760d0f46423SBarry Smith   p    = B->cmap->n;
3761170fe5c8SBarry Smith   a    = sub_a->v;
3762170fe5c8SBarry Smith   b    = sub_b->a;
3763170fe5c8SBarry Smith   c    = sub_c->v;
3764170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3765170fe5c8SBarry Smith 
3766170fe5c8SBarry Smith   ii  = sub_b->i;
3767170fe5c8SBarry Smith   idx = sub_b->j;
3768170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3769170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3770170fe5c8SBarry Smith     while (q-->0) {
3771170fe5c8SBarry Smith       c_q = c + m*(*idx);
3772170fe5c8SBarry Smith       a_q = a + m*i;
3773854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3774170fe5c8SBarry Smith       idx++;
3775170fe5c8SBarry Smith       b++;
3776170fe5c8SBarry Smith     }
3777170fe5c8SBarry Smith   }
3778170fe5c8SBarry Smith   PetscFunctionReturn(0);
3779170fe5c8SBarry Smith }
3780170fe5c8SBarry Smith 
3781170fe5c8SBarry Smith #undef __FUNCT__
3782170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3783170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3784170fe5c8SBarry Smith {
3785170fe5c8SBarry Smith   PetscErrorCode ierr;
3786d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3787170fe5c8SBarry Smith   Mat            Cmat;
3788170fe5c8SBarry Smith 
3789170fe5c8SBarry Smith   PetscFunctionBegin;
379060e0710aSBarry 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);
3791ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3792170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3793*33d57670SJed Brown   ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr);
3794170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37950298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3796d73949e8SHong Zhang 
3797d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37982205254eSKarl Rupp 
3799170fe5c8SBarry Smith   *C = Cmat;
3800170fe5c8SBarry Smith   PetscFunctionReturn(0);
3801170fe5c8SBarry Smith }
3802170fe5c8SBarry Smith 
3803170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3804170fe5c8SBarry Smith #undef __FUNCT__
3805170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3806170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3807170fe5c8SBarry Smith {
3808170fe5c8SBarry Smith   PetscErrorCode ierr;
3809170fe5c8SBarry Smith 
3810170fe5c8SBarry Smith   PetscFunctionBegin;
3811170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38123ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3813170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38143ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3815170fe5c8SBarry Smith   }
38163ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3817170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38183ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3819170fe5c8SBarry Smith   PetscFunctionReturn(0);
3820170fe5c8SBarry Smith }
3821170fe5c8SBarry Smith 
3822170fe5c8SBarry Smith 
38230bad9183SKris Buschelman /*MC
3824fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38250bad9183SKris Buschelman    based on compressed sparse row format.
38260bad9183SKris Buschelman 
38270bad9183SKris Buschelman    Options Database Keys:
38280bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38290bad9183SKris Buschelman 
38300bad9183SKris Buschelman   Level: beginner
38310bad9183SKris Buschelman 
3832f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38330bad9183SKris Buschelman M*/
38340bad9183SKris Buschelman 
3835ccd284c7SBarry Smith /*MC
3836ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3837ccd284c7SBarry Smith 
3838ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3839ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3840ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3841ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3842ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3843ccd284c7SBarry Smith 
3844ccd284c7SBarry Smith    Options Database Keys:
3845ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3846ccd284c7SBarry Smith 
3847ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3848ccd284c7SBarry Smith    enough exist.
3849ccd284c7SBarry Smith 
3850ccd284c7SBarry Smith   Level: beginner
3851ccd284c7SBarry Smith 
3852ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3853ccd284c7SBarry Smith M*/
3854ccd284c7SBarry Smith 
3855ccd284c7SBarry Smith /*MC
3856ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3857ccd284c7SBarry Smith 
3858ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3859ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3860ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3861ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3862ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3863ccd284c7SBarry Smith 
3864ccd284c7SBarry Smith    Options Database Keys:
3865ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3866ccd284c7SBarry Smith 
3867ccd284c7SBarry Smith   Level: beginner
3868ccd284c7SBarry Smith 
3869ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3870ccd284c7SBarry Smith M*/
3871ccd284c7SBarry Smith 
3872b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3874b5e56a35SBarry Smith #endif
3875ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3877af1023dbSSatish Balay #endif
38788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38817087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3882611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38838cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3884611f576cSBarry Smith #endif
3885611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3887611f576cSBarry Smith #endif
3888f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38898cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3890f3c0ef26SHong Zhang #endif
3891eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38928cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3893eb3b5408SSatish Balay #endif
3894586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3896586621ddSJed Brown #endif
3897719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3899719d5645SBarry Smith #endif
3900b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
39018cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
39027087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
39037087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3904b3866ffcSBarry Smith #endif
390517f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
39068cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
390717f1a0eaSHong Zhang #endif
390817667f90SBarry Smith 
3909c0c8ee5eSDmitry Karpeev 
39108c778c55SBarry Smith #undef __FUNCT__
39118c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39128c778c55SBarry Smith /*@C
39138c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39148c778c55SBarry Smith 
39158c778c55SBarry Smith    Not Collective
39168c778c55SBarry Smith 
39178c778c55SBarry Smith    Input Parameter:
39188c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39198c778c55SBarry Smith 
39208c778c55SBarry Smith    Output Parameter:
39218c778c55SBarry Smith .   array - pointer to the data
39228c778c55SBarry Smith 
39238c778c55SBarry Smith    Level: intermediate
39248c778c55SBarry Smith 
3925774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39268c778c55SBarry Smith @*/
39278c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39288c778c55SBarry Smith {
39298c778c55SBarry Smith   PetscErrorCode ierr;
39308c778c55SBarry Smith 
39318c778c55SBarry Smith   PetscFunctionBegin;
39328c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39338c778c55SBarry Smith   PetscFunctionReturn(0);
39348c778c55SBarry Smith }
39358c778c55SBarry Smith 
39368c778c55SBarry Smith #undef __FUNCT__
39378c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39388c778c55SBarry Smith /*@C
39398c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39408c778c55SBarry Smith 
39418c778c55SBarry Smith    Not Collective
39428c778c55SBarry Smith 
39438c778c55SBarry Smith    Input Parameters:
39448c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39458c778c55SBarry Smith .  array - pointer to the data
39468c778c55SBarry Smith 
39478c778c55SBarry Smith    Level: intermediate
39488c778c55SBarry Smith 
3949774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39508c778c55SBarry Smith @*/
39518c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39528c778c55SBarry Smith {
39538c778c55SBarry Smith   PetscErrorCode ierr;
39548c778c55SBarry Smith 
39558c778c55SBarry Smith   PetscFunctionBegin;
39568c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39578c778c55SBarry Smith   PetscFunctionReturn(0);
39588c778c55SBarry Smith }
39598c778c55SBarry Smith 
39604a2ae208SSatish Balay #undef __FUNCT__
39614a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39628cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3963273d9f13SBarry Smith {
3964273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3965dfbe8321SBarry Smith   PetscErrorCode ierr;
396638baddfdSBarry Smith   PetscMPIInt    size;
3967273d9f13SBarry Smith 
3968273d9f13SBarry Smith   PetscFunctionBegin;
3969ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3970e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3971273d9f13SBarry Smith 
3972b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39732205254eSKarl Rupp 
3974b0a32e0cSBarry Smith   B->data = (void*)b;
39752205254eSKarl Rupp 
3976549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39772205254eSKarl Rupp 
3978416022c9SBarry Smith   b->row                = 0;
3979416022c9SBarry Smith   b->col                = 0;
398082bf6240SBarry Smith   b->icol               = 0;
3981b810aeb4SBarry Smith   b->reallocs           = 0;
398236db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3983f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3984416022c9SBarry Smith   b->nonew              = 0;
3985416022c9SBarry Smith   b->diag               = 0;
3986416022c9SBarry Smith   b->solve_work         = 0;
39872a1b7f2aSHong Zhang   B->spptr              = 0;
3988be6bf707SBarry Smith   b->saved_values       = 0;
3989d7f994e1SBarry Smith   b->idiag              = 0;
399071f1c65dSBarry Smith   b->mdiag              = 0;
399171f1c65dSBarry Smith   b->ssor_work          = 0;
399271f1c65dSBarry Smith   b->omega              = 1.0;
399371f1c65dSBarry Smith   b->fshift             = 0.0;
399471f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3995bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3996a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3997a30b2313SHong Zhang   b->xtoy               = 0;
3998a30b2313SHong Zhang   b->XtoY               = 0;
399988e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
400017ab2063SBarry Smith 
400135d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4002bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4003bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
40048c778c55SBarry Smith 
4005b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4006bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4007bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4008bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4009b3866ffcSBarry Smith #endif
4010b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4011bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4012b5e56a35SBarry Smith #endif
4013ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4014bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4015719d5645SBarry Smith #endif
4016611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4017bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4018611f576cSBarry Smith #endif
4019f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4020bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4021f3c0ef26SHong Zhang #endif
4022611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4023bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4024611f576cSBarry Smith #endif
4025eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4026bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4027eb3b5408SSatish Balay #endif
4028586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4030586621ddSJed Brown #endif
4031719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4033719d5645SBarry Smith #endif
403417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
403617f1a0eaSHong Zhang #endif
403717f1a0eaSHong Zhang 
4038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4043bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4044bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40564108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
405717667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40583a40ed3dSBarry Smith   PetscFunctionReturn(0);
405917ab2063SBarry Smith }
406017ab2063SBarry Smith 
40614a2ae208SSatish Balay #undef __FUNCT__
4062b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4063b24902e0SBarry Smith /*
4064b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4065b24902e0SBarry Smith */
4066ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
406717ab2063SBarry Smith {
4068416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40696849ba73SBarry Smith   PetscErrorCode ierr;
4070d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
407117ab2063SBarry Smith 
40723a40ed3dSBarry Smith   PetscFunctionBegin;
4073273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4074273d9f13SBarry Smith 
4075d5f3da31SBarry Smith   C->factortype = A->factortype;
4076416022c9SBarry Smith   c->row        = 0;
4077416022c9SBarry Smith   c->col        = 0;
407882bf6240SBarry Smith   c->icol       = 0;
40796ad4291fSHong Zhang   c->reallocs   = 0;
408017ab2063SBarry Smith 
40816ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
408217ab2063SBarry Smith 
4083aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4084aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4085eec197d1SBarry Smith 
4086dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40873bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
408817ab2063SBarry Smith   for (i=0; i<m; i++) {
4089416022c9SBarry Smith     c->imax[i] = a->imax[i];
4090416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
409117ab2063SBarry Smith   }
409217ab2063SBarry Smith 
409317ab2063SBarry Smith   /* allocate the matrix space */
4094f77e22a1SHong Zhang   if (mallocmatspace) {
4095dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40963bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40972205254eSKarl Rupp 
4098f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40992205254eSKarl Rupp 
410097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
410117ab2063SBarry Smith     if (m > 0) {
410297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4103be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4104bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4105be6bf707SBarry Smith       } else {
4106bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
410717ab2063SBarry Smith       }
410808480c60SBarry Smith     }
4109f77e22a1SHong Zhang   }
411017ab2063SBarry Smith 
41116ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4112416022c9SBarry Smith   c->roworiented       = a->roworiented;
4113416022c9SBarry Smith   c->nonew             = a->nonew;
4114416022c9SBarry Smith   if (a->diag) {
4115785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
41163bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
411717ab2063SBarry Smith     for (i=0; i<m; i++) {
4118416022c9SBarry Smith       c->diag[i] = a->diag[i];
411917ab2063SBarry Smith     }
41203a40ed3dSBarry Smith   } else c->diag = 0;
41212205254eSKarl Rupp 
41226ad4291fSHong Zhang   c->solve_work         = 0;
41236ad4291fSHong Zhang   c->saved_values       = 0;
41246ad4291fSHong Zhang   c->idiag              = 0;
412571f1c65dSBarry Smith   c->ssor_work          = 0;
4126a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4127e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4128e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41296ad4291fSHong Zhang   c->xtoy               = 0;
41306ad4291fSHong Zhang   c->XtoY               = 0;
41316ad4291fSHong Zhang 
4132893ad86cSHong Zhang   c->rmax         = a->rmax;
4133416022c9SBarry Smith   c->nz           = a->nz;
41348ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4135273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4136754ec7b1SSatish Balay 
41376ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41386ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4139cd6b891eSBarry Smith   if (a->compressedrow.use) {
41406ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4141dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
41426ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41436ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
414427ea64f8SHong Zhang   } else {
414527ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41460298fd71SBarry Smith     c->compressedrow.i      = NULL;
41470298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41486ad4291fSHong Zhang   }
414988e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41504846f1f5SKris Buschelman 
41512205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4152140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41533a40ed3dSBarry Smith   PetscFunctionReturn(0);
415417ab2063SBarry Smith }
415517ab2063SBarry Smith 
41564a2ae208SSatish Balay #undef __FUNCT__
4157b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4158b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4159b24902e0SBarry Smith {
4160b24902e0SBarry Smith   PetscErrorCode ierr;
4161b24902e0SBarry Smith 
4162b24902e0SBarry Smith   PetscFunctionBegin;
4163ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41644b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4165cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
4166*33d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4167cfd3f464SBarry Smith   }
4168a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4169f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4170b24902e0SBarry Smith   PetscFunctionReturn(0);
4171b24902e0SBarry Smith }
4172b24902e0SBarry Smith 
4173b24902e0SBarry Smith #undef __FUNCT__
41744a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4175112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4176fbdbba38SShri Abhyankar {
4177fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4178fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4179fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4180fbdbba38SShri Abhyankar   int            fd;
4181fbdbba38SShri Abhyankar   PetscMPIInt    size;
4182fbdbba38SShri Abhyankar   MPI_Comm       comm;
4183bbead8a2SBarry Smith   PetscInt       bs = 1;
4184fbdbba38SShri Abhyankar 
4185fbdbba38SShri Abhyankar   PetscFunctionBegin;
4186fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4187fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4188fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4189bbead8a2SBarry Smith 
41900298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41910298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4192bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41931814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4194bbead8a2SBarry Smith 
4195fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4196fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4197fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4198fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4199fbdbba38SShri Abhyankar 
4200bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4201fbdbba38SShri Abhyankar 
4202fbdbba38SShri Abhyankar   /* read in row lengths */
4203785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4204fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4205fbdbba38SShri Abhyankar 
4206fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4207fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
420860e0710aSBarry Smith   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %dD, sum-row-lengths = %D\n",nz,sum);
4209fbdbba38SShri Abhyankar 
4210fbdbba38SShri Abhyankar   /* set global size if not set already*/
4211f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4212fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4213aabbc4fbSShri Abhyankar   } else {
4214fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4215fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42164c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42174c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42184c5b953cSHong Zhang     }
421960e0710aSBarry Smith     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);
4220aabbc4fbSShri Abhyankar   }
4221fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4222fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4223fbdbba38SShri Abhyankar 
4224fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4225fbdbba38SShri Abhyankar 
4226fbdbba38SShri Abhyankar   /* read in nonzero values */
4227fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4228fbdbba38SShri Abhyankar 
4229fbdbba38SShri Abhyankar   /* set matrix "i" values */
4230fbdbba38SShri Abhyankar   a->i[0] = 0;
4231fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4232fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4233fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4234fbdbba38SShri Abhyankar   }
4235fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4236fbdbba38SShri Abhyankar 
4237fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4238fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4239fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4240fbdbba38SShri Abhyankar }
4241fbdbba38SShri Abhyankar 
4242fbdbba38SShri Abhyankar #undef __FUNCT__
4243b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4244ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42457264ac53SSatish Balay {
42467264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4247dfbe8321SBarry Smith   PetscErrorCode ierr;
4248eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4249eeffb40dSHong Zhang   PetscInt k;
4250eeffb40dSHong Zhang #endif
42517264ac53SSatish Balay 
42523a40ed3dSBarry Smith   PetscFunctionBegin;
4253bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4254d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4255ca44d042SBarry Smith     *flg = PETSC_FALSE;
4256ca44d042SBarry Smith     PetscFunctionReturn(0);
4257bcd2baecSBarry Smith   }
42587264ac53SSatish Balay 
42597264ac53SSatish Balay   /* if the a->i are the same */
4260d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4261abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42627264ac53SSatish Balay 
42637264ac53SSatish Balay   /* if a->j are the same */
426497f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4265abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4266bcd2baecSBarry Smith 
4267bcd2baecSBarry Smith   /* if a->a are the same */
4268eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4269eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4270eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4271eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42723a40ed3dSBarry Smith       PetscFunctionReturn(0);
4273eeffb40dSHong Zhang     }
4274eeffb40dSHong Zhang   }
4275eeffb40dSHong Zhang #else
4276eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4277eeffb40dSHong Zhang #endif
4278eeffb40dSHong Zhang   PetscFunctionReturn(0);
42797264ac53SSatish Balay }
428036db0b34SBarry Smith 
42814a2ae208SSatish Balay #undef __FUNCT__
42824a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
428305869f15SSatish Balay /*@
428436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
428536db0b34SBarry Smith               provided by the user.
428636db0b34SBarry Smith 
4287c75a6043SHong Zhang       Collective on MPI_Comm
428836db0b34SBarry Smith 
428936db0b34SBarry Smith    Input Parameters:
429036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
429136db0b34SBarry Smith .   m - number of rows
429236db0b34SBarry Smith .   n - number of columns
429336db0b34SBarry Smith .   i - row indices
429436db0b34SBarry Smith .   j - column indices
429536db0b34SBarry Smith -   a - matrix values
429636db0b34SBarry Smith 
429736db0b34SBarry Smith    Output Parameter:
429836db0b34SBarry Smith .   mat - the matrix
429936db0b34SBarry Smith 
430036db0b34SBarry Smith    Level: intermediate
430136db0b34SBarry Smith 
430236db0b34SBarry Smith    Notes:
43030551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4304292fb18eSBarry Smith     once the matrix is destroyed and not before
430536db0b34SBarry Smith 
430636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
430736db0b34SBarry Smith 
4308bfeeae90SHong Zhang        The i and j indices are 0 based
430936db0b34SBarry Smith 
4310a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4311a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4312a4552177SSatish Balay     as shown:
4313a4552177SSatish Balay 
4314a4552177SSatish Balay         1 0 0
4315a4552177SSatish Balay         2 0 3
4316a4552177SSatish Balay         4 5 6
4317a4552177SSatish Balay 
4318a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43199985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4320a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4321a4552177SSatish Balay 
43229985e31cSBarry Smith 
432369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
432436db0b34SBarry Smith 
432536db0b34SBarry Smith @*/
43267087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
432736db0b34SBarry Smith {
4328dfbe8321SBarry Smith   PetscErrorCode ierr;
4329cbcfb4deSHong Zhang   PetscInt       ii;
433036db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4331cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4332cbcfb4deSHong Zhang   PetscInt jj;
4333cbcfb4deSHong Zhang #endif
433436db0b34SBarry Smith 
433536db0b34SBarry Smith   PetscFunctionBegin;
4336f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4337f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4338f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4339a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4340ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4341ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4342ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4343dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4344ab93d7beSBarry Smith 
434536db0b34SBarry Smith   aij->i            = i;
434636db0b34SBarry Smith   aij->j            = j;
434736db0b34SBarry Smith   aij->a            = a;
434836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
434936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4350e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4351e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
435236db0b34SBarry Smith 
435336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
435436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43552515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
435660e0710aSBarry 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]);
43579985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4358e32f2f54SBarry 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);
4359e32f2f54SBarry 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);
43609985e31cSBarry Smith     }
436136db0b34SBarry Smith #endif
436236db0b34SBarry Smith   }
43632515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
436436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
436560e0710aSBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]);
436660e0710aSBarry 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]);
436736db0b34SBarry Smith   }
436836db0b34SBarry Smith #endif
436936db0b34SBarry Smith 
4370b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4371b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
437236db0b34SBarry Smith   PetscFunctionReturn(0);
437336db0b34SBarry Smith }
43748a0b0e6bSVictor Minden #undef __FUNCT__
43758a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
437680ef6e79SMatthew G Knepley /*@C
4377d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43788a0b0e6bSVictor Minden               provided by the user.
43798a0b0e6bSVictor Minden 
43808a0b0e6bSVictor Minden       Collective on MPI_Comm
43818a0b0e6bSVictor Minden 
43828a0b0e6bSVictor Minden    Input Parameters:
43838a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43848a0b0e6bSVictor Minden .   m   - number of rows
43858a0b0e6bSVictor Minden .   n   - number of columns
43868a0b0e6bSVictor Minden .   i   - row indices
43878a0b0e6bSVictor Minden .   j   - column indices
43881230e6d1SVictor Minden .   a   - matrix values
43891230e6d1SVictor Minden .   nz  - number of nonzeros
43901230e6d1SVictor Minden -   idx - 0 or 1 based
43918a0b0e6bSVictor Minden 
43928a0b0e6bSVictor Minden    Output Parameter:
43938a0b0e6bSVictor Minden .   mat - the matrix
43948a0b0e6bSVictor Minden 
43958a0b0e6bSVictor Minden    Level: intermediate
43968a0b0e6bSVictor Minden 
43978a0b0e6bSVictor Minden    Notes:
43988a0b0e6bSVictor Minden        The i and j indices are 0 based
43998a0b0e6bSVictor Minden 
44008a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
44018a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
44028a0b0e6bSVictor Minden     as shown:
44038a0b0e6bSVictor Minden 
44048a0b0e6bSVictor Minden         1 0 0
44058a0b0e6bSVictor Minden         2 0 3
44068a0b0e6bSVictor Minden         4 5 6
44078a0b0e6bSVictor Minden 
44088a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
44098a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
44108a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44118a0b0e6bSVictor Minden 
44128a0b0e6bSVictor Minden 
441369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44148a0b0e6bSVictor Minden 
44158a0b0e6bSVictor Minden @*/
44161230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44178a0b0e6bSVictor Minden {
44188a0b0e6bSVictor Minden   PetscErrorCode ierr;
4419d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44208a0b0e6bSVictor Minden 
44218a0b0e6bSVictor Minden 
44228a0b0e6bSVictor Minden   PetscFunctionBegin;
44231795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
44241230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4425c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
44261230e6d1SVictor Minden   }
44278a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44288a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
44298a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44301230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44311230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44321230e6d1SVictor Minden     if (idx) {
44331230e6d1SVictor Minden       row = i[ii] - 1;
44341230e6d1SVictor Minden       col = j[ii] - 1;
44351230e6d1SVictor Minden     } else {
44361230e6d1SVictor Minden       row = i[ii];
44371230e6d1SVictor Minden       col = j[ii];
44388a0b0e6bSVictor Minden     }
44391230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44408a0b0e6bSVictor Minden   }
44418a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44428a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4443d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44448a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44458a0b0e6bSVictor Minden }
444636db0b34SBarry Smith 
4447cc8ba8e1SBarry Smith #undef __FUNCT__
4448ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4449dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4450cc8ba8e1SBarry Smith {
4451dfbe8321SBarry Smith   PetscErrorCode ierr;
4452cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
445336db0b34SBarry Smith 
4454cc8ba8e1SBarry Smith   PetscFunctionBegin;
44558ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4456cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4457cc8ba8e1SBarry Smith     a->coloring = coloring;
445812c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
445997f1f81fSBarry Smith     PetscInt        i,*larray;
446012c595b3SBarry Smith     ISColoring      ocoloring;
446108b6dcc0SBarry Smith     ISColoringValue *colors;
446212c595b3SBarry Smith 
446312c595b3SBarry Smith     /* set coloring for diagonal portion */
4464785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
44652205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44660298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4467785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
44682205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
446912c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4470d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
447112c595b3SBarry Smith     a->coloring = ocoloring;
447212c595b3SBarry Smith   }
4473cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4474cc8ba8e1SBarry Smith }
4475cc8ba8e1SBarry Smith 
4476ee4f033dSBarry Smith #undef __FUNCT__
4477ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
447897f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4479ee4f033dSBarry Smith {
4480ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4481d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
448254f21887SBarry Smith   MatScalar       *v      = a->a;
448354f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
448408b6dcc0SBarry Smith   ISColoringValue *color;
4485ee4f033dSBarry Smith 
4486ee4f033dSBarry Smith   PetscFunctionBegin;
4487e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4488ee4f033dSBarry Smith   color = a->coloring->colors;
4489ee4f033dSBarry Smith   /* loop over rows */
4490ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4491ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4492ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44932205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4494ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4495cc8ba8e1SBarry Smith   }
4496cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4497cc8ba8e1SBarry Smith }
449836db0b34SBarry Smith 
4499acf2f550SJed Brown #undef __FUNCT__
4500acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4501acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4502acf2f550SJed Brown {
4503acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4504acf2f550SJed Brown   PetscErrorCode ierr;
4505acf2f550SJed Brown 
4506acf2f550SJed Brown   PetscFunctionBegin;
4507acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4508acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45092205254eSKarl Rupp 
4510acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4511acf2f550SJed Brown   PetscFunctionReturn(0);
4512acf2f550SJed Brown }
4513acf2f550SJed Brown 
451481824310SBarry Smith /*
451581824310SBarry Smith     Special version for direct calls from Fortran
451681824310SBarry Smith */
4517b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
451881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
451981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
452081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
452181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
452281824310SBarry Smith #endif
452381824310SBarry Smith 
452481824310SBarry Smith /* Change these macros so can be used in void function */
452581824310SBarry Smith #undef CHKERRQ
4526ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
452781824310SBarry Smith #undef SETERRQ2
4528e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45294994cf47SJed Brown #undef SETERRQ3
45304994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
453181824310SBarry Smith 
453281824310SBarry Smith #undef __FUNCT__
453381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45348cc058d9SJed 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)
453581824310SBarry Smith {
453681824310SBarry Smith   Mat            A  = *AA;
453781824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
453881824310SBarry Smith   InsertMode     is = *isis;
453981824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
454081824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
454181824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
454281824310SBarry Smith   PetscErrorCode ierr;
454381824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
454454f21887SBarry Smith   MatScalar      *ap,value,*aa;
4545ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4546ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
454781824310SBarry Smith 
454881824310SBarry Smith   PetscFunctionBegin;
45494994cf47SJed Brown   MatCheckPreallocated(A,1);
455081824310SBarry Smith   imax  = a->imax;
455181824310SBarry Smith   ai    = a->i;
455281824310SBarry Smith   ailen = a->ilen;
455381824310SBarry Smith   aj    = a->j;
455481824310SBarry Smith   aa    = a->a;
455581824310SBarry Smith 
455681824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
455781824310SBarry Smith     row = im[k];
455881824310SBarry Smith     if (row < 0) continue;
455981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4560ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
456181824310SBarry Smith #endif
456281824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
456381824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
456481824310SBarry Smith     low  = 0;
456581824310SBarry Smith     high = nrow;
456681824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
456781824310SBarry Smith       if (in[l] < 0) continue;
456881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4569ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
457081824310SBarry Smith #endif
457181824310SBarry Smith       col = in[l];
45722205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45732205254eSKarl Rupp       else value = v[k + l*m];
45742205254eSKarl Rupp 
457581824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
457681824310SBarry Smith 
45772205254eSKarl Rupp       if (col <= lastcol) low = 0;
45782205254eSKarl Rupp       else high = nrow;
457981824310SBarry Smith       lastcol = col;
458081824310SBarry Smith       while (high-low > 5) {
458181824310SBarry Smith         t = (low+high)/2;
458281824310SBarry Smith         if (rp[t] > col) high = t;
458381824310SBarry Smith         else             low  = t;
458481824310SBarry Smith       }
458581824310SBarry Smith       for (i=low; i<high; i++) {
458681824310SBarry Smith         if (rp[i] > col) break;
458781824310SBarry Smith         if (rp[i] == col) {
458881824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
458981824310SBarry Smith           else                  ap[i] = value;
459081824310SBarry Smith           goto noinsert;
459181824310SBarry Smith         }
459281824310SBarry Smith       }
459381824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
459481824310SBarry Smith       if (nonew == 1) goto noinsert;
4595ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4596fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
459781824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
459881824310SBarry Smith       /* shift up all the later entries in this row */
459981824310SBarry Smith       for (ii=N; ii>=i; ii--) {
460081824310SBarry Smith         rp[ii+1] = rp[ii];
460181824310SBarry Smith         ap[ii+1] = ap[ii];
460281824310SBarry Smith       }
460381824310SBarry Smith       rp[i] = col;
460481824310SBarry Smith       ap[i] = value;
460581824310SBarry Smith noinsert:;
460681824310SBarry Smith       low = i + 1;
460781824310SBarry Smith     }
460881824310SBarry Smith     ailen[row] = nrow;
460981824310SBarry Smith   }
461081824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
461181824310SBarry Smith   PetscFunctionReturnVoid();
461281824310SBarry Smith }
46139f7953f8SBarry Smith 
461462298a1eSBarry Smith 
4615