xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 169f6850ef94cafd5e9227ac1972b77d01bf00ae)
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__
483a062f41SBarry Smith #define __FUNCT__ "MatFindOffBlockDiagonalEntries_SeqAIJ"
493a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
503a062f41SBarry Smith {
513a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
523a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
533a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
543a062f41SBarry Smith   PetscInt        *rows;
553a062f41SBarry Smith   PetscErrorCode  ierr;
563a062f41SBarry Smith 
573a062f41SBarry Smith   PetscFunctionBegin;
583a062f41SBarry Smith   for (i=0; i<m; i++) {
593a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
603a062f41SBarry Smith       cnt++;
613a062f41SBarry Smith     }
623a062f41SBarry Smith   }
633a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
643a062f41SBarry Smith   cnt  = 0;
653a062f41SBarry Smith   for (i=0; i<m; i++) {
663a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
673a062f41SBarry Smith       rows[cnt] = i;
683a062f41SBarry Smith       cnt++;
693a062f41SBarry Smith     }
703a062f41SBarry Smith   }
713a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
723a062f41SBarry Smith   PetscFunctionReturn(0);
733a062f41SBarry Smith }
743a062f41SBarry Smith 
753a062f41SBarry Smith #undef __FUNCT__
76f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
77f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
786ce1633cSBarry Smith {
796ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
806ce1633cSBarry Smith   const MatScalar *aa = a->a;
816ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
826ce1633cSBarry Smith   const PetscInt  *jj = a->j,*diag;
836ce1633cSBarry Smith   PetscInt        *rows;
846ce1633cSBarry Smith   PetscErrorCode  ierr;
856ce1633cSBarry Smith 
866ce1633cSBarry Smith   PetscFunctionBegin;
876ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
886ce1633cSBarry Smith   diag = a->diag;
896ce1633cSBarry Smith   for (i=0; i<m; i++) {
906ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
916ce1633cSBarry Smith       cnt++;
926ce1633cSBarry Smith     }
936ce1633cSBarry Smith   }
94785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
956ce1633cSBarry Smith   cnt  = 0;
966ce1633cSBarry Smith   for (i=0; i<m; i++) {
976ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
986ce1633cSBarry Smith       rows[cnt++] = i;
996ce1633cSBarry Smith     }
1006ce1633cSBarry Smith   }
101f1f41ecbSJed Brown   *nrows = cnt;
102f1f41ecbSJed Brown   *zrows = rows;
103f1f41ecbSJed Brown   PetscFunctionReturn(0);
104f1f41ecbSJed Brown }
105f1f41ecbSJed Brown 
106f1f41ecbSJed Brown #undef __FUNCT__
107f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
108f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
109f1f41ecbSJed Brown {
110f1f41ecbSJed Brown   PetscInt       nrows,*rows;
111f1f41ecbSJed Brown   PetscErrorCode ierr;
112f1f41ecbSJed Brown 
113f1f41ecbSJed Brown   PetscFunctionBegin;
1140298fd71SBarry Smith   *zrows = NULL;
115f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
116ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1176ce1633cSBarry Smith   PetscFunctionReturn(0);
1186ce1633cSBarry Smith }
1196ce1633cSBarry Smith 
1206ce1633cSBarry Smith #undef __FUNCT__
121b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
122b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
123b3a44c85SBarry Smith {
124b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
125b3a44c85SBarry Smith   const MatScalar *aa;
126b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
127b3a44c85SBarry Smith   const PetscInt  *ii;
128b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
129b3a44c85SBarry Smith   PetscErrorCode  ierr;
130b3a44c85SBarry Smith 
131b3a44c85SBarry Smith   PetscFunctionBegin;
132b3a44c85SBarry Smith   *keptrows = 0;
133b3a44c85SBarry Smith   ii        = a->i;
134b3a44c85SBarry Smith   for (i=0; i<m; i++) {
135b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
136b3a44c85SBarry Smith     if (!n) {
137b3a44c85SBarry Smith       cnt++;
138b3a44c85SBarry Smith       goto ok1;
139b3a44c85SBarry Smith     }
140b3a44c85SBarry Smith     aa = a->a + ii[i];
141b3a44c85SBarry Smith     for (j=0; j<n; j++) {
142b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
143b3a44c85SBarry Smith     }
144b3a44c85SBarry Smith     cnt++;
145b3a44c85SBarry Smith ok1:;
146b3a44c85SBarry Smith   }
147b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
148785e854fSJed Brown   ierr = PetscMalloc1((A->rmap->n-cnt),&rows);CHKERRQ(ierr);
149b3a44c85SBarry Smith   cnt  = 0;
150b3a44c85SBarry Smith   for (i=0; i<m; i++) {
151b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
152b3a44c85SBarry Smith     if (!n) continue;
153b3a44c85SBarry Smith     aa = a->a + ii[i];
154b3a44c85SBarry Smith     for (j=0; j<n; j++) {
155b3a44c85SBarry Smith       if (aa[j] != 0.0) {
156b3a44c85SBarry Smith         rows[cnt++] = i;
157b3a44c85SBarry Smith         break;
158b3a44c85SBarry Smith       }
159b3a44c85SBarry Smith     }
160b3a44c85SBarry Smith   }
161b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
162b3a44c85SBarry Smith   PetscFunctionReturn(0);
163b3a44c85SBarry Smith }
164b3a44c85SBarry Smith 
165b3a44c85SBarry Smith #undef __FUNCT__
16679299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1677087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
16879299369SBarry Smith {
16979299369SBarry Smith   PetscErrorCode ierr;
17079299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
171d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
17254f21887SBarry Smith   MatScalar      *aa = aij->a;
17354f21887SBarry Smith   PetscScalar    *v;
174ace3abfcSBarry Smith   PetscBool      missing;
17579299369SBarry Smith 
17679299369SBarry Smith   PetscFunctionBegin;
17709f38230SBarry Smith   if (Y->assembled) {
1780298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
17909f38230SBarry Smith     if (!missing) {
18079299369SBarry Smith       diag = aij->diag;
18179299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
18279299369SBarry Smith       if (is == INSERT_VALUES) {
18379299369SBarry Smith         for (i=0; i<m; i++) {
18479299369SBarry Smith           aa[diag[i]] = v[i];
18579299369SBarry Smith         }
18679299369SBarry Smith       } else {
18779299369SBarry Smith         for (i=0; i<m; i++) {
18879299369SBarry Smith           aa[diag[i]] += v[i];
18979299369SBarry Smith         }
19079299369SBarry Smith       }
19179299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
19279299369SBarry Smith       PetscFunctionReturn(0);
19379299369SBarry Smith     }
194acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
19509f38230SBarry Smith   }
19609f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
19709f38230SBarry Smith   PetscFunctionReturn(0);
19809f38230SBarry Smith }
19979299369SBarry Smith 
20079299369SBarry Smith #undef __FUNCT__
2014a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
2021a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
20317ab2063SBarry Smith {
204416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
205dfbe8321SBarry Smith   PetscErrorCode ierr;
20697f1f81fSBarry Smith   PetscInt       i,ishift;
20717ab2063SBarry Smith 
2083a40ed3dSBarry Smith   PetscFunctionBegin;
209d0f46423SBarry Smith   *m = A->rmap->n;
2103a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
211bfeeae90SHong Zhang   ishift = 0;
21253e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
2131a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
214bfeeae90SHong Zhang   } else if (oshift == 1) {
2151a83f524SJed Brown     PetscInt *tia;
216d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2173b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
218785e854fSJed Brown     ierr = PetscMalloc1((A->rmap->n+1),&tia);CHKERRQ(ierr);
2191a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2201a83f524SJed Brown     *ia = tia;
221ecc77c7aSBarry Smith     if (ja) {
2221a83f524SJed Brown       PetscInt *tja;
223785e854fSJed Brown       ierr = PetscMalloc1((nz+1),&tja);CHKERRQ(ierr);
2241a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2251a83f524SJed Brown       *ja = tja;
226ecc77c7aSBarry Smith     }
2276945ee14SBarry Smith   } else {
228ecc77c7aSBarry Smith     *ia = a->i;
229ecc77c7aSBarry Smith     if (ja) *ja = a->j;
230a2ce50c7SBarry Smith   }
2313a40ed3dSBarry Smith   PetscFunctionReturn(0);
232a2744918SBarry Smith }
233a2744918SBarry Smith 
2344a2ae208SSatish Balay #undef __FUNCT__
2354a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
2361a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2376945ee14SBarry Smith {
238dfbe8321SBarry Smith   PetscErrorCode ierr;
2396945ee14SBarry Smith 
2403a40ed3dSBarry Smith   PetscFunctionBegin;
2413a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
242bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
243606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
244ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
245bcd2baecSBarry Smith   }
2463a40ed3dSBarry Smith   PetscFunctionReturn(0);
24717ab2063SBarry Smith }
24817ab2063SBarry Smith 
2494a2ae208SSatish Balay #undef __FUNCT__
2504a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
2511a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2523b2fbd54SBarry Smith {
2533b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
254dfbe8321SBarry Smith   PetscErrorCode ierr;
255d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
25697f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2573b2fbd54SBarry Smith 
2583a40ed3dSBarry Smith   PetscFunctionBegin;
259899cda47SBarry Smith   *nn = n;
2603a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2613b2fbd54SBarry Smith   if (symmetric) {
2621a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2633b2fbd54SBarry Smith   } else {
2641795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
265785e854fSJed Brown     ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
266785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
2673b2fbd54SBarry Smith     jj   = a->j;
2683b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
269bfeeae90SHong Zhang       collengths[jj[i]]++;
2703b2fbd54SBarry Smith     }
2713b2fbd54SBarry Smith     cia[0] = oshift;
2723b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2733b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2743b2fbd54SBarry Smith     }
27597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2763b2fbd54SBarry Smith     jj   = a->j;
277a93ec695SBarry Smith     for (row=0; row<m; row++) {
278a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
279a93ec695SBarry Smith       for (i=0; i<mr; i++) {
280bfeeae90SHong Zhang         col = *jj++;
2812205254eSKarl Rupp 
2823b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2833b2fbd54SBarry Smith       }
2843b2fbd54SBarry Smith     }
285606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2863b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2873b2fbd54SBarry Smith   }
2883a40ed3dSBarry Smith   PetscFunctionReturn(0);
2893b2fbd54SBarry Smith }
2903b2fbd54SBarry Smith 
2914a2ae208SSatish Balay #undef __FUNCT__
2924a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2931a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2943b2fbd54SBarry Smith {
295dfbe8321SBarry Smith   PetscErrorCode ierr;
296606d414cSSatish Balay 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
2983a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2993b2fbd54SBarry Smith 
300606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
301606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
3023a40ed3dSBarry Smith   PetscFunctionReturn(0);
3033b2fbd54SBarry Smith }
3043b2fbd54SBarry Smith 
3057cee066cSHong Zhang /*
3067cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
3077cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
308040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
3097cee066cSHong Zhang */
3107cee066cSHong Zhang #undef __FUNCT__
3117cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
3127cee066cSHong 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)
3137cee066cSHong Zhang {
3147cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3157cee066cSHong Zhang   PetscErrorCode ierr;
3167cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
3177cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
3187cee066cSHong Zhang   PetscInt       *cspidx;
3197cee066cSHong Zhang 
3207cee066cSHong Zhang   PetscFunctionBegin;
3217cee066cSHong Zhang   *nn = n;
3227cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
323625f6d37SHong Zhang 
3241795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
325785e854fSJed Brown   ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
326785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
327785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr);
3287cee066cSHong Zhang   jj   = a->j;
3297cee066cSHong Zhang   for (i=0; i<nz; i++) {
3307cee066cSHong Zhang     collengths[jj[i]]++;
3317cee066cSHong Zhang   }
3327cee066cSHong Zhang   cia[0] = oshift;
3337cee066cSHong Zhang   for (i=0; i<n; i++) {
3347cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3357cee066cSHong Zhang   }
3367cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3377cee066cSHong Zhang   jj   = a->j;
3387cee066cSHong Zhang   for (row=0; row<m; row++) {
3397cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3407cee066cSHong Zhang     for (i=0; i<mr; i++) {
3417cee066cSHong Zhang       col = *jj++;
3427cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3437cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3447cee066cSHong Zhang     }
3457cee066cSHong Zhang   }
3467cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3477cee066cSHong Zhang   *ia    = cia; *ja = cja;
3487cee066cSHong Zhang   *spidx = cspidx;
3497cee066cSHong Zhang   PetscFunctionReturn(0);
3507cee066cSHong Zhang }
3517cee066cSHong Zhang 
3527cee066cSHong Zhang #undef __FUNCT__
3537cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3547cee066cSHong 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)
3557cee066cSHong Zhang {
3567cee066cSHong Zhang   PetscErrorCode ierr;
3577cee066cSHong Zhang 
3587cee066cSHong Zhang   PetscFunctionBegin;
3595243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3607cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3617cee066cSHong Zhang   PetscFunctionReturn(0);
3627cee066cSHong Zhang }
3637cee066cSHong Zhang 
36487d4246cSBarry Smith #undef __FUNCT__
36587d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
36687d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
36787d4246cSBarry Smith {
36887d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
36987d4246cSBarry Smith   PetscInt       *ai = a->i;
37087d4246cSBarry Smith   PetscErrorCode ierr;
37187d4246cSBarry Smith 
37287d4246cSBarry Smith   PetscFunctionBegin;
37387d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
37487d4246cSBarry Smith   PetscFunctionReturn(0);
37587d4246cSBarry Smith }
37687d4246cSBarry Smith 
3774a2ae208SSatish Balay #undef __FUNCT__
378bd04181cSBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast"
379bd04181cSBarry Smith /*
380bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
381bd04181cSBarry Smith 
382bd04181cSBarry Smith       -   a single row of values is set with each call
383bd04181cSBarry Smith       -   the local to global mapping is the identity
384bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
385bd04181cSBarry Smith       -   the values are always added to the matrix, not set
386bd04181cSBarry Smith       -   the columns indices on each call are sorted
387bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
388bd04181cSBarry Smith 
389bd04181cSBarry Smith */
390bd04181cSBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
391bd04181cSBarry Smith {
392bd04181cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
393bd04181cSBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
394bd04181cSBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen;
395bd04181cSBarry Smith   const PetscInt *aj = a->j;
396bd04181cSBarry Smith   MatScalar      *ap,*aa = a->a;
397bd04181cSBarry Smith PetscBool      found;
398bd04181cSBarry Smith 
399bd04181cSBarry Smith   PetscFunctionBegin;
400bd04181cSBarry Smith if (m >1) printf("trouble1\n");
401bd04181cSBarry Smith   row = im[0];
402bd04181cSBarry Smith   rp   = aj + ai[row];
403bd04181cSBarry Smith   ap   = aa + ai[row];
404bd04181cSBarry Smith   nrow = ailen[row];
405bd04181cSBarry Smith   low  = 0;
406bd04181cSBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
407bd04181cSBarry Smith     col = in[l];
408bd04181cSBarry Smith     high = nrow;
409bd04181cSBarry Smith found = PETSC_FALSE;
410bd04181cSBarry Smith printf("%d %d %d %d %d %d\n",l,low,high-1,rp[low],rp[high-1],col);
411bd04181cSBarry Smith if (l > 0 && in[l] < in[l-1]) printf("trouble3 %d %d\n",in[l-1],in[l]);
412bd04181cSBarry Smith     while (high-low > 5) {
413bd04181cSBarry Smith       t = (low+high)/2;
414bd04181cSBarry Smith       if (rp[t] > col) high = t;
415bd04181cSBarry Smith       else low = t;
416bd04181cSBarry Smith     }
417bd04181cSBarry Smith     for (i=low; i<high; i++) {
418bd04181cSBarry Smith       if (rp[i] == col) {
419bd04181cSBarry Smith         ap[i] += v[l];
420bd04181cSBarry Smith         low = i + 1;
421bd04181cSBarry Smith found = PETSC_TRUE;
422bd04181cSBarry Smith         break;
423bd04181cSBarry Smith       }
424bd04181cSBarry Smith     }
425bd04181cSBarry Smith if (!found) printf("trouble2 %d %d %d %d %d\n",low,high-1,rp[low],rp[high-1],col);
426bd04181cSBarry Smith   }
427bd04181cSBarry Smith   PetscFunctionReturn(0);
428bd04181cSBarry Smith }
429bd04181cSBarry Smith 
430bd04181cSBarry Smith #undef __FUNCT__
4314a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
43297f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
43317ab2063SBarry Smith {
434416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
435e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
43697f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
4376849ba73SBarry Smith   PetscErrorCode ierr;
438e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
43954f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
440ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
441ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
44217ab2063SBarry Smith 
4433a40ed3dSBarry Smith   PetscFunctionBegin;
44471fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
44517ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
446416022c9SBarry Smith     row = im[k];
4475ef9f2a5SBarry Smith     if (row < 0) continue;
4482515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
449e32f2f54SBarry 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);
4503b2fbd54SBarry Smith #endif
451bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
45217ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
453416022c9SBarry Smith     low  = 0;
454c71e6ed7SBarry Smith     high = nrow;
45517ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4565ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4572515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
458e32f2f54SBarry 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);
4593b2fbd54SBarry Smith #endif
460bfeeae90SHong Zhang       col = in[l];
46116371a99SBarry Smith       if (v) {
4624b0e389bSBarry Smith         if (roworiented) {
4635ef9f2a5SBarry Smith           value = v[l + k*n];
464bef8e0ddSBarry Smith         } else {
4654b0e389bSBarry Smith           value = v[k + l*m];
4664b0e389bSBarry Smith         }
46716371a99SBarry Smith       } else {
46875567043SBarry Smith         value = 0.;
46916371a99SBarry Smith       }
47033b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
47136db0b34SBarry Smith 
4722205254eSKarl Rupp       if (col <= lastcol) low = 0;
4732205254eSKarl Rupp       else high = nrow;
474e2ee6c50SBarry Smith       lastcol = col;
475416022c9SBarry Smith       while (high-low > 5) {
476416022c9SBarry Smith         t = (low+high)/2;
477416022c9SBarry Smith         if (rp[t] > col) high = t;
478416022c9SBarry Smith         else low = t;
47917ab2063SBarry Smith       }
480416022c9SBarry Smith       for (i=low; i<high; i++) {
48117ab2063SBarry Smith         if (rp[i] > col) break;
48217ab2063SBarry Smith         if (rp[i] == col) {
483416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
48417ab2063SBarry Smith           else ap[i] = value;
485e44c0bd4SBarry Smith           low = i + 1;
48617ab2063SBarry Smith           goto noinsert;
48717ab2063SBarry Smith         }
48817ab2063SBarry Smith       }
489abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
490c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
491e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
492fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
493c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
494416022c9SBarry Smith       /* shift up all the later entries in this row */
495416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
49617ab2063SBarry Smith         rp[ii+1] = rp[ii];
49717ab2063SBarry Smith         ap[ii+1] = ap[ii];
49817ab2063SBarry Smith       }
49917ab2063SBarry Smith       rp[i] = col;
50017ab2063SBarry Smith       ap[i] = value;
501416022c9SBarry Smith       low   = i + 1;
502e44c0bd4SBarry Smith noinsert:;
50317ab2063SBarry Smith     }
50417ab2063SBarry Smith     ailen[row] = nrow;
50517ab2063SBarry Smith   }
50688e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
5073a40ed3dSBarry Smith   PetscFunctionReturn(0);
50817ab2063SBarry Smith }
50917ab2063SBarry Smith 
51081824310SBarry Smith 
5114a2ae208SSatish Balay #undef __FUNCT__
5124a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
513a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
5147eb43aa7SLois Curfman McInnes {
5157eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
51697f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
51797f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
51854f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
5197eb43aa7SLois Curfman McInnes 
5203a40ed3dSBarry Smith   PetscFunctionBegin;
5217eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
5227eb43aa7SLois Curfman McInnes     row = im[k];
523e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
524e32f2f54SBarry 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);
525bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
5267eb43aa7SLois Curfman McInnes     nrow = ailen[row];
5277eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
528e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
529e32f2f54SBarry 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);
530bfeeae90SHong Zhang       col  = in[l];
5317eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5327eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5337eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5347eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5357eb43aa7SLois Curfman McInnes         else low = t;
5367eb43aa7SLois Curfman McInnes       }
5377eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5387eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5397eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
540b49de8d1SLois Curfman McInnes           *v++ = ap[i];
5417eb43aa7SLois Curfman McInnes           goto finished;
5427eb43aa7SLois Curfman McInnes         }
5437eb43aa7SLois Curfman McInnes       }
54497e567efSBarry Smith       *v++ = 0.0;
5457eb43aa7SLois Curfman McInnes finished:;
5467eb43aa7SLois Curfman McInnes     }
5477eb43aa7SLois Curfman McInnes   }
5483a40ed3dSBarry Smith   PetscFunctionReturn(0);
5497eb43aa7SLois Curfman McInnes }
5507eb43aa7SLois Curfman McInnes 
55117ab2063SBarry Smith 
5524a2ae208SSatish Balay #undef __FUNCT__
5534a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
554dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
55517ab2063SBarry Smith {
556416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5576849ba73SBarry Smith   PetscErrorCode ierr;
5586f69ff64SBarry Smith   PetscInt       i,*col_lens;
5596f69ff64SBarry Smith   int            fd;
560b37d52dbSMark F. Adams   FILE           *file;
56117ab2063SBarry Smith 
5623a40ed3dSBarry Smith   PetscFunctionBegin;
563b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
564785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
5652205254eSKarl Rupp 
5660700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
567d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
568d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
569416022c9SBarry Smith   col_lens[3] = a->nz;
570416022c9SBarry Smith 
571416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
572d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
573416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
57417ab2063SBarry Smith   }
575d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
576606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
577416022c9SBarry Smith 
578416022c9SBarry Smith   /* store column indices (zero start index) */
5796f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
580416022c9SBarry Smith 
581416022c9SBarry Smith   /* store nonzero values */
5826f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
583b37d52dbSMark F. Adams 
584b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
585b37d52dbSMark F. Adams   if (file) {
586b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
587b37d52dbSMark F. Adams   }
5883a40ed3dSBarry Smith   PetscFunctionReturn(0);
58917ab2063SBarry Smith }
590416022c9SBarry Smith 
59109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
592cd155464SBarry Smith 
5934a2ae208SSatish Balay #undef __FUNCT__
5944a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
595dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
596416022c9SBarry Smith {
597416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
598dfbe8321SBarry Smith   PetscErrorCode    ierr;
599d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
600e060cb09SBarry Smith   const char        *name;
601f3ef73ceSBarry Smith   PetscViewerFormat format;
60217ab2063SBarry Smith 
6033a40ed3dSBarry Smith   PetscFunctionBegin;
604b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
60571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
60697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
607014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
608d00d2cf4SBarry Smith       nofinalvalue = 1;
609d00d2cf4SBarry Smith     }
610d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
611d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
61277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
61377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
614b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
61517ab2063SBarry Smith 
61617ab2063SBarry Smith     for (i=0; i<m; i++) {
617416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
618aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
61977431f27SBarry 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);
62017ab2063SBarry Smith #else
62177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
62217ab2063SBarry Smith #endif
62317ab2063SBarry Smith       }
62417ab2063SBarry Smith     }
625d00d2cf4SBarry Smith     if (nofinalvalue) {
626d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
627d00d2cf4SBarry Smith     }
628317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
629fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
630d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
63168369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
632cd155464SBarry Smith     PetscFunctionReturn(0);
633fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
634d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
635dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
63644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
63777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
63844cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
639aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
641ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
643ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
64436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
645ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6466831982aSBarry Smith         }
64744cd7ae7SLois Curfman McInnes #else
648ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
64944cd7ae7SLois Curfman McInnes #endif
65044cd7ae7SLois Curfman McInnes       }
651b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
65244cd7ae7SLois Curfman McInnes     }
653d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
654fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
65597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
656d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
657dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
658785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
659496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
660496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
661496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
662496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
663aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
66436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
665496be53dSLois Curfman McInnes #else
666496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
667496be53dSLois Curfman McInnes #endif
668496be53dSLois Curfman McInnes         }
669496be53dSLois Curfman McInnes       }
670496be53dSLois Curfman McInnes     }
6712e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
67277431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6732e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6742205254eSKarl Rupp       if (i+4<m) {
6752205254eSKarl 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);
6762205254eSKarl Rupp       } else if (i+3<m) {
6772205254eSKarl 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);
6782205254eSKarl Rupp       } else if (i+2<m) {
6792205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6802205254eSKarl Rupp       } else if (i+1<m) {
6812205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6822205254eSKarl Rupp       } else if (i<m) {
6832205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6842205254eSKarl Rupp       } else {
6852205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6862205254eSKarl Rupp       }
687496be53dSLois Curfman McInnes     }
688b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
689606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
690496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
691496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
69277431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
693496be53dSLois Curfman McInnes       }
694b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
695496be53dSLois Curfman McInnes     }
696b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
697496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
698496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
699496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
700aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
702b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7036831982aSBarry Smith           }
704496be53dSLois Curfman McInnes #else
705b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
706496be53dSLois Curfman McInnes #endif
707496be53dSLois Curfman McInnes         }
708496be53dSLois Curfman McInnes       }
709b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
710496be53dSLois Curfman McInnes     }
711d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
712fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
71397f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
71487828ca2SBarry Smith     PetscScalar value;
71568f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
71668f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
71768f1ed48SBarry Smith 
71868f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
71968f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
72068f1ed48SBarry Smith         realonly = PETSC_FALSE;
72168f1ed48SBarry Smith         break;
72268f1ed48SBarry Smith       }
72368f1ed48SBarry Smith     }
72468f1ed48SBarry Smith #endif
72502594712SBarry Smith 
726d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
727dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
72802594712SBarry Smith     for (i=0; i<m; i++) {
72902594712SBarry Smith       jcnt = 0;
730d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
731e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
73202594712SBarry Smith           value = a->a[cnt++];
733e24b481bSBarry Smith           jcnt++;
73402594712SBarry Smith         } else {
73502594712SBarry Smith           value = 0.0;
73602594712SBarry Smith         }
737aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
73868f1ed48SBarry Smith         if (realonly) {
73968f1ed48SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",PetscRealPart(value));CHKERRQ(ierr);
74068f1ed48SBarry Smith         } else {
741b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
74268f1ed48SBarry Smith         }
74302594712SBarry Smith #else
744b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
74502594712SBarry Smith #endif
74602594712SBarry Smith       }
747b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
74802594712SBarry Smith     }
749d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7503c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
751150b93efSMatthew G. Knepley     PetscInt fshift=1;
752d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7533c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
7543c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
7553c215bfdSMatthew Knepley #else
7563c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
7573c215bfdSMatthew Knepley #endif
758d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7593c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
7603c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
7613c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
7623c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
763150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7643c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
765150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7663c215bfdSMatthew Knepley         } else {
767150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
7683c215bfdSMatthew Knepley         }
7693c215bfdSMatthew Knepley #else
770150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7713c215bfdSMatthew Knepley #endif
7723c215bfdSMatthew Knepley       }
7733c215bfdSMatthew Knepley     }
774d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7753a40ed3dSBarry Smith   } else {
776d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
777dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
778d5f3da31SBarry Smith     if (A->factortype) {
77916cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
78016cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
78116cd7e1dSShri Abhyankar         /* L part */
78216cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
78316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
78416cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
785ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
78616cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
787ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
78816cd7e1dSShri Abhyankar           } else {
789ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
79016cd7e1dSShri Abhyankar           }
79116cd7e1dSShri Abhyankar #else
792ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
79316cd7e1dSShri Abhyankar #endif
79416cd7e1dSShri Abhyankar         }
79516cd7e1dSShri Abhyankar         /* diagonal */
79616cd7e1dSShri Abhyankar         j = a->diag[i];
79716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
79816cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
799ba0e910bSBarry 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);
80016cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
801ba0e910bSBarry 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);
80216cd7e1dSShri Abhyankar         } else {
803ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
80416cd7e1dSShri Abhyankar         }
80516cd7e1dSShri Abhyankar #else
806ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
80716cd7e1dSShri Abhyankar #endif
80816cd7e1dSShri Abhyankar 
80916cd7e1dSShri Abhyankar         /* U part */
81016cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
81116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
81216cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
813ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
81416cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
815ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
81616cd7e1dSShri Abhyankar           } else {
817ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
81816cd7e1dSShri Abhyankar           }
81916cd7e1dSShri Abhyankar #else
820ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
82116cd7e1dSShri Abhyankar #endif
82216cd7e1dSShri Abhyankar         }
82316cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
82416cd7e1dSShri Abhyankar       }
82516cd7e1dSShri Abhyankar     } else {
82617ab2063SBarry Smith       for (i=0; i<m; i++) {
82777431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
828416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
829aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
83036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
831ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
83236db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
833ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8343a40ed3dSBarry Smith           } else {
835ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
83617ab2063SBarry Smith           }
83717ab2063SBarry Smith #else
838ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
83917ab2063SBarry Smith #endif
84017ab2063SBarry Smith         }
841b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
84217ab2063SBarry Smith       }
84316cd7e1dSShri Abhyankar     }
844d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
84517ab2063SBarry Smith   }
846b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
8473a40ed3dSBarry Smith   PetscFunctionReturn(0);
848416022c9SBarry Smith }
849416022c9SBarry Smith 
8509804daf3SBarry Smith #include <petscdraw.h>
8514a2ae208SSatish Balay #undef __FUNCT__
8524a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
853dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
854416022c9SBarry Smith {
855480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
856416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
857dfbe8321SBarry Smith   PetscErrorCode    ierr;
858d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
85936db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
860b0a32e0cSBarry Smith   PetscViewer       viewer;
861f3ef73ceSBarry Smith   PetscViewerFormat format;
862cddf8d76SBarry Smith 
8633a40ed3dSBarry Smith   PetscFunctionBegin;
864480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
865b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
86619bcc07fSBarry Smith 
867b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
868416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8690513a670SBarry Smith 
870fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
8710513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
872b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
873416022c9SBarry Smith     for (i=0; i<m; i++) {
874cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
875bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
876bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
87736db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
878b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
879cddf8d76SBarry Smith       }
880cddf8d76SBarry Smith     }
881b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
882cddf8d76SBarry Smith     for (i=0; i<m; i++) {
883cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
884bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
885bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
886cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
887b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
888cddf8d76SBarry Smith       }
889cddf8d76SBarry Smith     }
890b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
891cddf8d76SBarry Smith     for (i=0; i<m; i++) {
892cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
893bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
894bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
89536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
896b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
897416022c9SBarry Smith       }
898416022c9SBarry Smith     }
8990513a670SBarry Smith   } else {
9000513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
9010513a670SBarry Smith     /* first determine max of all nonzero values */
90297f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
903b0a32e0cSBarry Smith     PetscDraw popup;
90436db0b34SBarry Smith     PetscReal scale;
9050513a670SBarry Smith 
9060513a670SBarry Smith     for (i=0; i<nz; i++) {
9070513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
9080513a670SBarry Smith     }
909b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
910b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
9112205254eSKarl Rupp     if (popup) {
9122205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
9132205254eSKarl Rupp     }
9140513a670SBarry Smith     count = 0;
9150513a670SBarry Smith     for (i=0; i<m; i++) {
9160513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
917bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
918bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
91997f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
920b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
9210513a670SBarry Smith         count++;
9220513a670SBarry Smith       }
9230513a670SBarry Smith     }
9240513a670SBarry Smith   }
925480ef9eaSBarry Smith   PetscFunctionReturn(0);
926480ef9eaSBarry Smith }
927cddf8d76SBarry Smith 
9289804daf3SBarry Smith #include <petscdraw.h>
9294a2ae208SSatish Balay #undef __FUNCT__
9304a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
931dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
932480ef9eaSBarry Smith {
933dfbe8321SBarry Smith   PetscErrorCode ierr;
934b0a32e0cSBarry Smith   PetscDraw      draw;
93536db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
936ace3abfcSBarry Smith   PetscBool      isnull;
937480ef9eaSBarry Smith 
938480ef9eaSBarry Smith   PetscFunctionBegin;
939b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
940b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
941480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
942480ef9eaSBarry Smith 
943480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
944d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
945480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
946b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
947b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
9480298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
9493a40ed3dSBarry Smith   PetscFunctionReturn(0);
950416022c9SBarry Smith }
951416022c9SBarry Smith 
9524a2ae208SSatish Balay #undef __FUNCT__
9534a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
954dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
955416022c9SBarry Smith {
956dfbe8321SBarry Smith   PetscErrorCode ierr;
957ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
958416022c9SBarry Smith 
9593a40ed3dSBarry Smith   PetscFunctionBegin;
960251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
961251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
962251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
963c45a1595SBarry Smith   if (iascii) {
9643a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9650f5bd95cSBarry Smith   } else if (isbinary) {
9663a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9670f5bd95cSBarry Smith   } else if (isdraw) {
9683a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
96911aeaf0aSBarry Smith   }
9704108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9713a40ed3dSBarry Smith   PetscFunctionReturn(0);
97217ab2063SBarry Smith }
97319bcc07fSBarry Smith 
9744a2ae208SSatish Balay #undef __FUNCT__
9754a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
976dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
97717ab2063SBarry Smith {
978416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9796849ba73SBarry Smith   PetscErrorCode ierr;
98097f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
981d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
98254f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9833447b6efSHong Zhang   PetscReal      ratio  = 0.6;
98417ab2063SBarry Smith 
9853a40ed3dSBarry Smith   PetscFunctionBegin;
9863a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
98717ab2063SBarry Smith 
98843ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
98917ab2063SBarry Smith   for (i=1; i<m; i++) {
990416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
99117ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
99294a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
99317ab2063SBarry Smith     if (fshift) {
994bfeeae90SHong Zhang       ip = aj + ai[i];
995bfeeae90SHong Zhang       ap = aa + ai[i];
99617ab2063SBarry Smith       N  = ailen[i];
99717ab2063SBarry Smith       for (j=0; j<N; j++) {
99817ab2063SBarry Smith         ip[j-fshift] = ip[j];
99917ab2063SBarry Smith         ap[j-fshift] = ap[j];
100017ab2063SBarry Smith       }
100117ab2063SBarry Smith     }
100217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
100317ab2063SBarry Smith   }
100417ab2063SBarry Smith   if (m) {
100517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
100617ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
100717ab2063SBarry Smith   }
10087b083b7cSBarry Smith 
100917ab2063SBarry Smith   /* reset ilen and imax for each row */
10107b083b7cSBarry Smith   a->nonzerorowcnt = 0;
101117ab2063SBarry Smith   for (i=0; i<m; i++) {
101217ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
10137b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
101417ab2063SBarry Smith   }
1015bfeeae90SHong Zhang   a->nz = ai[m];
101665e19b50SBarry 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);
101717ab2063SBarry Smith 
101809f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1019d0f46423SBarry 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);
1020ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
1021ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
10222205254eSKarl Rupp 
10238e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1024dd5f02e7SSatish Balay   a->reallocs         = 0;
10254e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
102636db0b34SBarry Smith   a->rmax             = rmax;
10274e220ebcSLois Curfman McInnes 
102811e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
10292205254eSKarl Rupp 
103088e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
103171c2f376SKris Buschelman 
10324108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
103371f1c65dSBarry Smith 
1034acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10353a40ed3dSBarry Smith   PetscFunctionReturn(0);
103617ab2063SBarry Smith }
103717ab2063SBarry Smith 
10384a2ae208SSatish Balay #undef __FUNCT__
103999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
104099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
104199cafbc1SBarry Smith {
104299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
104399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
104454f21887SBarry Smith   MatScalar      *aa = a->a;
1045acf2f550SJed Brown   PetscErrorCode ierr;
104699cafbc1SBarry Smith 
104799cafbc1SBarry Smith   PetscFunctionBegin;
104899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1049acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
105099cafbc1SBarry Smith   PetscFunctionReturn(0);
105199cafbc1SBarry Smith }
105299cafbc1SBarry Smith 
105399cafbc1SBarry Smith #undef __FUNCT__
105499cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
105599cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
105699cafbc1SBarry Smith {
105799cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
105899cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
105954f21887SBarry Smith   MatScalar      *aa = a->a;
1060acf2f550SJed Brown   PetscErrorCode ierr;
106199cafbc1SBarry Smith 
106299cafbc1SBarry Smith   PetscFunctionBegin;
106399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1064acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
106599cafbc1SBarry Smith   PetscFunctionReturn(0);
106699cafbc1SBarry Smith }
106799cafbc1SBarry Smith 
106878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
106978b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
107078b84d54SShri Abhyankar {
107178b84d54SShri Abhyankar   PetscErrorCode ierr;
107278b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
107378b84d54SShri Abhyankar   PetscInt       n,start,end;
107478b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
107578b84d54SShri Abhyankar 
107678b84d54SShri Abhyankar   start = trstarts[thread_id];
107778b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
107819baf141SJed Brown   n     = a->i[end] - a->i[start];
107919baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
108078b84d54SShri Abhyankar   return 0;
108178b84d54SShri Abhyankar }
108278b84d54SShri Abhyankar 
108378b84d54SShri Abhyankar #undef __FUNCT__
108478b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
108578b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
108678b84d54SShri Abhyankar {
108778b84d54SShri Abhyankar   PetscErrorCode ierr;
108878b84d54SShri Abhyankar 
108978b84d54SShri Abhyankar   PetscFunctionBegin;
1090ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1091acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
109278b84d54SShri Abhyankar   PetscFunctionReturn(0);
109378b84d54SShri Abhyankar }
109478b84d54SShri Abhyankar #else
109599cafbc1SBarry Smith #undef __FUNCT__
10964a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1097dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
109817ab2063SBarry Smith {
1099416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1100dfbe8321SBarry Smith   PetscErrorCode ierr;
11013a40ed3dSBarry Smith 
11023a40ed3dSBarry Smith   PetscFunctionBegin;
1103d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1104acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
11053a40ed3dSBarry Smith   PetscFunctionReturn(0);
110617ab2063SBarry Smith }
110778b84d54SShri Abhyankar #endif
1108416022c9SBarry Smith 
11094a2ae208SSatish Balay #undef __FUNCT__
11104a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1111dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
111217ab2063SBarry Smith {
1113416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1114dfbe8321SBarry Smith   PetscErrorCode ierr;
1115d5d45c9bSBarry Smith 
11163a40ed3dSBarry Smith   PetscFunctionBegin;
1117aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1118d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
111917ab2063SBarry Smith #endif
1120e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
11216bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
11226bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
112305b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1124d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
112505b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
112671f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
112705b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
11286bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
112905b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
11306bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
113105b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
11326bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1133cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
11340b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1135a30b2313SHong Zhang 
11364108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1137bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1138901853e0SKris Buschelman 
1139dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1140bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1141bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1142bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1143bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1144bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1145bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1146bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1147bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1148bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1149bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
115117ab2063SBarry Smith }
115217ab2063SBarry Smith 
11534a2ae208SSatish Balay #undef __FUNCT__
11544a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1155ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
115617ab2063SBarry Smith {
1157416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11584846f1f5SKris Buschelman   PetscErrorCode ierr;
11593a40ed3dSBarry Smith 
11603a40ed3dSBarry Smith   PetscFunctionBegin;
1161a65d3064SKris Buschelman   switch (op) {
1162a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11634e0d8c25SBarry Smith     a->roworiented = flg;
1164a65d3064SKris Buschelman     break;
1165a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1166a9817697SBarry Smith     a->keepnonzeropattern = flg;
1167a65d3064SKris Buschelman     break;
1168512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1169512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1170a65d3064SKris Buschelman     break;
1171a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11724e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1173a65d3064SKris Buschelman     break;
1174a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11754e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1176a65d3064SKris Buschelman     break;
117728b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
117828b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
117928b2fa4aSMatthew Knepley     break;
1180a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11814e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11820df259c2SBarry Smith     break;
11833d472b54SHong Zhang   case MAT_SPD:
1184b1646e73SJed Brown   case MAT_SYMMETRIC:
1185b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1186b1646e73SJed Brown   case MAT_HERMITIAN:
1187b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11885021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11895021d80fSJed Brown     break;
11904e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1191a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1192a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1193290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1194a65d3064SKris Buschelman     break;
1195b87ac2d8SJed Brown   case MAT_USE_INODES:
1196b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1197b87ac2d8SJed Brown     break;
1198a65d3064SKris Buschelman   default:
1199e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1200a65d3064SKris Buschelman   }
12014108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
12023a40ed3dSBarry Smith   PetscFunctionReturn(0);
120317ab2063SBarry Smith }
120417ab2063SBarry Smith 
12054a2ae208SSatish Balay #undef __FUNCT__
12064a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1207dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
120817ab2063SBarry Smith {
1209416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12106849ba73SBarry Smith   PetscErrorCode ierr;
1211d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
121235e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
121317ab2063SBarry Smith 
12143a40ed3dSBarry Smith   PetscFunctionBegin;
1215d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1216e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
121735e7444dSHong Zhang 
1218d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1219d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
122035e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
12212c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
122235e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
122335e7444dSHong Zhang     PetscFunctionReturn(0);
122435e7444dSHong Zhang   }
122535e7444dSHong Zhang 
12262dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
12271ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
122835e7444dSHong Zhang   for (i=0; i<n; i++) {
122935e7444dSHong Zhang     nz = ai[i+1] - ai[i];
12302f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
123135e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
123235e7444dSHong Zhang       if (aj[j] == i) {
123335e7444dSHong Zhang         x[i] = aa[j];
123417ab2063SBarry Smith         break;
123517ab2063SBarry Smith       }
123617ab2063SBarry Smith     }
123717ab2063SBarry Smith   }
12381ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
12393a40ed3dSBarry Smith   PetscFunctionReturn(0);
124017ab2063SBarry Smith }
124117ab2063SBarry Smith 
1242c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
12434a2ae208SSatish Balay #undef __FUNCT__
12444a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1245dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
124617ab2063SBarry Smith {
1247416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12485c897100SBarry Smith   PetscScalar    *x,*y;
1249dfbe8321SBarry Smith   PetscErrorCode ierr;
1250d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
12515c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1252a77337e4SBarry Smith   MatScalar         *v;
1253a77337e4SBarry Smith   PetscScalar       alpha;
12540298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
12553447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1256ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
12575c897100SBarry Smith #endif
125817ab2063SBarry Smith 
12593a40ed3dSBarry Smith   PetscFunctionBegin;
12602e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
12611ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
12621ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12635c897100SBarry Smith 
12645c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1265bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12665c897100SBarry Smith #else
12673447b6efSHong Zhang   if (usecprow) {
12683447b6efSHong Zhang     m    = cprow.nrows;
12693447b6efSHong Zhang     ii   = cprow.i;
12707b2bb3b9SHong Zhang     ridx = cprow.rindex;
12713447b6efSHong Zhang   } else {
12723447b6efSHong Zhang     ii = a->i;
12733447b6efSHong Zhang   }
127417ab2063SBarry Smith   for (i=0; i<m; i++) {
12753447b6efSHong Zhang     idx = a->j + ii[i];
12763447b6efSHong Zhang     v   = a->a + ii[i];
12773447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12783447b6efSHong Zhang     if (usecprow) {
12797b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12803447b6efSHong Zhang     } else {
128117ab2063SBarry Smith       alpha = x[i];
12823447b6efSHong Zhang     }
128304fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
128417ab2063SBarry Smith   }
12855c897100SBarry Smith #endif
1286dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
12871ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12881ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12893a40ed3dSBarry Smith   PetscFunctionReturn(0);
129017ab2063SBarry Smith }
129117ab2063SBarry Smith 
12924a2ae208SSatish Balay #undef __FUNCT__
12935c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1294dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12955c897100SBarry Smith {
1296dfbe8321SBarry Smith   PetscErrorCode ierr;
12975c897100SBarry Smith 
12985c897100SBarry Smith   PetscFunctionBegin;
1299170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
13005c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
13015c897100SBarry Smith   PetscFunctionReturn(0);
13025c897100SBarry Smith }
13035c897100SBarry Smith 
1304c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
130578b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
130678b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
130778b84d54SShri Abhyankar {
130878b84d54SShri Abhyankar   PetscErrorCode    ierr;
130978b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
131078b84d54SShri Abhyankar   PetscScalar       *y;
131178b84d54SShri Abhyankar   const PetscScalar *x;
131278b84d54SShri Abhyankar   const MatScalar   *aa;
131378b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
131478b84d54SShri Abhyankar   PetscInt          n,start,end,i;
131578b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
131678b84d54SShri Abhyankar   PetscScalar       sum;
131778b84d54SShri Abhyankar 
131878b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
131978b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
132078b84d54SShri Abhyankar   start = trstarts[thread_id];
132178b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
132278b84d54SShri Abhyankar   aj    = a->j;
132378b84d54SShri Abhyankar   aa    = a->a;
132478b84d54SShri Abhyankar   ai    = a->i;
132578b84d54SShri Abhyankar   for (i=start; i<end; i++) {
132678b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
132778b84d54SShri Abhyankar     aj  = a->j + ai[i];
132878b84d54SShri Abhyankar     aa  = a->a + ai[i];
132978b84d54SShri Abhyankar     sum = 0.0;
133078b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
133178b84d54SShri Abhyankar     y[i] = sum;
133278b84d54SShri Abhyankar   }
133378b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
133478b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
133578b84d54SShri Abhyankar   return 0;
133678b84d54SShri Abhyankar }
133778b84d54SShri Abhyankar 
133878b84d54SShri Abhyankar #undef __FUNCT__
133978b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
134078b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
134178b84d54SShri Abhyankar {
134278b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
134378b84d54SShri Abhyankar   PetscScalar       *y;
134478b84d54SShri Abhyankar   const PetscScalar *x;
134578b84d54SShri Abhyankar   const MatScalar   *aa;
134678b84d54SShri Abhyankar   PetscErrorCode    ierr;
134778b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
13480298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13497b083b7cSBarry Smith   PetscInt          n,i;
135078b84d54SShri Abhyankar   PetscScalar       sum;
135178b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
135278b84d54SShri Abhyankar 
135378b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
135478b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
135578b84d54SShri Abhyankar #endif
135678b84d54SShri Abhyankar 
135778b84d54SShri Abhyankar   PetscFunctionBegin;
135878b84d54SShri Abhyankar   aj = a->j;
135978b84d54SShri Abhyankar   aa = a->a;
136078b84d54SShri Abhyankar   ii = a->i;
136178b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
136278b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
136378b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
136478b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
136578b84d54SShri Abhyankar     ii   = a->compressedrow.i;
136678b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
136778b84d54SShri Abhyankar     for (i=0; i<m; i++) {
136878b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
136978b84d54SShri Abhyankar       aj          = a->j + ii[i];
137078b84d54SShri Abhyankar       aa          = a->a + ii[i];
137178b84d54SShri Abhyankar       sum         = 0.0;
137278b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
137378b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
137478b84d54SShri Abhyankar       y[*ridx++] = sum;
137578b84d54SShri Abhyankar     }
137678b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
137778b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
137878b84d54SShri Abhyankar   } else { /* do not use compressed row format */
137978b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
138078b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
138178b84d54SShri Abhyankar #else
1382ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
138378b84d54SShri Abhyankar #endif
138478b84d54SShri Abhyankar   }
13857b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
138678b84d54SShri Abhyankar   PetscFunctionReturn(0);
138778b84d54SShri Abhyankar }
138878b84d54SShri Abhyankar #else
13895c897100SBarry Smith #undef __FUNCT__
13904a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1391dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
139217ab2063SBarry Smith {
1393416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1394d9fead3dSBarry Smith   PetscScalar       *y;
139554f21887SBarry Smith   const PetscScalar *x;
139654f21887SBarry Smith   const MatScalar   *aa;
1397dfbe8321SBarry Smith   PetscErrorCode    ierr;
1398003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13990298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14007b083b7cSBarry Smith   PetscInt          n,i;
1401362ced78SSatish Balay   PetscScalar       sum;
1402ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
140317ab2063SBarry Smith 
1404b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
140597952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1406fee21e36SBarry Smith #endif
1407fee21e36SBarry Smith 
14083a40ed3dSBarry Smith   PetscFunctionBegin;
14093649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14101ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
141197952fefSHong Zhang   aj   = a->j;
141297952fefSHong Zhang   aa   = a->a;
1413416022c9SBarry Smith   ii   = a->i;
14144eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
141597952fefSHong Zhang     m    = a->compressedrow.nrows;
141697952fefSHong Zhang     ii   = a->compressedrow.i;
141797952fefSHong Zhang     ridx = a->compressedrow.rindex;
141897952fefSHong Zhang     for (i=0; i<m; i++) {
141997952fefSHong Zhang       n           = ii[i+1] - ii[i];
142097952fefSHong Zhang       aj          = a->j + ii[i];
142197952fefSHong Zhang       aa          = a->a + ii[i];
142297952fefSHong Zhang       sum         = 0.0;
1423003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1424003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
142597952fefSHong Zhang       y[*ridx++] = sum;
142697952fefSHong Zhang     }
142797952fefSHong Zhang   } else { /* do not use compressed row format */
1428b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1429b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1430b05257ddSBarry Smith #else
143178b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1432ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
143378b84d54SShri Abhyankar #else
143417ab2063SBarry Smith     for (i=0; i<m; i++) {
1435003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1436003131ecSBarry Smith       aj          = a->j + ii[i];
1437003131ecSBarry Smith       aa          = a->a + ii[i];
143817ab2063SBarry Smith       sum         = 0.0;
1439003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
144017ab2063SBarry Smith       y[i] = sum;
144117ab2063SBarry Smith     }
14428d195f9aSBarry Smith #endif
144378b84d54SShri Abhyankar #endif
1444b05257ddSBarry Smith   }
14457b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
14463649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
14471ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
14483a40ed3dSBarry Smith   PetscFunctionReturn(0);
144917ab2063SBarry Smith }
145078b84d54SShri Abhyankar #endif
145117ab2063SBarry Smith 
1452b434eb95SMatthew G. Knepley #undef __FUNCT__
1453b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1454b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1455b434eb95SMatthew G. Knepley {
1456b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1457b434eb95SMatthew G. Knepley   PetscScalar       *y;
1458b434eb95SMatthew G. Knepley   const PetscScalar *x;
1459b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1460b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1461b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1462b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1463b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1464b434eb95SMatthew G. Knepley   PetscScalar       sum;
1465b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1466b434eb95SMatthew G. Knepley 
1467b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1468b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1469b434eb95SMatthew G. Knepley #endif
1470b434eb95SMatthew G. Knepley 
1471b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1472b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1473b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1474b434eb95SMatthew G. Knepley   aj   = a->j;
1475b434eb95SMatthew G. Knepley   aa   = a->a;
1476b434eb95SMatthew G. Knepley   ii   = a->i;
1477b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1478b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1479b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1480b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1481b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1482b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1483b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1484b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1485b434eb95SMatthew G. Knepley       sum         = 0.0;
1486b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1487b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1488b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1489b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1490b434eb95SMatthew G. Knepley     }
1491b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1492b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1493b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1494b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1495b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1496b434eb95SMatthew G. Knepley       sum         = 0.0;
1497b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1498b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1499b434eb95SMatthew G. Knepley       y[i] = sum;
1500b434eb95SMatthew G. Knepley     }
1501b434eb95SMatthew G. Knepley   }
1502b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1503b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1504b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1505b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1506b434eb95SMatthew G. Knepley }
1507b434eb95SMatthew G. Knepley 
1508b434eb95SMatthew G. Knepley #undef __FUNCT__
1509b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1510b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1511b434eb95SMatthew G. Knepley {
1512b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1513b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1514b434eb95SMatthew G. Knepley   const PetscScalar *x;
1515b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1516b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1517b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1518b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1519b434eb95SMatthew G. Knepley   PetscScalar       sum;
1520b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1521b434eb95SMatthew G. Knepley 
1522b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1523b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1524b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1525b434eb95SMatthew G. Knepley   if (zz != yy) {
1526b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1527b434eb95SMatthew G. Knepley   } else {
1528b434eb95SMatthew G. Knepley     z = y;
1529b434eb95SMatthew G. Knepley   }
1530b434eb95SMatthew G. Knepley 
1531b434eb95SMatthew G. Knepley   aj = a->j;
1532b434eb95SMatthew G. Knepley   aa = a->a;
1533b434eb95SMatthew G. Knepley   ii = a->i;
1534b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1535b434eb95SMatthew G. Knepley     if (zz != yy) {
1536b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1537b434eb95SMatthew G. Knepley     }
1538b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1539b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1540b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1541b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1542b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1543b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1544b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1545b434eb95SMatthew G. Knepley       sum = y[*ridx];
1546b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1547b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1548b434eb95SMatthew G. Knepley     }
1549b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1550b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1551b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1552b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1553b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1554b434eb95SMatthew G. Knepley       sum = y[i];
1555b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1556b434eb95SMatthew G. Knepley       z[i] = sum;
1557b434eb95SMatthew G. Knepley     }
1558b434eb95SMatthew G. Knepley   }
1559b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1560b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1561b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1562b434eb95SMatthew G. Knepley   if (zz != yy) {
1563b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1564b434eb95SMatthew G. Knepley   }
1565b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1566b434eb95SMatthew G. Knepley }
1567b434eb95SMatthew G. Knepley 
1568c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
15694a2ae208SSatish Balay #undef __FUNCT__
15704a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1571dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
157217ab2063SBarry Smith {
1573416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1574f15663dcSBarry Smith   PetscScalar       *y,*z;
1575f15663dcSBarry Smith   const PetscScalar *x;
157654f21887SBarry Smith   const MatScalar   *aa;
1577dfbe8321SBarry Smith   PetscErrorCode    ierr;
1578d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
15790298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1580362ced78SSatish Balay   PetscScalar       sum;
1581ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
15829ea0dfa2SSatish Balay 
15833a40ed3dSBarry Smith   PetscFunctionBegin;
1584f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15851ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15862e8a6d31SBarry Smith   if (zz != yy) {
15871ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15882e8a6d31SBarry Smith   } else {
15892e8a6d31SBarry Smith     z = y;
15902e8a6d31SBarry Smith   }
1591bfeeae90SHong Zhang 
159297952fefSHong Zhang   aj = a->j;
159397952fefSHong Zhang   aa = a->a;
1594cddf8d76SBarry Smith   ii = a->i;
15954eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15964eb6d288SHong Zhang     if (zz != yy) {
15974eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15984eb6d288SHong Zhang     }
159997952fefSHong Zhang     m    = a->compressedrow.nrows;
160097952fefSHong Zhang     ii   = a->compressedrow.i;
160197952fefSHong Zhang     ridx = a->compressedrow.rindex;
160297952fefSHong Zhang     for (i=0; i<m; i++) {
160397952fefSHong Zhang       n   = ii[i+1] - ii[i];
160497952fefSHong Zhang       aj  = a->j + ii[i];
160597952fefSHong Zhang       aa  = a->a + ii[i];
160697952fefSHong Zhang       sum = y[*ridx];
1607f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
160897952fefSHong Zhang       z[*ridx++] = sum;
160997952fefSHong Zhang     }
161097952fefSHong Zhang   } else { /* do not use compressed row format */
1611f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1612f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1613f15663dcSBarry Smith #else
161417ab2063SBarry Smith     for (i=0; i<m; i++) {
1615f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1616f15663dcSBarry Smith       aj  = a->j + ii[i];
1617f15663dcSBarry Smith       aa  = a->a + ii[i];
161817ab2063SBarry Smith       sum = y[i];
1619f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
162017ab2063SBarry Smith       z[i] = sum;
162117ab2063SBarry Smith     }
162202ab625aSSatish Balay #endif
1623f15663dcSBarry Smith   }
1624dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1625f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
16261ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
16272e8a6d31SBarry Smith   if (zz != yy) {
16281ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
16292e8a6d31SBarry Smith   }
16308154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
16316b375ea7SVictor Minden   /*
1632918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1633918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1634918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
16356b375ea7SVictor Minden   */
1636918e98c3SVictor Minden #endif
16373a40ed3dSBarry Smith   PetscFunctionReturn(0);
163817ab2063SBarry Smith }
163917ab2063SBarry Smith 
164017ab2063SBarry Smith /*
164117ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
164217ab2063SBarry Smith */
16434a2ae208SSatish Balay #undef __FUNCT__
16444a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1645dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
164617ab2063SBarry Smith {
1647416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
16486849ba73SBarry Smith   PetscErrorCode ierr;
1649d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
165017ab2063SBarry Smith 
16513a40ed3dSBarry Smith   PetscFunctionBegin;
165209f38230SBarry Smith   if (!a->diag) {
1653785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
16543bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
165509f38230SBarry Smith   }
1656d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
165709f38230SBarry Smith     a->diag[i] = a->i[i+1];
1658bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1659bfeeae90SHong Zhang       if (a->j[j] == i) {
166009f38230SBarry Smith         a->diag[i] = j;
166117ab2063SBarry Smith         break;
166217ab2063SBarry Smith       }
166317ab2063SBarry Smith     }
166417ab2063SBarry Smith   }
16653a40ed3dSBarry Smith   PetscFunctionReturn(0);
166617ab2063SBarry Smith }
166717ab2063SBarry Smith 
1668be5855fcSBarry Smith /*
1669be5855fcSBarry Smith      Checks for missing diagonals
1670be5855fcSBarry Smith */
16714a2ae208SSatish Balay #undef __FUNCT__
16724a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1673ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1674be5855fcSBarry Smith {
1675be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
167697f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1677be5855fcSBarry Smith 
1678be5855fcSBarry Smith   PetscFunctionBegin;
167909f38230SBarry Smith   *missing = PETSC_FALSE;
1680d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
168109f38230SBarry Smith     *missing = PETSC_TRUE;
168209f38230SBarry Smith     if (d) *d = 0;
1683358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
168409f38230SBarry Smith   } else {
1685f1e2ffcdSBarry Smith     diag = a->diag;
1686d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1687bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
168809f38230SBarry Smith         *missing = PETSC_TRUE;
168909f38230SBarry Smith         if (d) *d = i;
169009f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1691358d2f5dSShri Abhyankar         break;
169209f38230SBarry Smith       }
1693be5855fcSBarry Smith     }
1694be5855fcSBarry Smith   }
1695be5855fcSBarry Smith   PetscFunctionReturn(0);
1696be5855fcSBarry Smith }
1697be5855fcSBarry Smith 
169871f1c65dSBarry Smith #undef __FUNCT__
169971f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
17007087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
170171f1c65dSBarry Smith {
170271f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
170371f1c65dSBarry Smith   PetscErrorCode ierr;
1704d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
170554f21887SBarry Smith   MatScalar      *v = a->a;
170654f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
170771f1c65dSBarry Smith 
170871f1c65dSBarry Smith   PetscFunctionBegin;
170971f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
171071f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
171171f1c65dSBarry Smith   diag = a->diag;
171271f1c65dSBarry Smith   if (!a->idiag) {
1713dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
17143bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
171571f1c65dSBarry Smith     v    = a->a;
171671f1c65dSBarry Smith   }
171771f1c65dSBarry Smith   mdiag = a->mdiag;
171871f1c65dSBarry Smith   idiag = a->idiag;
171971f1c65dSBarry Smith 
1720028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
172171f1c65dSBarry Smith     for (i=0; i<m; i++) {
172271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1723e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
172471f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
172571f1c65dSBarry Smith     }
172671f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
172771f1c65dSBarry Smith   } else {
172871f1c65dSBarry Smith     for (i=0; i<m; i++) {
172971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
173071f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
173171f1c65dSBarry Smith     }
1732dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
173371f1c65dSBarry Smith   }
173471f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
173571f1c65dSBarry Smith   PetscFunctionReturn(0);
173671f1c65dSBarry Smith }
173771f1c65dSBarry Smith 
1738c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
17394a2ae208SSatish Balay #undef __FUNCT__
174041f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
174141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
174217ab2063SBarry Smith {
1743416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1744e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1745e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
174654f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1747dfbe8321SBarry Smith   PetscErrorCode    ierr;
1748d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
174997f1f81fSBarry Smith   const PetscInt    *idx,*diag;
175017ab2063SBarry Smith 
17513a40ed3dSBarry Smith   PetscFunctionBegin;
1752b965ef7fSBarry Smith   its = its*lits;
175391723122SBarry Smith 
175471f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
175571f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
175671f1c65dSBarry Smith   a->fshift = fshift;
175771f1c65dSBarry Smith   a->omega  = omega;
1758ed480e8bSBarry Smith 
175971f1c65dSBarry Smith   diag  = a->diag;
176071f1c65dSBarry Smith   t     = a->ssor_work;
1761ed480e8bSBarry Smith   idiag = a->idiag;
176271f1c65dSBarry Smith   mdiag = a->mdiag;
1763ed480e8bSBarry Smith 
17641ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
17653649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1766ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
176717ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
176817ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1769ed480e8bSBarry Smith     bs = b;
177017ab2063SBarry Smith     for (i=0; i<m; i++) {
177171f1c65dSBarry Smith       d   = fshift + mdiag[i];
1772416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1773ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1774ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
177517ab2063SBarry Smith       sum = b[i]*d/omega;
1776003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
177717ab2063SBarry Smith       x[i] = sum;
177817ab2063SBarry Smith     }
17791ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17803649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1781efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17823a40ed3dSBarry Smith     PetscFunctionReturn(0);
178317ab2063SBarry Smith   }
1784c783ea89SBarry Smith 
17852205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17862205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
178717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1788887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
178917ab2063SBarry Smith 
179017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
179117ab2063SBarry Smith 
1792887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
179317ab2063SBarry Smith     */
179417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
179517ab2063SBarry Smith 
179617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
179717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1798416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1799ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1800ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
180117ab2063SBarry Smith       sum = b[i];
1802e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1803ed480e8bSBarry Smith       x[i] = sum*idiag[i];
180417ab2063SBarry Smith     }
180517ab2063SBarry Smith 
180617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1807416022c9SBarry Smith     v = a->a;
18082205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
180917ab2063SBarry Smith 
181017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1811ed480e8bSBarry Smith     ts   = t;
1812416022c9SBarry Smith     diag = a->diag;
181317ab2063SBarry Smith     for (i=0; i<m; i++) {
1814416022c9SBarry Smith       n   = diag[i] - a->i[i];
1815ed480e8bSBarry Smith       idx = a->j + a->i[i];
1816ed480e8bSBarry Smith       v   = a->a + a->i[i];
181717ab2063SBarry Smith       sum = t[i];
1818003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1819ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1820733d66baSBarry Smith       /*  x = x + t */
1821733d66baSBarry Smith       x[i] += t[i];
182217ab2063SBarry Smith     }
182317ab2063SBarry Smith 
1824dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
18251ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18263649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
18273a40ed3dSBarry Smith     PetscFunctionReturn(0);
182817ab2063SBarry Smith   }
182917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
183017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
183117ab2063SBarry Smith       for (i=0; i<m; i++) {
1832416022c9SBarry Smith         n   = diag[i] - a->i[i];
1833ed480e8bSBarry Smith         idx = a->j + a->i[i];
1834ed480e8bSBarry Smith         v   = a->a + a->i[i];
183517ab2063SBarry Smith         sum = b[i];
1836e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
18375c99c7daSBarry Smith         t[i] = sum;
1838ed480e8bSBarry Smith         x[i] = sum*idiag[i];
183917ab2063SBarry Smith       }
18405c99c7daSBarry Smith       xb   = t;
1841efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
18423a40ed3dSBarry Smith     } else xb = b;
184317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
184417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1845416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1846ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1847ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
184817ab2063SBarry Smith         sum = xb[i];
1849e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
18505c99c7daSBarry Smith         if (xb == b) {
1851ed480e8bSBarry Smith           x[i] = sum*idiag[i];
18525c99c7daSBarry Smith         } else {
1853b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
185417ab2063SBarry Smith         }
18555c99c7daSBarry Smith       }
1856b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
185717ab2063SBarry Smith     }
185817ab2063SBarry Smith     its--;
185917ab2063SBarry Smith   }
186017ab2063SBarry Smith   while (its--) {
186117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
186217ab2063SBarry Smith       for (i=0; i<m; i++) {
1863b19a5dc2SMark Adams         /* lower */
1864b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1865ed480e8bSBarry Smith         idx = a->j + a->i[i];
1866ed480e8bSBarry Smith         v   = a->a + a->i[i];
186717ab2063SBarry Smith         sum = b[i];
1868e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1869b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1870b19a5dc2SMark Adams         /* upper */
1871b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1872b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1873b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1874b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1875b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
187617ab2063SBarry Smith       }
1877b19a5dc2SMark Adams       xb   = t;
18789f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1879b19a5dc2SMark Adams     } else xb = b;
188017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
188117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1882b19a5dc2SMark Adams         sum = xb[i];
1883b19a5dc2SMark Adams         if (xb == b) {
1884b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1885416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1886ed480e8bSBarry Smith           idx = a->j + a->i[i];
1887ed480e8bSBarry Smith           v   = a->a + a->i[i];
1888e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1889ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1890b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1891b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1892b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1893b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1894b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1895b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
189617ab2063SBarry Smith         }
1897b19a5dc2SMark Adams       }
1898b19a5dc2SMark Adams       if (xb == b) {
18999f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1900b19a5dc2SMark Adams       } else {
1901b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1902b19a5dc2SMark Adams       }
190317ab2063SBarry Smith     }
190417ab2063SBarry Smith   }
19051ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
19063649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1907365a8a9eSBarry Smith   PetscFunctionReturn(0);
190817ab2063SBarry Smith }
190917ab2063SBarry Smith 
19102af78befSBarry Smith 
19114a2ae208SSatish Balay #undef __FUNCT__
19124a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1913dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
191417ab2063SBarry Smith {
1915416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19164e220ebcSLois Curfman McInnes 
19173a40ed3dSBarry Smith   PetscFunctionBegin;
19184e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
19194e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
19204e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
19214e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
19224e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
19238e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
19247adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1925d5f3da31SBarry Smith   if (A->factortype) {
19264e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
19274e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
19284e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
19294e220ebcSLois Curfman McInnes   } else {
19304e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
19314e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
19324e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
19334e220ebcSLois Curfman McInnes   }
19343a40ed3dSBarry Smith   PetscFunctionReturn(0);
193517ab2063SBarry Smith }
193617ab2063SBarry Smith 
19374a2ae208SSatish Balay #undef __FUNCT__
19384a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
19392b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
194017ab2063SBarry Smith {
1941416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19423b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
19436849ba73SBarry Smith   PetscErrorCode    ierr;
194497b48c8fSBarry Smith   const PetscScalar *xx;
194597b48c8fSBarry Smith   PetscScalar       *bb;
1946ace3abfcSBarry Smith   PetscBool         missing;
194717ab2063SBarry Smith 
19483a40ed3dSBarry Smith   PetscFunctionBegin;
194997b48c8fSBarry Smith   if (x && b) {
195097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
195197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
195297b48c8fSBarry Smith     for (i=0; i<N; i++) {
195397b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
195497b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
195597b48c8fSBarry Smith     }
195697b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
195797b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
195897b48c8fSBarry Smith   }
195997b48c8fSBarry Smith 
1960a9817697SBarry Smith   if (a->keepnonzeropattern) {
1961f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1962e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1963bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1964f1e2ffcdSBarry Smith     }
1965f4df32b1SMatthew Knepley     if (diag != 0.0) {
196609f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1967e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1968f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1969f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1970f1e2ffcdSBarry Smith       }
1971f1e2ffcdSBarry Smith     }
197288e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1973f1e2ffcdSBarry Smith   } else {
1974f4df32b1SMatthew Knepley     if (diag != 0.0) {
197517ab2063SBarry Smith       for (i=0; i<N; i++) {
1976e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19777ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1978416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1979f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1980bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
19817ae801bdSBarry Smith         } else { /* in case row was completely empty */
1982f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
198317ab2063SBarry Smith         }
198417ab2063SBarry Smith       }
19853a40ed3dSBarry Smith     } else {
198617ab2063SBarry Smith       for (i=0; i<N; i++) {
1987e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1988416022c9SBarry Smith         a->ilen[rows[i]] = 0;
198917ab2063SBarry Smith       }
199017ab2063SBarry Smith     }
199188e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1992f1e2ffcdSBarry Smith   }
199343a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19943a40ed3dSBarry Smith   PetscFunctionReturn(0);
199517ab2063SBarry Smith }
199617ab2063SBarry Smith 
19974a2ae208SSatish Balay #undef __FUNCT__
19986e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19996e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20006e169961SBarry Smith {
20016e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
20026e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
20036e169961SBarry Smith   PetscErrorCode    ierr;
20042b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
20056e169961SBarry Smith   const PetscScalar *xx;
20066e169961SBarry Smith   PetscScalar       *bb;
20076e169961SBarry Smith 
20086e169961SBarry Smith   PetscFunctionBegin;
20096e169961SBarry Smith   if (x && b) {
20106e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
20116e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
20122b40b63fSBarry Smith     vecs = PETSC_TRUE;
20136e169961SBarry Smith   }
20141795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
20156e169961SBarry Smith   for (i=0; i<N; i++) {
20166e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
20176e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
20182205254eSKarl Rupp 
20196e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
20206e169961SBarry Smith   }
20216e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
20226e169961SBarry Smith     if (!zeroed[i]) {
20236e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
20246e169961SBarry Smith         if (zeroed[a->j[j]]) {
20252b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
20266e169961SBarry Smith           a->a[j] = 0.0;
20276e169961SBarry Smith         }
20286e169961SBarry Smith       }
20292b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
20306e169961SBarry Smith   }
20316e169961SBarry Smith   if (x && b) {
20326e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
20336e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
20346e169961SBarry Smith   }
20356e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
20366e169961SBarry Smith   if (diag != 0.0) {
20376e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
20386e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
20396e169961SBarry Smith     for (i=0; i<N; i++) {
20406e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
20416e169961SBarry Smith     }
20426e169961SBarry Smith   }
20436e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
20446e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20456e169961SBarry Smith   PetscFunctionReturn(0);
20466e169961SBarry Smith }
20476e169961SBarry Smith 
20486e169961SBarry Smith #undef __FUNCT__
20494a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
2050a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
205117ab2063SBarry Smith {
2052416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
205397f1f81fSBarry Smith   PetscInt   *itmp;
205417ab2063SBarry Smith 
20553a40ed3dSBarry Smith   PetscFunctionBegin;
2056e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
205717ab2063SBarry Smith 
2058416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
2059bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
206017ab2063SBarry Smith   if (idx) {
2061bfeeae90SHong Zhang     itmp = a->j + a->i[row];
206226fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
206317ab2063SBarry Smith     else *idx = 0;
206417ab2063SBarry Smith   }
20653a40ed3dSBarry Smith   PetscFunctionReturn(0);
206617ab2063SBarry Smith }
206717ab2063SBarry Smith 
2068bfeeae90SHong Zhang /* remove this function? */
20694a2ae208SSatish Balay #undef __FUNCT__
20704a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
2071a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
207217ab2063SBarry Smith {
20733a40ed3dSBarry Smith   PetscFunctionBegin;
20743a40ed3dSBarry Smith   PetscFunctionReturn(0);
207517ab2063SBarry Smith }
207617ab2063SBarry Smith 
20774a2ae208SSatish Balay #undef __FUNCT__
20784a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
2079dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
208017ab2063SBarry Smith {
2081416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
208254f21887SBarry Smith   MatScalar      *v  = a->a;
208336db0b34SBarry Smith   PetscReal      sum = 0.0;
20846849ba73SBarry Smith   PetscErrorCode ierr;
208597f1f81fSBarry Smith   PetscInt       i,j;
208617ab2063SBarry Smith 
20873a40ed3dSBarry Smith   PetscFunctionBegin;
208817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2089416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
209036db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
209117ab2063SBarry Smith     }
20928f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20933a40ed3dSBarry Smith   } else if (type == NORM_1) {
209436db0b34SBarry Smith     PetscReal *tmp;
209597f1f81fSBarry Smith     PetscInt  *jj = a->j;
20961795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2097064f8208SBarry Smith     *nrm = 0.0;
2098416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2099bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
210017ab2063SBarry Smith     }
2101d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2102064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
210317ab2063SBarry Smith     }
2104606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
21053a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2106064f8208SBarry Smith     *nrm = 0.0;
2107d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2108bfeeae90SHong Zhang       v   = a->a + a->i[j];
210917ab2063SBarry Smith       sum = 0.0;
2110416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2111cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
211217ab2063SBarry Smith       }
2113064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
211417ab2063SBarry Smith     }
2115f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
21163a40ed3dSBarry Smith   PetscFunctionReturn(0);
211717ab2063SBarry Smith }
211817ab2063SBarry Smith 
21194e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
21204e938277SHong Zhang #undef __FUNCT__
21214e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
21224e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
21234e938277SHong Zhang {
21244e938277SHong Zhang   PetscErrorCode ierr;
21254e938277SHong Zhang   PetscInt       i,j,anzj;
21264e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
21274e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
21284e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
21294e938277SHong Zhang 
21304e938277SHong Zhang   PetscFunctionBegin;
21314e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
21321795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2133785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2134785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
21354e938277SHong Zhang 
21364e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
21374e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
213826fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
21394e938277SHong Zhang   /* Form ati for csr format of A^T. */
214026fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
21414e938277SHong Zhang 
21424e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
21434e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
21444e938277SHong Zhang 
21454e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
21464e938277SHong Zhang   for (i=0;i<am;i++) {
21474e938277SHong Zhang     anzj = ai[i+1] - ai[i];
21484e938277SHong Zhang     for (j=0;j<anzj;j++) {
21494e938277SHong Zhang       atj[atfill[*aj]] = i;
21504e938277SHong Zhang       atfill[*aj++]   += 1;
21514e938277SHong Zhang     }
21524e938277SHong Zhang   }
21534e938277SHong Zhang 
21544e938277SHong Zhang   /* Clean up temporary space and complete requests. */
21554e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2156ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
21572205254eSKarl Rupp 
2158a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2159a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2160a2f3521dSMark F. Adams 
21614e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
21624e938277SHong Zhang   b->free_a  = PETSC_FALSE;
21634e938277SHong Zhang   b->free_ij = PETSC_TRUE;
21644e938277SHong Zhang   b->nonew   = 0;
21654e938277SHong Zhang   PetscFunctionReturn(0);
21664e938277SHong Zhang }
21674e938277SHong Zhang 
21684a2ae208SSatish Balay #undef __FUNCT__
21694a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2170fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
217117ab2063SBarry Smith {
2172416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2173416022c9SBarry Smith   Mat            C;
21746849ba73SBarry Smith   PetscErrorCode ierr;
2175d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
217654f21887SBarry Smith   MatScalar      *array = a->a;
217717ab2063SBarry Smith 
21783a40ed3dSBarry Smith   PetscFunctionBegin;
2179e32f2f54SBarry 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");
2180fc4dec0aSBarry Smith 
2181fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
21821795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2183bfeeae90SHong Zhang 
2184bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2185ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2186d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2187a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21887adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2189ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2190606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2191a541d17aSBarry Smith   } else {
2192a541d17aSBarry Smith     C = *B;
2193a541d17aSBarry Smith   }
2194a541d17aSBarry Smith 
219517ab2063SBarry Smith   for (i=0; i<m; i++) {
219617ab2063SBarry Smith     len    = ai[i+1]-ai[i];
219787d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2198b9b97703SBarry Smith     array += len;
2199b9b97703SBarry Smith     aj    += len;
220017ab2063SBarry Smith   }
22016d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22026d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
220317ab2063SBarry Smith 
2204815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2205416022c9SBarry Smith     *B = C;
220617ab2063SBarry Smith   } else {
2207eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
220817ab2063SBarry Smith   }
22093a40ed3dSBarry Smith   PetscFunctionReturn(0);
221017ab2063SBarry Smith }
221117ab2063SBarry Smith 
2212cd0d46ebSvictorle #undef __FUNCT__
22135fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
22147087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2215cd0d46ebSvictorle {
2216cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
221754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
221854f21887SBarry Smith   MatScalar      *va,*vb;
22196849ba73SBarry Smith   PetscErrorCode ierr;
222097f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2221cd0d46ebSvictorle 
2222cd0d46ebSvictorle   PetscFunctionBegin;
2223cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2224cd0d46ebSvictorle 
2225cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2226cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22275485867bSBarry Smith   if (ma!=nb || na!=mb) {
22285485867bSBarry Smith     *f = PETSC_FALSE;
22295485867bSBarry Smith     PetscFunctionReturn(0);
22305485867bSBarry Smith   }
2231cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2232cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2233cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2234785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2235785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2236cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2237cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2238cd0d46ebSvictorle 
2239cd0d46ebSvictorle   *f = PETSC_TRUE;
2240cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2241cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
224297f1f81fSBarry Smith       PetscInt    idc,idr;
22435485867bSBarry Smith       PetscScalar vc,vr;
2244cd0d46ebSvictorle       /* column/row index/value */
22455485867bSBarry Smith       idc = adx[aptr[i]];
22465485867bSBarry Smith       idr = bdx[bptr[idc]];
22475485867bSBarry Smith       vc  = va[aptr[i]];
22485485867bSBarry Smith       vr  = vb[bptr[idc]];
22495485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
22505485867bSBarry Smith         *f = PETSC_FALSE;
22515485867bSBarry Smith         goto done;
2252cd0d46ebSvictorle       } else {
22535485867bSBarry Smith         aptr[i]++;
22545485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2255cd0d46ebSvictorle       }
2256cd0d46ebSvictorle     }
2257cd0d46ebSvictorle   }
2258cd0d46ebSvictorle done:
2259cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
22603aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2261cd0d46ebSvictorle   PetscFunctionReturn(0);
2262cd0d46ebSvictorle }
2263cd0d46ebSvictorle 
22641cbb95d3SBarry Smith #undef __FUNCT__
22651cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
22667087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
22671cbb95d3SBarry Smith {
22681cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
226954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
227054f21887SBarry Smith   MatScalar      *va,*vb;
22711cbb95d3SBarry Smith   PetscErrorCode ierr;
22721cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
22731cbb95d3SBarry Smith 
22741cbb95d3SBarry Smith   PetscFunctionBegin;
22751cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
22761cbb95d3SBarry Smith 
22771cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
22781cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22791cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
22801cbb95d3SBarry Smith     *f = PETSC_FALSE;
22811cbb95d3SBarry Smith     PetscFunctionReturn(0);
22821cbb95d3SBarry Smith   }
22831cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22841cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22851cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2286785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2287785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
22881cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22891cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22901cbb95d3SBarry Smith 
22911cbb95d3SBarry Smith   *f = PETSC_TRUE;
22921cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22931cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22941cbb95d3SBarry Smith       PetscInt    idc,idr;
22951cbb95d3SBarry Smith       PetscScalar vc,vr;
22961cbb95d3SBarry Smith       /* column/row index/value */
22971cbb95d3SBarry Smith       idc = adx[aptr[i]];
22981cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22991cbb95d3SBarry Smith       vc  = va[aptr[i]];
23001cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
23011cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
23021cbb95d3SBarry Smith         *f = PETSC_FALSE;
23031cbb95d3SBarry Smith         goto done;
23041cbb95d3SBarry Smith       } else {
23051cbb95d3SBarry Smith         aptr[i]++;
23061cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
23071cbb95d3SBarry Smith       }
23081cbb95d3SBarry Smith     }
23091cbb95d3SBarry Smith   }
23101cbb95d3SBarry Smith done:
23111cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
23121cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
23131cbb95d3SBarry Smith   PetscFunctionReturn(0);
23141cbb95d3SBarry Smith }
23151cbb95d3SBarry Smith 
23169e29f15eSvictorle #undef __FUNCT__
23179e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2318ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
23199e29f15eSvictorle {
2320dfbe8321SBarry Smith   PetscErrorCode ierr;
23216e111a19SKarl Rupp 
23229e29f15eSvictorle   PetscFunctionBegin;
23235485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
23249e29f15eSvictorle   PetscFunctionReturn(0);
23259e29f15eSvictorle }
23269e29f15eSvictorle 
23274a2ae208SSatish Balay #undef __FUNCT__
23281cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2329ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
23301cbb95d3SBarry Smith {
23311cbb95d3SBarry Smith   PetscErrorCode ierr;
23326e111a19SKarl Rupp 
23331cbb95d3SBarry Smith   PetscFunctionBegin;
23341cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
23351cbb95d3SBarry Smith   PetscFunctionReturn(0);
23361cbb95d3SBarry Smith }
23371cbb95d3SBarry Smith 
23381cbb95d3SBarry Smith #undef __FUNCT__
23394a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2340dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
234117ab2063SBarry Smith {
2342416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
234354f21887SBarry Smith   PetscScalar    *l,*r,x;
234454f21887SBarry Smith   MatScalar      *v;
2345dfbe8321SBarry Smith   PetscErrorCode ierr;
2346d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
234717ab2063SBarry Smith 
23483a40ed3dSBarry Smith   PetscFunctionBegin;
234917ab2063SBarry Smith   if (ll) {
23503ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
23513ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2352e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2353e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
23541ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2355416022c9SBarry Smith     v    = a->a;
235617ab2063SBarry Smith     for (i=0; i<m; i++) {
235717ab2063SBarry Smith       x = l[i];
2358416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
23592205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
236017ab2063SBarry Smith     }
23611ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2362efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
236317ab2063SBarry Smith   }
236417ab2063SBarry Smith   if (rr) {
2365e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2366e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
23671ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2368416022c9SBarry Smith     v    = a->a; jj = a->j;
23692205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
23701ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2371efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
237217ab2063SBarry Smith   }
2373acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
23743a40ed3dSBarry Smith   PetscFunctionReturn(0);
237517ab2063SBarry Smith }
237617ab2063SBarry Smith 
23774a2ae208SSatish Balay #undef __FUNCT__
23784a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
237997f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
238017ab2063SBarry Smith {
2381db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23826849ba73SBarry Smith   PetscErrorCode ierr;
2383d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
238497f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23855d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23865d0c19d7SBarry Smith   PetscInt       nrows,ncols;
238797f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
238854f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2389416022c9SBarry Smith   Mat            C;
2390ace3abfcSBarry Smith   PetscBool      stride,sorted;
239117ab2063SBarry Smith 
23923a40ed3dSBarry Smith   PetscFunctionBegin;
239314ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2394e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
239514ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2396e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
239799141d43SSatish Balay 
239817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2399b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2400b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
240117ab2063SBarry Smith 
2402fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2403251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2404fee21e36SBarry Smith   if (stride && step == 1) {
240502834360SBarry Smith     /* special case of contiguous rows */
2406dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
240702834360SBarry Smith     /* loop over new rows determining lens and starting points */
240802834360SBarry Smith     for (i=0; i<nrows; i++) {
2409bfeeae90SHong Zhang       kstart = ai[irow[i]];
2410a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
241102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2412bfeeae90SHong Zhang         if (aj[k] >= first) {
241302834360SBarry Smith           starts[i] = k;
241402834360SBarry Smith           break;
241502834360SBarry Smith         }
241602834360SBarry Smith       }
2417a2744918SBarry Smith       sum = 0;
241802834360SBarry Smith       while (k < kend) {
2419bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2420a2744918SBarry Smith         sum++;
242102834360SBarry Smith       }
2422a2744918SBarry Smith       lens[i] = sum;
242302834360SBarry Smith     }
242402834360SBarry Smith     /* create submatrix */
2425cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
242697f1f81fSBarry Smith       PetscInt n_cols,n_rows;
242708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2428e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2429d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
243008480c60SBarry Smith       C    = *B;
24313a40ed3dSBarry Smith     } else {
24323bef6203SJed Brown       PetscInt rbs,cbs;
2433ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2434f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24353bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24363bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24373bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24387adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2439ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
244008480c60SBarry Smith     }
2441db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2442db02288aSLois Curfman McInnes 
244302834360SBarry Smith     /* loop over rows inserting into submatrix */
2444db02288aSLois Curfman McInnes     a_new = c->a;
2445db02288aSLois Curfman McInnes     j_new = c->j;
2446db02288aSLois Curfman McInnes     i_new = c->i;
2447bfeeae90SHong Zhang 
244802834360SBarry Smith     for (i=0; i<nrows; i++) {
2449a2744918SBarry Smith       ii    = starts[i];
2450a2744918SBarry Smith       lensi = lens[i];
2451a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2452a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
245302834360SBarry Smith       }
245487828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2455a2744918SBarry Smith       a_new     += lensi;
2456a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2457a2744918SBarry Smith       c->ilen[i] = lensi;
245802834360SBarry Smith     }
24590e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
24603a40ed3dSBarry Smith   } else {
246102834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
24621795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2463785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
24644dcab191SBarry Smith     for (i=0; i<ncols; i++) {
24654dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
24664dcab191SBarry 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);
24674dcab191SBarry Smith #endif
24684dcab191SBarry Smith       smap[icol[i]] = i+1;
24694dcab191SBarry Smith     }
24704dcab191SBarry Smith 
247102834360SBarry Smith     /* determine lens of each row */
247202834360SBarry Smith     for (i=0; i<nrows; i++) {
2473bfeeae90SHong Zhang       kstart  = ai[irow[i]];
247402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
247502834360SBarry Smith       lens[i] = 0;
247602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2477bfeeae90SHong Zhang         if (smap[aj[k]]) {
247802834360SBarry Smith           lens[i]++;
247902834360SBarry Smith         }
248002834360SBarry Smith       }
248102834360SBarry Smith     }
248217ab2063SBarry Smith     /* Create and fill new matrix */
2483a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2484ace3abfcSBarry Smith       PetscBool equal;
24850f5bd95cSBarry Smith 
248699141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2487e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2488d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2489f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2490d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
249108480c60SBarry Smith       C    = *B;
24923a40ed3dSBarry Smith     } else {
24933bef6203SJed Brown       PetscInt rbs,cbs;
2494ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2495f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24963bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24973bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24983bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24997adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2500ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
250108480c60SBarry Smith     }
250299141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
250317ab2063SBarry Smith     for (i=0; i<nrows; i++) {
250499141d43SSatish Balay       row      = irow[i];
2505bfeeae90SHong Zhang       kstart   = ai[row];
250699141d43SSatish Balay       kend     = kstart + a->ilen[row];
2507bfeeae90SHong Zhang       mat_i    = c->i[i];
250899141d43SSatish Balay       mat_j    = c->j + mat_i;
250999141d43SSatish Balay       mat_a    = c->a + mat_i;
251099141d43SSatish Balay       mat_ilen = c->ilen + i;
251117ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2512bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2513ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
251499141d43SSatish Balay           *mat_a++ = a->a[k];
251599141d43SSatish Balay           (*mat_ilen)++;
251699141d43SSatish Balay 
251717ab2063SBarry Smith         }
251817ab2063SBarry Smith       }
251917ab2063SBarry Smith     }
252002834360SBarry Smith     /* Free work space */
252102834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2522606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2523606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
252402834360SBarry Smith   }
25256d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25266d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
252717ab2063SBarry Smith 
252817ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2529416022c9SBarry Smith   *B   = C;
25303a40ed3dSBarry Smith   PetscFunctionReturn(0);
253117ab2063SBarry Smith }
253217ab2063SBarry Smith 
25331df811f5SHong Zhang #undef __FUNCT__
253482d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2535fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
253682d44351SHong Zhang {
253782d44351SHong Zhang   PetscErrorCode ierr;
253882d44351SHong Zhang   Mat            B;
253982d44351SHong Zhang 
254082d44351SHong Zhang   PetscFunctionBegin;
2541c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
254282d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
254382d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2544a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
254582d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
254682d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
254782d44351SHong Zhang     *subMat = B;
2548c2d650bdSHong Zhang   } else {
2549c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2550c2d650bdSHong Zhang   }
255182d44351SHong Zhang   PetscFunctionReturn(0);
255282d44351SHong Zhang }
255382d44351SHong Zhang 
255482d44351SHong Zhang #undef __FUNCT__
25554a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
25560481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2557a871dcd8SBarry Smith {
255863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2559dfbe8321SBarry Smith   PetscErrorCode ierr;
256063b91edcSBarry Smith   Mat            outA;
2561ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
256263b91edcSBarry Smith 
25633a40ed3dSBarry Smith   PetscFunctionBegin;
2564e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
25651df811f5SHong Zhang 
2566b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2567b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2568a871dcd8SBarry Smith 
256963b91edcSBarry Smith   outA             = inA;
2570d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
25712205254eSKarl Rupp 
2572c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
25736bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
25742205254eSKarl Rupp 
2575c3122656SLisandro Dalcin   a->row = row;
25762205254eSKarl Rupp 
2577c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
25786bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
25792205254eSKarl Rupp 
2580c3122656SLisandro Dalcin   a->col = col;
258163b91edcSBarry Smith 
258236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
25836bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
25844c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25853bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2586f0ec6fceSSatish Balay 
258794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2588785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
25893bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
259094a9d846SBarry Smith   }
259163b91edcSBarry Smith 
2592f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2593137fb511SHong Zhang   if (row_identity && col_identity) {
2594ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2595137fb511SHong Zhang   } else {
2596719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2597137fb511SHong Zhang   }
25983a40ed3dSBarry Smith   PetscFunctionReturn(0);
2599a871dcd8SBarry Smith }
2600a871dcd8SBarry Smith 
26014a2ae208SSatish Balay #undef __FUNCT__
26024a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2603f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2604f0b747eeSBarry Smith {
2605f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2606f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2607efee365bSSatish Balay   PetscErrorCode ierr;
2608c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
26093a40ed3dSBarry Smith 
26103a40ed3dSBarry Smith   PetscFunctionBegin;
2611c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
26128b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2613efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2614acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
26153a40ed3dSBarry Smith   PetscFunctionReturn(0);
2616f0b747eeSBarry Smith }
2617f0b747eeSBarry Smith 
26184a2ae208SSatish Balay #undef __FUNCT__
26194a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
262097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2621cddf8d76SBarry Smith {
2622dfbe8321SBarry Smith   PetscErrorCode ierr;
262397f1f81fSBarry Smith   PetscInt       i;
2624cddf8d76SBarry Smith 
26253a40ed3dSBarry Smith   PetscFunctionBegin;
2626cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2627785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2628cddf8d76SBarry Smith   }
2629cddf8d76SBarry Smith 
2630cddf8d76SBarry Smith   for (i=0; i<n; i++) {
26316a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2632cddf8d76SBarry Smith   }
26333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2634cddf8d76SBarry Smith }
2635cddf8d76SBarry Smith 
26364a2ae208SSatish Balay #undef __FUNCT__
26374a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
263897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
26394dcbc457SBarry Smith {
2640e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26416849ba73SBarry Smith   PetscErrorCode ierr;
26425d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
26435d0c19d7SBarry Smith   const PetscInt *idx;
264497f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2645f1af5d2fSBarry Smith   PetscBT        table;
2646bbd702dbSSatish Balay 
26473a40ed3dSBarry Smith   PetscFunctionBegin;
2648d0f46423SBarry Smith   m  = A->rmap->n;
2649e4d965acSSatish Balay   ai = a->i;
2650bfeeae90SHong Zhang   aj = a->j;
26518a047759SSatish Balay 
2652e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
265306763907SSatish Balay 
2654785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
265553b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
265606763907SSatish Balay 
2657e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2658b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2659e4d965acSSatish Balay     isz  = 0;
26606831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2661e4d965acSSatish Balay 
2662e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
26634dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2664b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2665e4d965acSSatish Balay 
2666dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2667e4d965acSSatish Balay     for (j=0; j<n; ++j) {
26682205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
26694dcbc457SBarry Smith     }
267006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
26716bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2672e4d965acSSatish Balay 
267304a348a9SBarry Smith     k = 0;
267404a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
267504a348a9SBarry Smith       n = isz;
267606763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2677e4d965acSSatish Balay         row   = nidx[k];
2678e4d965acSSatish Balay         start = ai[row];
2679e4d965acSSatish Balay         end   = ai[row+1];
268004a348a9SBarry Smith         for (l = start; l<end; l++) {
2681efb16452SHong Zhang           val = aj[l];
26822205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2683e4d965acSSatish Balay         }
2684e4d965acSSatish Balay       }
2685e4d965acSSatish Balay     }
268670b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2687e4d965acSSatish Balay   }
268894bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2689606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26903a40ed3dSBarry Smith   PetscFunctionReturn(0);
26914dcbc457SBarry Smith }
269217ab2063SBarry Smith 
26930513a670SBarry Smith /* -------------------------------------------------------------- */
26944a2ae208SSatish Balay #undef __FUNCT__
26954a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2696dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26970513a670SBarry Smith {
26980513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26996849ba73SBarry Smith   PetscErrorCode ierr;
27003b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
27015d0c19d7SBarry Smith   const PetscInt *row,*col;
27025d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
270356cd22aeSBarry Smith   IS             icolp,irowp;
27040298fd71SBarry Smith   PetscInt       *cwork = NULL;
27050298fd71SBarry Smith   PetscScalar    *vwork = NULL;
27060513a670SBarry Smith 
27073a40ed3dSBarry Smith   PetscFunctionBegin;
27084c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
270956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
27104c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
271156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
27120513a670SBarry Smith 
27130513a670SBarry Smith   /* determine lengths of permuted rows */
2714785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
27152205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2716ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2717f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2718a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
27197adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2720ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2721606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
27220513a670SBarry Smith 
2723785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
27240513a670SBarry Smith   for (i=0; i<m; i++) {
272532ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
27262205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2727cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
272832ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
27290513a670SBarry Smith   }
2730606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
27312205254eSKarl Rupp 
27323c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
27332205254eSKarl Rupp 
27340513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
27350513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
273656cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
273756cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
27386bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
27396bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
27403a40ed3dSBarry Smith   PetscFunctionReturn(0);
27410513a670SBarry Smith }
27420513a670SBarry Smith 
27434a2ae208SSatish Balay #undef __FUNCT__
27444a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2745dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2746cb5b572fSBarry Smith {
2747dfbe8321SBarry Smith   PetscErrorCode ierr;
2748cb5b572fSBarry Smith 
2749cb5b572fSBarry Smith   PetscFunctionBegin;
275033f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
275133f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2752be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2753be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2754be6bf707SBarry Smith 
2755700c5bfcSBarry 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");
2756d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2757cb5b572fSBarry Smith   } else {
2758cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2759cb5b572fSBarry Smith   }
2760cb5b572fSBarry Smith   PetscFunctionReturn(0);
2761cb5b572fSBarry Smith }
2762cb5b572fSBarry Smith 
27634a2ae208SSatish Balay #undef __FUNCT__
27644994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
27654994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2766273d9f13SBarry Smith {
2767dfbe8321SBarry Smith   PetscErrorCode ierr;
2768273d9f13SBarry Smith 
2769273d9f13SBarry Smith   PetscFunctionBegin;
2770ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2771273d9f13SBarry Smith   PetscFunctionReturn(0);
2772273d9f13SBarry Smith }
2773273d9f13SBarry Smith 
27744a2ae208SSatish Balay #undef __FUNCT__
27758c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
27768c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
27776c0721eeSBarry Smith {
27786c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
27796e111a19SKarl Rupp 
27806c0721eeSBarry Smith   PetscFunctionBegin;
27816c0721eeSBarry Smith   *array = a->a;
27826c0721eeSBarry Smith   PetscFunctionReturn(0);
27836c0721eeSBarry Smith }
27846c0721eeSBarry Smith 
27854a2ae208SSatish Balay #undef __FUNCT__
27868c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27878c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27886c0721eeSBarry Smith {
27896c0721eeSBarry Smith   PetscFunctionBegin;
27906c0721eeSBarry Smith   PetscFunctionReturn(0);
27916c0721eeSBarry Smith }
2792273d9f13SBarry Smith 
27938229c054SShri Abhyankar /*
27948229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27958229c054SShri Abhyankar    have different nonzero structure.
27968229c054SShri Abhyankar */
2797ac90fabeSBarry Smith #undef __FUNCT__
27988229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27998229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2800ec7775f6SShri Abhyankar {
28018229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2802ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2803ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2804ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2805ec7775f6SShri Abhyankar 
2806ec7775f6SShri Abhyankar   PetscFunctionBegin;
2807ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2808ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
28098af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
28108af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
28118af7cee1SJed Brown     nnz[i] = 0;
28128af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
28138af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
28148af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
28158af7cee1SJed Brown       nnz[i]++;
28168af7cee1SJed Brown     }
28178af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2818ec7775f6SShri Abhyankar   }
2819ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2820ec7775f6SShri Abhyankar }
2821ec7775f6SShri Abhyankar 
2822ec7775f6SShri Abhyankar #undef __FUNCT__
2823ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2824f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2825ac90fabeSBarry Smith {
2826dfbe8321SBarry Smith   PetscErrorCode ierr;
282797f1f81fSBarry Smith   PetscInt       i;
2828ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2829c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2830ac90fabeSBarry Smith 
2831ac90fabeSBarry Smith   PetscFunctionBegin;
2832c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2833ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2834f4df32b1SMatthew Knepley     PetscScalar alpha = a;
28358b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2836acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2837c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2838a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2839a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
28406bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2841a30b2313SHong Zhang     }
2842a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
28430298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2844a30b2313SHong Zhang       y->XtoY = X;
2845407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2846c537a176SHong Zhang     }
2847f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2848ba0e910bSBarry 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);
2849ac90fabeSBarry Smith   } else {
28508229c054SShri Abhyankar     Mat      B;
28518229c054SShri Abhyankar     PetscInt *nnz;
2852785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2853ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2854bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
28554aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2856a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2857176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
28588229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2859ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2860ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2861ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
28628229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2863ac90fabeSBarry Smith   }
2864ac90fabeSBarry Smith   PetscFunctionReturn(0);
2865ac90fabeSBarry Smith }
2866ac90fabeSBarry Smith 
2867521d7252SBarry Smith #undef __FUNCT__
2868354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
28697087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2870354c94deSBarry Smith {
2871354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2872354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2873354c94deSBarry Smith   PetscInt    i,nz;
2874354c94deSBarry Smith   PetscScalar *a;
2875354c94deSBarry Smith 
2876354c94deSBarry Smith   PetscFunctionBegin;
2877354c94deSBarry Smith   nz = aij->nz;
2878354c94deSBarry Smith   a  = aij->a;
28792205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2880354c94deSBarry Smith #else
2881354c94deSBarry Smith   PetscFunctionBegin;
2882354c94deSBarry Smith #endif
2883354c94deSBarry Smith   PetscFunctionReturn(0);
2884354c94deSBarry Smith }
2885354c94deSBarry Smith 
2886e34fafa9SBarry Smith #undef __FUNCT__
2887985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2888985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2889e34fafa9SBarry Smith {
2890e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2891e34fafa9SBarry Smith   PetscErrorCode ierr;
2892d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2893e34fafa9SBarry Smith   PetscReal      atmp;
2894985db425SBarry Smith   PetscScalar    *x;
2895e34fafa9SBarry Smith   MatScalar      *aa;
2896e34fafa9SBarry Smith 
2897e34fafa9SBarry Smith   PetscFunctionBegin;
2898e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2899e34fafa9SBarry Smith   aa = a->a;
2900e34fafa9SBarry Smith   ai = a->i;
2901e34fafa9SBarry Smith   aj = a->j;
2902e34fafa9SBarry Smith 
2903985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2904e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2905e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2906e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2907e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2908e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
29099189402eSHong Zhang     x[i]  = 0.0;
2910e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2911985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2912985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2913985db425SBarry Smith       aa++; aj++;
2914985db425SBarry Smith     }
2915985db425SBarry Smith   }
2916985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2917985db425SBarry Smith   PetscFunctionReturn(0);
2918985db425SBarry Smith }
2919985db425SBarry Smith 
2920985db425SBarry Smith #undef __FUNCT__
2921985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2922985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2923985db425SBarry Smith {
2924985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2925985db425SBarry Smith   PetscErrorCode ierr;
2926d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2927985db425SBarry Smith   PetscScalar    *x;
2928985db425SBarry Smith   MatScalar      *aa;
2929985db425SBarry Smith 
2930985db425SBarry Smith   PetscFunctionBegin;
2931e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2932985db425SBarry Smith   aa = a->a;
2933985db425SBarry Smith   ai = a->i;
2934985db425SBarry Smith   aj = a->j;
2935985db425SBarry Smith 
2936985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2937985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2938985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2939e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2940985db425SBarry Smith   for (i=0; i<m; i++) {
2941985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2942d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2943985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2944985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2945985db425SBarry Smith       x[i] = 0.0;
2946985db425SBarry Smith       if (idx) {
2947985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2948985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2949985db425SBarry Smith           if (aj[j] > j) {
2950985db425SBarry Smith             idx[i] = j;
2951985db425SBarry Smith             break;
2952985db425SBarry Smith           }
2953985db425SBarry Smith         }
2954985db425SBarry Smith       }
2955985db425SBarry Smith     }
2956985db425SBarry Smith     for (j=0; j<ncols; j++) {
2957985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2958985db425SBarry Smith       aa++; aj++;
2959985db425SBarry Smith     }
2960985db425SBarry Smith   }
2961985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2962985db425SBarry Smith   PetscFunctionReturn(0);
2963985db425SBarry Smith }
2964985db425SBarry Smith 
2965985db425SBarry Smith #undef __FUNCT__
2966c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2967c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2968c87e5d42SMatthew Knepley {
2969c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2970c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2971c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2972c87e5d42SMatthew Knepley   PetscReal      atmp;
2973c87e5d42SMatthew Knepley   PetscScalar    *x;
2974c87e5d42SMatthew Knepley   MatScalar      *aa;
2975c87e5d42SMatthew Knepley 
2976c87e5d42SMatthew Knepley   PetscFunctionBegin;
2977e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2978c87e5d42SMatthew Knepley   aa = a->a;
2979c87e5d42SMatthew Knepley   ai = a->i;
2980c87e5d42SMatthew Knepley   aj = a->j;
2981c87e5d42SMatthew Knepley 
2982c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2983c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2984c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
29853bb78c5cSMatthew 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);
2986c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2987c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2988289a08f5SMatthew Knepley     if (ncols) {
2989289a08f5SMatthew Knepley       /* Get first nonzero */
2990289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2991289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29922205254eSKarl Rupp         if (atmp > 1.0e-12) {
29932205254eSKarl Rupp           x[i] = atmp;
29942205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29952205254eSKarl Rupp           break;
29962205254eSKarl Rupp         }
2997289a08f5SMatthew Knepley       }
299812431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2999289a08f5SMatthew Knepley     } else {
3000289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
3001289a08f5SMatthew Knepley     }
3002c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
3003c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
3004289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3005c87e5d42SMatthew Knepley       aa++; aj++;
3006c87e5d42SMatthew Knepley     }
3007c87e5d42SMatthew Knepley   }
3008c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3009c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
3010c87e5d42SMatthew Knepley }
3011c87e5d42SMatthew Knepley 
3012c87e5d42SMatthew Knepley #undef __FUNCT__
3013985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
3014985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3015985db425SBarry Smith {
3016985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3017985db425SBarry Smith   PetscErrorCode ierr;
3018d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3019985db425SBarry Smith   PetscScalar    *x;
3020985db425SBarry Smith   MatScalar      *aa;
3021985db425SBarry Smith 
3022985db425SBarry Smith   PetscFunctionBegin;
3023e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3024985db425SBarry Smith   aa = a->a;
3025985db425SBarry Smith   ai = a->i;
3026985db425SBarry Smith   aj = a->j;
3027985db425SBarry Smith 
3028985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3029985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3030985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3031e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3032985db425SBarry Smith   for (i=0; i<m; i++) {
3033985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3034d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3035985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3036985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
3037985db425SBarry Smith       x[i] = 0.0;
3038985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
3039985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3040985db425SBarry Smith         for (j=0; j<ncols; j++) {
3041985db425SBarry Smith           if (aj[j] > j) {
3042985db425SBarry Smith             idx[i] = j;
3043985db425SBarry Smith             break;
3044985db425SBarry Smith           }
3045985db425SBarry Smith         }
3046985db425SBarry Smith       }
3047985db425SBarry Smith     }
3048985db425SBarry Smith     for (j=0; j<ncols; j++) {
3049985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3050985db425SBarry Smith       aa++; aj++;
3051e34fafa9SBarry Smith     }
3052e34fafa9SBarry Smith   }
3053e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3054e34fafa9SBarry Smith   PetscFunctionReturn(0);
3055e34fafa9SBarry Smith }
3056bbead8a2SBarry Smith 
3057bbead8a2SBarry Smith #include <petscblaslapack.h>
305806873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
3059bbead8a2SBarry Smith 
3060bbead8a2SBarry Smith #undef __FUNCT__
3061bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
3062713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3063bbead8a2SBarry Smith {
3064bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
3065bbead8a2SBarry Smith   PetscErrorCode ierr;
306634fc4b71SJed 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;
3067bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
3068bbead8a2SBarry Smith   PetscReal      shift = 0.0;
3069bbead8a2SBarry Smith 
3070bbead8a2SBarry Smith   PetscFunctionBegin;
30714a0d0026SBarry Smith   if (a->ibdiagvalid) {
30724a0d0026SBarry Smith     if (values) *values = a->ibdiag;
30734a0d0026SBarry Smith     PetscFunctionReturn(0);
30744a0d0026SBarry Smith   }
3075bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3076bbead8a2SBarry Smith   if (!a->ibdiag) {
3077785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
30783bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3079bbead8a2SBarry Smith   }
3080bbead8a2SBarry Smith   diag = a->ibdiag;
3081bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3082bbead8a2SBarry Smith   /* factor and invert each block */
3083bbead8a2SBarry Smith   switch (bs) {
3084bbead8a2SBarry Smith   case 1:
3085bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3086bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3087bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3088bbead8a2SBarry Smith     }
3089bbead8a2SBarry Smith     break;
3090bbead8a2SBarry Smith   case 2:
3091bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3092bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3093bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
309496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
309596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3096bbead8a2SBarry Smith       diag += 4;
3097bbead8a2SBarry Smith     }
3098bbead8a2SBarry Smith     break;
3099bbead8a2SBarry Smith   case 3:
3100bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3101bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3102bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
310396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
310496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3105bbead8a2SBarry Smith       diag += 9;
3106bbead8a2SBarry Smith     }
3107bbead8a2SBarry Smith     break;
3108bbead8a2SBarry Smith   case 4:
3109bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3110bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3111bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
311296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
311396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3114bbead8a2SBarry Smith       diag += 16;
3115bbead8a2SBarry Smith     }
3116bbead8a2SBarry Smith     break;
3117bbead8a2SBarry Smith   case 5:
3118bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3119bbead8a2SBarry 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;
3120bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
312196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
312296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3123bbead8a2SBarry Smith       diag += 25;
3124bbead8a2SBarry Smith     }
3125bbead8a2SBarry Smith     break;
3126bbead8a2SBarry Smith   case 6:
3127bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3128bbead8a2SBarry 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;
3129bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
313096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
313196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3132bbead8a2SBarry Smith       diag += 36;
3133bbead8a2SBarry Smith     }
3134bbead8a2SBarry Smith     break;
3135bbead8a2SBarry Smith   case 7:
3136bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3137bbead8a2SBarry 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;
3138bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
313996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
314096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3141bbead8a2SBarry Smith       diag += 49;
3142bbead8a2SBarry Smith     }
3143bbead8a2SBarry Smith     break;
3144bbead8a2SBarry Smith   default:
3145dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3146bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3147bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3148bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3149bbead8a2SBarry Smith       }
3150bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
315196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
315296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3153bbead8a2SBarry Smith       diag += bs2;
3154bbead8a2SBarry Smith     }
3155bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3156bbead8a2SBarry Smith   }
3157bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3158bbead8a2SBarry Smith   PetscFunctionReturn(0);
3159bbead8a2SBarry Smith }
3160bbead8a2SBarry Smith 
316173a71a0fSBarry Smith #undef __FUNCT__
316273a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
316373a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
316473a71a0fSBarry Smith {
316573a71a0fSBarry Smith   PetscErrorCode ierr;
316673a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
316773a71a0fSBarry Smith   PetscScalar    a;
316873a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
316973a71a0fSBarry Smith 
317073a71a0fSBarry Smith   PetscFunctionBegin;
317173a71a0fSBarry Smith   if (!x->assembled) {
317273a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
317373a71a0fSBarry Smith     for (i=0; i<m; i++) {
317473a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
317573a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
317673a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
317773a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
317873a71a0fSBarry Smith       }
317973a71a0fSBarry Smith     }
318073a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
318173a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
318273a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
318373a71a0fSBarry Smith   PetscFunctionReturn(0);
318473a71a0fSBarry Smith }
318573a71a0fSBarry Smith 
3186682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31870a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3188cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3189cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3190cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
319197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31927c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31937c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3194db4efbfdSBarry Smith                                         0,
3195db4efbfdSBarry Smith                                         0,
3196db4efbfdSBarry Smith                                         0,
3197db4efbfdSBarry Smith                                 /* 10*/ 0,
3198cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3199cb5b572fSBarry Smith                                         0,
320041f059aeSBarry Smith                                         MatSOR_SeqAIJ,
320117ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
320297304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3203cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3204cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3205cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3206cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
320797304618SKris Buschelman                                 /* 20*/ 0,
3208cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3209cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3210cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3211d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3212db4efbfdSBarry Smith                                         0,
3213db4efbfdSBarry Smith                                         0,
3214db4efbfdSBarry Smith                                         0,
3215db4efbfdSBarry Smith                                         0,
32164994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3217db4efbfdSBarry Smith                                         0,
3218db4efbfdSBarry Smith                                         0,
32198c778c55SBarry Smith                                         0,
32208c778c55SBarry Smith                                         0,
3221d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3222cb5b572fSBarry Smith                                         0,
3223cb5b572fSBarry Smith                                         0,
3224cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3225cb5b572fSBarry Smith                                         0,
3226d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3227cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3228cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3229cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3230cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3231d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3232cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3233cb5b572fSBarry Smith                                         0,
323479299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
32356e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
323673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
32373b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
32383b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
32393b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3240a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
324193dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3242b9617806SBarry Smith                                         0,
32430513a670SBarry Smith                                         0,
3244cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3245cda55fadSBarry Smith                                         0,
3246d519adbfSMatthew Knepley                                 /* 59*/ 0,
3247b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3248b9b97703SBarry Smith                                         MatView_SeqAIJ,
3249357abbc8SBarry Smith                                         0,
3250321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3251321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3252321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3253ee4f033dSBarry Smith                                         0,
3254ee4f033dSBarry Smith                                         0,
3255ee4f033dSBarry Smith                                         0,
3256d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3257c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3258ee4f033dSBarry Smith                                         0,
3259ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3260dcf5cc72SBarry Smith                                         0,
3261d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
32623acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
326397304618SKris Buschelman                                         0,
326497304618SKris Buschelman                                         0,
326597304618SKris Buschelman                                         0,
32666ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
326797304618SKris Buschelman                                         0,
326897304618SKris Buschelman                                         0,
326997304618SKris Buschelman                                         0,
3270bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3271d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
32721cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
32736284ec50SHong Zhang                                         0,
32746284ec50SHong Zhang                                         0,
3275bc011b1eSHong Zhang                                         0,
3276d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
327726be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
327826be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
327965e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
32804a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
328165e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
32826fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
32836fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
32846fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32852121bac1SHong Zhang                                         0,
32862121bac1SHong Zhang                                 /* 99*/ 0,
3287609c6c4dSKris Buschelman                                         0,
3288609c6c4dSKris Buschelman                                         0,
328987d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
329087d4246cSBarry Smith                                         0,
3291d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
329299cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3293f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3294f5edf698SHong Zhang                                         0,
32952bebee5dSHong Zhang                                         0,
3296cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3297985db425SBarry Smith                                         0,
32982af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32992af78befSBarry Smith                                         0,
3300599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3301d519adbfSMatthew Knepley                                 /*114*/ 0,
3302599ef60dSHong Zhang                                         0,
33033c2a7987SHong Zhang                                         0,
3304fe97e370SBarry Smith                                         0,
3305fbdbba38SShri Abhyankar                                         0,
3306fbdbba38SShri Abhyankar                                 /*119*/ 0,
3307fbdbba38SShri Abhyankar                                         0,
3308fbdbba38SShri Abhyankar                                         0,
330982d44351SHong Zhang                                         0,
3310b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
33110716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3312bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
331337868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
331437868618SMatthew G Knepley                                         0,
331537868618SMatthew G Knepley                                         0,
33165df89d91SHong Zhang                                 /*129*/ 0,
331775648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
331875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
331975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3320b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3321b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
33222b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
33232b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
33242b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
33253964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
33263964eb88SJed Brown                                  /*139*/0,
3327f9426fe0SMark Adams                                         0,
33281919a2e2SJed Brown                                         0,
33293a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
33303a062f41SBarry Smith                                         MatFindOffBlockDiagonalEntries_SeqAIJ
33319e29f15eSvictorle };
333217ab2063SBarry Smith 
33334a2ae208SSatish Balay #undef __FUNCT__
33344a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
33357087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3336bef8e0ddSBarry Smith {
3337bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
333897f1f81fSBarry Smith   PetscInt   i,nz,n;
3339bef8e0ddSBarry Smith 
3340bef8e0ddSBarry Smith   PetscFunctionBegin;
3341bef8e0ddSBarry Smith   nz = aij->maxnz;
3342d0f46423SBarry Smith   n  = mat->rmap->n;
3343bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3344bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3345bef8e0ddSBarry Smith   }
3346bef8e0ddSBarry Smith   aij->nz = nz;
3347bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3348bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3349bef8e0ddSBarry Smith   }
3350bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3351bef8e0ddSBarry Smith }
3352bef8e0ddSBarry Smith 
33534a2ae208SSatish Balay #undef __FUNCT__
33544a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3355bef8e0ddSBarry Smith /*@
3356bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3357bef8e0ddSBarry Smith        in the matrix.
3358bef8e0ddSBarry Smith 
3359bef8e0ddSBarry Smith   Input Parameters:
3360bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3361bef8e0ddSBarry Smith -  indices - the column indices
3362bef8e0ddSBarry Smith 
336315091d37SBarry Smith   Level: advanced
336415091d37SBarry Smith 
3365bef8e0ddSBarry Smith   Notes:
3366bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3367bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3368bef8e0ddSBarry Smith   of the MatSetValues() operation.
3369bef8e0ddSBarry Smith 
3370bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3371d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3372bef8e0ddSBarry Smith 
3373bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3374bef8e0ddSBarry Smith 
3375b9617806SBarry Smith     The indices should start with zero, not one.
3376b9617806SBarry Smith 
3377bef8e0ddSBarry Smith @*/
33787087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3379bef8e0ddSBarry Smith {
33804ac538c5SBarry Smith   PetscErrorCode ierr;
3381bef8e0ddSBarry Smith 
3382bef8e0ddSBarry Smith   PetscFunctionBegin;
33830700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33844482741eSBarry Smith   PetscValidPointer(indices,2);
33854ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3386bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3387bef8e0ddSBarry Smith }
3388bef8e0ddSBarry Smith 
3389be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3390be6bf707SBarry Smith 
33914a2ae208SSatish Balay #undef __FUNCT__
33924a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33937087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3394be6bf707SBarry Smith {
3395be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33966849ba73SBarry Smith   PetscErrorCode ierr;
3397d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3398be6bf707SBarry Smith 
3399be6bf707SBarry Smith   PetscFunctionBegin;
3400*169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3401be6bf707SBarry Smith 
3402be6bf707SBarry Smith   /* allocate space for values if not already there */
3403be6bf707SBarry Smith   if (!aij->saved_values) {
3404785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
34053bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3406be6bf707SBarry Smith   }
3407be6bf707SBarry Smith 
3408be6bf707SBarry Smith   /* copy values over */
340987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3410be6bf707SBarry Smith   PetscFunctionReturn(0);
3411be6bf707SBarry Smith }
3412be6bf707SBarry Smith 
34134a2ae208SSatish Balay #undef __FUNCT__
3414b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3415be6bf707SBarry Smith /*@
3416be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3417be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3418be6bf707SBarry Smith        nonlinear portion.
3419be6bf707SBarry Smith 
3420be6bf707SBarry Smith    Collect on Mat
3421be6bf707SBarry Smith 
3422be6bf707SBarry Smith   Input Parameters:
34230e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3424be6bf707SBarry Smith 
342515091d37SBarry Smith   Level: advanced
342615091d37SBarry Smith 
3427be6bf707SBarry Smith   Common Usage, with SNESSolve():
3428be6bf707SBarry Smith $    Create Jacobian matrix
3429be6bf707SBarry Smith $    Set linear terms into matrix
3430be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3431be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3432be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3433512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3434be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3435be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3436be6bf707SBarry Smith $    In your Jacobian routine
3437be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3438be6bf707SBarry Smith $      Set nonlinear terms in matrix
3439be6bf707SBarry Smith 
3440be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3441be6bf707SBarry Smith $    // build linear portion of Jacobian
3442512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3443be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3444be6bf707SBarry Smith $    loop over nonlinear iterations
3445be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3446be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3447be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3448be6bf707SBarry Smith $       Solve linear system with Jacobian
3449be6bf707SBarry Smith $    endloop
3450be6bf707SBarry Smith 
3451be6bf707SBarry Smith   Notes:
3452be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3453512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3454be6bf707SBarry Smith     calling this routine.
3455be6bf707SBarry Smith 
34560c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
34570c468ba9SBarry Smith     and does not allocated additional space.
34580c468ba9SBarry Smith 
3459be6bf707SBarry Smith .seealso: MatRetrieveValues()
3460be6bf707SBarry Smith 
3461be6bf707SBarry Smith @*/
34627087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3463be6bf707SBarry Smith {
34644ac538c5SBarry Smith   PetscErrorCode ierr;
3465be6bf707SBarry Smith 
3466be6bf707SBarry Smith   PetscFunctionBegin;
34670700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3468e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3469e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34704ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3471be6bf707SBarry Smith   PetscFunctionReturn(0);
3472be6bf707SBarry Smith }
3473be6bf707SBarry Smith 
34744a2ae208SSatish Balay #undef __FUNCT__
34754a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
34767087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3477be6bf707SBarry Smith {
3478be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
34796849ba73SBarry Smith   PetscErrorCode ierr;
3480d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3481be6bf707SBarry Smith 
3482be6bf707SBarry Smith   PetscFunctionBegin;
3483*169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3484f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3485be6bf707SBarry Smith   /* copy values over */
348687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3487be6bf707SBarry Smith   PetscFunctionReturn(0);
3488be6bf707SBarry Smith }
3489be6bf707SBarry Smith 
34904a2ae208SSatish Balay #undef __FUNCT__
34914a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3492be6bf707SBarry Smith /*@
3493be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3494be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3495be6bf707SBarry Smith        nonlinear portion.
3496be6bf707SBarry Smith 
3497be6bf707SBarry Smith    Collect on Mat
3498be6bf707SBarry Smith 
3499be6bf707SBarry Smith   Input Parameters:
3500be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3501be6bf707SBarry Smith 
350215091d37SBarry Smith   Level: advanced
350315091d37SBarry Smith 
3504be6bf707SBarry Smith .seealso: MatStoreValues()
3505be6bf707SBarry Smith 
3506be6bf707SBarry Smith @*/
35077087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3508be6bf707SBarry Smith {
35094ac538c5SBarry Smith   PetscErrorCode ierr;
3510be6bf707SBarry Smith 
3511be6bf707SBarry Smith   PetscFunctionBegin;
35120700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3513e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3514e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
35154ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3516be6bf707SBarry Smith   PetscFunctionReturn(0);
3517be6bf707SBarry Smith }
3518be6bf707SBarry Smith 
3519f83d6046SBarry Smith 
3520be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
35214a2ae208SSatish Balay #undef __FUNCT__
35224a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
352317ab2063SBarry Smith /*@C
3524682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
35250d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
35266e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
352751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
35282bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
352917ab2063SBarry Smith 
3530db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3531db81eaa0SLois Curfman McInnes 
353217ab2063SBarry Smith    Input Parameters:
3533db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
353417ab2063SBarry Smith .  m - number of rows
353517ab2063SBarry Smith .  n - number of columns
353617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
353751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35380298fd71SBarry Smith          (possibly different for each row) or NULL
353917ab2063SBarry Smith 
354017ab2063SBarry Smith    Output Parameter:
3541416022c9SBarry Smith .  A - the matrix
354217ab2063SBarry Smith 
3543175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3544ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3545175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3546175b88e8SBarry Smith 
3547b259b22eSLois Curfman McInnes    Notes:
354849a6f317SBarry Smith    If nnz is given then nz is ignored
354949a6f317SBarry Smith 
355017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
355117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
35520002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
355344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
355417ab2063SBarry Smith 
355517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35560298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
35573d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
35586da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
355917ab2063SBarry Smith 
3560682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
35614fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3562682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
35636c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
35646c7ebb05SLois Curfman McInnes 
35656c7ebb05SLois Curfman McInnes    Options Database Keys:
3566698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
35679db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
356817ab2063SBarry Smith 
3569027ccd11SLois Curfman McInnes    Level: intermediate
3570027ccd11SLois Curfman McInnes 
357169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
357236db0b34SBarry Smith 
357317ab2063SBarry Smith @*/
35747087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
357517ab2063SBarry Smith {
3576dfbe8321SBarry Smith   PetscErrorCode ierr;
35776945ee14SBarry Smith 
35783a40ed3dSBarry Smith   PetscFunctionBegin;
3579f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3580117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3581c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3582d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3583273d9f13SBarry Smith   PetscFunctionReturn(0);
3584273d9f13SBarry Smith }
3585273d9f13SBarry Smith 
35864a2ae208SSatish Balay #undef __FUNCT__
35874a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3588273d9f13SBarry Smith /*@C
3589273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3590273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3591273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3592273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3593273d9f13SBarry Smith 
3594273d9f13SBarry Smith    Collective on MPI_Comm
3595273d9f13SBarry Smith 
3596273d9f13SBarry Smith    Input Parameters:
3597117016b1SBarry Smith +  B - The matrix-free
3598273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3599273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
36000298fd71SBarry Smith          (possibly different for each row) or NULL
3601273d9f13SBarry Smith 
3602273d9f13SBarry Smith    Notes:
360349a6f317SBarry Smith      If nnz is given then nz is ignored
360449a6f317SBarry Smith 
3605273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3606273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3607273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3608273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3609273d9f13SBarry Smith 
3610273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
36110298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3612273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3613273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3614273d9f13SBarry Smith 
3615aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3616aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3617aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3618aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3619aa95bbe8SBarry Smith 
3620a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3621a96a251dSBarry Smith    entries or columns indices
3622a96a251dSBarry Smith 
3623273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3624273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3625273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3626273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3627273d9f13SBarry Smith 
3628273d9f13SBarry Smith    Options Database Keys:
3629698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3630698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3631273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3632273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3633273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3634273d9f13SBarry Smith 
3635273d9f13SBarry Smith    Level: intermediate
3636273d9f13SBarry Smith 
363769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3638273d9f13SBarry Smith 
3639273d9f13SBarry Smith @*/
36407087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3641273d9f13SBarry Smith {
36424ac538c5SBarry Smith   PetscErrorCode ierr;
3643a23d5eceSKris Buschelman 
3644a23d5eceSKris Buschelman   PetscFunctionBegin;
36456ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
36466ba663aaSJed Brown   PetscValidType(B,1);
36474ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3648a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3649a23d5eceSKris Buschelman }
3650a23d5eceSKris Buschelman 
3651a23d5eceSKris Buschelman #undef __FUNCT__
3652a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
36537087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3654a23d5eceSKris Buschelman {
3655273d9f13SBarry Smith   Mat_SeqAIJ     *b;
36562576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
36576849ba73SBarry Smith   PetscErrorCode ierr;
365897f1f81fSBarry Smith   PetscInt       i;
3659273d9f13SBarry Smith 
3660273d9f13SBarry Smith   PetscFunctionBegin;
36612576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3662a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3663c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3664c461c341SBarry Smith     nz             = 0;
3665c461c341SBarry Smith   }
3666c461c341SBarry Smith 
366726283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
366826283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3669899cda47SBarry Smith 
3670435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3671e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3672b73539f3SBarry Smith   if (nnz) {
3673d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3674e32f2f54SBarry 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]);
3675e32f2f54SBarry 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);
3676b73539f3SBarry Smith     }
3677b73539f3SBarry Smith   }
3678b73539f3SBarry Smith 
3679273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
36802205254eSKarl Rupp 
3681273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3682273d9f13SBarry Smith 
3683ab93d7beSBarry Smith   if (!skipallocation) {
36842ee49352SLisandro Dalcin     if (!b->imax) {
3685dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
36863bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36872ee49352SLisandro Dalcin     }
3688273d9f13SBarry Smith     if (!nnz) {
3689435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3690c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3691d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3692d0f46423SBarry Smith       nz = nz*B->rmap->n;
3693273d9f13SBarry Smith     } else {
3694273d9f13SBarry Smith       nz = 0;
3695d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3696273d9f13SBarry Smith     }
3697ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36982205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3699ab93d7beSBarry Smith 
3700273d9f13SBarry Smith     /* allocate the matrix space */
37012ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3702dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
37033bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3704bfeeae90SHong Zhang     b->i[0] = 0;
3705d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
37065da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
37075da197adSKris Buschelman     }
3708273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3709e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3710e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3711b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3712b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3713b31eba2aSShri Abhyankar #endif
3714c461c341SBarry Smith   } else {
3715e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3716e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3717c461c341SBarry Smith   }
3718273d9f13SBarry Smith 
3719273d9f13SBarry Smith   b->nz               = 0;
3720273d9f13SBarry Smith   b->maxnz            = nz;
3721273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
37222205254eSKarl Rupp   if (realalloc) {
37232205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
37242205254eSKarl Rupp   }
3725273d9f13SBarry Smith   PetscFunctionReturn(0);
3726273d9f13SBarry Smith }
3727273d9f13SBarry Smith 
3728a1661176SMatthew Knepley #undef  __FUNCT__
3729a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
373058d36128SBarry Smith /*@
3731a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3732a1661176SMatthew Knepley 
3733a1661176SMatthew Knepley    Input Parameters:
3734a1661176SMatthew Knepley +  B - the matrix
3735a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3736a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3737a1661176SMatthew Knepley -  v - optional values in the matrix
3738a1661176SMatthew Knepley 
3739a1661176SMatthew Knepley    Level: developer
3740a1661176SMatthew Knepley 
374158d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
374258d36128SBarry Smith 
3743a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3744a1661176SMatthew Knepley 
3745a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3746a1661176SMatthew Knepley @*/
3747a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3748a1661176SMatthew Knepley {
3749a1661176SMatthew Knepley   PetscErrorCode ierr;
3750a1661176SMatthew Knepley 
3751a1661176SMatthew Knepley   PetscFunctionBegin;
37520700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
37536ba663aaSJed Brown   PetscValidType(B,1);
37544ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3755a1661176SMatthew Knepley   PetscFunctionReturn(0);
3756a1661176SMatthew Knepley }
3757a1661176SMatthew Knepley 
3758a1661176SMatthew Knepley #undef  __FUNCT__
3759a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
37607087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3761a1661176SMatthew Knepley {
3762a1661176SMatthew Knepley   PetscInt       i;
3763a1661176SMatthew Knepley   PetscInt       m,n;
3764a1661176SMatthew Knepley   PetscInt       nz;
3765a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3766a1661176SMatthew Knepley   PetscScalar    *values;
3767a1661176SMatthew Knepley   PetscErrorCode ierr;
3768a1661176SMatthew Knepley 
3769a1661176SMatthew Knepley   PetscFunctionBegin;
377065e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3771779a8d59SSatish Balay 
3772779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3773779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3774779a8d59SSatish Balay 
3775779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3776785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3777a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3778b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3779a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
378065e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3781a1661176SMatthew Knepley     nnz[i] = nz;
3782a1661176SMatthew Knepley   }
3783a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3784a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3785a1661176SMatthew Knepley 
3786a1661176SMatthew Knepley   if (v) {
3787a1661176SMatthew Knepley     values = (PetscScalar*) v;
3788a1661176SMatthew Knepley   } else {
37891795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3790a1661176SMatthew Knepley   }
3791a1661176SMatthew Knepley 
3792a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3793b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3794b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3795a1661176SMatthew Knepley   }
3796a1661176SMatthew Knepley 
3797a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3798a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3799a1661176SMatthew Knepley 
3800a1661176SMatthew Knepley   if (!v) {
3801a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3802a1661176SMatthew Knepley   }
38037827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3804a1661176SMatthew Knepley   PetscFunctionReturn(0);
3805a1661176SMatthew Knepley }
3806a1661176SMatthew Knepley 
3807c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
380806873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3809170fe5c8SBarry Smith 
3810170fe5c8SBarry Smith #undef __FUNCT__
3811170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3812170fe5c8SBarry Smith /*
3813170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3814170fe5c8SBarry Smith 
3815170fe5c8SBarry Smith                n                       p                          p
3816170fe5c8SBarry Smith         (              )       (              )         (                  )
3817170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3818170fe5c8SBarry Smith         (              )       (              )         (                  )
3819170fe5c8SBarry Smith 
3820170fe5c8SBarry Smith */
3821170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3822170fe5c8SBarry Smith {
3823170fe5c8SBarry Smith   PetscErrorCode    ierr;
3824170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3825170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3826170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
38271de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3828170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3829170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3830170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3831170fe5c8SBarry Smith 
3832170fe5c8SBarry Smith   PetscFunctionBegin;
3833d0f46423SBarry Smith   m    = A->rmap->n;
3834d0f46423SBarry Smith   n    = A->cmap->n;
3835d0f46423SBarry Smith   p    = B->cmap->n;
3836170fe5c8SBarry Smith   a    = sub_a->v;
3837170fe5c8SBarry Smith   b    = sub_b->a;
3838170fe5c8SBarry Smith   c    = sub_c->v;
3839170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3840170fe5c8SBarry Smith 
3841170fe5c8SBarry Smith   ii  = sub_b->i;
3842170fe5c8SBarry Smith   idx = sub_b->j;
3843170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3844170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3845170fe5c8SBarry Smith     while (q-->0) {
3846170fe5c8SBarry Smith       c_q = c + m*(*idx);
3847170fe5c8SBarry Smith       a_q = a + m*i;
3848854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3849170fe5c8SBarry Smith       idx++;
3850170fe5c8SBarry Smith       b++;
3851170fe5c8SBarry Smith     }
3852170fe5c8SBarry Smith   }
3853170fe5c8SBarry Smith   PetscFunctionReturn(0);
3854170fe5c8SBarry Smith }
3855170fe5c8SBarry Smith 
3856170fe5c8SBarry Smith #undef __FUNCT__
3857170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3858170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3859170fe5c8SBarry Smith {
3860170fe5c8SBarry Smith   PetscErrorCode ierr;
3861d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3862170fe5c8SBarry Smith   Mat            Cmat;
3863170fe5c8SBarry Smith 
3864170fe5c8SBarry Smith   PetscFunctionBegin;
3865e32f2f54SBarry 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);
3866ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3867170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3868a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3869170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
38700298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3871d73949e8SHong Zhang 
3872d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
38732205254eSKarl Rupp 
3874170fe5c8SBarry Smith   *C = Cmat;
3875170fe5c8SBarry Smith   PetscFunctionReturn(0);
3876170fe5c8SBarry Smith }
3877170fe5c8SBarry Smith 
3878170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3879170fe5c8SBarry Smith #undef __FUNCT__
3880170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3881170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3882170fe5c8SBarry Smith {
3883170fe5c8SBarry Smith   PetscErrorCode ierr;
3884170fe5c8SBarry Smith 
3885170fe5c8SBarry Smith   PetscFunctionBegin;
3886170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38873ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3888170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38893ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3890170fe5c8SBarry Smith   }
38913ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3892170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38933ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3894170fe5c8SBarry Smith   PetscFunctionReturn(0);
3895170fe5c8SBarry Smith }
3896170fe5c8SBarry Smith 
3897170fe5c8SBarry Smith 
38980bad9183SKris Buschelman /*MC
3899fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
39000bad9183SKris Buschelman    based on compressed sparse row format.
39010bad9183SKris Buschelman 
39020bad9183SKris Buschelman    Options Database Keys:
39030bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
39040bad9183SKris Buschelman 
39050bad9183SKris Buschelman   Level: beginner
39060bad9183SKris Buschelman 
3907f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
39080bad9183SKris Buschelman M*/
39090bad9183SKris Buschelman 
3910ccd284c7SBarry Smith /*MC
3911ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3912ccd284c7SBarry Smith 
3913ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3914ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3915ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3916ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3917ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3918ccd284c7SBarry Smith 
3919ccd284c7SBarry Smith    Options Database Keys:
3920ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3921ccd284c7SBarry Smith 
3922ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3923ccd284c7SBarry Smith    enough exist.
3924ccd284c7SBarry Smith 
3925ccd284c7SBarry Smith   Level: beginner
3926ccd284c7SBarry Smith 
3927ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3928ccd284c7SBarry Smith M*/
3929ccd284c7SBarry Smith 
3930ccd284c7SBarry Smith /*MC
3931ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3932ccd284c7SBarry Smith 
3933ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3934ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3935ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3936ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3937ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3938ccd284c7SBarry Smith 
3939ccd284c7SBarry Smith    Options Database Keys:
3940ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3941ccd284c7SBarry Smith 
3942ccd284c7SBarry Smith   Level: beginner
3943ccd284c7SBarry Smith 
3944ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3945ccd284c7SBarry Smith M*/
3946ccd284c7SBarry Smith 
3947b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
39488cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3949b5e56a35SBarry Smith #endif
3950ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
39518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3952af1023dbSSatish Balay #endif
39538cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
39548cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
39558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
39567087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3957611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
39588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3959611f576cSBarry Smith #endif
3960611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
39618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3962611f576cSBarry Smith #endif
3963f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
39648cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3965f3c0ef26SHong Zhang #endif
3966eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
39678cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3968eb3b5408SSatish Balay #endif
3969586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
39708cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3971586621ddSJed Brown #endif
3972719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
39738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3974719d5645SBarry Smith #endif
3975b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
39768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
39777087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
39787087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3979b3866ffcSBarry Smith #endif
398017f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
39818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
398217f1a0eaSHong Zhang #endif
398317667f90SBarry Smith 
3984c0c8ee5eSDmitry Karpeev 
39858c778c55SBarry Smith #undef __FUNCT__
39868c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39878c778c55SBarry Smith /*@C
39888c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39898c778c55SBarry Smith 
39908c778c55SBarry Smith    Not Collective
39918c778c55SBarry Smith 
39928c778c55SBarry Smith    Input Parameter:
39938c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39948c778c55SBarry Smith 
39958c778c55SBarry Smith    Output Parameter:
39968c778c55SBarry Smith .   array - pointer to the data
39978c778c55SBarry Smith 
39988c778c55SBarry Smith    Level: intermediate
39998c778c55SBarry Smith 
4000774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
40018c778c55SBarry Smith @*/
40028c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
40038c778c55SBarry Smith {
40048c778c55SBarry Smith   PetscErrorCode ierr;
40058c778c55SBarry Smith 
40068c778c55SBarry Smith   PetscFunctionBegin;
40078c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
40088c778c55SBarry Smith   PetscFunctionReturn(0);
40098c778c55SBarry Smith }
40108c778c55SBarry Smith 
40118c778c55SBarry Smith #undef __FUNCT__
40128c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
40138c778c55SBarry Smith /*@C
40148c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
40158c778c55SBarry Smith 
40168c778c55SBarry Smith    Not Collective
40178c778c55SBarry Smith 
40188c778c55SBarry Smith    Input Parameters:
40198c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
40208c778c55SBarry Smith .  array - pointer to the data
40218c778c55SBarry Smith 
40228c778c55SBarry Smith    Level: intermediate
40238c778c55SBarry Smith 
4024774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
40258c778c55SBarry Smith @*/
40268c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
40278c778c55SBarry Smith {
40288c778c55SBarry Smith   PetscErrorCode ierr;
40298c778c55SBarry Smith 
40308c778c55SBarry Smith   PetscFunctionBegin;
40318c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
40328c778c55SBarry Smith   PetscFunctionReturn(0);
40338c778c55SBarry Smith }
40348c778c55SBarry Smith 
40354a2ae208SSatish Balay #undef __FUNCT__
40364a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
40378cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
4038273d9f13SBarry Smith {
4039273d9f13SBarry Smith   Mat_SeqAIJ     *b;
4040dfbe8321SBarry Smith   PetscErrorCode ierr;
404138baddfdSBarry Smith   PetscMPIInt    size;
4042273d9f13SBarry Smith 
4043273d9f13SBarry Smith   PetscFunctionBegin;
4044ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
4045e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
4046273d9f13SBarry Smith 
4047b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
40482205254eSKarl Rupp 
4049b0a32e0cSBarry Smith   B->data = (void*)b;
40502205254eSKarl Rupp 
4051549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
40522205254eSKarl Rupp 
4053416022c9SBarry Smith   b->row                = 0;
4054416022c9SBarry Smith   b->col                = 0;
405582bf6240SBarry Smith   b->icol               = 0;
4056b810aeb4SBarry Smith   b->reallocs           = 0;
405736db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4058f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4059416022c9SBarry Smith   b->nonew              = 0;
4060416022c9SBarry Smith   b->diag               = 0;
4061416022c9SBarry Smith   b->solve_work         = 0;
40622a1b7f2aSHong Zhang   B->spptr              = 0;
4063be6bf707SBarry Smith   b->saved_values       = 0;
4064d7f994e1SBarry Smith   b->idiag              = 0;
406571f1c65dSBarry Smith   b->mdiag              = 0;
406671f1c65dSBarry Smith   b->ssor_work          = 0;
406771f1c65dSBarry Smith   b->omega              = 1.0;
406871f1c65dSBarry Smith   b->fshift             = 0.0;
406971f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4070bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4071a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
4072a30b2313SHong Zhang   b->xtoy               = 0;
4073a30b2313SHong Zhang   b->XtoY               = 0;
407488e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
407517ab2063SBarry Smith 
407635d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4077bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4078bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
40798c778c55SBarry Smith 
4080b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4081bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4082bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4083bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4084b3866ffcSBarry Smith #endif
4085b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4086bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4087b5e56a35SBarry Smith #endif
4088ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4089bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4090719d5645SBarry Smith #endif
4091611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4092bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4093611f576cSBarry Smith #endif
4094f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4095bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4096f3c0ef26SHong Zhang #endif
4097611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4098bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4099611f576cSBarry Smith #endif
4100eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4101bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4102eb3b5408SSatish Balay #endif
4103586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4104bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4105586621ddSJed Brown #endif
4106719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4107bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4108719d5645SBarry Smith #endif
410917f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4110bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
411117f1a0eaSHong Zhang #endif
411217f1a0eaSHong Zhang 
4113bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4114bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4115bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4116bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4117bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4118bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4119bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4120bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4121bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4122bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4123bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4124bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4125bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4126bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4127bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4128bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4129bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4130bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
41314108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
413217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
41333a40ed3dSBarry Smith   PetscFunctionReturn(0);
413417ab2063SBarry Smith }
413517ab2063SBarry Smith 
41364a2ae208SSatish Balay #undef __FUNCT__
4137b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4138b24902e0SBarry Smith /*
4139b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4140b24902e0SBarry Smith */
4141ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
414217ab2063SBarry Smith {
4143416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
41446849ba73SBarry Smith   PetscErrorCode ierr;
4145d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
414617ab2063SBarry Smith 
41473a40ed3dSBarry Smith   PetscFunctionBegin;
4148273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4149273d9f13SBarry Smith 
4150d5f3da31SBarry Smith   C->factortype = A->factortype;
4151416022c9SBarry Smith   c->row        = 0;
4152416022c9SBarry Smith   c->col        = 0;
415382bf6240SBarry Smith   c->icol       = 0;
41546ad4291fSHong Zhang   c->reallocs   = 0;
415517ab2063SBarry Smith 
41566ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
415717ab2063SBarry Smith 
4158aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4159aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4160eec197d1SBarry Smith 
4161dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
41623bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
416317ab2063SBarry Smith   for (i=0; i<m; i++) {
4164416022c9SBarry Smith     c->imax[i] = a->imax[i];
4165416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
416617ab2063SBarry Smith   }
416717ab2063SBarry Smith 
416817ab2063SBarry Smith   /* allocate the matrix space */
4169f77e22a1SHong Zhang   if (mallocmatspace) {
4170dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
41713bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
41722205254eSKarl Rupp 
4173f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
41742205254eSKarl Rupp 
417597f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
417617ab2063SBarry Smith     if (m > 0) {
417797f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4178be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4179bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4180be6bf707SBarry Smith       } else {
4181bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
418217ab2063SBarry Smith       }
418308480c60SBarry Smith     }
4184f77e22a1SHong Zhang   }
418517ab2063SBarry Smith 
41866ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4187416022c9SBarry Smith   c->roworiented       = a->roworiented;
4188416022c9SBarry Smith   c->nonew             = a->nonew;
4189416022c9SBarry Smith   if (a->diag) {
4190785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
41913bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
419217ab2063SBarry Smith     for (i=0; i<m; i++) {
4193416022c9SBarry Smith       c->diag[i] = a->diag[i];
419417ab2063SBarry Smith     }
41953a40ed3dSBarry Smith   } else c->diag = 0;
41962205254eSKarl Rupp 
41976ad4291fSHong Zhang   c->solve_work         = 0;
41986ad4291fSHong Zhang   c->saved_values       = 0;
41996ad4291fSHong Zhang   c->idiag              = 0;
420071f1c65dSBarry Smith   c->ssor_work          = 0;
4201a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4202e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4203e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
42046ad4291fSHong Zhang   c->xtoy               = 0;
42056ad4291fSHong Zhang   c->XtoY               = 0;
42066ad4291fSHong Zhang 
4207893ad86cSHong Zhang   c->rmax         = a->rmax;
4208416022c9SBarry Smith   c->nz           = a->nz;
42098ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4210273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4211754ec7b1SSatish Balay 
42126ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
42136ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4214cd6b891eSBarry Smith   if (a->compressedrow.use) {
42156ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4216dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
42176ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
42186ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
421927ea64f8SHong Zhang   } else {
422027ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
42210298fd71SBarry Smith     c->compressedrow.i      = NULL;
42220298fd71SBarry Smith     c->compressedrow.rindex = NULL;
42236ad4291fSHong Zhang   }
422488e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
42254846f1f5SKris Buschelman 
42262205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4227140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
42283a40ed3dSBarry Smith   PetscFunctionReturn(0);
422917ab2063SBarry Smith }
423017ab2063SBarry Smith 
42314a2ae208SSatish Balay #undef __FUNCT__
4232b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4233b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4234b24902e0SBarry Smith {
4235b24902e0SBarry Smith   PetscErrorCode ierr;
4236b24902e0SBarry Smith 
4237b24902e0SBarry Smith   PetscFunctionBegin;
4238ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
42394b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4240cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
4241a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4242cfd3f464SBarry Smith   }
4243a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4244f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4245b24902e0SBarry Smith   PetscFunctionReturn(0);
4246b24902e0SBarry Smith }
4247b24902e0SBarry Smith 
4248b24902e0SBarry Smith #undef __FUNCT__
42494a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4250112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4251fbdbba38SShri Abhyankar {
4252fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4253fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4254fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4255fbdbba38SShri Abhyankar   int            fd;
4256fbdbba38SShri Abhyankar   PetscMPIInt    size;
4257fbdbba38SShri Abhyankar   MPI_Comm       comm;
4258bbead8a2SBarry Smith   PetscInt       bs = 1;
4259fbdbba38SShri Abhyankar 
4260fbdbba38SShri Abhyankar   PetscFunctionBegin;
4261fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4262fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4263fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4264bbead8a2SBarry Smith 
42650298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
42660298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4267bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
42681814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4269bbead8a2SBarry Smith 
4270fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4271fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4272fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4273fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4274fbdbba38SShri Abhyankar 
4275bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4276fbdbba38SShri Abhyankar 
4277fbdbba38SShri Abhyankar   /* read in row lengths */
4278785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4279fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4280fbdbba38SShri Abhyankar 
4281fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4282fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4283fbdbba38SShri 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);
4284fbdbba38SShri Abhyankar 
4285fbdbba38SShri Abhyankar   /* set global size if not set already*/
4286f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4287fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4288aabbc4fbSShri Abhyankar   } else {
4289fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4290fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42914c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42924c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42934c5b953cSHong Zhang     }
4294f501eaabSShri 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);
4295aabbc4fbSShri Abhyankar   }
4296fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4297fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4298fbdbba38SShri Abhyankar 
4299fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4300fbdbba38SShri Abhyankar 
4301fbdbba38SShri Abhyankar   /* read in nonzero values */
4302fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4303fbdbba38SShri Abhyankar 
4304fbdbba38SShri Abhyankar   /* set matrix "i" values */
4305fbdbba38SShri Abhyankar   a->i[0] = 0;
4306fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4307fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4308fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4309fbdbba38SShri Abhyankar   }
4310fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4311fbdbba38SShri Abhyankar 
4312fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4313fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4314fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4315fbdbba38SShri Abhyankar }
4316fbdbba38SShri Abhyankar 
4317fbdbba38SShri Abhyankar #undef __FUNCT__
4318b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4319ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
43207264ac53SSatish Balay {
43217264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4322dfbe8321SBarry Smith   PetscErrorCode ierr;
4323eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4324eeffb40dSHong Zhang   PetscInt k;
4325eeffb40dSHong Zhang #endif
43267264ac53SSatish Balay 
43273a40ed3dSBarry Smith   PetscFunctionBegin;
4328bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4329d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4330ca44d042SBarry Smith     *flg = PETSC_FALSE;
4331ca44d042SBarry Smith     PetscFunctionReturn(0);
4332bcd2baecSBarry Smith   }
43337264ac53SSatish Balay 
43347264ac53SSatish Balay   /* if the a->i are the same */
4335d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4336abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
43377264ac53SSatish Balay 
43387264ac53SSatish Balay   /* if a->j are the same */
433997f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4340abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4341bcd2baecSBarry Smith 
4342bcd2baecSBarry Smith   /* if a->a are the same */
4343eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4344eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4345eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4346eeffb40dSHong Zhang       *flg = PETSC_FALSE;
43473a40ed3dSBarry Smith       PetscFunctionReturn(0);
4348eeffb40dSHong Zhang     }
4349eeffb40dSHong Zhang   }
4350eeffb40dSHong Zhang #else
4351eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4352eeffb40dSHong Zhang #endif
4353eeffb40dSHong Zhang   PetscFunctionReturn(0);
43547264ac53SSatish Balay }
435536db0b34SBarry Smith 
43564a2ae208SSatish Balay #undef __FUNCT__
43574a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
435805869f15SSatish Balay /*@
435936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
436036db0b34SBarry Smith               provided by the user.
436136db0b34SBarry Smith 
4362c75a6043SHong Zhang       Collective on MPI_Comm
436336db0b34SBarry Smith 
436436db0b34SBarry Smith    Input Parameters:
436536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
436636db0b34SBarry Smith .   m - number of rows
436736db0b34SBarry Smith .   n - number of columns
436836db0b34SBarry Smith .   i - row indices
436936db0b34SBarry Smith .   j - column indices
437036db0b34SBarry Smith -   a - matrix values
437136db0b34SBarry Smith 
437236db0b34SBarry Smith    Output Parameter:
437336db0b34SBarry Smith .   mat - the matrix
437436db0b34SBarry Smith 
437536db0b34SBarry Smith    Level: intermediate
437636db0b34SBarry Smith 
437736db0b34SBarry Smith    Notes:
43780551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4379292fb18eSBarry Smith     once the matrix is destroyed and not before
438036db0b34SBarry Smith 
438136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
438236db0b34SBarry Smith 
4383bfeeae90SHong Zhang        The i and j indices are 0 based
438436db0b34SBarry Smith 
4385a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4386a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4387a4552177SSatish Balay     as shown:
4388a4552177SSatish Balay 
4389a4552177SSatish Balay         1 0 0
4390a4552177SSatish Balay         2 0 3
4391a4552177SSatish Balay         4 5 6
4392a4552177SSatish Balay 
4393a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43949985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4395a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4396a4552177SSatish Balay 
43979985e31cSBarry Smith 
439869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
439936db0b34SBarry Smith 
440036db0b34SBarry Smith @*/
44017087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
440236db0b34SBarry Smith {
4403dfbe8321SBarry Smith   PetscErrorCode ierr;
4404cbcfb4deSHong Zhang   PetscInt       ii;
440536db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4406cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4407cbcfb4deSHong Zhang   PetscInt jj;
4408cbcfb4deSHong Zhang #endif
440936db0b34SBarry Smith 
441036db0b34SBarry Smith   PetscFunctionBegin;
4411f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4412f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4413f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4414a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4415ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4416ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4417ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4418dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4419ab93d7beSBarry Smith 
442036db0b34SBarry Smith   aij->i            = i;
442136db0b34SBarry Smith   aij->j            = j;
442236db0b34SBarry Smith   aij->a            = a;
442336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
442436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4425e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4426e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
442736db0b34SBarry Smith 
442836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
442936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
44302515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4431e32f2f54SBarry 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]);
44329985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4433e32f2f54SBarry 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);
4434e32f2f54SBarry 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);
44359985e31cSBarry Smith     }
443636db0b34SBarry Smith #endif
443736db0b34SBarry Smith   }
44382515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
443936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4440e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4441e32f2f54SBarry 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]);
444236db0b34SBarry Smith   }
444336db0b34SBarry Smith #endif
444436db0b34SBarry Smith 
4445b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4446b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
444736db0b34SBarry Smith   PetscFunctionReturn(0);
444836db0b34SBarry Smith }
44498a0b0e6bSVictor Minden #undef __FUNCT__
44508a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
445180ef6e79SMatthew G Knepley /*@C
4452d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
44538a0b0e6bSVictor Minden               provided by the user.
44548a0b0e6bSVictor Minden 
44558a0b0e6bSVictor Minden       Collective on MPI_Comm
44568a0b0e6bSVictor Minden 
44578a0b0e6bSVictor Minden    Input Parameters:
44588a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
44598a0b0e6bSVictor Minden .   m   - number of rows
44608a0b0e6bSVictor Minden .   n   - number of columns
44618a0b0e6bSVictor Minden .   i   - row indices
44628a0b0e6bSVictor Minden .   j   - column indices
44631230e6d1SVictor Minden .   a   - matrix values
44641230e6d1SVictor Minden .   nz  - number of nonzeros
44651230e6d1SVictor Minden -   idx - 0 or 1 based
44668a0b0e6bSVictor Minden 
44678a0b0e6bSVictor Minden    Output Parameter:
44688a0b0e6bSVictor Minden .   mat - the matrix
44698a0b0e6bSVictor Minden 
44708a0b0e6bSVictor Minden    Level: intermediate
44718a0b0e6bSVictor Minden 
44728a0b0e6bSVictor Minden    Notes:
44738a0b0e6bSVictor Minden        The i and j indices are 0 based
44748a0b0e6bSVictor Minden 
44758a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
44768a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
44778a0b0e6bSVictor Minden     as shown:
44788a0b0e6bSVictor Minden 
44798a0b0e6bSVictor Minden         1 0 0
44808a0b0e6bSVictor Minden         2 0 3
44818a0b0e6bSVictor Minden         4 5 6
44828a0b0e6bSVictor Minden 
44838a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
44848a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
44858a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44868a0b0e6bSVictor Minden 
44878a0b0e6bSVictor Minden 
448869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44898a0b0e6bSVictor Minden 
44908a0b0e6bSVictor Minden @*/
44911230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44928a0b0e6bSVictor Minden {
44938a0b0e6bSVictor Minden   PetscErrorCode ierr;
4494d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44958a0b0e6bSVictor Minden 
44968a0b0e6bSVictor Minden 
44978a0b0e6bSVictor Minden   PetscFunctionBegin;
44981795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
44991230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4500c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
45011230e6d1SVictor Minden   }
45028a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
45038a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
45048a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
45051230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
45061230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
45071230e6d1SVictor Minden     if (idx) {
45081230e6d1SVictor Minden       row = i[ii] - 1;
45091230e6d1SVictor Minden       col = j[ii] - 1;
45101230e6d1SVictor Minden     } else {
45111230e6d1SVictor Minden       row = i[ii];
45121230e6d1SVictor Minden       col = j[ii];
45138a0b0e6bSVictor Minden     }
45141230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
45158a0b0e6bSVictor Minden   }
45168a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
45178a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4518d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
45198a0b0e6bSVictor Minden   PetscFunctionReturn(0);
45208a0b0e6bSVictor Minden }
452136db0b34SBarry Smith 
4522cc8ba8e1SBarry Smith #undef __FUNCT__
4523ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4524dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4525cc8ba8e1SBarry Smith {
4526dfbe8321SBarry Smith   PetscErrorCode ierr;
4527cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
452836db0b34SBarry Smith 
4529cc8ba8e1SBarry Smith   PetscFunctionBegin;
45308ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4531cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4532cc8ba8e1SBarry Smith     a->coloring = coloring;
453312c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
453497f1f81fSBarry Smith     PetscInt        i,*larray;
453512c595b3SBarry Smith     ISColoring      ocoloring;
453608b6dcc0SBarry Smith     ISColoringValue *colors;
453712c595b3SBarry Smith 
453812c595b3SBarry Smith     /* set coloring for diagonal portion */
4539785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
45402205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
45410298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4542785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
45432205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
454412c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4545d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
454612c595b3SBarry Smith     a->coloring = ocoloring;
454712c595b3SBarry Smith   }
4548cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4549cc8ba8e1SBarry Smith }
4550cc8ba8e1SBarry Smith 
4551ee4f033dSBarry Smith #undef __FUNCT__
4552ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
455397f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4554ee4f033dSBarry Smith {
4555ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4556d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
455754f21887SBarry Smith   MatScalar       *v      = a->a;
455854f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
455908b6dcc0SBarry Smith   ISColoringValue *color;
4560ee4f033dSBarry Smith 
4561ee4f033dSBarry Smith   PetscFunctionBegin;
4562e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4563ee4f033dSBarry Smith   color = a->coloring->colors;
4564ee4f033dSBarry Smith   /* loop over rows */
4565ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4566ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4567ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
45682205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4569ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4570cc8ba8e1SBarry Smith   }
4571cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4572cc8ba8e1SBarry Smith }
457336db0b34SBarry Smith 
4574acf2f550SJed Brown #undef __FUNCT__
4575acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4576acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4577acf2f550SJed Brown {
4578acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4579acf2f550SJed Brown   PetscErrorCode ierr;
4580acf2f550SJed Brown 
4581acf2f550SJed Brown   PetscFunctionBegin;
4582acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4583acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45842205254eSKarl Rupp 
4585acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4586acf2f550SJed Brown   PetscFunctionReturn(0);
4587acf2f550SJed Brown }
4588acf2f550SJed Brown 
458981824310SBarry Smith /*
459081824310SBarry Smith     Special version for direct calls from Fortran
459181824310SBarry Smith */
4592b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
459381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
459481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
459581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
459681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
459781824310SBarry Smith #endif
459881824310SBarry Smith 
459981824310SBarry Smith /* Change these macros so can be used in void function */
460081824310SBarry Smith #undef CHKERRQ
4601ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
460281824310SBarry Smith #undef SETERRQ2
4603e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
46044994cf47SJed Brown #undef SETERRQ3
46054994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
460681824310SBarry Smith 
460781824310SBarry Smith #undef __FUNCT__
460881824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
46098cc058d9SJed 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)
461081824310SBarry Smith {
461181824310SBarry Smith   Mat            A  = *AA;
461281824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
461381824310SBarry Smith   InsertMode     is = *isis;
461481824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
461581824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
461681824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
461781824310SBarry Smith   PetscErrorCode ierr;
461881824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
461954f21887SBarry Smith   MatScalar      *ap,value,*aa;
4620ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4621ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
462281824310SBarry Smith 
462381824310SBarry Smith   PetscFunctionBegin;
46244994cf47SJed Brown   MatCheckPreallocated(A,1);
462581824310SBarry Smith   imax  = a->imax;
462681824310SBarry Smith   ai    = a->i;
462781824310SBarry Smith   ailen = a->ilen;
462881824310SBarry Smith   aj    = a->j;
462981824310SBarry Smith   aa    = a->a;
463081824310SBarry Smith 
463181824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
463281824310SBarry Smith     row = im[k];
463381824310SBarry Smith     if (row < 0) continue;
463481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4635ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
463681824310SBarry Smith #endif
463781824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
463881824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
463981824310SBarry Smith     low  = 0;
464081824310SBarry Smith     high = nrow;
464181824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
464281824310SBarry Smith       if (in[l] < 0) continue;
464381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4644ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
464581824310SBarry Smith #endif
464681824310SBarry Smith       col = in[l];
46472205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
46482205254eSKarl Rupp       else value = v[k + l*m];
46492205254eSKarl Rupp 
465081824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
465181824310SBarry Smith 
46522205254eSKarl Rupp       if (col <= lastcol) low = 0;
46532205254eSKarl Rupp       else high = nrow;
465481824310SBarry Smith       lastcol = col;
465581824310SBarry Smith       while (high-low > 5) {
465681824310SBarry Smith         t = (low+high)/2;
465781824310SBarry Smith         if (rp[t] > col) high = t;
465881824310SBarry Smith         else             low  = t;
465981824310SBarry Smith       }
466081824310SBarry Smith       for (i=low; i<high; i++) {
466181824310SBarry Smith         if (rp[i] > col) break;
466281824310SBarry Smith         if (rp[i] == col) {
466381824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
466481824310SBarry Smith           else                  ap[i] = value;
466581824310SBarry Smith           goto noinsert;
466681824310SBarry Smith         }
466781824310SBarry Smith       }
466881824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
466981824310SBarry Smith       if (nonew == 1) goto noinsert;
4670ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4671fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
467281824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
467381824310SBarry Smith       /* shift up all the later entries in this row */
467481824310SBarry Smith       for (ii=N; ii>=i; ii--) {
467581824310SBarry Smith         rp[ii+1] = rp[ii];
467681824310SBarry Smith         ap[ii+1] = ap[ii];
467781824310SBarry Smith       }
467881824310SBarry Smith       rp[i] = col;
467981824310SBarry Smith       ap[i] = value;
468081824310SBarry Smith noinsert:;
468181824310SBarry Smith       low = i + 1;
468281824310SBarry Smith     }
468381824310SBarry Smith     ailen[row] = nrow;
468481824310SBarry Smith   }
468581824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
468681824310SBarry Smith   PetscFunctionReturnVoid();
468781824310SBarry Smith }
46889f7953f8SBarry Smith 
468962298a1eSBarry Smith 
4690