xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 1795a4d16c893ec2fc06bbbc6c5ce592a2de75d4)
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 {
236*1795a4d1SJed 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 
296*1795a4d1SJed 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       }
389abc0a331SBarry 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) {
505b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)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;
518d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
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;
526014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
527d00d2cf4SBarry Smith       nofinalvalue = 1;
528d00d2cf4SBarry Smith     }
529d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
530d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
53177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
53277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
533b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
53417ab2063SBarry Smith 
53517ab2063SBarry Smith     for (i=0; i<m; i++) {
536416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
537aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
53877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
53917ab2063SBarry Smith #else
54077431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
54117ab2063SBarry Smith #endif
54217ab2063SBarry Smith       }
54317ab2063SBarry Smith     }
544d00d2cf4SBarry Smith     if (nofinalvalue) {
545d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
546d00d2cf4SBarry Smith     }
547317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
548fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
549d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
55068369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
551cd155464SBarry Smith     PetscFunctionReturn(0);
552fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
553d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
554dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
55544cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
55677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
55744cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
558aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
55936db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
560ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56136db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
562ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
56336db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
564ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5656831982aSBarry Smith         }
56644cd7ae7SLois Curfman McInnes #else
567ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
56844cd7ae7SLois Curfman McInnes #endif
56944cd7ae7SLois Curfman McInnes       }
570b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
57144cd7ae7SLois Curfman McInnes     }
572d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
573fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
57497f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
575d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
576dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
577785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
578496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
579496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
580496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
581496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
582aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
584496be53dSLois Curfman McInnes #else
585496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
586496be53dSLois Curfman McInnes #endif
587496be53dSLois Curfman McInnes         }
588496be53dSLois Curfman McInnes       }
589496be53dSLois Curfman McInnes     }
5902e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
59177431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
5922e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
5932205254eSKarl Rupp       if (i+4<m) {
5942205254eSKarl 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);
5952205254eSKarl Rupp       } else if (i+3<m) {
5962205254eSKarl 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);
5972205254eSKarl Rupp       } else if (i+2<m) {
5982205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
5992205254eSKarl Rupp       } else if (i+1<m) {
6002205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6012205254eSKarl Rupp       } else if (i<m) {
6022205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6032205254eSKarl Rupp       } else {
6042205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6052205254eSKarl Rupp       }
606496be53dSLois Curfman McInnes     }
607b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
608606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
609496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
610496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
61177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
612496be53dSLois Curfman McInnes       }
613b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
614496be53dSLois Curfman McInnes     }
615b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
616496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
617496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
618496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
619aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
62036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
621b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6226831982aSBarry Smith           }
623496be53dSLois Curfman McInnes #else
624b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
625496be53dSLois Curfman McInnes #endif
626496be53dSLois Curfman McInnes         }
627496be53dSLois Curfman McInnes       }
628b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
629496be53dSLois Curfman McInnes     }
630d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
631fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
63297f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
63387828ca2SBarry Smith     PetscScalar value;
63402594712SBarry Smith 
635d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
636dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
63702594712SBarry Smith     for (i=0; i<m; i++) {
63802594712SBarry Smith       jcnt = 0;
639d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
640e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
64102594712SBarry Smith           value = a->a[cnt++];
642e24b481bSBarry Smith           jcnt++;
64302594712SBarry Smith         } else {
64402594712SBarry Smith           value = 0.0;
64502594712SBarry Smith         }
646aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
647b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
64802594712SBarry Smith #else
649b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
65002594712SBarry Smith #endif
65102594712SBarry Smith       }
652b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65302594712SBarry Smith     }
654d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6553c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
656d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
657dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
6583c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6593c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6603c215bfdSMatthew Knepley #else
6613c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6623c215bfdSMatthew Knepley #endif
663d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6643c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
6653c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
6663c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6673c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
668ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6693c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
670ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6713c215bfdSMatthew Knepley         } else {
672ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6733c215bfdSMatthew Knepley         }
6743c215bfdSMatthew Knepley #else
675ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr);
6763c215bfdSMatthew Knepley #endif
6773c215bfdSMatthew Knepley       }
6783c215bfdSMatthew Knepley     }
679d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6803a40ed3dSBarry Smith   } else {
681d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
682dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
683d5f3da31SBarry Smith     if (A->factortype) {
68416cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
68516cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
68616cd7e1dSShri Abhyankar         /* L part */
68716cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
68816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
68916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
690ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
692ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
69316cd7e1dSShri Abhyankar           } else {
694ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
69516cd7e1dSShri Abhyankar           }
69616cd7e1dSShri Abhyankar #else
697ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
69816cd7e1dSShri Abhyankar #endif
69916cd7e1dSShri Abhyankar         }
70016cd7e1dSShri Abhyankar         /* diagonal */
70116cd7e1dSShri Abhyankar         j = a->diag[i];
70216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
70316cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
704ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
70516cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
706ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
70716cd7e1dSShri Abhyankar         } else {
708ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
70916cd7e1dSShri Abhyankar         }
71016cd7e1dSShri Abhyankar #else
711ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
71216cd7e1dSShri Abhyankar #endif
71316cd7e1dSShri Abhyankar 
71416cd7e1dSShri Abhyankar         /* U part */
71516cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
71616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
71716cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
718ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
71916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
720ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72116cd7e1dSShri Abhyankar           } else {
722ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
72316cd7e1dSShri Abhyankar           }
72416cd7e1dSShri Abhyankar #else
725ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
72616cd7e1dSShri Abhyankar #endif
72716cd7e1dSShri Abhyankar         }
72816cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
72916cd7e1dSShri Abhyankar       }
73016cd7e1dSShri Abhyankar     } else {
73117ab2063SBarry Smith       for (i=0; i<m; i++) {
73277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
733416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
734aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
736ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73736db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
738ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7393a40ed3dSBarry Smith           } else {
740ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
74117ab2063SBarry Smith           }
74217ab2063SBarry Smith #else
743ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
74417ab2063SBarry Smith #endif
74517ab2063SBarry Smith         }
746b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74717ab2063SBarry Smith       }
74816cd7e1dSShri Abhyankar     }
749d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
75017ab2063SBarry Smith   }
751b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7523a40ed3dSBarry Smith   PetscFunctionReturn(0);
753416022c9SBarry Smith }
754416022c9SBarry Smith 
7559804daf3SBarry Smith #include <petscdraw.h>
7564a2ae208SSatish Balay #undef __FUNCT__
7574a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
758dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
759416022c9SBarry Smith {
760480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
761416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
762dfbe8321SBarry Smith   PetscErrorCode    ierr;
763d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
76436db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
765b0a32e0cSBarry Smith   PetscViewer       viewer;
766f3ef73ceSBarry Smith   PetscViewerFormat format;
767cddf8d76SBarry Smith 
7683a40ed3dSBarry Smith   PetscFunctionBegin;
769480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
770b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
77119bcc07fSBarry Smith 
772b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
773416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7740513a670SBarry Smith 
775fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7760513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
777b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
778416022c9SBarry Smith     for (i=0; i<m; i++) {
779cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
780bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
781bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
78236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
783b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
784cddf8d76SBarry Smith       }
785cddf8d76SBarry Smith     }
786b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
787cddf8d76SBarry Smith     for (i=0; i<m; i++) {
788cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
789bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
790bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
791cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
792b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
793cddf8d76SBarry Smith       }
794cddf8d76SBarry Smith     }
795b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
796cddf8d76SBarry Smith     for (i=0; i<m; i++) {
797cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
798bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
799bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
80036db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
801b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
802416022c9SBarry Smith       }
803416022c9SBarry Smith     }
8040513a670SBarry Smith   } else {
8050513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8060513a670SBarry Smith     /* first determine max of all nonzero values */
80797f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
808b0a32e0cSBarry Smith     PetscDraw popup;
80936db0b34SBarry Smith     PetscReal scale;
8100513a670SBarry Smith 
8110513a670SBarry Smith     for (i=0; i<nz; i++) {
8120513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8130513a670SBarry Smith     }
814b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
815b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8162205254eSKarl Rupp     if (popup) {
8172205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8182205254eSKarl Rupp     }
8190513a670SBarry Smith     count = 0;
8200513a670SBarry Smith     for (i=0; i<m; i++) {
8210513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
822bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
823bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
82497f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
825b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8260513a670SBarry Smith         count++;
8270513a670SBarry Smith       }
8280513a670SBarry Smith     }
8290513a670SBarry Smith   }
830480ef9eaSBarry Smith   PetscFunctionReturn(0);
831480ef9eaSBarry Smith }
832cddf8d76SBarry Smith 
8339804daf3SBarry Smith #include <petscdraw.h>
8344a2ae208SSatish Balay #undef __FUNCT__
8354a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
836dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
837480ef9eaSBarry Smith {
838dfbe8321SBarry Smith   PetscErrorCode ierr;
839b0a32e0cSBarry Smith   PetscDraw      draw;
84036db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
841ace3abfcSBarry Smith   PetscBool      isnull;
842480ef9eaSBarry Smith 
843480ef9eaSBarry Smith   PetscFunctionBegin;
844b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
845b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
846480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
847480ef9eaSBarry Smith 
848480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
849d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
850480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
851b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
852b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8530298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8543a40ed3dSBarry Smith   PetscFunctionReturn(0);
855416022c9SBarry Smith }
856416022c9SBarry Smith 
8574a2ae208SSatish Balay #undef __FUNCT__
8584a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
859dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
860416022c9SBarry Smith {
861dfbe8321SBarry Smith   PetscErrorCode ierr;
862ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
863416022c9SBarry Smith 
8643a40ed3dSBarry Smith   PetscFunctionBegin;
865251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
866251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
867251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
868c45a1595SBarry Smith   if (iascii) {
8693a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8700f5bd95cSBarry Smith   } else if (isbinary) {
8713a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8720f5bd95cSBarry Smith   } else if (isdraw) {
8733a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
87411aeaf0aSBarry Smith   }
8754108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8763a40ed3dSBarry Smith   PetscFunctionReturn(0);
87717ab2063SBarry Smith }
87819bcc07fSBarry Smith 
8794a2ae208SSatish Balay #undef __FUNCT__
8804a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
881dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
88217ab2063SBarry Smith {
883416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8846849ba73SBarry Smith   PetscErrorCode ierr;
88597f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
886d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
88754f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
8883447b6efSHong Zhang   PetscReal      ratio  = 0.6;
88917ab2063SBarry Smith 
8903a40ed3dSBarry Smith   PetscFunctionBegin;
8913a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
89217ab2063SBarry Smith 
89343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
89417ab2063SBarry Smith   for (i=1; i<m; i++) {
895416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
89617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
89794a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
89817ab2063SBarry Smith     if (fshift) {
899bfeeae90SHong Zhang       ip = aj + ai[i];
900bfeeae90SHong Zhang       ap = aa + ai[i];
90117ab2063SBarry Smith       N  = ailen[i];
90217ab2063SBarry Smith       for (j=0; j<N; j++) {
90317ab2063SBarry Smith         ip[j-fshift] = ip[j];
90417ab2063SBarry Smith         ap[j-fshift] = ap[j];
90517ab2063SBarry Smith       }
90617ab2063SBarry Smith     }
90717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
90817ab2063SBarry Smith   }
90917ab2063SBarry Smith   if (m) {
91017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
91117ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
91217ab2063SBarry Smith   }
9137b083b7cSBarry Smith 
91417ab2063SBarry Smith   /* reset ilen and imax for each row */
9157b083b7cSBarry Smith   a->nonzerorowcnt = 0;
91617ab2063SBarry Smith   for (i=0; i<m; i++) {
91717ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9187b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
91917ab2063SBarry Smith   }
920bfeeae90SHong Zhang   a->nz = ai[m];
92165e19b50SBarry 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);
92217ab2063SBarry Smith 
92309f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
924d0f46423SBarry 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);
925ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
926ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9272205254eSKarl Rupp 
9288e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
929dd5f02e7SSatish Balay   a->reallocs         = 0;
9304e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
93136db0b34SBarry Smith   a->rmax             = rmax;
9324e220ebcSLois Curfman McInnes 
93311e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9342205254eSKarl Rupp 
93588e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
93671c2f376SKris Buschelman 
9374108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
93871f1c65dSBarry Smith 
939acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9403a40ed3dSBarry Smith   PetscFunctionReturn(0);
94117ab2063SBarry Smith }
94217ab2063SBarry Smith 
9434a2ae208SSatish Balay #undef __FUNCT__
94499cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
94599cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
94699cafbc1SBarry Smith {
94799cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
94899cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
94954f21887SBarry Smith   MatScalar      *aa = a->a;
950acf2f550SJed Brown   PetscErrorCode ierr;
95199cafbc1SBarry Smith 
95299cafbc1SBarry Smith   PetscFunctionBegin;
95399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
954acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
95599cafbc1SBarry Smith   PetscFunctionReturn(0);
95699cafbc1SBarry Smith }
95799cafbc1SBarry Smith 
95899cafbc1SBarry Smith #undef __FUNCT__
95999cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
96099cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
96199cafbc1SBarry Smith {
96299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
96454f21887SBarry Smith   MatScalar      *aa = a->a;
965acf2f550SJed Brown   PetscErrorCode ierr;
96699cafbc1SBarry Smith 
96799cafbc1SBarry Smith   PetscFunctionBegin;
96899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
969acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
97099cafbc1SBarry Smith   PetscFunctionReturn(0);
97199cafbc1SBarry Smith }
97299cafbc1SBarry Smith 
97378b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
97478b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
97578b84d54SShri Abhyankar {
97678b84d54SShri Abhyankar   PetscErrorCode ierr;
97778b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
97878b84d54SShri Abhyankar   PetscInt       n,start,end;
97978b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98078b84d54SShri Abhyankar 
98178b84d54SShri Abhyankar   start = trstarts[thread_id];
98278b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
98319baf141SJed Brown   n     = a->i[end] - a->i[start];
98419baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
98578b84d54SShri Abhyankar   return 0;
98678b84d54SShri Abhyankar }
98778b84d54SShri Abhyankar 
98878b84d54SShri Abhyankar #undef __FUNCT__
98978b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
99078b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
99178b84d54SShri Abhyankar {
99278b84d54SShri Abhyankar   PetscErrorCode ierr;
99378b84d54SShri Abhyankar 
99478b84d54SShri Abhyankar   PetscFunctionBegin;
995ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
996acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99778b84d54SShri Abhyankar   PetscFunctionReturn(0);
99878b84d54SShri Abhyankar }
99978b84d54SShri Abhyankar #else
100099cafbc1SBarry Smith #undef __FUNCT__
10014a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1002dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
100317ab2063SBarry Smith {
1004416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1005dfbe8321SBarry Smith   PetscErrorCode ierr;
10063a40ed3dSBarry Smith 
10073a40ed3dSBarry Smith   PetscFunctionBegin;
1008d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1009acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10103a40ed3dSBarry Smith   PetscFunctionReturn(0);
101117ab2063SBarry Smith }
101278b84d54SShri Abhyankar #endif
1013416022c9SBarry Smith 
10144a2ae208SSatish Balay #undef __FUNCT__
10154a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1016dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
101717ab2063SBarry Smith {
1018416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1019dfbe8321SBarry Smith   PetscErrorCode ierr;
1020d5d45c9bSBarry Smith 
10213a40ed3dSBarry Smith   PetscFunctionBegin;
1022aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1023d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
102417ab2063SBarry Smith #endif
1025e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10266bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10276bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
102805b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1029d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
103005b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
103171f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
103205b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10336bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
103405b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10356bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
103605b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10376bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1038cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10390b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1040a30b2313SHong Zhang 
10414108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1042bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1043901853e0SKris Buschelman 
1044dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1046bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1047bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1049bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1050bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10553a40ed3dSBarry Smith   PetscFunctionReturn(0);
105617ab2063SBarry Smith }
105717ab2063SBarry Smith 
10584a2ae208SSatish Balay #undef __FUNCT__
10594a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1060ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
106117ab2063SBarry Smith {
1062416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10634846f1f5SKris Buschelman   PetscErrorCode ierr;
10643a40ed3dSBarry Smith 
10653a40ed3dSBarry Smith   PetscFunctionBegin;
1066a65d3064SKris Buschelman   switch (op) {
1067a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10684e0d8c25SBarry Smith     a->roworiented = flg;
1069a65d3064SKris Buschelman     break;
1070a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1071a9817697SBarry Smith     a->keepnonzeropattern = flg;
1072a65d3064SKris Buschelman     break;
1073512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1074512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1075a65d3064SKris Buschelman     break;
1076a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10774e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1078a65d3064SKris Buschelman     break;
1079a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10804e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1081a65d3064SKris Buschelman     break;
108228b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
108328b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
108428b2fa4aSMatthew Knepley     break;
1085a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10864e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10870df259c2SBarry Smith     break;
10883d472b54SHong Zhang   case MAT_SPD:
1089b1646e73SJed Brown   case MAT_SYMMETRIC:
1090b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1091b1646e73SJed Brown   case MAT_HERMITIAN:
1092b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
10935021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
10945021d80fSJed Brown     break;
10954e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1096a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1097a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1098290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1099a65d3064SKris Buschelman     break;
1100b87ac2d8SJed Brown   case MAT_USE_INODES:
1101b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1102b87ac2d8SJed Brown     break;
1103a65d3064SKris Buschelman   default:
1104e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1105a65d3064SKris Buschelman   }
11064108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11073a40ed3dSBarry Smith   PetscFunctionReturn(0);
110817ab2063SBarry Smith }
110917ab2063SBarry Smith 
11104a2ae208SSatish Balay #undef __FUNCT__
11114a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1112dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
111317ab2063SBarry Smith {
1114416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11156849ba73SBarry Smith   PetscErrorCode ierr;
1116d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
111735e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
111817ab2063SBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
1120d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1121e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
112235e7444dSHong Zhang 
1123d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1124d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
112535e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11262c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
112735e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
112835e7444dSHong Zhang     PetscFunctionReturn(0);
112935e7444dSHong Zhang   }
113035e7444dSHong Zhang 
11312dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11321ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
113335e7444dSHong Zhang   for (i=0; i<n; i++) {
113435e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11352f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
113635e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
113735e7444dSHong Zhang       if (aj[j] == i) {
113835e7444dSHong Zhang         x[i] = aa[j];
113917ab2063SBarry Smith         break;
114017ab2063SBarry Smith       }
114117ab2063SBarry Smith     }
114217ab2063SBarry Smith   }
11431ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11443a40ed3dSBarry Smith   PetscFunctionReturn(0);
114517ab2063SBarry Smith }
114617ab2063SBarry Smith 
1147c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11484a2ae208SSatish Balay #undef __FUNCT__
11494a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1150dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
115117ab2063SBarry Smith {
1152416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11535c897100SBarry Smith   PetscScalar    *x,*y;
1154dfbe8321SBarry Smith   PetscErrorCode ierr;
1155d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11565c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1157a77337e4SBarry Smith   MatScalar         *v;
1158a77337e4SBarry Smith   PetscScalar       alpha;
11590298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11603447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1161ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11625c897100SBarry Smith #endif
116317ab2063SBarry Smith 
11643a40ed3dSBarry Smith   PetscFunctionBegin;
11652e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11661ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11671ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11685c897100SBarry Smith 
11695c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1170bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11715c897100SBarry Smith #else
11723447b6efSHong Zhang   if (usecprow) {
11733447b6efSHong Zhang     m    = cprow.nrows;
11743447b6efSHong Zhang     ii   = cprow.i;
11757b2bb3b9SHong Zhang     ridx = cprow.rindex;
11763447b6efSHong Zhang   } else {
11773447b6efSHong Zhang     ii = a->i;
11783447b6efSHong Zhang   }
117917ab2063SBarry Smith   for (i=0; i<m; i++) {
11803447b6efSHong Zhang     idx = a->j + ii[i];
11813447b6efSHong Zhang     v   = a->a + ii[i];
11823447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11833447b6efSHong Zhang     if (usecprow) {
11847b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11853447b6efSHong Zhang     } else {
118617ab2063SBarry Smith       alpha = x[i];
11873447b6efSHong Zhang     }
118804fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
118917ab2063SBarry Smith   }
11905c897100SBarry Smith #endif
1191dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
11921ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11931ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
11943a40ed3dSBarry Smith   PetscFunctionReturn(0);
119517ab2063SBarry Smith }
119617ab2063SBarry Smith 
11974a2ae208SSatish Balay #undef __FUNCT__
11985c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1199dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12005c897100SBarry Smith {
1201dfbe8321SBarry Smith   PetscErrorCode ierr;
12025c897100SBarry Smith 
12035c897100SBarry Smith   PetscFunctionBegin;
1204170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12055c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12065c897100SBarry Smith   PetscFunctionReturn(0);
12075c897100SBarry Smith }
12085c897100SBarry Smith 
1209c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
121078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
121178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
121278b84d54SShri Abhyankar {
121378b84d54SShri Abhyankar   PetscErrorCode    ierr;
121478b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
121578b84d54SShri Abhyankar   PetscScalar       *y;
121678b84d54SShri Abhyankar   const PetscScalar *x;
121778b84d54SShri Abhyankar   const MatScalar   *aa;
121878b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
121978b84d54SShri Abhyankar   PetscInt          n,start,end,i;
122078b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
122178b84d54SShri Abhyankar   PetscScalar       sum;
122278b84d54SShri Abhyankar 
122378b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
122478b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
122578b84d54SShri Abhyankar   start = trstarts[thread_id];
122678b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
122778b84d54SShri Abhyankar   aj    = a->j;
122878b84d54SShri Abhyankar   aa    = a->a;
122978b84d54SShri Abhyankar   ai    = a->i;
123078b84d54SShri Abhyankar   for (i=start; i<end; i++) {
123178b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
123278b84d54SShri Abhyankar     aj  = a->j + ai[i];
123378b84d54SShri Abhyankar     aa  = a->a + ai[i];
123478b84d54SShri Abhyankar     sum = 0.0;
123578b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
123678b84d54SShri Abhyankar     y[i] = sum;
123778b84d54SShri Abhyankar   }
123878b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
123978b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
124078b84d54SShri Abhyankar   return 0;
124178b84d54SShri Abhyankar }
124278b84d54SShri Abhyankar 
124378b84d54SShri Abhyankar #undef __FUNCT__
124478b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
124578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
124678b84d54SShri Abhyankar {
124778b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
124878b84d54SShri Abhyankar   PetscScalar       *y;
124978b84d54SShri Abhyankar   const PetscScalar *x;
125078b84d54SShri Abhyankar   const MatScalar   *aa;
125178b84d54SShri Abhyankar   PetscErrorCode    ierr;
125278b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12530298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12547b083b7cSBarry Smith   PetscInt          n,i;
125578b84d54SShri Abhyankar   PetscScalar       sum;
125678b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
125778b84d54SShri Abhyankar 
125878b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
125978b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
126078b84d54SShri Abhyankar #endif
126178b84d54SShri Abhyankar 
126278b84d54SShri Abhyankar   PetscFunctionBegin;
126378b84d54SShri Abhyankar   aj = a->j;
126478b84d54SShri Abhyankar   aa = a->a;
126578b84d54SShri Abhyankar   ii = a->i;
126678b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
126778b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
126878b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
126978b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
127078b84d54SShri Abhyankar     ii   = a->compressedrow.i;
127178b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
127278b84d54SShri Abhyankar     for (i=0; i<m; i++) {
127378b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
127478b84d54SShri Abhyankar       aj          = a->j + ii[i];
127578b84d54SShri Abhyankar       aa          = a->a + ii[i];
127678b84d54SShri Abhyankar       sum         = 0.0;
127778b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
127878b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
127978b84d54SShri Abhyankar       y[*ridx++] = sum;
128078b84d54SShri Abhyankar     }
128178b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
128278b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
128378b84d54SShri Abhyankar   } else { /* do not use compressed row format */
128478b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
128578b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
128678b84d54SShri Abhyankar #else
1287ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
128878b84d54SShri Abhyankar #endif
128978b84d54SShri Abhyankar   }
12907b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
129178b84d54SShri Abhyankar   PetscFunctionReturn(0);
129278b84d54SShri Abhyankar }
129378b84d54SShri Abhyankar #else
12945c897100SBarry Smith #undef __FUNCT__
12954a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1296dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
129717ab2063SBarry Smith {
1298416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1299d9fead3dSBarry Smith   PetscScalar       *y;
130054f21887SBarry Smith   const PetscScalar *x;
130154f21887SBarry Smith   const MatScalar   *aa;
1302dfbe8321SBarry Smith   PetscErrorCode    ierr;
1303003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13040298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13057b083b7cSBarry Smith   PetscInt          n,i;
1306362ced78SSatish Balay   PetscScalar       sum;
1307ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
130817ab2063SBarry Smith 
1309b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
131097952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1311fee21e36SBarry Smith #endif
1312fee21e36SBarry Smith 
13133a40ed3dSBarry Smith   PetscFunctionBegin;
13143649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13151ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
131697952fefSHong Zhang   aj   = a->j;
131797952fefSHong Zhang   aa   = a->a;
1318416022c9SBarry Smith   ii   = a->i;
13194eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
132097952fefSHong Zhang     m    = a->compressedrow.nrows;
132197952fefSHong Zhang     ii   = a->compressedrow.i;
132297952fefSHong Zhang     ridx = a->compressedrow.rindex;
132397952fefSHong Zhang     for (i=0; i<m; i++) {
132497952fefSHong Zhang       n           = ii[i+1] - ii[i];
132597952fefSHong Zhang       aj          = a->j + ii[i];
132697952fefSHong Zhang       aa          = a->a + ii[i];
132797952fefSHong Zhang       sum         = 0.0;
1328003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1329003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
133097952fefSHong Zhang       y[*ridx++] = sum;
133197952fefSHong Zhang     }
133297952fefSHong Zhang   } else { /* do not use compressed row format */
1333b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1334b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1335b05257ddSBarry Smith #else
133678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1337ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
133878b84d54SShri Abhyankar #else
133917ab2063SBarry Smith     for (i=0; i<m; i++) {
1340003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1341003131ecSBarry Smith       aj          = a->j + ii[i];
1342003131ecSBarry Smith       aa          = a->a + ii[i];
134317ab2063SBarry Smith       sum         = 0.0;
1344003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
134517ab2063SBarry Smith       y[i] = sum;
134617ab2063SBarry Smith     }
13478d195f9aSBarry Smith #endif
134878b84d54SShri Abhyankar #endif
1349b05257ddSBarry Smith   }
13507b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13513649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13521ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13533a40ed3dSBarry Smith   PetscFunctionReturn(0);
135417ab2063SBarry Smith }
135578b84d54SShri Abhyankar #endif
135617ab2063SBarry Smith 
1357b434eb95SMatthew G. Knepley #undef __FUNCT__
1358b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1359b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1360b434eb95SMatthew G. Knepley {
1361b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1362b434eb95SMatthew G. Knepley   PetscScalar       *y;
1363b434eb95SMatthew G. Knepley   const PetscScalar *x;
1364b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1365b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1366b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1367b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1368b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1369b434eb95SMatthew G. Knepley   PetscScalar       sum;
1370b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1371b434eb95SMatthew G. Knepley 
1372b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1373b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1374b434eb95SMatthew G. Knepley #endif
1375b434eb95SMatthew G. Knepley 
1376b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1377b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1378b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1379b434eb95SMatthew G. Knepley   aj   = a->j;
1380b434eb95SMatthew G. Knepley   aa   = a->a;
1381b434eb95SMatthew G. Knepley   ii   = a->i;
1382b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1383b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1384b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1385b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1386b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1387b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1388b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1389b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1390b434eb95SMatthew G. Knepley       sum         = 0.0;
1391b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1392b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1393b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1394b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1395b434eb95SMatthew G. Knepley     }
1396b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1397b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1398b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1399b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1400b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1401b434eb95SMatthew G. Knepley       sum         = 0.0;
1402b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1403b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1404b434eb95SMatthew G. Knepley       y[i] = sum;
1405b434eb95SMatthew G. Knepley     }
1406b434eb95SMatthew G. Knepley   }
1407b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1408b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1409b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1410b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1411b434eb95SMatthew G. Knepley }
1412b434eb95SMatthew G. Knepley 
1413b434eb95SMatthew G. Knepley #undef __FUNCT__
1414b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1415b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1416b434eb95SMatthew G. Knepley {
1417b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1418b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1419b434eb95SMatthew G. Knepley   const PetscScalar *x;
1420b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1421b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1422b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1423b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1424b434eb95SMatthew G. Knepley   PetscScalar       sum;
1425b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1426b434eb95SMatthew G. Knepley 
1427b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1428b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1429b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1430b434eb95SMatthew G. Knepley   if (zz != yy) {
1431b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1432b434eb95SMatthew G. Knepley   } else {
1433b434eb95SMatthew G. Knepley     z = y;
1434b434eb95SMatthew G. Knepley   }
1435b434eb95SMatthew G. Knepley 
1436b434eb95SMatthew G. Knepley   aj = a->j;
1437b434eb95SMatthew G. Knepley   aa = a->a;
1438b434eb95SMatthew G. Knepley   ii = a->i;
1439b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1440b434eb95SMatthew G. Knepley     if (zz != yy) {
1441b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1442b434eb95SMatthew G. Knepley     }
1443b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1444b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1445b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1446b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1447b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1448b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1449b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1450b434eb95SMatthew G. Knepley       sum = y[*ridx];
1451b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1452b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1453b434eb95SMatthew G. Knepley     }
1454b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1455b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1456b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1457b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1458b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1459b434eb95SMatthew G. Knepley       sum = y[i];
1460b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1461b434eb95SMatthew G. Knepley       z[i] = sum;
1462b434eb95SMatthew G. Knepley     }
1463b434eb95SMatthew G. Knepley   }
1464b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1465b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1466b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1467b434eb95SMatthew G. Knepley   if (zz != yy) {
1468b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1469b434eb95SMatthew G. Knepley   }
1470b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1471b434eb95SMatthew G. Knepley }
1472b434eb95SMatthew G. Knepley 
1473c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14744a2ae208SSatish Balay #undef __FUNCT__
14754a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1476dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
147717ab2063SBarry Smith {
1478416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1479f15663dcSBarry Smith   PetscScalar       *y,*z;
1480f15663dcSBarry Smith   const PetscScalar *x;
148154f21887SBarry Smith   const MatScalar   *aa;
1482dfbe8321SBarry Smith   PetscErrorCode    ierr;
1483d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14840298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1485362ced78SSatish Balay   PetscScalar       sum;
1486ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
14879ea0dfa2SSatish Balay 
14883a40ed3dSBarry Smith   PetscFunctionBegin;
1489f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14901ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
14912e8a6d31SBarry Smith   if (zz != yy) {
14921ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
14932e8a6d31SBarry Smith   } else {
14942e8a6d31SBarry Smith     z = y;
14952e8a6d31SBarry Smith   }
1496bfeeae90SHong Zhang 
149797952fefSHong Zhang   aj = a->j;
149897952fefSHong Zhang   aa = a->a;
1499cddf8d76SBarry Smith   ii = a->i;
15004eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15014eb6d288SHong Zhang     if (zz != yy) {
15024eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15034eb6d288SHong Zhang     }
150497952fefSHong Zhang     m    = a->compressedrow.nrows;
150597952fefSHong Zhang     ii   = a->compressedrow.i;
150697952fefSHong Zhang     ridx = a->compressedrow.rindex;
150797952fefSHong Zhang     for (i=0; i<m; i++) {
150897952fefSHong Zhang       n   = ii[i+1] - ii[i];
150997952fefSHong Zhang       aj  = a->j + ii[i];
151097952fefSHong Zhang       aa  = a->a + ii[i];
151197952fefSHong Zhang       sum = y[*ridx];
1512f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
151397952fefSHong Zhang       z[*ridx++] = sum;
151497952fefSHong Zhang     }
151597952fefSHong Zhang   } else { /* do not use compressed row format */
1516f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1517f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1518f15663dcSBarry Smith #else
151917ab2063SBarry Smith     for (i=0; i<m; i++) {
1520f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1521f15663dcSBarry Smith       aj  = a->j + ii[i];
1522f15663dcSBarry Smith       aa  = a->a + ii[i];
152317ab2063SBarry Smith       sum = y[i];
1524f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152517ab2063SBarry Smith       z[i] = sum;
152617ab2063SBarry Smith     }
152702ab625aSSatish Balay #endif
1528f15663dcSBarry Smith   }
1529dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1530f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15311ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15322e8a6d31SBarry Smith   if (zz != yy) {
15331ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15342e8a6d31SBarry Smith   }
15358154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15366b375ea7SVictor Minden   /*
1537918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1538918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1539918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15406b375ea7SVictor Minden   */
1541918e98c3SVictor Minden #endif
15423a40ed3dSBarry Smith   PetscFunctionReturn(0);
154317ab2063SBarry Smith }
154417ab2063SBarry Smith 
154517ab2063SBarry Smith /*
154617ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
154717ab2063SBarry Smith */
15484a2ae208SSatish Balay #undef __FUNCT__
15494a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1550dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
155117ab2063SBarry Smith {
1552416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15536849ba73SBarry Smith   PetscErrorCode ierr;
1554d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
155517ab2063SBarry Smith 
15563a40ed3dSBarry Smith   PetscFunctionBegin;
155709f38230SBarry Smith   if (!a->diag) {
1558785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
15593bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
156009f38230SBarry Smith   }
1561d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
156209f38230SBarry Smith     a->diag[i] = a->i[i+1];
1563bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1564bfeeae90SHong Zhang       if (a->j[j] == i) {
156509f38230SBarry Smith         a->diag[i] = j;
156617ab2063SBarry Smith         break;
156717ab2063SBarry Smith       }
156817ab2063SBarry Smith     }
156917ab2063SBarry Smith   }
15703a40ed3dSBarry Smith   PetscFunctionReturn(0);
157117ab2063SBarry Smith }
157217ab2063SBarry Smith 
1573be5855fcSBarry Smith /*
1574be5855fcSBarry Smith      Checks for missing diagonals
1575be5855fcSBarry Smith */
15764a2ae208SSatish Balay #undef __FUNCT__
15774a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1578ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1579be5855fcSBarry Smith {
1580be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
158197f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1582be5855fcSBarry Smith 
1583be5855fcSBarry Smith   PetscFunctionBegin;
158409f38230SBarry Smith   *missing = PETSC_FALSE;
1585d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
158609f38230SBarry Smith     *missing = PETSC_TRUE;
158709f38230SBarry Smith     if (d) *d = 0;
1588358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
158909f38230SBarry Smith   } else {
1590f1e2ffcdSBarry Smith     diag = a->diag;
1591d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1592bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
159309f38230SBarry Smith         *missing = PETSC_TRUE;
159409f38230SBarry Smith         if (d) *d = i;
159509f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1596358d2f5dSShri Abhyankar         break;
159709f38230SBarry Smith       }
1598be5855fcSBarry Smith     }
1599be5855fcSBarry Smith   }
1600be5855fcSBarry Smith   PetscFunctionReturn(0);
1601be5855fcSBarry Smith }
1602be5855fcSBarry Smith 
160371f1c65dSBarry Smith #undef __FUNCT__
160471f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16057087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
160671f1c65dSBarry Smith {
160771f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
160871f1c65dSBarry Smith   PetscErrorCode ierr;
1609d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
161054f21887SBarry Smith   MatScalar      *v = a->a;
161154f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
161271f1c65dSBarry Smith 
161371f1c65dSBarry Smith   PetscFunctionBegin;
161471f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
161571f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
161671f1c65dSBarry Smith   diag = a->diag;
161771f1c65dSBarry Smith   if (!a->idiag) {
1618dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
16193bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
162071f1c65dSBarry Smith     v    = a->a;
162171f1c65dSBarry Smith   }
162271f1c65dSBarry Smith   mdiag = a->mdiag;
162371f1c65dSBarry Smith   idiag = a->idiag;
162471f1c65dSBarry Smith 
1625028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
162671f1c65dSBarry Smith     for (i=0; i<m; i++) {
162771f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1628e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
162971f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
163071f1c65dSBarry Smith     }
163171f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
163271f1c65dSBarry Smith   } else {
163371f1c65dSBarry Smith     for (i=0; i<m; i++) {
163471f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
163571f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
163671f1c65dSBarry Smith     }
1637dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
163871f1c65dSBarry Smith   }
163971f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
164071f1c65dSBarry Smith   PetscFunctionReturn(0);
164171f1c65dSBarry Smith }
164271f1c65dSBarry Smith 
1643c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16444a2ae208SSatish Balay #undef __FUNCT__
164541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
164641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
164717ab2063SBarry Smith {
1648416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1649e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1650e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
165154f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1652dfbe8321SBarry Smith   PetscErrorCode    ierr;
1653d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
165497f1f81fSBarry Smith   const PetscInt    *idx,*diag;
165517ab2063SBarry Smith 
16563a40ed3dSBarry Smith   PetscFunctionBegin;
1657b965ef7fSBarry Smith   its = its*lits;
165891723122SBarry Smith 
165971f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
166071f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
166171f1c65dSBarry Smith   a->fshift = fshift;
166271f1c65dSBarry Smith   a->omega  = omega;
1663ed480e8bSBarry Smith 
166471f1c65dSBarry Smith   diag  = a->diag;
166571f1c65dSBarry Smith   t     = a->ssor_work;
1666ed480e8bSBarry Smith   idiag = a->idiag;
166771f1c65dSBarry Smith   mdiag = a->mdiag;
1668ed480e8bSBarry Smith 
16691ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16703649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1671ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
167217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
167317ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1674ed480e8bSBarry Smith     bs = b;
167517ab2063SBarry Smith     for (i=0; i<m; i++) {
167671f1c65dSBarry Smith       d   = fshift + mdiag[i];
1677416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1678ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1679ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
168017ab2063SBarry Smith       sum = b[i]*d/omega;
1681003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
168217ab2063SBarry Smith       x[i] = sum;
168317ab2063SBarry Smith     }
16841ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16853649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1686efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
16873a40ed3dSBarry Smith     PetscFunctionReturn(0);
168817ab2063SBarry Smith   }
1689c783ea89SBarry Smith 
16902205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
16912205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
169217ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1693887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
169417ab2063SBarry Smith 
169517ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
169617ab2063SBarry Smith 
1697887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
169817ab2063SBarry Smith     */
169917ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
170017ab2063SBarry Smith 
170117ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
170217ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1703416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1704ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1705ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
170617ab2063SBarry Smith       sum = b[i];
1707e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1708ed480e8bSBarry Smith       x[i] = sum*idiag[i];
170917ab2063SBarry Smith     }
171017ab2063SBarry Smith 
171117ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1712416022c9SBarry Smith     v = a->a;
17132205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
171417ab2063SBarry Smith 
171517ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1716ed480e8bSBarry Smith     ts   = t;
1717416022c9SBarry Smith     diag = a->diag;
171817ab2063SBarry Smith     for (i=0; i<m; i++) {
1719416022c9SBarry Smith       n   = diag[i] - a->i[i];
1720ed480e8bSBarry Smith       idx = a->j + a->i[i];
1721ed480e8bSBarry Smith       v   = a->a + a->i[i];
172217ab2063SBarry Smith       sum = t[i];
1723003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1724ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1725733d66baSBarry Smith       /*  x = x + t */
1726733d66baSBarry Smith       x[i] += t[i];
172717ab2063SBarry Smith     }
172817ab2063SBarry Smith 
1729dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17301ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17313649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17323a40ed3dSBarry Smith     PetscFunctionReturn(0);
173317ab2063SBarry Smith   }
173417ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
173517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
173617ab2063SBarry Smith       for (i=0; i<m; i++) {
1737416022c9SBarry Smith         n   = diag[i] - a->i[i];
1738ed480e8bSBarry Smith         idx = a->j + a->i[i];
1739ed480e8bSBarry Smith         v   = a->a + a->i[i];
174017ab2063SBarry Smith         sum = b[i];
1741e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17425c99c7daSBarry Smith         t[i] = sum;
1743ed480e8bSBarry Smith         x[i] = sum*idiag[i];
174417ab2063SBarry Smith       }
17455c99c7daSBarry Smith       xb   = t;
1746efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17473a40ed3dSBarry Smith     } else xb = b;
174817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
174917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1750416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1751ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1752ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
175317ab2063SBarry Smith         sum = xb[i];
1754e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17555c99c7daSBarry Smith         if (xb == b) {
1756ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17575c99c7daSBarry Smith         } else {
1758b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
175917ab2063SBarry Smith         }
17605c99c7daSBarry Smith       }
1761b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
176217ab2063SBarry Smith     }
176317ab2063SBarry Smith     its--;
176417ab2063SBarry Smith   }
176517ab2063SBarry Smith   while (its--) {
176617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
176717ab2063SBarry Smith       for (i=0; i<m; i++) {
1768b19a5dc2SMark Adams         /* lower */
1769b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1770ed480e8bSBarry Smith         idx = a->j + a->i[i];
1771ed480e8bSBarry Smith         v   = a->a + a->i[i];
177217ab2063SBarry Smith         sum = b[i];
1773e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1774b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1775b19a5dc2SMark Adams         /* upper */
1776b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1777b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1778b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1779b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1780b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
178117ab2063SBarry Smith       }
1782b19a5dc2SMark Adams       xb   = t;
17839f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1784b19a5dc2SMark Adams     } else xb = b;
178517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
178617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1787b19a5dc2SMark Adams         sum = xb[i];
1788b19a5dc2SMark Adams         if (xb == b) {
1789b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1790416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1791ed480e8bSBarry Smith           idx = a->j + a->i[i];
1792ed480e8bSBarry Smith           v   = a->a + a->i[i];
1793e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1794ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1795b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1796b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1797b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1798b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1799b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1800b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
180117ab2063SBarry Smith         }
1802b19a5dc2SMark Adams       }
1803b19a5dc2SMark Adams       if (xb == b) {
18049f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1805b19a5dc2SMark Adams       } else {
1806b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1807b19a5dc2SMark Adams       }
180817ab2063SBarry Smith     }
180917ab2063SBarry Smith   }
18101ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18113649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1812365a8a9eSBarry Smith   PetscFunctionReturn(0);
181317ab2063SBarry Smith }
181417ab2063SBarry Smith 
18152af78befSBarry Smith 
18164a2ae208SSatish Balay #undef __FUNCT__
18174a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1818dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
181917ab2063SBarry Smith {
1820416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18214e220ebcSLois Curfman McInnes 
18223a40ed3dSBarry Smith   PetscFunctionBegin;
18234e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18244e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18254e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18264e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18274e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18288e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18297adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1830d5f3da31SBarry Smith   if (A->factortype) {
18314e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18324e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18334e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18344e220ebcSLois Curfman McInnes   } else {
18354e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18364e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18374e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18384e220ebcSLois Curfman McInnes   }
18393a40ed3dSBarry Smith   PetscFunctionReturn(0);
184017ab2063SBarry Smith }
184117ab2063SBarry Smith 
18424a2ae208SSatish Balay #undef __FUNCT__
18434a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18442b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
184517ab2063SBarry Smith {
1846416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18473b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18486849ba73SBarry Smith   PetscErrorCode    ierr;
184997b48c8fSBarry Smith   const PetscScalar *xx;
185097b48c8fSBarry Smith   PetscScalar       *bb;
1851ace3abfcSBarry Smith   PetscBool         missing;
185217ab2063SBarry Smith 
18533a40ed3dSBarry Smith   PetscFunctionBegin;
185497b48c8fSBarry Smith   if (x && b) {
185597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
185697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
185797b48c8fSBarry Smith     for (i=0; i<N; i++) {
185897b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
185997b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
186097b48c8fSBarry Smith     }
186197b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
186297b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
186397b48c8fSBarry Smith   }
186497b48c8fSBarry Smith 
1865a9817697SBarry Smith   if (a->keepnonzeropattern) {
1866f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1867e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1868bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1869f1e2ffcdSBarry Smith     }
1870f4df32b1SMatthew Knepley     if (diag != 0.0) {
187109f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1872e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1873f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1874f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1875f1e2ffcdSBarry Smith       }
1876f1e2ffcdSBarry Smith     }
187788e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1878f1e2ffcdSBarry Smith   } else {
1879f4df32b1SMatthew Knepley     if (diag != 0.0) {
188017ab2063SBarry Smith       for (i=0; i<N; i++) {
1881e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18827ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1883416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1884f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1885bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18867ae801bdSBarry Smith         } else { /* in case row was completely empty */
1887f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
188817ab2063SBarry Smith         }
188917ab2063SBarry Smith       }
18903a40ed3dSBarry Smith     } else {
189117ab2063SBarry Smith       for (i=0; i<N; i++) {
1892e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1893416022c9SBarry Smith         a->ilen[rows[i]] = 0;
189417ab2063SBarry Smith       }
189517ab2063SBarry Smith     }
189688e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1897f1e2ffcdSBarry Smith   }
189843a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18993a40ed3dSBarry Smith   PetscFunctionReturn(0);
190017ab2063SBarry Smith }
190117ab2063SBarry Smith 
19024a2ae208SSatish Balay #undef __FUNCT__
19036e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19046e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19056e169961SBarry Smith {
19066e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19076e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19086e169961SBarry Smith   PetscErrorCode    ierr;
19092b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19106e169961SBarry Smith   const PetscScalar *xx;
19116e169961SBarry Smith   PetscScalar       *bb;
19126e169961SBarry Smith 
19136e169961SBarry Smith   PetscFunctionBegin;
19146e169961SBarry Smith   if (x && b) {
19156e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19166e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19172b40b63fSBarry Smith     vecs = PETSC_TRUE;
19186e169961SBarry Smith   }
1919*1795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
19206e169961SBarry Smith   for (i=0; i<N; i++) {
19216e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19226e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19232205254eSKarl Rupp 
19246e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19256e169961SBarry Smith   }
19266e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19276e169961SBarry Smith     if (!zeroed[i]) {
19286e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19296e169961SBarry Smith         if (zeroed[a->j[j]]) {
19302b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19316e169961SBarry Smith           a->a[j] = 0.0;
19326e169961SBarry Smith         }
19336e169961SBarry Smith       }
19342b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19356e169961SBarry Smith   }
19366e169961SBarry Smith   if (x && b) {
19376e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19386e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19396e169961SBarry Smith   }
19406e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19416e169961SBarry Smith   if (diag != 0.0) {
19426e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19436e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19446e169961SBarry Smith     for (i=0; i<N; i++) {
19456e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19466e169961SBarry Smith     }
19476e169961SBarry Smith   }
19486e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19496e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19506e169961SBarry Smith   PetscFunctionReturn(0);
19516e169961SBarry Smith }
19526e169961SBarry Smith 
19536e169961SBarry Smith #undef __FUNCT__
19544a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1955a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
195617ab2063SBarry Smith {
1957416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
195897f1f81fSBarry Smith   PetscInt   *itmp;
195917ab2063SBarry Smith 
19603a40ed3dSBarry Smith   PetscFunctionBegin;
1961e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
196217ab2063SBarry Smith 
1963416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1964bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
196517ab2063SBarry Smith   if (idx) {
1966bfeeae90SHong Zhang     itmp = a->j + a->i[row];
196726fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
196817ab2063SBarry Smith     else *idx = 0;
196917ab2063SBarry Smith   }
19703a40ed3dSBarry Smith   PetscFunctionReturn(0);
197117ab2063SBarry Smith }
197217ab2063SBarry Smith 
1973bfeeae90SHong Zhang /* remove this function? */
19744a2ae208SSatish Balay #undef __FUNCT__
19754a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1976a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
197717ab2063SBarry Smith {
19783a40ed3dSBarry Smith   PetscFunctionBegin;
19793a40ed3dSBarry Smith   PetscFunctionReturn(0);
198017ab2063SBarry Smith }
198117ab2063SBarry Smith 
19824a2ae208SSatish Balay #undef __FUNCT__
19834a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1984dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
198517ab2063SBarry Smith {
1986416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
198754f21887SBarry Smith   MatScalar      *v  = a->a;
198836db0b34SBarry Smith   PetscReal      sum = 0.0;
19896849ba73SBarry Smith   PetscErrorCode ierr;
199097f1f81fSBarry Smith   PetscInt       i,j;
199117ab2063SBarry Smith 
19923a40ed3dSBarry Smith   PetscFunctionBegin;
199317ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1994416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
199536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
199617ab2063SBarry Smith     }
19978f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
19983a40ed3dSBarry Smith   } else if (type == NORM_1) {
199936db0b34SBarry Smith     PetscReal *tmp;
200097f1f81fSBarry Smith     PetscInt  *jj = a->j;
2001*1795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2002064f8208SBarry Smith     *nrm = 0.0;
2003416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2004bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
200517ab2063SBarry Smith     }
2006d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2007064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
200817ab2063SBarry Smith     }
2009606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20103a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2011064f8208SBarry Smith     *nrm = 0.0;
2012d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2013bfeeae90SHong Zhang       v   = a->a + a->i[j];
201417ab2063SBarry Smith       sum = 0.0;
2015416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2016cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
201717ab2063SBarry Smith       }
2018064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
201917ab2063SBarry Smith     }
2020f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20213a40ed3dSBarry Smith   PetscFunctionReturn(0);
202217ab2063SBarry Smith }
202317ab2063SBarry Smith 
20244e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20254e938277SHong Zhang #undef __FUNCT__
20264e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20274e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20284e938277SHong Zhang {
20294e938277SHong Zhang   PetscErrorCode ierr;
20304e938277SHong Zhang   PetscInt       i,j,anzj;
20314e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20324e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20334e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20344e938277SHong Zhang 
20354e938277SHong Zhang   PetscFunctionBegin;
20364e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
2037*1795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2038785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2039785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
20404e938277SHong Zhang 
20414e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20424e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
204326fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20444e938277SHong Zhang   /* Form ati for csr format of A^T. */
204526fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20464e938277SHong Zhang 
20474e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20484e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20494e938277SHong Zhang 
20504e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20514e938277SHong Zhang   for (i=0;i<am;i++) {
20524e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20534e938277SHong Zhang     for (j=0;j<anzj;j++) {
20544e938277SHong Zhang       atj[atfill[*aj]] = i;
20554e938277SHong Zhang       atfill[*aj++]   += 1;
20564e938277SHong Zhang     }
20574e938277SHong Zhang   }
20584e938277SHong Zhang 
20594e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20604e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2061ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20622205254eSKarl Rupp 
2063a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2064a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2065a2f3521dSMark F. Adams 
20664e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20674e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20684e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20694e938277SHong Zhang   b->nonew   = 0;
20704e938277SHong Zhang   PetscFunctionReturn(0);
20714e938277SHong Zhang }
20724e938277SHong Zhang 
20734a2ae208SSatish Balay #undef __FUNCT__
20744a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2075fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
207617ab2063SBarry Smith {
2077416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2078416022c9SBarry Smith   Mat            C;
20796849ba73SBarry Smith   PetscErrorCode ierr;
2080d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
208154f21887SBarry Smith   MatScalar      *array = a->a;
208217ab2063SBarry Smith 
20833a40ed3dSBarry Smith   PetscFunctionBegin;
2084e32f2f54SBarry 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");
2085fc4dec0aSBarry Smith 
2086fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
2087*1795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2088bfeeae90SHong Zhang 
2089bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2090ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2091d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2092a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
20937adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2094ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2095606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2096a541d17aSBarry Smith   } else {
2097a541d17aSBarry Smith     C = *B;
2098a541d17aSBarry Smith   }
2099a541d17aSBarry Smith 
210017ab2063SBarry Smith   for (i=0; i<m; i++) {
210117ab2063SBarry Smith     len    = ai[i+1]-ai[i];
210287d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2103b9b97703SBarry Smith     array += len;
2104b9b97703SBarry Smith     aj    += len;
210517ab2063SBarry Smith   }
21066d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21076d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
210817ab2063SBarry Smith 
2109815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2110416022c9SBarry Smith     *B = C;
211117ab2063SBarry Smith   } else {
2112eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
211317ab2063SBarry Smith   }
21143a40ed3dSBarry Smith   PetscFunctionReturn(0);
211517ab2063SBarry Smith }
211617ab2063SBarry Smith 
2117cd0d46ebSvictorle #undef __FUNCT__
21185fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21197087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2120cd0d46ebSvictorle {
2121cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
212254f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
212354f21887SBarry Smith   MatScalar      *va,*vb;
21246849ba73SBarry Smith   PetscErrorCode ierr;
212597f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2126cd0d46ebSvictorle 
2127cd0d46ebSvictorle   PetscFunctionBegin;
2128cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2129cd0d46ebSvictorle 
2130cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2131cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21325485867bSBarry Smith   if (ma!=nb || na!=mb) {
21335485867bSBarry Smith     *f = PETSC_FALSE;
21345485867bSBarry Smith     PetscFunctionReturn(0);
21355485867bSBarry Smith   }
2136cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2137cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2138cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2139785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2140785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2141cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2142cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2143cd0d46ebSvictorle 
2144cd0d46ebSvictorle   *f = PETSC_TRUE;
2145cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2146cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
214797f1f81fSBarry Smith       PetscInt    idc,idr;
21485485867bSBarry Smith       PetscScalar vc,vr;
2149cd0d46ebSvictorle       /* column/row index/value */
21505485867bSBarry Smith       idc = adx[aptr[i]];
21515485867bSBarry Smith       idr = bdx[bptr[idc]];
21525485867bSBarry Smith       vc  = va[aptr[i]];
21535485867bSBarry Smith       vr  = vb[bptr[idc]];
21545485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21555485867bSBarry Smith         *f = PETSC_FALSE;
21565485867bSBarry Smith         goto done;
2157cd0d46ebSvictorle       } else {
21585485867bSBarry Smith         aptr[i]++;
21595485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2160cd0d46ebSvictorle       }
2161cd0d46ebSvictorle     }
2162cd0d46ebSvictorle   }
2163cd0d46ebSvictorle done:
2164cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21653aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2166cd0d46ebSvictorle   PetscFunctionReturn(0);
2167cd0d46ebSvictorle }
2168cd0d46ebSvictorle 
21691cbb95d3SBarry Smith #undef __FUNCT__
21701cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21717087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21721cbb95d3SBarry Smith {
21731cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
217454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
217554f21887SBarry Smith   MatScalar      *va,*vb;
21761cbb95d3SBarry Smith   PetscErrorCode ierr;
21771cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21781cbb95d3SBarry Smith 
21791cbb95d3SBarry Smith   PetscFunctionBegin;
21801cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21811cbb95d3SBarry Smith 
21821cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
21831cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21841cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
21851cbb95d3SBarry Smith     *f = PETSC_FALSE;
21861cbb95d3SBarry Smith     PetscFunctionReturn(0);
21871cbb95d3SBarry Smith   }
21881cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
21891cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
21901cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2191785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2192785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
21931cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
21941cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
21951cbb95d3SBarry Smith 
21961cbb95d3SBarry Smith   *f = PETSC_TRUE;
21971cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
21981cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
21991cbb95d3SBarry Smith       PetscInt    idc,idr;
22001cbb95d3SBarry Smith       PetscScalar vc,vr;
22011cbb95d3SBarry Smith       /* column/row index/value */
22021cbb95d3SBarry Smith       idc = adx[aptr[i]];
22031cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22041cbb95d3SBarry Smith       vc  = va[aptr[i]];
22051cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22061cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22071cbb95d3SBarry Smith         *f = PETSC_FALSE;
22081cbb95d3SBarry Smith         goto done;
22091cbb95d3SBarry Smith       } else {
22101cbb95d3SBarry Smith         aptr[i]++;
22111cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22121cbb95d3SBarry Smith       }
22131cbb95d3SBarry Smith     }
22141cbb95d3SBarry Smith   }
22151cbb95d3SBarry Smith done:
22161cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22171cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22181cbb95d3SBarry Smith   PetscFunctionReturn(0);
22191cbb95d3SBarry Smith }
22201cbb95d3SBarry Smith 
22219e29f15eSvictorle #undef __FUNCT__
22229e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2223ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22249e29f15eSvictorle {
2225dfbe8321SBarry Smith   PetscErrorCode ierr;
22266e111a19SKarl Rupp 
22279e29f15eSvictorle   PetscFunctionBegin;
22285485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22299e29f15eSvictorle   PetscFunctionReturn(0);
22309e29f15eSvictorle }
22319e29f15eSvictorle 
22324a2ae208SSatish Balay #undef __FUNCT__
22331cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2234ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22351cbb95d3SBarry Smith {
22361cbb95d3SBarry Smith   PetscErrorCode ierr;
22376e111a19SKarl Rupp 
22381cbb95d3SBarry Smith   PetscFunctionBegin;
22391cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22401cbb95d3SBarry Smith   PetscFunctionReturn(0);
22411cbb95d3SBarry Smith }
22421cbb95d3SBarry Smith 
22431cbb95d3SBarry Smith #undef __FUNCT__
22444a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2245dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
224617ab2063SBarry Smith {
2247416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
224854f21887SBarry Smith   PetscScalar    *l,*r,x;
224954f21887SBarry Smith   MatScalar      *v;
2250dfbe8321SBarry Smith   PetscErrorCode ierr;
2251d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
225217ab2063SBarry Smith 
22533a40ed3dSBarry Smith   PetscFunctionBegin;
225417ab2063SBarry Smith   if (ll) {
22553ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22563ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2257e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2258e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22591ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2260416022c9SBarry Smith     v    = a->a;
226117ab2063SBarry Smith     for (i=0; i<m; i++) {
226217ab2063SBarry Smith       x = l[i];
2263416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22642205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
226517ab2063SBarry Smith     }
22661ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2267efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
226817ab2063SBarry Smith   }
226917ab2063SBarry Smith   if (rr) {
2270e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2271e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22721ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2273416022c9SBarry Smith     v    = a->a; jj = a->j;
22742205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22751ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2276efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
227717ab2063SBarry Smith   }
2278acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22793a40ed3dSBarry Smith   PetscFunctionReturn(0);
228017ab2063SBarry Smith }
228117ab2063SBarry Smith 
22824a2ae208SSatish Balay #undef __FUNCT__
22834a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
228497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
228517ab2063SBarry Smith {
2286db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
22876849ba73SBarry Smith   PetscErrorCode ierr;
2288d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
228997f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
22905d0c19d7SBarry Smith   const PetscInt *irow,*icol;
22915d0c19d7SBarry Smith   PetscInt       nrows,ncols;
229297f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
229354f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2294416022c9SBarry Smith   Mat            C;
2295ace3abfcSBarry Smith   PetscBool      stride,sorted;
229617ab2063SBarry Smith 
22973a40ed3dSBarry Smith   PetscFunctionBegin;
229814ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2299e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
230014ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2301e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
230299141d43SSatish Balay 
230317ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2304b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2305b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
230617ab2063SBarry Smith 
2307fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2308251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2309fee21e36SBarry Smith   if (stride && step == 1) {
231002834360SBarry Smith     /* special case of contiguous rows */
2311dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
231202834360SBarry Smith     /* loop over new rows determining lens and starting points */
231302834360SBarry Smith     for (i=0; i<nrows; i++) {
2314bfeeae90SHong Zhang       kstart = ai[irow[i]];
2315a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
231602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2317bfeeae90SHong Zhang         if (aj[k] >= first) {
231802834360SBarry Smith           starts[i] = k;
231902834360SBarry Smith           break;
232002834360SBarry Smith         }
232102834360SBarry Smith       }
2322a2744918SBarry Smith       sum = 0;
232302834360SBarry Smith       while (k < kend) {
2324bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2325a2744918SBarry Smith         sum++;
232602834360SBarry Smith       }
2327a2744918SBarry Smith       lens[i] = sum;
232802834360SBarry Smith     }
232902834360SBarry Smith     /* create submatrix */
2330cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
233197f1f81fSBarry Smith       PetscInt n_cols,n_rows;
233208480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2333e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2334d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
233508480c60SBarry Smith       C    = *B;
23363a40ed3dSBarry Smith     } else {
23373bef6203SJed Brown       PetscInt rbs,cbs;
2338ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2339f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23403bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23413bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23423bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23437adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2344ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
234508480c60SBarry Smith     }
2346db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2347db02288aSLois Curfman McInnes 
234802834360SBarry Smith     /* loop over rows inserting into submatrix */
2349db02288aSLois Curfman McInnes     a_new = c->a;
2350db02288aSLois Curfman McInnes     j_new = c->j;
2351db02288aSLois Curfman McInnes     i_new = c->i;
2352bfeeae90SHong Zhang 
235302834360SBarry Smith     for (i=0; i<nrows; i++) {
2354a2744918SBarry Smith       ii    = starts[i];
2355a2744918SBarry Smith       lensi = lens[i];
2356a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2357a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
235802834360SBarry Smith       }
235987828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2360a2744918SBarry Smith       a_new     += lensi;
2361a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2362a2744918SBarry Smith       c->ilen[i] = lensi;
236302834360SBarry Smith     }
23640e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23653a40ed3dSBarry Smith   } else {
236602834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2367*1795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2368785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
23694dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23704dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23714dcab191SBarry 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);
23724dcab191SBarry Smith #endif
23734dcab191SBarry Smith       smap[icol[i]] = i+1;
23744dcab191SBarry Smith     }
23754dcab191SBarry Smith 
237602834360SBarry Smith     /* determine lens of each row */
237702834360SBarry Smith     for (i=0; i<nrows; i++) {
2378bfeeae90SHong Zhang       kstart  = ai[irow[i]];
237902834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
238002834360SBarry Smith       lens[i] = 0;
238102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2382bfeeae90SHong Zhang         if (smap[aj[k]]) {
238302834360SBarry Smith           lens[i]++;
238402834360SBarry Smith         }
238502834360SBarry Smith       }
238602834360SBarry Smith     }
238717ab2063SBarry Smith     /* Create and fill new matrix */
2388a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2389ace3abfcSBarry Smith       PetscBool equal;
23900f5bd95cSBarry Smith 
239199141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2392e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2393d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2394f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2395d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
239608480c60SBarry Smith       C    = *B;
23973a40ed3dSBarry Smith     } else {
23983bef6203SJed Brown       PetscInt rbs,cbs;
2399ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2400f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24013bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24023bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24033bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24047adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2405ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
240608480c60SBarry Smith     }
240799141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
240817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
240999141d43SSatish Balay       row      = irow[i];
2410bfeeae90SHong Zhang       kstart   = ai[row];
241199141d43SSatish Balay       kend     = kstart + a->ilen[row];
2412bfeeae90SHong Zhang       mat_i    = c->i[i];
241399141d43SSatish Balay       mat_j    = c->j + mat_i;
241499141d43SSatish Balay       mat_a    = c->a + mat_i;
241599141d43SSatish Balay       mat_ilen = c->ilen + i;
241617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2417bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2418ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
241999141d43SSatish Balay           *mat_a++ = a->a[k];
242099141d43SSatish Balay           (*mat_ilen)++;
242199141d43SSatish Balay 
242217ab2063SBarry Smith         }
242317ab2063SBarry Smith       }
242417ab2063SBarry Smith     }
242502834360SBarry Smith     /* Free work space */
242602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2427606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2428606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
242902834360SBarry Smith   }
24306d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24316d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
243217ab2063SBarry Smith 
243317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2434416022c9SBarry Smith   *B   = C;
24353a40ed3dSBarry Smith   PetscFunctionReturn(0);
243617ab2063SBarry Smith }
243717ab2063SBarry Smith 
24381df811f5SHong Zhang #undef __FUNCT__
243982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2440fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
244182d44351SHong Zhang {
244282d44351SHong Zhang   PetscErrorCode ierr;
244382d44351SHong Zhang   Mat            B;
244482d44351SHong Zhang 
244582d44351SHong Zhang   PetscFunctionBegin;
2446c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
244782d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
244882d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2449a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
245082d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
245182d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
245282d44351SHong Zhang     *subMat = B;
2453c2d650bdSHong Zhang   } else {
2454c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2455c2d650bdSHong Zhang   }
245682d44351SHong Zhang   PetscFunctionReturn(0);
245782d44351SHong Zhang }
245882d44351SHong Zhang 
245982d44351SHong Zhang #undef __FUNCT__
24604a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24610481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2462a871dcd8SBarry Smith {
246363b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2464dfbe8321SBarry Smith   PetscErrorCode ierr;
246563b91edcSBarry Smith   Mat            outA;
2466ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
246763b91edcSBarry Smith 
24683a40ed3dSBarry Smith   PetscFunctionBegin;
2469e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24701df811f5SHong Zhang 
2471b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2472b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2473a871dcd8SBarry Smith 
247463b91edcSBarry Smith   outA             = inA;
2475d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24762205254eSKarl Rupp 
2477c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24786bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24792205254eSKarl Rupp 
2480c3122656SLisandro Dalcin   a->row = row;
24812205254eSKarl Rupp 
2482c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
24836bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
24842205254eSKarl Rupp 
2485c3122656SLisandro Dalcin   a->col = col;
248663b91edcSBarry Smith 
248736db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
24886bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
24894c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
24903bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2491f0ec6fceSSatish Balay 
249294a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2493785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
24943bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
249594a9d846SBarry Smith   }
249663b91edcSBarry Smith 
2497f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2498137fb511SHong Zhang   if (row_identity && col_identity) {
2499ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2500137fb511SHong Zhang   } else {
2501719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2502137fb511SHong Zhang   }
25033a40ed3dSBarry Smith   PetscFunctionReturn(0);
2504a871dcd8SBarry Smith }
2505a871dcd8SBarry Smith 
25064a2ae208SSatish Balay #undef __FUNCT__
25074a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2508f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2509f0b747eeSBarry Smith {
2510f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2511f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2512efee365bSSatish Balay   PetscErrorCode ierr;
2513c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25143a40ed3dSBarry Smith 
25153a40ed3dSBarry Smith   PetscFunctionBegin;
2516c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25178b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2518efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2519acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25203a40ed3dSBarry Smith   PetscFunctionReturn(0);
2521f0b747eeSBarry Smith }
2522f0b747eeSBarry Smith 
25234a2ae208SSatish Balay #undef __FUNCT__
25244a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
252597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2526cddf8d76SBarry Smith {
2527dfbe8321SBarry Smith   PetscErrorCode ierr;
252897f1f81fSBarry Smith   PetscInt       i;
2529cddf8d76SBarry Smith 
25303a40ed3dSBarry Smith   PetscFunctionBegin;
2531cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2532785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2533cddf8d76SBarry Smith   }
2534cddf8d76SBarry Smith 
2535cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25366a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2537cddf8d76SBarry Smith   }
25383a40ed3dSBarry Smith   PetscFunctionReturn(0);
2539cddf8d76SBarry Smith }
2540cddf8d76SBarry Smith 
25414a2ae208SSatish Balay #undef __FUNCT__
25424a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
254397f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25444dcbc457SBarry Smith {
2545e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25466849ba73SBarry Smith   PetscErrorCode ierr;
25475d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25485d0c19d7SBarry Smith   const PetscInt *idx;
254997f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2550f1af5d2fSBarry Smith   PetscBT        table;
2551bbd702dbSSatish Balay 
25523a40ed3dSBarry Smith   PetscFunctionBegin;
2553d0f46423SBarry Smith   m  = A->rmap->n;
2554e4d965acSSatish Balay   ai = a->i;
2555bfeeae90SHong Zhang   aj = a->j;
25568a047759SSatish Balay 
2557e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
255806763907SSatish Balay 
2559785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
256053b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
256106763907SSatish Balay 
2562e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2563b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2564e4d965acSSatish Balay     isz  = 0;
25656831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2566e4d965acSSatish Balay 
2567e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25684dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2569b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2570e4d965acSSatish Balay 
2571dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2572e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25732205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25744dcbc457SBarry Smith     }
257506763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25766bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2577e4d965acSSatish Balay 
257804a348a9SBarry Smith     k = 0;
257904a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
258004a348a9SBarry Smith       n = isz;
258106763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2582e4d965acSSatish Balay         row   = nidx[k];
2583e4d965acSSatish Balay         start = ai[row];
2584e4d965acSSatish Balay         end   = ai[row+1];
258504a348a9SBarry Smith         for (l = start; l<end; l++) {
2586efb16452SHong Zhang           val = aj[l];
25872205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2588e4d965acSSatish Balay         }
2589e4d965acSSatish Balay       }
2590e4d965acSSatish Balay     }
259170b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2592e4d965acSSatish Balay   }
259394bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2594606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
25953a40ed3dSBarry Smith   PetscFunctionReturn(0);
25964dcbc457SBarry Smith }
259717ab2063SBarry Smith 
25980513a670SBarry Smith /* -------------------------------------------------------------- */
25994a2ae208SSatish Balay #undef __FUNCT__
26004a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2601dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26020513a670SBarry Smith {
26030513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26046849ba73SBarry Smith   PetscErrorCode ierr;
26053b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26065d0c19d7SBarry Smith   const PetscInt *row,*col;
26075d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
260856cd22aeSBarry Smith   IS             icolp,irowp;
26090298fd71SBarry Smith   PetscInt       *cwork = NULL;
26100298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26110513a670SBarry Smith 
26123a40ed3dSBarry Smith   PetscFunctionBegin;
26134c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
261456cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26154c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
261656cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26170513a670SBarry Smith 
26180513a670SBarry Smith   /* determine lengths of permuted rows */
2619785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
26202205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2621ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2622f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2623a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26247adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2625ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2626606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26270513a670SBarry Smith 
2628785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26290513a670SBarry Smith   for (i=0; i<m; i++) {
263032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26312205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2632cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
263332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26340513a670SBarry Smith   }
2635606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26362205254eSKarl Rupp 
26373c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26382205254eSKarl Rupp 
26390513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26400513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
264156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
264256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26436bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26446bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26453a40ed3dSBarry Smith   PetscFunctionReturn(0);
26460513a670SBarry Smith }
26470513a670SBarry Smith 
26484a2ae208SSatish Balay #undef __FUNCT__
26494a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2650dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2651cb5b572fSBarry Smith {
2652dfbe8321SBarry Smith   PetscErrorCode ierr;
2653cb5b572fSBarry Smith 
2654cb5b572fSBarry Smith   PetscFunctionBegin;
265533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
265633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2657be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2658be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2659be6bf707SBarry Smith 
2660700c5bfcSBarry 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");
2661d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2662cb5b572fSBarry Smith   } else {
2663cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2664cb5b572fSBarry Smith   }
2665cb5b572fSBarry Smith   PetscFunctionReturn(0);
2666cb5b572fSBarry Smith }
2667cb5b572fSBarry Smith 
26684a2ae208SSatish Balay #undef __FUNCT__
26694994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26704994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2671273d9f13SBarry Smith {
2672dfbe8321SBarry Smith   PetscErrorCode ierr;
2673273d9f13SBarry Smith 
2674273d9f13SBarry Smith   PetscFunctionBegin;
2675ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2676273d9f13SBarry Smith   PetscFunctionReturn(0);
2677273d9f13SBarry Smith }
2678273d9f13SBarry Smith 
26794a2ae208SSatish Balay #undef __FUNCT__
26808c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
26818c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
26826c0721eeSBarry Smith {
26836c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
26846e111a19SKarl Rupp 
26856c0721eeSBarry Smith   PetscFunctionBegin;
26866c0721eeSBarry Smith   *array = a->a;
26876c0721eeSBarry Smith   PetscFunctionReturn(0);
26886c0721eeSBarry Smith }
26896c0721eeSBarry Smith 
26904a2ae208SSatish Balay #undef __FUNCT__
26918c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
26928c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
26936c0721eeSBarry Smith {
26946c0721eeSBarry Smith   PetscFunctionBegin;
26956c0721eeSBarry Smith   PetscFunctionReturn(0);
26966c0721eeSBarry Smith }
2697273d9f13SBarry Smith 
26988229c054SShri Abhyankar /*
26998229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27008229c054SShri Abhyankar    have different nonzero structure.
27018229c054SShri Abhyankar */
2702ac90fabeSBarry Smith #undef __FUNCT__
27038229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27048229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2705ec7775f6SShri Abhyankar {
27068229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2707ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2708ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2709ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2710ec7775f6SShri Abhyankar 
2711ec7775f6SShri Abhyankar   PetscFunctionBegin;
2712ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2713ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27148af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27158af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27168af7cee1SJed Brown     nnz[i] = 0;
27178af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27188af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27198af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27208af7cee1SJed Brown       nnz[i]++;
27218af7cee1SJed Brown     }
27228af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2723ec7775f6SShri Abhyankar   }
2724ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2725ec7775f6SShri Abhyankar }
2726ec7775f6SShri Abhyankar 
2727ec7775f6SShri Abhyankar #undef __FUNCT__
2728ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2729f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2730ac90fabeSBarry Smith {
2731dfbe8321SBarry Smith   PetscErrorCode ierr;
273297f1f81fSBarry Smith   PetscInt       i;
2733ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2734c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2735ac90fabeSBarry Smith 
2736ac90fabeSBarry Smith   PetscFunctionBegin;
2737c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2738ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2739f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27408b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2741acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2742c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2743a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2744a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27456bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2746a30b2313SHong Zhang     }
2747a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27480298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2749a30b2313SHong Zhang       y->XtoY = X;
2750407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2751c537a176SHong Zhang     }
2752f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2753ba0e910bSBarry 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);
2754ac90fabeSBarry Smith   } else {
27558229c054SShri Abhyankar     Mat      B;
27568229c054SShri Abhyankar     PetscInt *nnz;
2757785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2758ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2759bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
27604aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2761a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2762176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
27638229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2764ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2765ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2766ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
27678229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2768ac90fabeSBarry Smith   }
2769ac90fabeSBarry Smith   PetscFunctionReturn(0);
2770ac90fabeSBarry Smith }
2771ac90fabeSBarry Smith 
2772521d7252SBarry Smith #undef __FUNCT__
2773354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
27747087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2775354c94deSBarry Smith {
2776354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2777354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2778354c94deSBarry Smith   PetscInt    i,nz;
2779354c94deSBarry Smith   PetscScalar *a;
2780354c94deSBarry Smith 
2781354c94deSBarry Smith   PetscFunctionBegin;
2782354c94deSBarry Smith   nz = aij->nz;
2783354c94deSBarry Smith   a  = aij->a;
27842205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2785354c94deSBarry Smith #else
2786354c94deSBarry Smith   PetscFunctionBegin;
2787354c94deSBarry Smith #endif
2788354c94deSBarry Smith   PetscFunctionReturn(0);
2789354c94deSBarry Smith }
2790354c94deSBarry Smith 
2791e34fafa9SBarry Smith #undef __FUNCT__
2792985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2793985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2794e34fafa9SBarry Smith {
2795e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2796e34fafa9SBarry Smith   PetscErrorCode ierr;
2797d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2798e34fafa9SBarry Smith   PetscReal      atmp;
2799985db425SBarry Smith   PetscScalar    *x;
2800e34fafa9SBarry Smith   MatScalar      *aa;
2801e34fafa9SBarry Smith 
2802e34fafa9SBarry Smith   PetscFunctionBegin;
2803e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2804e34fafa9SBarry Smith   aa = a->a;
2805e34fafa9SBarry Smith   ai = a->i;
2806e34fafa9SBarry Smith   aj = a->j;
2807e34fafa9SBarry Smith 
2808985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2809e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2810e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2811e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2812e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2813e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28149189402eSHong Zhang     x[i]  = 0.0;
2815e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2816985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2817985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2818985db425SBarry Smith       aa++; aj++;
2819985db425SBarry Smith     }
2820985db425SBarry Smith   }
2821985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2822985db425SBarry Smith   PetscFunctionReturn(0);
2823985db425SBarry Smith }
2824985db425SBarry Smith 
2825985db425SBarry Smith #undef __FUNCT__
2826985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2827985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2828985db425SBarry Smith {
2829985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2830985db425SBarry Smith   PetscErrorCode ierr;
2831d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2832985db425SBarry Smith   PetscScalar    *x;
2833985db425SBarry Smith   MatScalar      *aa;
2834985db425SBarry Smith 
2835985db425SBarry Smith   PetscFunctionBegin;
2836e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2837985db425SBarry Smith   aa = a->a;
2838985db425SBarry Smith   ai = a->i;
2839985db425SBarry Smith   aj = a->j;
2840985db425SBarry Smith 
2841985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2842985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2843985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2844e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2845985db425SBarry Smith   for (i=0; i<m; i++) {
2846985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2847d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2848985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2849985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2850985db425SBarry Smith       x[i] = 0.0;
2851985db425SBarry Smith       if (idx) {
2852985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2853985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2854985db425SBarry Smith           if (aj[j] > j) {
2855985db425SBarry Smith             idx[i] = j;
2856985db425SBarry Smith             break;
2857985db425SBarry Smith           }
2858985db425SBarry Smith         }
2859985db425SBarry Smith       }
2860985db425SBarry Smith     }
2861985db425SBarry Smith     for (j=0; j<ncols; j++) {
2862985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2863985db425SBarry Smith       aa++; aj++;
2864985db425SBarry Smith     }
2865985db425SBarry Smith   }
2866985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2867985db425SBarry Smith   PetscFunctionReturn(0);
2868985db425SBarry Smith }
2869985db425SBarry Smith 
2870985db425SBarry Smith #undef __FUNCT__
2871c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2872c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2873c87e5d42SMatthew Knepley {
2874c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2875c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2876c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2877c87e5d42SMatthew Knepley   PetscReal      atmp;
2878c87e5d42SMatthew Knepley   PetscScalar    *x;
2879c87e5d42SMatthew Knepley   MatScalar      *aa;
2880c87e5d42SMatthew Knepley 
2881c87e5d42SMatthew Knepley   PetscFunctionBegin;
2882e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2883c87e5d42SMatthew Knepley   aa = a->a;
2884c87e5d42SMatthew Knepley   ai = a->i;
2885c87e5d42SMatthew Knepley   aj = a->j;
2886c87e5d42SMatthew Knepley 
2887c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2888c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2889c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
28903bb78c5cSMatthew G Knepley   if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %d vs. %d rows", A->rmap->n, n);
2891c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2892c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2893289a08f5SMatthew Knepley     if (ncols) {
2894289a08f5SMatthew Knepley       /* Get first nonzero */
2895289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2896289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
28972205254eSKarl Rupp         if (atmp > 1.0e-12) {
28982205254eSKarl Rupp           x[i] = atmp;
28992205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29002205254eSKarl Rupp           break;
29012205254eSKarl Rupp         }
2902289a08f5SMatthew Knepley       }
290312431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2904289a08f5SMatthew Knepley     } else {
2905289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2906289a08f5SMatthew Knepley     }
2907c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2908c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2909289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2910c87e5d42SMatthew Knepley       aa++; aj++;
2911c87e5d42SMatthew Knepley     }
2912c87e5d42SMatthew Knepley   }
2913c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2914c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2915c87e5d42SMatthew Knepley }
2916c87e5d42SMatthew Knepley 
2917c87e5d42SMatthew Knepley #undef __FUNCT__
2918985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2919985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2920985db425SBarry Smith {
2921985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2922985db425SBarry Smith   PetscErrorCode ierr;
2923d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2924985db425SBarry Smith   PetscScalar    *x;
2925985db425SBarry Smith   MatScalar      *aa;
2926985db425SBarry Smith 
2927985db425SBarry Smith   PetscFunctionBegin;
2928e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2929985db425SBarry Smith   aa = a->a;
2930985db425SBarry Smith   ai = a->i;
2931985db425SBarry Smith   aj = a->j;
2932985db425SBarry Smith 
2933985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2934985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2935985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2936e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2937985db425SBarry Smith   for (i=0; i<m; i++) {
2938985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2939d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2940985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2941985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2942985db425SBarry Smith       x[i] = 0.0;
2943985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2944985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2945985db425SBarry Smith         for (j=0; j<ncols; j++) {
2946985db425SBarry Smith           if (aj[j] > j) {
2947985db425SBarry Smith             idx[i] = j;
2948985db425SBarry Smith             break;
2949985db425SBarry Smith           }
2950985db425SBarry Smith         }
2951985db425SBarry Smith       }
2952985db425SBarry Smith     }
2953985db425SBarry Smith     for (j=0; j<ncols; j++) {
2954985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2955985db425SBarry Smith       aa++; aj++;
2956e34fafa9SBarry Smith     }
2957e34fafa9SBarry Smith   }
2958e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2959e34fafa9SBarry Smith   PetscFunctionReturn(0);
2960e34fafa9SBarry Smith }
2961bbead8a2SBarry Smith 
2962bbead8a2SBarry Smith #include <petscblaslapack.h>
296306873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
2964bbead8a2SBarry Smith 
2965bbead8a2SBarry Smith #undef __FUNCT__
2966bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
2967713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
2968bbead8a2SBarry Smith {
2969bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
2970bbead8a2SBarry Smith   PetscErrorCode ierr;
297134fc4b71SJed Brown   PetscInt       i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
2972bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
2973bbead8a2SBarry Smith   PetscReal      shift = 0.0;
2974bbead8a2SBarry Smith 
2975bbead8a2SBarry Smith   PetscFunctionBegin;
29764a0d0026SBarry Smith   if (a->ibdiagvalid) {
29774a0d0026SBarry Smith     if (values) *values = a->ibdiag;
29784a0d0026SBarry Smith     PetscFunctionReturn(0);
29794a0d0026SBarry Smith   }
2980bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
2981bbead8a2SBarry Smith   if (!a->ibdiag) {
2982785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
29833bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
2984bbead8a2SBarry Smith   }
2985bbead8a2SBarry Smith   diag = a->ibdiag;
2986bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
2987bbead8a2SBarry Smith   /* factor and invert each block */
2988bbead8a2SBarry Smith   switch (bs) {
2989bbead8a2SBarry Smith   case 1:
2990bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2991bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
2992bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
2993bbead8a2SBarry Smith     }
2994bbead8a2SBarry Smith     break;
2995bbead8a2SBarry Smith   case 2:
2996bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
2997bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
2998bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
299996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
300096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3001bbead8a2SBarry Smith       diag += 4;
3002bbead8a2SBarry Smith     }
3003bbead8a2SBarry Smith     break;
3004bbead8a2SBarry Smith   case 3:
3005bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3006bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3007bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
300896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
300996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3010bbead8a2SBarry Smith       diag += 9;
3011bbead8a2SBarry Smith     }
3012bbead8a2SBarry Smith     break;
3013bbead8a2SBarry Smith   case 4:
3014bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3015bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3016bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
301796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
301896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3019bbead8a2SBarry Smith       diag += 16;
3020bbead8a2SBarry Smith     }
3021bbead8a2SBarry Smith     break;
3022bbead8a2SBarry Smith   case 5:
3023bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3024bbead8a2SBarry 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;
3025bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
302696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
302796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3028bbead8a2SBarry Smith       diag += 25;
3029bbead8a2SBarry Smith     }
3030bbead8a2SBarry Smith     break;
3031bbead8a2SBarry Smith   case 6:
3032bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3033bbead8a2SBarry 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;
3034bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
303596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
303696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3037bbead8a2SBarry Smith       diag += 36;
3038bbead8a2SBarry Smith     }
3039bbead8a2SBarry Smith     break;
3040bbead8a2SBarry Smith   case 7:
3041bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3042bbead8a2SBarry 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;
3043bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
304496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
304596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3046bbead8a2SBarry Smith       diag += 49;
3047bbead8a2SBarry Smith     }
3048bbead8a2SBarry Smith     break;
3049bbead8a2SBarry Smith   default:
3050dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3051bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3052bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3053bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3054bbead8a2SBarry Smith       }
3055bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
305696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
305796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3058bbead8a2SBarry Smith       diag += bs2;
3059bbead8a2SBarry Smith     }
3060bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3061bbead8a2SBarry Smith   }
3062bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3063bbead8a2SBarry Smith   PetscFunctionReturn(0);
3064bbead8a2SBarry Smith }
3065bbead8a2SBarry Smith 
306673a71a0fSBarry Smith #undef __FUNCT__
306773a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
306873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
306973a71a0fSBarry Smith {
307073a71a0fSBarry Smith   PetscErrorCode ierr;
307173a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
307273a71a0fSBarry Smith   PetscScalar    a;
307373a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
307473a71a0fSBarry Smith 
307573a71a0fSBarry Smith   PetscFunctionBegin;
307673a71a0fSBarry Smith   if (!x->assembled) {
307773a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
307873a71a0fSBarry Smith     for (i=0; i<m; i++) {
307973a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
308073a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
308173a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
308273a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
308373a71a0fSBarry Smith       }
308473a71a0fSBarry Smith     }
308573a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
308673a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
308773a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
308873a71a0fSBarry Smith   PetscFunctionReturn(0);
308973a71a0fSBarry Smith }
309073a71a0fSBarry Smith 
3091682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
30920a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3093cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3094cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3095cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
309697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
30977c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
30987c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3099db4efbfdSBarry Smith                                         0,
3100db4efbfdSBarry Smith                                         0,
3101db4efbfdSBarry Smith                                         0,
3102db4efbfdSBarry Smith                                 /* 10*/ 0,
3103cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3104cb5b572fSBarry Smith                                         0,
310541f059aeSBarry Smith                                         MatSOR_SeqAIJ,
310617ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
310797304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3108cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3109cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3110cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3111cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
311297304618SKris Buschelman                                 /* 20*/ 0,
3113cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3114cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3115cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3116d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3117db4efbfdSBarry Smith                                         0,
3118db4efbfdSBarry Smith                                         0,
3119db4efbfdSBarry Smith                                         0,
3120db4efbfdSBarry Smith                                         0,
31214994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3122db4efbfdSBarry Smith                                         0,
3123db4efbfdSBarry Smith                                         0,
31248c778c55SBarry Smith                                         0,
31258c778c55SBarry Smith                                         0,
3126d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3127cb5b572fSBarry Smith                                         0,
3128cb5b572fSBarry Smith                                         0,
3129cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3130cb5b572fSBarry Smith                                         0,
3131d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3132cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3133cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3134cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3135cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3136d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3137cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3138cb5b572fSBarry Smith                                         0,
313979299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31406e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
314173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31423b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31433b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31443b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3145a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
314693dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3147b9617806SBarry Smith                                         0,
31480513a670SBarry Smith                                         0,
3149cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3150cda55fadSBarry Smith                                         0,
3151d519adbfSMatthew Knepley                                 /* 59*/ 0,
3152b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3153b9b97703SBarry Smith                                         MatView_SeqAIJ,
3154357abbc8SBarry Smith                                         0,
3155321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3156321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3157321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3158ee4f033dSBarry Smith                                         0,
3159ee4f033dSBarry Smith                                         0,
3160ee4f033dSBarry Smith                                         0,
3161d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3162c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3163ee4f033dSBarry Smith                                         0,
3164ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3165dcf5cc72SBarry Smith                                         0,
3166d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
31673acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
316897304618SKris Buschelman                                         0,
316997304618SKris Buschelman                                         0,
317097304618SKris Buschelman                                         0,
31716ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
317297304618SKris Buschelman                                         0,
317397304618SKris Buschelman                                         0,
317497304618SKris Buschelman                                         0,
3175bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3176d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
31771cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
31786284ec50SHong Zhang                                         0,
31796284ec50SHong Zhang                                         0,
3180bc011b1eSHong Zhang                                         0,
3181d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
318226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
318326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
318465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
31854a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
318665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
31876fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
31886fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
31896fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
31902121bac1SHong Zhang                                         0,
31912121bac1SHong Zhang                                 /* 99*/ 0,
3192609c6c4dSKris Buschelman                                         0,
3193609c6c4dSKris Buschelman                                         0,
319487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
319587d4246cSBarry Smith                                         0,
3196d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
319799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3198f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3199f5edf698SHong Zhang                                         0,
32002bebee5dSHong Zhang                                         0,
3201cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3202985db425SBarry Smith                                         0,
32032af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32042af78befSBarry Smith                                         0,
3205599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3206d519adbfSMatthew Knepley                                 /*114*/ 0,
3207599ef60dSHong Zhang                                         0,
32083c2a7987SHong Zhang                                         0,
3209fe97e370SBarry Smith                                         0,
3210fbdbba38SShri Abhyankar                                         0,
3211fbdbba38SShri Abhyankar                                 /*119*/ 0,
3212fbdbba38SShri Abhyankar                                         0,
3213fbdbba38SShri Abhyankar                                         0,
321482d44351SHong Zhang                                         0,
3215b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32160716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3217bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
321837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
321937868618SMatthew G Knepley                                         0,
322037868618SMatthew G Knepley                                         0,
32215df89d91SHong Zhang                                 /*129*/ 0,
322275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
322375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
322475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3225b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3226b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32272b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32282b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32292b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32303964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32313964eb88SJed Brown                                  /*139*/0,
3232f9426fe0SMark Adams                                         0,
32331919a2e2SJed Brown                                         0,
3234f86b9fbaSHong Zhang                                         MatFDColoringSetUp_SeqXAIJ
32359e29f15eSvictorle };
323617ab2063SBarry Smith 
32374a2ae208SSatish Balay #undef __FUNCT__
32384a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32397087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3240bef8e0ddSBarry Smith {
3241bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
324297f1f81fSBarry Smith   PetscInt   i,nz,n;
3243bef8e0ddSBarry Smith 
3244bef8e0ddSBarry Smith   PetscFunctionBegin;
3245bef8e0ddSBarry Smith   nz = aij->maxnz;
3246d0f46423SBarry Smith   n  = mat->rmap->n;
3247bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3248bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3249bef8e0ddSBarry Smith   }
3250bef8e0ddSBarry Smith   aij->nz = nz;
3251bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3252bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3253bef8e0ddSBarry Smith   }
3254bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3255bef8e0ddSBarry Smith }
3256bef8e0ddSBarry Smith 
32574a2ae208SSatish Balay #undef __FUNCT__
32584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3259bef8e0ddSBarry Smith /*@
3260bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3261bef8e0ddSBarry Smith        in the matrix.
3262bef8e0ddSBarry Smith 
3263bef8e0ddSBarry Smith   Input Parameters:
3264bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3265bef8e0ddSBarry Smith -  indices - the column indices
3266bef8e0ddSBarry Smith 
326715091d37SBarry Smith   Level: advanced
326815091d37SBarry Smith 
3269bef8e0ddSBarry Smith   Notes:
3270bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3271bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3272bef8e0ddSBarry Smith   of the MatSetValues() operation.
3273bef8e0ddSBarry Smith 
3274bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3275d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3276bef8e0ddSBarry Smith 
3277bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3278bef8e0ddSBarry Smith 
3279b9617806SBarry Smith     The indices should start with zero, not one.
3280b9617806SBarry Smith 
3281bef8e0ddSBarry Smith @*/
32827087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3283bef8e0ddSBarry Smith {
32844ac538c5SBarry Smith   PetscErrorCode ierr;
3285bef8e0ddSBarry Smith 
3286bef8e0ddSBarry Smith   PetscFunctionBegin;
32870700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
32884482741eSBarry Smith   PetscValidPointer(indices,2);
32894ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3290bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3291bef8e0ddSBarry Smith }
3292bef8e0ddSBarry Smith 
3293be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3294be6bf707SBarry Smith 
32954a2ae208SSatish Balay #undef __FUNCT__
32964a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
32977087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3298be6bf707SBarry Smith {
3299be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33006849ba73SBarry Smith   PetscErrorCode ierr;
3301d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3302be6bf707SBarry Smith 
3303be6bf707SBarry Smith   PetscFunctionBegin;
3304f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3305be6bf707SBarry Smith 
3306be6bf707SBarry Smith   /* allocate space for values if not already there */
3307be6bf707SBarry Smith   if (!aij->saved_values) {
3308785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
33093bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3310be6bf707SBarry Smith   }
3311be6bf707SBarry Smith 
3312be6bf707SBarry Smith   /* copy values over */
331387828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3314be6bf707SBarry Smith   PetscFunctionReturn(0);
3315be6bf707SBarry Smith }
3316be6bf707SBarry Smith 
33174a2ae208SSatish Balay #undef __FUNCT__
3318b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3319be6bf707SBarry Smith /*@
3320be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3321be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3322be6bf707SBarry Smith        nonlinear portion.
3323be6bf707SBarry Smith 
3324be6bf707SBarry Smith    Collect on Mat
3325be6bf707SBarry Smith 
3326be6bf707SBarry Smith   Input Parameters:
33270e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3328be6bf707SBarry Smith 
332915091d37SBarry Smith   Level: advanced
333015091d37SBarry Smith 
3331be6bf707SBarry Smith   Common Usage, with SNESSolve():
3332be6bf707SBarry Smith $    Create Jacobian matrix
3333be6bf707SBarry Smith $    Set linear terms into matrix
3334be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3335be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3336be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3337512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3338be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3339be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3340be6bf707SBarry Smith $    In your Jacobian routine
3341be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3342be6bf707SBarry Smith $      Set nonlinear terms in matrix
3343be6bf707SBarry Smith 
3344be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3345be6bf707SBarry Smith $    // build linear portion of Jacobian
3346512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3347be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3348be6bf707SBarry Smith $    loop over nonlinear iterations
3349be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3350be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3351be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3352be6bf707SBarry Smith $       Solve linear system with Jacobian
3353be6bf707SBarry Smith $    endloop
3354be6bf707SBarry Smith 
3355be6bf707SBarry Smith   Notes:
3356be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3357512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3358be6bf707SBarry Smith     calling this routine.
3359be6bf707SBarry Smith 
33600c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
33610c468ba9SBarry Smith     and does not allocated additional space.
33620c468ba9SBarry Smith 
3363be6bf707SBarry Smith .seealso: MatRetrieveValues()
3364be6bf707SBarry Smith 
3365be6bf707SBarry Smith @*/
33667087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3367be6bf707SBarry Smith {
33684ac538c5SBarry Smith   PetscErrorCode ierr;
3369be6bf707SBarry Smith 
3370be6bf707SBarry Smith   PetscFunctionBegin;
33710700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3372e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3373e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
33744ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3375be6bf707SBarry Smith   PetscFunctionReturn(0);
3376be6bf707SBarry Smith }
3377be6bf707SBarry Smith 
33784a2ae208SSatish Balay #undef __FUNCT__
33794a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
33807087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3381be6bf707SBarry Smith {
3382be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33836849ba73SBarry Smith   PetscErrorCode ierr;
3384d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3385be6bf707SBarry Smith 
3386be6bf707SBarry Smith   PetscFunctionBegin;
3387f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3388f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3389be6bf707SBarry Smith   /* copy values over */
339087828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3391be6bf707SBarry Smith   PetscFunctionReturn(0);
3392be6bf707SBarry Smith }
3393be6bf707SBarry Smith 
33944a2ae208SSatish Balay #undef __FUNCT__
33954a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3396be6bf707SBarry Smith /*@
3397be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3398be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3399be6bf707SBarry Smith        nonlinear portion.
3400be6bf707SBarry Smith 
3401be6bf707SBarry Smith    Collect on Mat
3402be6bf707SBarry Smith 
3403be6bf707SBarry Smith   Input Parameters:
3404be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3405be6bf707SBarry Smith 
340615091d37SBarry Smith   Level: advanced
340715091d37SBarry Smith 
3408be6bf707SBarry Smith .seealso: MatStoreValues()
3409be6bf707SBarry Smith 
3410be6bf707SBarry Smith @*/
34117087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3412be6bf707SBarry Smith {
34134ac538c5SBarry Smith   PetscErrorCode ierr;
3414be6bf707SBarry Smith 
3415be6bf707SBarry Smith   PetscFunctionBegin;
34160700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3417e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3418e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34194ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3420be6bf707SBarry Smith   PetscFunctionReturn(0);
3421be6bf707SBarry Smith }
3422be6bf707SBarry Smith 
3423f83d6046SBarry Smith 
3424be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34254a2ae208SSatish Balay #undef __FUNCT__
34264a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
342717ab2063SBarry Smith /*@C
3428682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34290d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34306e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
343151c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34322bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
343317ab2063SBarry Smith 
3434db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3435db81eaa0SLois Curfman McInnes 
343617ab2063SBarry Smith    Input Parameters:
3437db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
343817ab2063SBarry Smith .  m - number of rows
343917ab2063SBarry Smith .  n - number of columns
344017ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
344151c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34420298fd71SBarry Smith          (possibly different for each row) or NULL
344317ab2063SBarry Smith 
344417ab2063SBarry Smith    Output Parameter:
3445416022c9SBarry Smith .  A - the matrix
344617ab2063SBarry Smith 
3447175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3448ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3449175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3450175b88e8SBarry Smith 
3451b259b22eSLois Curfman McInnes    Notes:
345249a6f317SBarry Smith    If nnz is given then nz is ignored
345349a6f317SBarry Smith 
345417ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
345517ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34560002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
345744cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
345817ab2063SBarry Smith 
345917ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
34600298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
34613d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
34626da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
346317ab2063SBarry Smith 
3464682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
34654fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3466682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
34676c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
34686c7ebb05SLois Curfman McInnes 
34696c7ebb05SLois Curfman McInnes    Options Database Keys:
3470698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
34719db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
347217ab2063SBarry Smith 
3473027ccd11SLois Curfman McInnes    Level: intermediate
3474027ccd11SLois Curfman McInnes 
347569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
347636db0b34SBarry Smith 
347717ab2063SBarry Smith @*/
34787087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
347917ab2063SBarry Smith {
3480dfbe8321SBarry Smith   PetscErrorCode ierr;
34816945ee14SBarry Smith 
34823a40ed3dSBarry Smith   PetscFunctionBegin;
3483f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3484117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3485c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3486d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3487273d9f13SBarry Smith   PetscFunctionReturn(0);
3488273d9f13SBarry Smith }
3489273d9f13SBarry Smith 
34904a2ae208SSatish Balay #undef __FUNCT__
34914a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3492273d9f13SBarry Smith /*@C
3493273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3494273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3495273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3496273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3497273d9f13SBarry Smith 
3498273d9f13SBarry Smith    Collective on MPI_Comm
3499273d9f13SBarry Smith 
3500273d9f13SBarry Smith    Input Parameters:
3501117016b1SBarry Smith +  B - The matrix-free
3502273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3503273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35040298fd71SBarry Smith          (possibly different for each row) or NULL
3505273d9f13SBarry Smith 
3506273d9f13SBarry Smith    Notes:
350749a6f317SBarry Smith      If nnz is given then nz is ignored
350849a6f317SBarry Smith 
3509273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3510273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3511273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3512273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3513273d9f13SBarry Smith 
3514273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35150298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3516273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3517273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3518273d9f13SBarry Smith 
3519aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3520aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3521aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3522aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3523aa95bbe8SBarry Smith 
3524a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3525a96a251dSBarry Smith    entries or columns indices
3526a96a251dSBarry Smith 
3527273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3528273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3529273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3530273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3531273d9f13SBarry Smith 
3532273d9f13SBarry Smith    Options Database Keys:
3533698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3534698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3535273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3536273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3537273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3538273d9f13SBarry Smith 
3539273d9f13SBarry Smith    Level: intermediate
3540273d9f13SBarry Smith 
354169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3542273d9f13SBarry Smith 
3543273d9f13SBarry Smith @*/
35447087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3545273d9f13SBarry Smith {
35464ac538c5SBarry Smith   PetscErrorCode ierr;
3547a23d5eceSKris Buschelman 
3548a23d5eceSKris Buschelman   PetscFunctionBegin;
35496ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35506ba663aaSJed Brown   PetscValidType(B,1);
35514ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3552a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3553a23d5eceSKris Buschelman }
3554a23d5eceSKris Buschelman 
3555a23d5eceSKris Buschelman #undef __FUNCT__
3556a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
35577087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3558a23d5eceSKris Buschelman {
3559273d9f13SBarry Smith   Mat_SeqAIJ     *b;
35602576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
35616849ba73SBarry Smith   PetscErrorCode ierr;
356297f1f81fSBarry Smith   PetscInt       i;
3563273d9f13SBarry Smith 
3564273d9f13SBarry Smith   PetscFunctionBegin;
35652576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3566a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3567c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3568c461c341SBarry Smith     nz             = 0;
3569c461c341SBarry Smith   }
3570c461c341SBarry Smith 
357126283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
357226283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3573899cda47SBarry Smith 
3574435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3575e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3576b73539f3SBarry Smith   if (nnz) {
3577d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3578e32f2f54SBarry 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]);
3579e32f2f54SBarry 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);
3580b73539f3SBarry Smith     }
3581b73539f3SBarry Smith   }
3582b73539f3SBarry Smith 
3583273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
35842205254eSKarl Rupp 
3585273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3586273d9f13SBarry Smith 
3587ab93d7beSBarry Smith   if (!skipallocation) {
35882ee49352SLisandro Dalcin     if (!b->imax) {
3589dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
35903bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
35912ee49352SLisandro Dalcin     }
3592273d9f13SBarry Smith     if (!nnz) {
3593435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3594c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3595d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3596d0f46423SBarry Smith       nz = nz*B->rmap->n;
3597273d9f13SBarry Smith     } else {
3598273d9f13SBarry Smith       nz = 0;
3599d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3600273d9f13SBarry Smith     }
3601ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36022205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3603ab93d7beSBarry Smith 
3604273d9f13SBarry Smith     /* allocate the matrix space */
36052ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3606dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
36073bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3608bfeeae90SHong Zhang     b->i[0] = 0;
3609d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36105da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36115da197adSKris Buschelman     }
3612273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3613e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3614e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3615b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3616b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3617b31eba2aSShri Abhyankar #endif
3618c461c341SBarry Smith   } else {
3619e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3620e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3621c461c341SBarry Smith   }
3622273d9f13SBarry Smith 
3623273d9f13SBarry Smith   b->nz               = 0;
3624273d9f13SBarry Smith   b->maxnz            = nz;
3625273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36262205254eSKarl Rupp   if (realalloc) {
36272205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36282205254eSKarl Rupp   }
3629273d9f13SBarry Smith   PetscFunctionReturn(0);
3630273d9f13SBarry Smith }
3631273d9f13SBarry Smith 
3632a1661176SMatthew Knepley #undef  __FUNCT__
3633a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
363458d36128SBarry Smith /*@
3635a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3636a1661176SMatthew Knepley 
3637a1661176SMatthew Knepley    Input Parameters:
3638a1661176SMatthew Knepley +  B - the matrix
3639a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3640a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3641a1661176SMatthew Knepley -  v - optional values in the matrix
3642a1661176SMatthew Knepley 
3643a1661176SMatthew Knepley    Level: developer
3644a1661176SMatthew Knepley 
364558d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
364658d36128SBarry Smith 
3647a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3648a1661176SMatthew Knepley 
3649a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3650a1661176SMatthew Knepley @*/
3651a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3652a1661176SMatthew Knepley {
3653a1661176SMatthew Knepley   PetscErrorCode ierr;
3654a1661176SMatthew Knepley 
3655a1661176SMatthew Knepley   PetscFunctionBegin;
36560700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36576ba663aaSJed Brown   PetscValidType(B,1);
36584ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3659a1661176SMatthew Knepley   PetscFunctionReturn(0);
3660a1661176SMatthew Knepley }
3661a1661176SMatthew Knepley 
3662a1661176SMatthew Knepley #undef  __FUNCT__
3663a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
36647087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3665a1661176SMatthew Knepley {
3666a1661176SMatthew Knepley   PetscInt       i;
3667a1661176SMatthew Knepley   PetscInt       m,n;
3668a1661176SMatthew Knepley   PetscInt       nz;
3669a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3670a1661176SMatthew Knepley   PetscScalar    *values;
3671a1661176SMatthew Knepley   PetscErrorCode ierr;
3672a1661176SMatthew Knepley 
3673a1661176SMatthew Knepley   PetscFunctionBegin;
367465e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3675779a8d59SSatish Balay 
3676779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3677779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3678779a8d59SSatish Balay 
3679779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3680785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3681a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3682b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3683a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
368465e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3685a1661176SMatthew Knepley     nnz[i] = nz;
3686a1661176SMatthew Knepley   }
3687a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3688a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3689a1661176SMatthew Knepley 
3690a1661176SMatthew Knepley   if (v) {
3691a1661176SMatthew Knepley     values = (PetscScalar*) v;
3692a1661176SMatthew Knepley   } else {
3693*1795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3694a1661176SMatthew Knepley   }
3695a1661176SMatthew Knepley 
3696a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3697b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3698b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3699a1661176SMatthew Knepley   }
3700a1661176SMatthew Knepley 
3701a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3702a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3703a1661176SMatthew Knepley 
3704a1661176SMatthew Knepley   if (!v) {
3705a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3706a1661176SMatthew Knepley   }
37077827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3708a1661176SMatthew Knepley   PetscFunctionReturn(0);
3709a1661176SMatthew Knepley }
3710a1661176SMatthew Knepley 
3711c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
371206873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3713170fe5c8SBarry Smith 
3714170fe5c8SBarry Smith #undef __FUNCT__
3715170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3716170fe5c8SBarry Smith /*
3717170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3718170fe5c8SBarry Smith 
3719170fe5c8SBarry Smith                n                       p                          p
3720170fe5c8SBarry Smith         (              )       (              )         (                  )
3721170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3722170fe5c8SBarry Smith         (              )       (              )         (                  )
3723170fe5c8SBarry Smith 
3724170fe5c8SBarry Smith */
3725170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3726170fe5c8SBarry Smith {
3727170fe5c8SBarry Smith   PetscErrorCode    ierr;
3728170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3729170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3730170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37311de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3732170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3733170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3734170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3735170fe5c8SBarry Smith 
3736170fe5c8SBarry Smith   PetscFunctionBegin;
3737d0f46423SBarry Smith   m    = A->rmap->n;
3738d0f46423SBarry Smith   n    = A->cmap->n;
3739d0f46423SBarry Smith   p    = B->cmap->n;
3740170fe5c8SBarry Smith   a    = sub_a->v;
3741170fe5c8SBarry Smith   b    = sub_b->a;
3742170fe5c8SBarry Smith   c    = sub_c->v;
3743170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3744170fe5c8SBarry Smith 
3745170fe5c8SBarry Smith   ii  = sub_b->i;
3746170fe5c8SBarry Smith   idx = sub_b->j;
3747170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3748170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3749170fe5c8SBarry Smith     while (q-->0) {
3750170fe5c8SBarry Smith       c_q = c + m*(*idx);
3751170fe5c8SBarry Smith       a_q = a + m*i;
3752854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3753170fe5c8SBarry Smith       idx++;
3754170fe5c8SBarry Smith       b++;
3755170fe5c8SBarry Smith     }
3756170fe5c8SBarry Smith   }
3757170fe5c8SBarry Smith   PetscFunctionReturn(0);
3758170fe5c8SBarry Smith }
3759170fe5c8SBarry Smith 
3760170fe5c8SBarry Smith #undef __FUNCT__
3761170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3762170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3763170fe5c8SBarry Smith {
3764170fe5c8SBarry Smith   PetscErrorCode ierr;
3765d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3766170fe5c8SBarry Smith   Mat            Cmat;
3767170fe5c8SBarry Smith 
3768170fe5c8SBarry Smith   PetscFunctionBegin;
3769e32f2f54SBarry 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);
3770ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3771170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3772a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3773170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
37740298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3775d73949e8SHong Zhang 
3776d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
37772205254eSKarl Rupp 
3778170fe5c8SBarry Smith   *C = Cmat;
3779170fe5c8SBarry Smith   PetscFunctionReturn(0);
3780170fe5c8SBarry Smith }
3781170fe5c8SBarry Smith 
3782170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3783170fe5c8SBarry Smith #undef __FUNCT__
3784170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3785170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3786170fe5c8SBarry Smith {
3787170fe5c8SBarry Smith   PetscErrorCode ierr;
3788170fe5c8SBarry Smith 
3789170fe5c8SBarry Smith   PetscFunctionBegin;
3790170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
37913ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3792170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
37933ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3794170fe5c8SBarry Smith   }
37953ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3796170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
37973ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3798170fe5c8SBarry Smith   PetscFunctionReturn(0);
3799170fe5c8SBarry Smith }
3800170fe5c8SBarry Smith 
3801170fe5c8SBarry Smith 
38020bad9183SKris Buschelman /*MC
3803fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38040bad9183SKris Buschelman    based on compressed sparse row format.
38050bad9183SKris Buschelman 
38060bad9183SKris Buschelman    Options Database Keys:
38070bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38080bad9183SKris Buschelman 
38090bad9183SKris Buschelman   Level: beginner
38100bad9183SKris Buschelman 
3811f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38120bad9183SKris Buschelman M*/
38130bad9183SKris Buschelman 
3814ccd284c7SBarry Smith /*MC
3815ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3816ccd284c7SBarry Smith 
3817ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3818ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3819ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3820ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3821ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3822ccd284c7SBarry Smith 
3823ccd284c7SBarry Smith    Options Database Keys:
3824ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3825ccd284c7SBarry Smith 
3826ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3827ccd284c7SBarry Smith    enough exist.
3828ccd284c7SBarry Smith 
3829ccd284c7SBarry Smith   Level: beginner
3830ccd284c7SBarry Smith 
3831ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3832ccd284c7SBarry Smith M*/
3833ccd284c7SBarry Smith 
3834ccd284c7SBarry Smith /*MC
3835ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3836ccd284c7SBarry Smith 
3837ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3838ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3839ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3840ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3841ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3842ccd284c7SBarry Smith 
3843ccd284c7SBarry Smith    Options Database Keys:
3844ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3845ccd284c7SBarry Smith 
3846ccd284c7SBarry Smith   Level: beginner
3847ccd284c7SBarry Smith 
3848ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3849ccd284c7SBarry Smith M*/
3850ccd284c7SBarry Smith 
3851b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38528cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3853b5e56a35SBarry Smith #endif
3854ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3856af1023dbSSatish Balay #endif
38578cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
38588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
38598cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
38607087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3861611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
38628cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3863611f576cSBarry Smith #endif
3864611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
38658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3866611f576cSBarry Smith #endif
3867f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
38688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3869f3c0ef26SHong Zhang #endif
3870eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3872eb3b5408SSatish Balay #endif
3873586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
38748cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3875586621ddSJed Brown #endif
3876719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
38778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3878719d5645SBarry Smith #endif
3879b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
38808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
38817087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
38827087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3883b3866ffcSBarry Smith #endif
388417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
388617f1a0eaSHong Zhang #endif
388717667f90SBarry Smith 
3888c0c8ee5eSDmitry Karpeev 
38898c778c55SBarry Smith #undef __FUNCT__
38908c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
38918c778c55SBarry Smith /*@C
38928c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
38938c778c55SBarry Smith 
38948c778c55SBarry Smith    Not Collective
38958c778c55SBarry Smith 
38968c778c55SBarry Smith    Input Parameter:
38978c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
38988c778c55SBarry Smith 
38998c778c55SBarry Smith    Output Parameter:
39008c778c55SBarry Smith .   array - pointer to the data
39018c778c55SBarry Smith 
39028c778c55SBarry Smith    Level: intermediate
39038c778c55SBarry Smith 
3904774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39058c778c55SBarry Smith @*/
39068c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39078c778c55SBarry Smith {
39088c778c55SBarry Smith   PetscErrorCode ierr;
39098c778c55SBarry Smith 
39108c778c55SBarry Smith   PetscFunctionBegin;
39118c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39128c778c55SBarry Smith   PetscFunctionReturn(0);
39138c778c55SBarry Smith }
39148c778c55SBarry Smith 
39158c778c55SBarry Smith #undef __FUNCT__
39168c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39178c778c55SBarry Smith /*@C
39188c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39198c778c55SBarry Smith 
39208c778c55SBarry Smith    Not Collective
39218c778c55SBarry Smith 
39228c778c55SBarry Smith    Input Parameters:
39238c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39248c778c55SBarry Smith .  array - pointer to the data
39258c778c55SBarry Smith 
39268c778c55SBarry Smith    Level: intermediate
39278c778c55SBarry Smith 
3928774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39298c778c55SBarry Smith @*/
39308c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39318c778c55SBarry Smith {
39328c778c55SBarry Smith   PetscErrorCode ierr;
39338c778c55SBarry Smith 
39348c778c55SBarry Smith   PetscFunctionBegin;
39358c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39368c778c55SBarry Smith   PetscFunctionReturn(0);
39378c778c55SBarry Smith }
39388c778c55SBarry Smith 
39394a2ae208SSatish Balay #undef __FUNCT__
39404a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39418cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3942273d9f13SBarry Smith {
3943273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3944dfbe8321SBarry Smith   PetscErrorCode ierr;
394538baddfdSBarry Smith   PetscMPIInt    size;
3946273d9f13SBarry Smith 
3947273d9f13SBarry Smith   PetscFunctionBegin;
3948ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3949e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3950273d9f13SBarry Smith 
395138f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
39522205254eSKarl Rupp 
3953b0a32e0cSBarry Smith   B->data = (void*)b;
39542205254eSKarl Rupp 
3955549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39562205254eSKarl Rupp 
3957416022c9SBarry Smith   b->row                = 0;
3958416022c9SBarry Smith   b->col                = 0;
395982bf6240SBarry Smith   b->icol               = 0;
3960b810aeb4SBarry Smith   b->reallocs           = 0;
396136db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
3962f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
3963416022c9SBarry Smith   b->nonew              = 0;
3964416022c9SBarry Smith   b->diag               = 0;
3965416022c9SBarry Smith   b->solve_work         = 0;
39662a1b7f2aSHong Zhang   B->spptr              = 0;
3967be6bf707SBarry Smith   b->saved_values       = 0;
3968d7f994e1SBarry Smith   b->idiag              = 0;
396971f1c65dSBarry Smith   b->mdiag              = 0;
397071f1c65dSBarry Smith   b->ssor_work          = 0;
397171f1c65dSBarry Smith   b->omega              = 1.0;
397271f1c65dSBarry Smith   b->fshift             = 0.0;
397371f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
3974bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
3975a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
3976a30b2313SHong Zhang   b->xtoy               = 0;
3977a30b2313SHong Zhang   b->XtoY               = 0;
397888e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
397917ab2063SBarry Smith 
398035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
3981bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
3982bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
39838c778c55SBarry Smith 
3984b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3985bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
3986bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
3987bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
3988b3866ffcSBarry Smith #endif
3989b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
3990bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
3991b5e56a35SBarry Smith #endif
3992ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
3993bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
3994719d5645SBarry Smith #endif
3995611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
3996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
3997611f576cSBarry Smith #endif
3998f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
3999bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4000f3c0ef26SHong Zhang #endif
4001611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4002bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4003611f576cSBarry Smith #endif
4004eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4005bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4006eb3b5408SSatish Balay #endif
4007586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4008bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4009586621ddSJed Brown #endif
4010719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4011bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4012719d5645SBarry Smith #endif
401317f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4014bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
401517f1a0eaSHong Zhang #endif
401617f1a0eaSHong Zhang 
4017bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4018bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4020bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4021bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4022bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4023bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4024bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4026bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4027bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4031bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4032bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4034bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40354108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
403617667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40373a40ed3dSBarry Smith   PetscFunctionReturn(0);
403817ab2063SBarry Smith }
403917ab2063SBarry Smith 
40404a2ae208SSatish Balay #undef __FUNCT__
4041b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4042b24902e0SBarry Smith /*
4043b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4044b24902e0SBarry Smith */
4045ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
404617ab2063SBarry Smith {
4047416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40486849ba73SBarry Smith   PetscErrorCode ierr;
4049d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
405017ab2063SBarry Smith 
40513a40ed3dSBarry Smith   PetscFunctionBegin;
4052273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4053273d9f13SBarry Smith 
4054d5f3da31SBarry Smith   C->factortype = A->factortype;
4055416022c9SBarry Smith   c->row        = 0;
4056416022c9SBarry Smith   c->col        = 0;
405782bf6240SBarry Smith   c->icol       = 0;
40586ad4291fSHong Zhang   c->reallocs   = 0;
405917ab2063SBarry Smith 
40606ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
406117ab2063SBarry Smith 
4062aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4063aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4064eec197d1SBarry Smith 
4065dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
40663bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
406717ab2063SBarry Smith   for (i=0; i<m; i++) {
4068416022c9SBarry Smith     c->imax[i] = a->imax[i];
4069416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
407017ab2063SBarry Smith   }
407117ab2063SBarry Smith 
407217ab2063SBarry Smith   /* allocate the matrix space */
4073f77e22a1SHong Zhang   if (mallocmatspace) {
4074dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
40753bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
40762205254eSKarl Rupp 
4077f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
40782205254eSKarl Rupp 
407997f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
408017ab2063SBarry Smith     if (m > 0) {
408197f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4082be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4083bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4084be6bf707SBarry Smith       } else {
4085bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
408617ab2063SBarry Smith       }
408708480c60SBarry Smith     }
4088f77e22a1SHong Zhang   }
408917ab2063SBarry Smith 
40906ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4091416022c9SBarry Smith   c->roworiented       = a->roworiented;
4092416022c9SBarry Smith   c->nonew             = a->nonew;
4093416022c9SBarry Smith   if (a->diag) {
4094785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
40953bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
409617ab2063SBarry Smith     for (i=0; i<m; i++) {
4097416022c9SBarry Smith       c->diag[i] = a->diag[i];
409817ab2063SBarry Smith     }
40993a40ed3dSBarry Smith   } else c->diag = 0;
41002205254eSKarl Rupp 
41016ad4291fSHong Zhang   c->solve_work         = 0;
41026ad4291fSHong Zhang   c->saved_values       = 0;
41036ad4291fSHong Zhang   c->idiag              = 0;
410471f1c65dSBarry Smith   c->ssor_work          = 0;
4105a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4106e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4107e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41086ad4291fSHong Zhang   c->xtoy               = 0;
41096ad4291fSHong Zhang   c->XtoY               = 0;
41106ad4291fSHong Zhang 
4111893ad86cSHong Zhang   c->rmax         = a->rmax;
4112416022c9SBarry Smith   c->nz           = a->nz;
41138ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4114273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4115754ec7b1SSatish Balay 
41166ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41176ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4118cd6b891eSBarry Smith   if (a->compressedrow.use) {
41196ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4120dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
41216ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41226ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
412327ea64f8SHong Zhang   } else {
412427ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41250298fd71SBarry Smith     c->compressedrow.i      = NULL;
41260298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41276ad4291fSHong Zhang   }
412888e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41294846f1f5SKris Buschelman 
41302205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4131140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41323a40ed3dSBarry Smith   PetscFunctionReturn(0);
413317ab2063SBarry Smith }
413417ab2063SBarry Smith 
41354a2ae208SSatish Balay #undef __FUNCT__
4136b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4137b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4138b24902e0SBarry Smith {
4139b24902e0SBarry Smith   PetscErrorCode ierr;
4140b24902e0SBarry Smith 
4141b24902e0SBarry Smith   PetscFunctionBegin;
4142ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41434b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4144a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4145a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4146f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4147b24902e0SBarry Smith   PetscFunctionReturn(0);
4148b24902e0SBarry Smith }
4149b24902e0SBarry Smith 
4150b24902e0SBarry Smith #undef __FUNCT__
41514a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4152112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4153fbdbba38SShri Abhyankar {
4154fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4155fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4156fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4157fbdbba38SShri Abhyankar   int            fd;
4158fbdbba38SShri Abhyankar   PetscMPIInt    size;
4159fbdbba38SShri Abhyankar   MPI_Comm       comm;
4160bbead8a2SBarry Smith   PetscInt       bs = 1;
4161fbdbba38SShri Abhyankar 
4162fbdbba38SShri Abhyankar   PetscFunctionBegin;
4163fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4164fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4165fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4166bbead8a2SBarry Smith 
41670298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
41680298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4169bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
41701814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4171bbead8a2SBarry Smith 
4172fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4173fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4174fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4175fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4176fbdbba38SShri Abhyankar 
4177bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4178fbdbba38SShri Abhyankar 
4179fbdbba38SShri Abhyankar   /* read in row lengths */
4180785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4181fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4182fbdbba38SShri Abhyankar 
4183fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4184fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4185fbdbba38SShri Abhyankar   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
4186fbdbba38SShri Abhyankar 
4187fbdbba38SShri Abhyankar   /* set global size if not set already*/
4188f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4189fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4190aabbc4fbSShri Abhyankar   } else {
4191fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4192fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
41934c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
41944c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
41954c5b953cSHong Zhang     }
4196f501eaabSShri Abhyankar     if (M != rows ||  N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
4197aabbc4fbSShri Abhyankar   }
4198fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4199fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4200fbdbba38SShri Abhyankar 
4201fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4202fbdbba38SShri Abhyankar 
4203fbdbba38SShri Abhyankar   /* read in nonzero values */
4204fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4205fbdbba38SShri Abhyankar 
4206fbdbba38SShri Abhyankar   /* set matrix "i" values */
4207fbdbba38SShri Abhyankar   a->i[0] = 0;
4208fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4209fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4210fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4211fbdbba38SShri Abhyankar   }
4212fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4213fbdbba38SShri Abhyankar 
4214fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4215fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4216fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4217fbdbba38SShri Abhyankar }
4218fbdbba38SShri Abhyankar 
4219fbdbba38SShri Abhyankar #undef __FUNCT__
4220b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4221ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42227264ac53SSatish Balay {
42237264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4224dfbe8321SBarry Smith   PetscErrorCode ierr;
4225eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4226eeffb40dSHong Zhang   PetscInt k;
4227eeffb40dSHong Zhang #endif
42287264ac53SSatish Balay 
42293a40ed3dSBarry Smith   PetscFunctionBegin;
4230bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4231d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4232ca44d042SBarry Smith     *flg = PETSC_FALSE;
4233ca44d042SBarry Smith     PetscFunctionReturn(0);
4234bcd2baecSBarry Smith   }
42357264ac53SSatish Balay 
42367264ac53SSatish Balay   /* if the a->i are the same */
4237d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4238abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42397264ac53SSatish Balay 
42407264ac53SSatish Balay   /* if a->j are the same */
424197f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4242abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4243bcd2baecSBarry Smith 
4244bcd2baecSBarry Smith   /* if a->a are the same */
4245eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4246eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4247eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4248eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42493a40ed3dSBarry Smith       PetscFunctionReturn(0);
4250eeffb40dSHong Zhang     }
4251eeffb40dSHong Zhang   }
4252eeffb40dSHong Zhang #else
4253eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4254eeffb40dSHong Zhang #endif
4255eeffb40dSHong Zhang   PetscFunctionReturn(0);
42567264ac53SSatish Balay }
425736db0b34SBarry Smith 
42584a2ae208SSatish Balay #undef __FUNCT__
42594a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
426005869f15SSatish Balay /*@
426136db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
426236db0b34SBarry Smith               provided by the user.
426336db0b34SBarry Smith 
4264c75a6043SHong Zhang       Collective on MPI_Comm
426536db0b34SBarry Smith 
426636db0b34SBarry Smith    Input Parameters:
426736db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
426836db0b34SBarry Smith .   m - number of rows
426936db0b34SBarry Smith .   n - number of columns
427036db0b34SBarry Smith .   i - row indices
427136db0b34SBarry Smith .   j - column indices
427236db0b34SBarry Smith -   a - matrix values
427336db0b34SBarry Smith 
427436db0b34SBarry Smith    Output Parameter:
427536db0b34SBarry Smith .   mat - the matrix
427636db0b34SBarry Smith 
427736db0b34SBarry Smith    Level: intermediate
427836db0b34SBarry Smith 
427936db0b34SBarry Smith    Notes:
42800551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4281292fb18eSBarry Smith     once the matrix is destroyed and not before
428236db0b34SBarry Smith 
428336db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
428436db0b34SBarry Smith 
4285bfeeae90SHong Zhang        The i and j indices are 0 based
428636db0b34SBarry Smith 
4287a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4288a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4289a4552177SSatish Balay     as shown:
4290a4552177SSatish Balay 
4291a4552177SSatish Balay         1 0 0
4292a4552177SSatish Balay         2 0 3
4293a4552177SSatish Balay         4 5 6
4294a4552177SSatish Balay 
4295a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
42969985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4297a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4298a4552177SSatish Balay 
42999985e31cSBarry Smith 
430069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
430136db0b34SBarry Smith 
430236db0b34SBarry Smith @*/
43037087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
430436db0b34SBarry Smith {
4305dfbe8321SBarry Smith   PetscErrorCode ierr;
4306cbcfb4deSHong Zhang   PetscInt       ii;
430736db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4308cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4309cbcfb4deSHong Zhang   PetscInt jj;
4310cbcfb4deSHong Zhang #endif
431136db0b34SBarry Smith 
431236db0b34SBarry Smith   PetscFunctionBegin;
4313f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4314f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4315f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4316a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4317ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4318ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4319ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4320dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4321ab93d7beSBarry Smith 
432236db0b34SBarry Smith   aij->i            = i;
432336db0b34SBarry Smith   aij->j            = j;
432436db0b34SBarry Smith   aij->a            = a;
432536db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
432636db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4327e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4328e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
432936db0b34SBarry Smith 
433036db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
433136db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43322515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4333e32f2f54SBarry 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]);
43349985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4335e32f2f54SBarry 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);
4336e32f2f54SBarry 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);
43379985e31cSBarry Smith     }
433836db0b34SBarry Smith #endif
433936db0b34SBarry Smith   }
43402515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
434136db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4342e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4343e32f2f54SBarry 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]);
434436db0b34SBarry Smith   }
434536db0b34SBarry Smith #endif
434636db0b34SBarry Smith 
4347b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4348b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
434936db0b34SBarry Smith   PetscFunctionReturn(0);
435036db0b34SBarry Smith }
43518a0b0e6bSVictor Minden #undef __FUNCT__
43528a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
435380ef6e79SMatthew G Knepley /*@C
4354d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
43558a0b0e6bSVictor Minden               provided by the user.
43568a0b0e6bSVictor Minden 
43578a0b0e6bSVictor Minden       Collective on MPI_Comm
43588a0b0e6bSVictor Minden 
43598a0b0e6bSVictor Minden    Input Parameters:
43608a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
43618a0b0e6bSVictor Minden .   m   - number of rows
43628a0b0e6bSVictor Minden .   n   - number of columns
43638a0b0e6bSVictor Minden .   i   - row indices
43648a0b0e6bSVictor Minden .   j   - column indices
43651230e6d1SVictor Minden .   a   - matrix values
43661230e6d1SVictor Minden .   nz  - number of nonzeros
43671230e6d1SVictor Minden -   idx - 0 or 1 based
43688a0b0e6bSVictor Minden 
43698a0b0e6bSVictor Minden    Output Parameter:
43708a0b0e6bSVictor Minden .   mat - the matrix
43718a0b0e6bSVictor Minden 
43728a0b0e6bSVictor Minden    Level: intermediate
43738a0b0e6bSVictor Minden 
43748a0b0e6bSVictor Minden    Notes:
43758a0b0e6bSVictor Minden        The i and j indices are 0 based
43768a0b0e6bSVictor Minden 
43778a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
43788a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
43798a0b0e6bSVictor Minden     as shown:
43808a0b0e6bSVictor Minden 
43818a0b0e6bSVictor Minden         1 0 0
43828a0b0e6bSVictor Minden         2 0 3
43838a0b0e6bSVictor Minden         4 5 6
43848a0b0e6bSVictor Minden 
43858a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
43868a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
43878a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
43888a0b0e6bSVictor Minden 
43898a0b0e6bSVictor Minden 
439069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
43918a0b0e6bSVictor Minden 
43928a0b0e6bSVictor Minden @*/
43931230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
43948a0b0e6bSVictor Minden {
43958a0b0e6bSVictor Minden   PetscErrorCode ierr;
4396d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
43978a0b0e6bSVictor Minden 
43988a0b0e6bSVictor Minden 
43998a0b0e6bSVictor Minden   PetscFunctionBegin;
4400*1795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
44011230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4402c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
44031230e6d1SVictor Minden   }
44048a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44058a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
44068a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44071230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44081230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44091230e6d1SVictor Minden     if (idx) {
44101230e6d1SVictor Minden       row = i[ii] - 1;
44111230e6d1SVictor Minden       col = j[ii] - 1;
44121230e6d1SVictor Minden     } else {
44131230e6d1SVictor Minden       row = i[ii];
44141230e6d1SVictor Minden       col = j[ii];
44158a0b0e6bSVictor Minden     }
44161230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44178a0b0e6bSVictor Minden   }
44188a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44198a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4420d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44218a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44228a0b0e6bSVictor Minden }
442336db0b34SBarry Smith 
4424cc8ba8e1SBarry Smith #undef __FUNCT__
4425ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4426dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4427cc8ba8e1SBarry Smith {
4428dfbe8321SBarry Smith   PetscErrorCode ierr;
4429cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
443036db0b34SBarry Smith 
4431cc8ba8e1SBarry Smith   PetscFunctionBegin;
44328ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4433cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4434cc8ba8e1SBarry Smith     a->coloring = coloring;
443512c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
443697f1f81fSBarry Smith     PetscInt        i,*larray;
443712c595b3SBarry Smith     ISColoring      ocoloring;
443808b6dcc0SBarry Smith     ISColoringValue *colors;
443912c595b3SBarry Smith 
444012c595b3SBarry Smith     /* set coloring for diagonal portion */
4441785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
44422205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44430298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4444785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
44452205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
444612c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4447d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
444812c595b3SBarry Smith     a->coloring = ocoloring;
444912c595b3SBarry Smith   }
4450cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4451cc8ba8e1SBarry Smith }
4452cc8ba8e1SBarry Smith 
4453ee4f033dSBarry Smith #undef __FUNCT__
4454ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
445597f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4456ee4f033dSBarry Smith {
4457ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4458d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
445954f21887SBarry Smith   MatScalar       *v      = a->a;
446054f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
446108b6dcc0SBarry Smith   ISColoringValue *color;
4462ee4f033dSBarry Smith 
4463ee4f033dSBarry Smith   PetscFunctionBegin;
4464e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4465ee4f033dSBarry Smith   color = a->coloring->colors;
4466ee4f033dSBarry Smith   /* loop over rows */
4467ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4468ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4469ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
44702205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4471ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4472cc8ba8e1SBarry Smith   }
4473cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4474cc8ba8e1SBarry Smith }
447536db0b34SBarry Smith 
4476acf2f550SJed Brown #undef __FUNCT__
4477acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4478acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4479acf2f550SJed Brown {
4480acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4481acf2f550SJed Brown   PetscErrorCode ierr;
4482acf2f550SJed Brown 
4483acf2f550SJed Brown   PetscFunctionBegin;
4484acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4485acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
44862205254eSKarl Rupp 
4487acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4488acf2f550SJed Brown   PetscFunctionReturn(0);
4489acf2f550SJed Brown }
4490acf2f550SJed Brown 
449181824310SBarry Smith /*
449281824310SBarry Smith     Special version for direct calls from Fortran
449381824310SBarry Smith */
4494b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
449581824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
449681824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
449781824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
449881824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
449981824310SBarry Smith #endif
450081824310SBarry Smith 
450181824310SBarry Smith /* Change these macros so can be used in void function */
450281824310SBarry Smith #undef CHKERRQ
4503ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
450481824310SBarry Smith #undef SETERRQ2
4505e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45064994cf47SJed Brown #undef SETERRQ3
45074994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
450881824310SBarry Smith 
450981824310SBarry Smith #undef __FUNCT__
451081824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45118cc058d9SJed 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)
451281824310SBarry Smith {
451381824310SBarry Smith   Mat            A  = *AA;
451481824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
451581824310SBarry Smith   InsertMode     is = *isis;
451681824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
451781824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
451881824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
451981824310SBarry Smith   PetscErrorCode ierr;
452081824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
452154f21887SBarry Smith   MatScalar      *ap,value,*aa;
4522ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4523ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
452481824310SBarry Smith 
452581824310SBarry Smith   PetscFunctionBegin;
45264994cf47SJed Brown   MatCheckPreallocated(A,1);
452781824310SBarry Smith   imax  = a->imax;
452881824310SBarry Smith   ai    = a->i;
452981824310SBarry Smith   ailen = a->ilen;
453081824310SBarry Smith   aj    = a->j;
453181824310SBarry Smith   aa    = a->a;
453281824310SBarry Smith 
453381824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
453481824310SBarry Smith     row = im[k];
453581824310SBarry Smith     if (row < 0) continue;
453681824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4537ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
453881824310SBarry Smith #endif
453981824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
454081824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
454181824310SBarry Smith     low  = 0;
454281824310SBarry Smith     high = nrow;
454381824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
454481824310SBarry Smith       if (in[l] < 0) continue;
454581824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4546ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
454781824310SBarry Smith #endif
454881824310SBarry Smith       col = in[l];
45492205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45502205254eSKarl Rupp       else value = v[k + l*m];
45512205254eSKarl Rupp 
455281824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
455381824310SBarry Smith 
45542205254eSKarl Rupp       if (col <= lastcol) low = 0;
45552205254eSKarl Rupp       else high = nrow;
455681824310SBarry Smith       lastcol = col;
455781824310SBarry Smith       while (high-low > 5) {
455881824310SBarry Smith         t = (low+high)/2;
455981824310SBarry Smith         if (rp[t] > col) high = t;
456081824310SBarry Smith         else             low  = t;
456181824310SBarry Smith       }
456281824310SBarry Smith       for (i=low; i<high; i++) {
456381824310SBarry Smith         if (rp[i] > col) break;
456481824310SBarry Smith         if (rp[i] == col) {
456581824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
456681824310SBarry Smith           else                  ap[i] = value;
456781824310SBarry Smith           goto noinsert;
456881824310SBarry Smith         }
456981824310SBarry Smith       }
457081824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
457181824310SBarry Smith       if (nonew == 1) goto noinsert;
4572ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4573fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
457481824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
457581824310SBarry Smith       /* shift up all the later entries in this row */
457681824310SBarry Smith       for (ii=N; ii>=i; ii--) {
457781824310SBarry Smith         rp[ii+1] = rp[ii];
457881824310SBarry Smith         ap[ii+1] = ap[ii];
457981824310SBarry Smith       }
458081824310SBarry Smith       rp[i] = col;
458181824310SBarry Smith       ap[i] = value;
458281824310SBarry Smith noinsert:;
458381824310SBarry Smith       low = i + 1;
458481824310SBarry Smith     }
458581824310SBarry Smith     ailen[row] = nrow;
458681824310SBarry Smith   }
458781824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
458881824310SBarry Smith   PetscFunctionReturnVoid();
458981824310SBarry Smith }
45909f7953f8SBarry Smith 
459162298a1eSBarry Smith 
4592