xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 3a062f41c0bc3be19c159685adbcbfeb7e235790)
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__
48*3a062f41SBarry Smith #define __FUNCT__ "MatFindOffBlockDiagonalEntries_SeqAIJ"
49*3a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
50*3a062f41SBarry Smith {
51*3a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
52*3a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
53*3a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
54*3a062f41SBarry Smith   PetscInt        *rows;
55*3a062f41SBarry Smith   PetscErrorCode  ierr;
56*3a062f41SBarry Smith 
57*3a062f41SBarry Smith   PetscFunctionBegin;
58*3a062f41SBarry Smith   for (i=0; i<m; i++) {
59*3a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
60*3a062f41SBarry Smith       cnt++;
61*3a062f41SBarry Smith     }
62*3a062f41SBarry Smith   }
63*3a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
64*3a062f41SBarry Smith   cnt  = 0;
65*3a062f41SBarry Smith   for (i=0; i<m; i++) {
66*3a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
67*3a062f41SBarry Smith       rows[cnt] = i;
68*3a062f41SBarry Smith       cnt++;
69*3a062f41SBarry Smith     }
70*3a062f41SBarry Smith   }
71*3a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
72*3a062f41SBarry Smith   PetscFunctionReturn(0);
73*3a062f41SBarry Smith }
74*3a062f41SBarry Smith 
75*3a062f41SBarry 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__
3784a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
37997f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
38017ab2063SBarry Smith {
381416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
382e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
38397f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3846849ba73SBarry Smith   PetscErrorCode ierr;
385e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
38654f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
387ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
388ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
38917ab2063SBarry Smith 
3903a40ed3dSBarry Smith   PetscFunctionBegin;
39171fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
39217ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
393416022c9SBarry Smith     row = im[k];
3945ef9f2a5SBarry Smith     if (row < 0) continue;
3952515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
396e32f2f54SBarry 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);
3973b2fbd54SBarry Smith #endif
398bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
39917ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
400416022c9SBarry Smith     low  = 0;
401c71e6ed7SBarry Smith     high = nrow;
40217ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4035ef9f2a5SBarry Smith       if (in[l] < 0) continue;
4042515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
405e32f2f54SBarry 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);
4063b2fbd54SBarry Smith #endif
407bfeeae90SHong Zhang       col = in[l];
40816371a99SBarry Smith       if (v) {
4094b0e389bSBarry Smith         if (roworiented) {
4105ef9f2a5SBarry Smith           value = v[l + k*n];
411bef8e0ddSBarry Smith         } else {
4124b0e389bSBarry Smith           value = v[k + l*m];
4134b0e389bSBarry Smith         }
41416371a99SBarry Smith       } else {
41575567043SBarry Smith         value = 0.;
41616371a99SBarry Smith       }
41733b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
41836db0b34SBarry Smith 
4192205254eSKarl Rupp       if (col <= lastcol) low = 0;
4202205254eSKarl Rupp       else high = nrow;
421e2ee6c50SBarry Smith       lastcol = col;
422416022c9SBarry Smith       while (high-low > 5) {
423416022c9SBarry Smith         t = (low+high)/2;
424416022c9SBarry Smith         if (rp[t] > col) high = t;
425416022c9SBarry Smith         else low = t;
42617ab2063SBarry Smith       }
427416022c9SBarry Smith       for (i=low; i<high; i++) {
42817ab2063SBarry Smith         if (rp[i] > col) break;
42917ab2063SBarry Smith         if (rp[i] == col) {
430416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
43117ab2063SBarry Smith           else ap[i] = value;
432e44c0bd4SBarry Smith           low = i + 1;
43317ab2063SBarry Smith           goto noinsert;
43417ab2063SBarry Smith         }
43517ab2063SBarry Smith       }
436abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
437c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
438e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
439fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
440c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
441416022c9SBarry Smith       /* shift up all the later entries in this row */
442416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
44317ab2063SBarry Smith         rp[ii+1] = rp[ii];
44417ab2063SBarry Smith         ap[ii+1] = ap[ii];
44517ab2063SBarry Smith       }
44617ab2063SBarry Smith       rp[i] = col;
44717ab2063SBarry Smith       ap[i] = value;
448416022c9SBarry Smith       low   = i + 1;
449e44c0bd4SBarry Smith noinsert:;
45017ab2063SBarry Smith     }
45117ab2063SBarry Smith     ailen[row] = nrow;
45217ab2063SBarry Smith   }
45388e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4543a40ed3dSBarry Smith   PetscFunctionReturn(0);
45517ab2063SBarry Smith }
45617ab2063SBarry Smith 
45781824310SBarry Smith 
4584a2ae208SSatish Balay #undef __FUNCT__
4594a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
460a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4617eb43aa7SLois Curfman McInnes {
4627eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
46397f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
46497f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
46554f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4667eb43aa7SLois Curfman McInnes 
4673a40ed3dSBarry Smith   PetscFunctionBegin;
4687eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4697eb43aa7SLois Curfman McInnes     row = im[k];
470e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
471e32f2f54SBarry 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);
472bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4737eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4747eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
475e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
476e32f2f54SBarry 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);
477bfeeae90SHong Zhang       col  = in[l];
4787eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4797eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4807eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4817eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4827eb43aa7SLois Curfman McInnes         else low = t;
4837eb43aa7SLois Curfman McInnes       }
4847eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4857eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4867eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
487b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4887eb43aa7SLois Curfman McInnes           goto finished;
4897eb43aa7SLois Curfman McInnes         }
4907eb43aa7SLois Curfman McInnes       }
49197e567efSBarry Smith       *v++ = 0.0;
4927eb43aa7SLois Curfman McInnes finished:;
4937eb43aa7SLois Curfman McInnes     }
4947eb43aa7SLois Curfman McInnes   }
4953a40ed3dSBarry Smith   PetscFunctionReturn(0);
4967eb43aa7SLois Curfman McInnes }
4977eb43aa7SLois Curfman McInnes 
49817ab2063SBarry Smith 
4994a2ae208SSatish Balay #undef __FUNCT__
5004a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
501dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
50217ab2063SBarry Smith {
503416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
5046849ba73SBarry Smith   PetscErrorCode ierr;
5056f69ff64SBarry Smith   PetscInt       i,*col_lens;
5066f69ff64SBarry Smith   int            fd;
507b37d52dbSMark F. Adams   FILE           *file;
50817ab2063SBarry Smith 
5093a40ed3dSBarry Smith   PetscFunctionBegin;
510b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
511785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
5122205254eSKarl Rupp 
5130700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
514d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
515d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
516416022c9SBarry Smith   col_lens[3] = a->nz;
517416022c9SBarry Smith 
518416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
519d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
520416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
52117ab2063SBarry Smith   }
522d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
523606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
524416022c9SBarry Smith 
525416022c9SBarry Smith   /* store column indices (zero start index) */
5266f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
527416022c9SBarry Smith 
528416022c9SBarry Smith   /* store nonzero values */
5296f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
530b37d52dbSMark F. Adams 
531b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
532b37d52dbSMark F. Adams   if (file) {
533b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
534b37d52dbSMark F. Adams   }
5353a40ed3dSBarry Smith   PetscFunctionReturn(0);
53617ab2063SBarry Smith }
537416022c9SBarry Smith 
53809573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
539cd155464SBarry Smith 
5404a2ae208SSatish Balay #undef __FUNCT__
5414a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
542dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
543416022c9SBarry Smith {
544416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
545dfbe8321SBarry Smith   PetscErrorCode    ierr;
546d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
547e060cb09SBarry Smith   const char        *name;
548f3ef73ceSBarry Smith   PetscViewerFormat format;
54917ab2063SBarry Smith 
5503a40ed3dSBarry Smith   PetscFunctionBegin;
551b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
55271c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
55397f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
554014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
555d00d2cf4SBarry Smith       nofinalvalue = 1;
556d00d2cf4SBarry Smith     }
557d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
558d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
55977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
56077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
561b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
56217ab2063SBarry Smith 
56317ab2063SBarry Smith     for (i=0; i<m; i++) {
564416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
565aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
56677431f27SBarry 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);
56717ab2063SBarry Smith #else
56877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
56917ab2063SBarry Smith #endif
57017ab2063SBarry Smith       }
57117ab2063SBarry Smith     }
572d00d2cf4SBarry Smith     if (nofinalvalue) {
573d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
574d00d2cf4SBarry Smith     }
575317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
576fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
577d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
57868369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
579cd155464SBarry Smith     PetscFunctionReturn(0);
580fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
581d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
582dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
58344cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
58477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
58544cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
586aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
58736db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
588ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
58936db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
590ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
59136db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
592ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5936831982aSBarry Smith         }
59444cd7ae7SLois Curfman McInnes #else
595ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
59644cd7ae7SLois Curfman McInnes #endif
59744cd7ae7SLois Curfman McInnes       }
598b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
59944cd7ae7SLois Curfman McInnes     }
600d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
601fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
60297f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
603d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
604dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
605785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
606496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
607496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
608496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
609496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
610aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
61136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
612496be53dSLois Curfman McInnes #else
613496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
614496be53dSLois Curfman McInnes #endif
615496be53dSLois Curfman McInnes         }
616496be53dSLois Curfman McInnes       }
617496be53dSLois Curfman McInnes     }
6182e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
61977431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6202e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6212205254eSKarl Rupp       if (i+4<m) {
6222205254eSKarl 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);
6232205254eSKarl Rupp       } else if (i+3<m) {
6242205254eSKarl 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);
6252205254eSKarl Rupp       } else if (i+2<m) {
6262205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6272205254eSKarl Rupp       } else if (i+1<m) {
6282205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6292205254eSKarl Rupp       } else if (i<m) {
6302205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6312205254eSKarl Rupp       } else {
6322205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6332205254eSKarl Rupp       }
634496be53dSLois Curfman McInnes     }
635b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
636606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
637496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
638496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
63977431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
640496be53dSLois Curfman McInnes       }
641b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
642496be53dSLois Curfman McInnes     }
643b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
644496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
645496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
646496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
647aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
64836db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
649b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6506831982aSBarry Smith           }
651496be53dSLois Curfman McInnes #else
652b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
653496be53dSLois Curfman McInnes #endif
654496be53dSLois Curfman McInnes         }
655496be53dSLois Curfman McInnes       }
656b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
657496be53dSLois Curfman McInnes     }
658d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
659fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
66097f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
66187828ca2SBarry Smith     PetscScalar value;
66268f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
66368f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
66468f1ed48SBarry Smith 
66568f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
66668f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
66768f1ed48SBarry Smith         realonly = PETSC_FALSE;
66868f1ed48SBarry Smith         break;
66968f1ed48SBarry Smith       }
67068f1ed48SBarry Smith     }
67168f1ed48SBarry Smith #endif
67202594712SBarry Smith 
673d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
674dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
67502594712SBarry Smith     for (i=0; i<m; i++) {
67602594712SBarry Smith       jcnt = 0;
677d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
678e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
67902594712SBarry Smith           value = a->a[cnt++];
680e24b481bSBarry Smith           jcnt++;
68102594712SBarry Smith         } else {
68202594712SBarry Smith           value = 0.0;
68302594712SBarry Smith         }
684aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
68568f1ed48SBarry Smith         if (realonly) {
68668f1ed48SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",PetscRealPart(value));CHKERRQ(ierr);
68768f1ed48SBarry Smith         } else {
688b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
68968f1ed48SBarry Smith         }
69002594712SBarry Smith #else
691b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
69202594712SBarry Smith #endif
69302594712SBarry Smith       }
694b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
69502594712SBarry Smith     }
696d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6973c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
698150b93efSMatthew G. Knepley     PetscInt fshift=1;
699d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7003c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
7013c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
7023c215bfdSMatthew Knepley #else
7033c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
7043c215bfdSMatthew Knepley #endif
705d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
7063c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
7073c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
7083c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
7093c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
710150b93efSMatthew 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);
7113c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
712150b93efSMatthew 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);
7133c215bfdSMatthew Knepley         } else {
714150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
7153c215bfdSMatthew Knepley         }
7163c215bfdSMatthew Knepley #else
717150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
7183c215bfdSMatthew Knepley #endif
7193c215bfdSMatthew Knepley       }
7203c215bfdSMatthew Knepley     }
721d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7223a40ed3dSBarry Smith   } else {
723d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
724dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
725d5f3da31SBarry Smith     if (A->factortype) {
72616cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
72716cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
72816cd7e1dSShri Abhyankar         /* L part */
72916cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
73016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
73116cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
732ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73316cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
734ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73516cd7e1dSShri Abhyankar           } else {
736ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
73716cd7e1dSShri Abhyankar           }
73816cd7e1dSShri Abhyankar #else
739ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
74016cd7e1dSShri Abhyankar #endif
74116cd7e1dSShri Abhyankar         }
74216cd7e1dSShri Abhyankar         /* diagonal */
74316cd7e1dSShri Abhyankar         j = a->diag[i];
74416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
74516cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
746ba0e910bSBarry 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);
74716cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
748ba0e910bSBarry 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);
74916cd7e1dSShri Abhyankar         } else {
750ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
75116cd7e1dSShri Abhyankar         }
75216cd7e1dSShri Abhyankar #else
753ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
75416cd7e1dSShri Abhyankar #endif
75516cd7e1dSShri Abhyankar 
75616cd7e1dSShri Abhyankar         /* U part */
75716cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
75816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
75916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
760ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
76116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
762ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
76316cd7e1dSShri Abhyankar           } else {
764ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
76516cd7e1dSShri Abhyankar           }
76616cd7e1dSShri Abhyankar #else
767ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
76816cd7e1dSShri Abhyankar #endif
76916cd7e1dSShri Abhyankar         }
77016cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
77116cd7e1dSShri Abhyankar       }
77216cd7e1dSShri Abhyankar     } else {
77317ab2063SBarry Smith       for (i=0; i<m; i++) {
77477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
775416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
776aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
77736db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
778ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
77936db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
780ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7813a40ed3dSBarry Smith           } else {
782ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
78317ab2063SBarry Smith           }
78417ab2063SBarry Smith #else
785ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
78617ab2063SBarry Smith #endif
78717ab2063SBarry Smith         }
788b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
78917ab2063SBarry Smith       }
79016cd7e1dSShri Abhyankar     }
791d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
79217ab2063SBarry Smith   }
793b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7943a40ed3dSBarry Smith   PetscFunctionReturn(0);
795416022c9SBarry Smith }
796416022c9SBarry Smith 
7979804daf3SBarry Smith #include <petscdraw.h>
7984a2ae208SSatish Balay #undef __FUNCT__
7994a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
800dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
801416022c9SBarry Smith {
802480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
803416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
804dfbe8321SBarry Smith   PetscErrorCode    ierr;
805d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
80636db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
807b0a32e0cSBarry Smith   PetscViewer       viewer;
808f3ef73ceSBarry Smith   PetscViewerFormat format;
809cddf8d76SBarry Smith 
8103a40ed3dSBarry Smith   PetscFunctionBegin;
811480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
812b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
81319bcc07fSBarry Smith 
814b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
815416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
8160513a670SBarry Smith 
817fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
8180513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
819b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
820416022c9SBarry Smith     for (i=0; i<m; i++) {
821cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
822bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
823bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
82436db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
825b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
826cddf8d76SBarry Smith       }
827cddf8d76SBarry Smith     }
828b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
829cddf8d76SBarry Smith     for (i=0; i<m; i++) {
830cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
831bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
832bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
833cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
834b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
835cddf8d76SBarry Smith       }
836cddf8d76SBarry Smith     }
837b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
838cddf8d76SBarry Smith     for (i=0; i<m; i++) {
839cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
840bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
841bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
84236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
843b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
844416022c9SBarry Smith       }
845416022c9SBarry Smith     }
8460513a670SBarry Smith   } else {
8470513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8480513a670SBarry Smith     /* first determine max of all nonzero values */
84997f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
850b0a32e0cSBarry Smith     PetscDraw popup;
85136db0b34SBarry Smith     PetscReal scale;
8520513a670SBarry Smith 
8530513a670SBarry Smith     for (i=0; i<nz; i++) {
8540513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8550513a670SBarry Smith     }
856b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
857b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8582205254eSKarl Rupp     if (popup) {
8592205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8602205254eSKarl Rupp     }
8610513a670SBarry Smith     count = 0;
8620513a670SBarry Smith     for (i=0; i<m; i++) {
8630513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
864bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
865bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
86697f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
867b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8680513a670SBarry Smith         count++;
8690513a670SBarry Smith       }
8700513a670SBarry Smith     }
8710513a670SBarry Smith   }
872480ef9eaSBarry Smith   PetscFunctionReturn(0);
873480ef9eaSBarry Smith }
874cddf8d76SBarry Smith 
8759804daf3SBarry Smith #include <petscdraw.h>
8764a2ae208SSatish Balay #undef __FUNCT__
8774a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
878dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
879480ef9eaSBarry Smith {
880dfbe8321SBarry Smith   PetscErrorCode ierr;
881b0a32e0cSBarry Smith   PetscDraw      draw;
88236db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
883ace3abfcSBarry Smith   PetscBool      isnull;
884480ef9eaSBarry Smith 
885480ef9eaSBarry Smith   PetscFunctionBegin;
886b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
887b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
888480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
889480ef9eaSBarry Smith 
890480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
891d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
892480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
893b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
894b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8950298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8963a40ed3dSBarry Smith   PetscFunctionReturn(0);
897416022c9SBarry Smith }
898416022c9SBarry Smith 
8994a2ae208SSatish Balay #undef __FUNCT__
9004a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
901dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
902416022c9SBarry Smith {
903dfbe8321SBarry Smith   PetscErrorCode ierr;
904ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
905416022c9SBarry Smith 
9063a40ed3dSBarry Smith   PetscFunctionBegin;
907251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
908251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
909251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
910c45a1595SBarry Smith   if (iascii) {
9113a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
9120f5bd95cSBarry Smith   } else if (isbinary) {
9133a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
9140f5bd95cSBarry Smith   } else if (isdraw) {
9153a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
91611aeaf0aSBarry Smith   }
9174108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
9183a40ed3dSBarry Smith   PetscFunctionReturn(0);
91917ab2063SBarry Smith }
92019bcc07fSBarry Smith 
9214a2ae208SSatish Balay #undef __FUNCT__
9224a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
923dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
92417ab2063SBarry Smith {
925416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
9266849ba73SBarry Smith   PetscErrorCode ierr;
92797f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
928d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
92954f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
9303447b6efSHong Zhang   PetscReal      ratio  = 0.6;
93117ab2063SBarry Smith 
9323a40ed3dSBarry Smith   PetscFunctionBegin;
9333a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
93417ab2063SBarry Smith 
93543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
93617ab2063SBarry Smith   for (i=1; i<m; i++) {
937416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
93817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
93994a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
94017ab2063SBarry Smith     if (fshift) {
941bfeeae90SHong Zhang       ip = aj + ai[i];
942bfeeae90SHong Zhang       ap = aa + ai[i];
94317ab2063SBarry Smith       N  = ailen[i];
94417ab2063SBarry Smith       for (j=0; j<N; j++) {
94517ab2063SBarry Smith         ip[j-fshift] = ip[j];
94617ab2063SBarry Smith         ap[j-fshift] = ap[j];
94717ab2063SBarry Smith       }
94817ab2063SBarry Smith     }
94917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
95017ab2063SBarry Smith   }
95117ab2063SBarry Smith   if (m) {
95217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
95317ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
95417ab2063SBarry Smith   }
9557b083b7cSBarry Smith 
95617ab2063SBarry Smith   /* reset ilen and imax for each row */
9577b083b7cSBarry Smith   a->nonzerorowcnt = 0;
95817ab2063SBarry Smith   for (i=0; i<m; i++) {
95917ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
9607b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
96117ab2063SBarry Smith   }
962bfeeae90SHong Zhang   a->nz = ai[m];
96365e19b50SBarry 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);
96417ab2063SBarry Smith 
96509f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
966d0f46423SBarry 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);
967ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
968ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9692205254eSKarl Rupp 
9708e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
971dd5f02e7SSatish Balay   a->reallocs         = 0;
9724e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
97336db0b34SBarry Smith   a->rmax             = rmax;
9744e220ebcSLois Curfman McInnes 
97511e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9762205254eSKarl Rupp 
97788e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
97871c2f376SKris Buschelman 
9794108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
98071f1c65dSBarry Smith 
981acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9823a40ed3dSBarry Smith   PetscFunctionReturn(0);
98317ab2063SBarry Smith }
98417ab2063SBarry Smith 
9854a2ae208SSatish Balay #undef __FUNCT__
98699cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
98799cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
98899cafbc1SBarry Smith {
98999cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
99099cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
99154f21887SBarry Smith   MatScalar      *aa = a->a;
992acf2f550SJed Brown   PetscErrorCode ierr;
99399cafbc1SBarry Smith 
99499cafbc1SBarry Smith   PetscFunctionBegin;
99599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
996acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
99799cafbc1SBarry Smith   PetscFunctionReturn(0);
99899cafbc1SBarry Smith }
99999cafbc1SBarry Smith 
100099cafbc1SBarry Smith #undef __FUNCT__
100199cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
100299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
100399cafbc1SBarry Smith {
100499cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
100599cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
100654f21887SBarry Smith   MatScalar      *aa = a->a;
1007acf2f550SJed Brown   PetscErrorCode ierr;
100899cafbc1SBarry Smith 
100999cafbc1SBarry Smith   PetscFunctionBegin;
101099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1011acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
101299cafbc1SBarry Smith   PetscFunctionReturn(0);
101399cafbc1SBarry Smith }
101499cafbc1SBarry Smith 
101578b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
101678b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
101778b84d54SShri Abhyankar {
101878b84d54SShri Abhyankar   PetscErrorCode ierr;
101978b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
102078b84d54SShri Abhyankar   PetscInt       n,start,end;
102178b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
102278b84d54SShri Abhyankar 
102378b84d54SShri Abhyankar   start = trstarts[thread_id];
102478b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
102519baf141SJed Brown   n     = a->i[end] - a->i[start];
102619baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
102778b84d54SShri Abhyankar   return 0;
102878b84d54SShri Abhyankar }
102978b84d54SShri Abhyankar 
103078b84d54SShri Abhyankar #undef __FUNCT__
103178b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
103278b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
103378b84d54SShri Abhyankar {
103478b84d54SShri Abhyankar   PetscErrorCode ierr;
103578b84d54SShri Abhyankar 
103678b84d54SShri Abhyankar   PetscFunctionBegin;
1037ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1038acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
103978b84d54SShri Abhyankar   PetscFunctionReturn(0);
104078b84d54SShri Abhyankar }
104178b84d54SShri Abhyankar #else
104299cafbc1SBarry Smith #undef __FUNCT__
10434a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1044dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
104517ab2063SBarry Smith {
1046416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1047dfbe8321SBarry Smith   PetscErrorCode ierr;
10483a40ed3dSBarry Smith 
10493a40ed3dSBarry Smith   PetscFunctionBegin;
1050d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1051acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10523a40ed3dSBarry Smith   PetscFunctionReturn(0);
105317ab2063SBarry Smith }
105478b84d54SShri Abhyankar #endif
1055416022c9SBarry Smith 
10564a2ae208SSatish Balay #undef __FUNCT__
10574a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1058dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
105917ab2063SBarry Smith {
1060416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1061dfbe8321SBarry Smith   PetscErrorCode ierr;
1062d5d45c9bSBarry Smith 
10633a40ed3dSBarry Smith   PetscFunctionBegin;
1064aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1065d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
106617ab2063SBarry Smith #endif
1067e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10686bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10696bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
107005b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1071d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
107205b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
107371f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
107405b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10756bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
107605b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10776bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
107805b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10796bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1080cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10810b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1082a30b2313SHong Zhang 
10834108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1084bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1085901853e0SKris Buschelman 
1086dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1087bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1088bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1089bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1090bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1091bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1092bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1093bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1094bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1095bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1096bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10973a40ed3dSBarry Smith   PetscFunctionReturn(0);
109817ab2063SBarry Smith }
109917ab2063SBarry Smith 
11004a2ae208SSatish Balay #undef __FUNCT__
11014a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1102ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
110317ab2063SBarry Smith {
1104416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11054846f1f5SKris Buschelman   PetscErrorCode ierr;
11063a40ed3dSBarry Smith 
11073a40ed3dSBarry Smith   PetscFunctionBegin;
1108a65d3064SKris Buschelman   switch (op) {
1109a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
11104e0d8c25SBarry Smith     a->roworiented = flg;
1111a65d3064SKris Buschelman     break;
1112a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1113a9817697SBarry Smith     a->keepnonzeropattern = flg;
1114a65d3064SKris Buschelman     break;
1115512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1116512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1117a65d3064SKris Buschelman     break;
1118a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
11194e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1120a65d3064SKris Buschelman     break;
1121a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
11224e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1123a65d3064SKris Buschelman     break;
112428b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
112528b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
112628b2fa4aSMatthew Knepley     break;
1127a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
11284e0d8c25SBarry Smith     a->ignorezeroentries = flg;
11290df259c2SBarry Smith     break;
11303d472b54SHong Zhang   case MAT_SPD:
1131b1646e73SJed Brown   case MAT_SYMMETRIC:
1132b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1133b1646e73SJed Brown   case MAT_HERMITIAN:
1134b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11355021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11365021d80fSJed Brown     break;
11374e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1138a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1139a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1140290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1141a65d3064SKris Buschelman     break;
1142b87ac2d8SJed Brown   case MAT_USE_INODES:
1143b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1144b87ac2d8SJed Brown     break;
1145a65d3064SKris Buschelman   default:
1146e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1147a65d3064SKris Buschelman   }
11484108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11493a40ed3dSBarry Smith   PetscFunctionReturn(0);
115017ab2063SBarry Smith }
115117ab2063SBarry Smith 
11524a2ae208SSatish Balay #undef __FUNCT__
11534a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1154dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
115517ab2063SBarry Smith {
1156416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11576849ba73SBarry Smith   PetscErrorCode ierr;
1158d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
115935e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
116017ab2063SBarry Smith 
11613a40ed3dSBarry Smith   PetscFunctionBegin;
1162d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1163e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
116435e7444dSHong Zhang 
1165d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1166d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
116735e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11682c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
116935e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
117035e7444dSHong Zhang     PetscFunctionReturn(0);
117135e7444dSHong Zhang   }
117235e7444dSHong Zhang 
11732dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11741ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
117535e7444dSHong Zhang   for (i=0; i<n; i++) {
117635e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11772f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
117835e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
117935e7444dSHong Zhang       if (aj[j] == i) {
118035e7444dSHong Zhang         x[i] = aa[j];
118117ab2063SBarry Smith         break;
118217ab2063SBarry Smith       }
118317ab2063SBarry Smith     }
118417ab2063SBarry Smith   }
11851ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11863a40ed3dSBarry Smith   PetscFunctionReturn(0);
118717ab2063SBarry Smith }
118817ab2063SBarry Smith 
1189c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11904a2ae208SSatish Balay #undef __FUNCT__
11914a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1192dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
119317ab2063SBarry Smith {
1194416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11955c897100SBarry Smith   PetscScalar    *x,*y;
1196dfbe8321SBarry Smith   PetscErrorCode ierr;
1197d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11985c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1199a77337e4SBarry Smith   MatScalar         *v;
1200a77337e4SBarry Smith   PetscScalar       alpha;
12010298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
12023447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1203ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
12045c897100SBarry Smith #endif
120517ab2063SBarry Smith 
12063a40ed3dSBarry Smith   PetscFunctionBegin;
12072e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
12081ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
12091ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12105c897100SBarry Smith 
12115c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1212bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
12135c897100SBarry Smith #else
12143447b6efSHong Zhang   if (usecprow) {
12153447b6efSHong Zhang     m    = cprow.nrows;
12163447b6efSHong Zhang     ii   = cprow.i;
12177b2bb3b9SHong Zhang     ridx = cprow.rindex;
12183447b6efSHong Zhang   } else {
12193447b6efSHong Zhang     ii = a->i;
12203447b6efSHong Zhang   }
122117ab2063SBarry Smith   for (i=0; i<m; i++) {
12223447b6efSHong Zhang     idx = a->j + ii[i];
12233447b6efSHong Zhang     v   = a->a + ii[i];
12243447b6efSHong Zhang     n   = ii[i+1] - ii[i];
12253447b6efSHong Zhang     if (usecprow) {
12267b2bb3b9SHong Zhang       alpha = x[ridx[i]];
12273447b6efSHong Zhang     } else {
122817ab2063SBarry Smith       alpha = x[i];
12293447b6efSHong Zhang     }
123004fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
123117ab2063SBarry Smith   }
12325c897100SBarry Smith #endif
1233dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
12341ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12351ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
123717ab2063SBarry Smith }
123817ab2063SBarry Smith 
12394a2ae208SSatish Balay #undef __FUNCT__
12405c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1241dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12425c897100SBarry Smith {
1243dfbe8321SBarry Smith   PetscErrorCode ierr;
12445c897100SBarry Smith 
12455c897100SBarry Smith   PetscFunctionBegin;
1246170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12475c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12485c897100SBarry Smith   PetscFunctionReturn(0);
12495c897100SBarry Smith }
12505c897100SBarry Smith 
1251c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
125278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
125378b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
125478b84d54SShri Abhyankar {
125578b84d54SShri Abhyankar   PetscErrorCode    ierr;
125678b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
125778b84d54SShri Abhyankar   PetscScalar       *y;
125878b84d54SShri Abhyankar   const PetscScalar *x;
125978b84d54SShri Abhyankar   const MatScalar   *aa;
126078b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
126178b84d54SShri Abhyankar   PetscInt          n,start,end,i;
126278b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
126378b84d54SShri Abhyankar   PetscScalar       sum;
126478b84d54SShri Abhyankar 
126578b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
126678b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
126778b84d54SShri Abhyankar   start = trstarts[thread_id];
126878b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
126978b84d54SShri Abhyankar   aj    = a->j;
127078b84d54SShri Abhyankar   aa    = a->a;
127178b84d54SShri Abhyankar   ai    = a->i;
127278b84d54SShri Abhyankar   for (i=start; i<end; i++) {
127378b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
127478b84d54SShri Abhyankar     aj  = a->j + ai[i];
127578b84d54SShri Abhyankar     aa  = a->a + ai[i];
127678b84d54SShri Abhyankar     sum = 0.0;
127778b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
127878b84d54SShri Abhyankar     y[i] = sum;
127978b84d54SShri Abhyankar   }
128078b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
128178b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
128278b84d54SShri Abhyankar   return 0;
128378b84d54SShri Abhyankar }
128478b84d54SShri Abhyankar 
128578b84d54SShri Abhyankar #undef __FUNCT__
128678b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
128778b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
128878b84d54SShri Abhyankar {
128978b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
129078b84d54SShri Abhyankar   PetscScalar       *y;
129178b84d54SShri Abhyankar   const PetscScalar *x;
129278b84d54SShri Abhyankar   const MatScalar   *aa;
129378b84d54SShri Abhyankar   PetscErrorCode    ierr;
129478b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12950298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
12967b083b7cSBarry Smith   PetscInt          n,i;
129778b84d54SShri Abhyankar   PetscScalar       sum;
129878b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
129978b84d54SShri Abhyankar 
130078b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
130178b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
130278b84d54SShri Abhyankar #endif
130378b84d54SShri Abhyankar 
130478b84d54SShri Abhyankar   PetscFunctionBegin;
130578b84d54SShri Abhyankar   aj = a->j;
130678b84d54SShri Abhyankar   aa = a->a;
130778b84d54SShri Abhyankar   ii = a->i;
130878b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
130978b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
131078b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
131178b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
131278b84d54SShri Abhyankar     ii   = a->compressedrow.i;
131378b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
131478b84d54SShri Abhyankar     for (i=0; i<m; i++) {
131578b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
131678b84d54SShri Abhyankar       aj          = a->j + ii[i];
131778b84d54SShri Abhyankar       aa          = a->a + ii[i];
131878b84d54SShri Abhyankar       sum         = 0.0;
131978b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
132078b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
132178b84d54SShri Abhyankar       y[*ridx++] = sum;
132278b84d54SShri Abhyankar     }
132378b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
132478b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
132578b84d54SShri Abhyankar   } else { /* do not use compressed row format */
132678b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
132778b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
132878b84d54SShri Abhyankar #else
1329ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
133078b84d54SShri Abhyankar #endif
133178b84d54SShri Abhyankar   }
13327b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
133378b84d54SShri Abhyankar   PetscFunctionReturn(0);
133478b84d54SShri Abhyankar }
133578b84d54SShri Abhyankar #else
13365c897100SBarry Smith #undef __FUNCT__
13374a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1338dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
133917ab2063SBarry Smith {
1340416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1341d9fead3dSBarry Smith   PetscScalar       *y;
134254f21887SBarry Smith   const PetscScalar *x;
134354f21887SBarry Smith   const MatScalar   *aa;
1344dfbe8321SBarry Smith   PetscErrorCode    ierr;
1345003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13460298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13477b083b7cSBarry Smith   PetscInt          n,i;
1348362ced78SSatish Balay   PetscScalar       sum;
1349ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
135017ab2063SBarry Smith 
1351b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
135297952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1353fee21e36SBarry Smith #endif
1354fee21e36SBarry Smith 
13553a40ed3dSBarry Smith   PetscFunctionBegin;
13563649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13571ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
135897952fefSHong Zhang   aj   = a->j;
135997952fefSHong Zhang   aa   = a->a;
1360416022c9SBarry Smith   ii   = a->i;
13614eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
136297952fefSHong Zhang     m    = a->compressedrow.nrows;
136397952fefSHong Zhang     ii   = a->compressedrow.i;
136497952fefSHong Zhang     ridx = a->compressedrow.rindex;
136597952fefSHong Zhang     for (i=0; i<m; i++) {
136697952fefSHong Zhang       n           = ii[i+1] - ii[i];
136797952fefSHong Zhang       aj          = a->j + ii[i];
136897952fefSHong Zhang       aa          = a->a + ii[i];
136997952fefSHong Zhang       sum         = 0.0;
1370003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1371003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
137297952fefSHong Zhang       y[*ridx++] = sum;
137397952fefSHong Zhang     }
137497952fefSHong Zhang   } else { /* do not use compressed row format */
1375b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1376b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1377b05257ddSBarry Smith #else
137878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1379ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
138078b84d54SShri Abhyankar #else
138117ab2063SBarry Smith     for (i=0; i<m; i++) {
1382003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1383003131ecSBarry Smith       aj          = a->j + ii[i];
1384003131ecSBarry Smith       aa          = a->a + ii[i];
138517ab2063SBarry Smith       sum         = 0.0;
1386003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
138717ab2063SBarry Smith       y[i] = sum;
138817ab2063SBarry Smith     }
13898d195f9aSBarry Smith #endif
139078b84d54SShri Abhyankar #endif
1391b05257ddSBarry Smith   }
13927b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
13933649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13941ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13953a40ed3dSBarry Smith   PetscFunctionReturn(0);
139617ab2063SBarry Smith }
139778b84d54SShri Abhyankar #endif
139817ab2063SBarry Smith 
1399b434eb95SMatthew G. Knepley #undef __FUNCT__
1400b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1401b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1402b434eb95SMatthew G. Knepley {
1403b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1404b434eb95SMatthew G. Knepley   PetscScalar       *y;
1405b434eb95SMatthew G. Knepley   const PetscScalar *x;
1406b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1407b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1408b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1409b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1410b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1411b434eb95SMatthew G. Knepley   PetscScalar       sum;
1412b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1413b434eb95SMatthew G. Knepley 
1414b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1415b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1416b434eb95SMatthew G. Knepley #endif
1417b434eb95SMatthew G. Knepley 
1418b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1419b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1420b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1421b434eb95SMatthew G. Knepley   aj   = a->j;
1422b434eb95SMatthew G. Knepley   aa   = a->a;
1423b434eb95SMatthew G. Knepley   ii   = a->i;
1424b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1425b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1426b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1427b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1428b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1429b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1430b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1431b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1432b434eb95SMatthew G. Knepley       sum         = 0.0;
1433b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1434b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1435b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1436b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1437b434eb95SMatthew G. Knepley     }
1438b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1439b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1440b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1441b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1442b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1443b434eb95SMatthew G. Knepley       sum         = 0.0;
1444b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1445b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1446b434eb95SMatthew G. Knepley       y[i] = sum;
1447b434eb95SMatthew G. Knepley     }
1448b434eb95SMatthew G. Knepley   }
1449b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1450b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1451b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1452b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1453b434eb95SMatthew G. Knepley }
1454b434eb95SMatthew G. Knepley 
1455b434eb95SMatthew G. Knepley #undef __FUNCT__
1456b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1457b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1458b434eb95SMatthew G. Knepley {
1459b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1460b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1461b434eb95SMatthew G. Knepley   const PetscScalar *x;
1462b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1463b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1464b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1465b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1466b434eb95SMatthew G. Knepley   PetscScalar       sum;
1467b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1468b434eb95SMatthew G. Knepley 
1469b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1470b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1471b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1472b434eb95SMatthew G. Knepley   if (zz != yy) {
1473b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1474b434eb95SMatthew G. Knepley   } else {
1475b434eb95SMatthew G. Knepley     z = y;
1476b434eb95SMatthew G. Knepley   }
1477b434eb95SMatthew G. Knepley 
1478b434eb95SMatthew G. Knepley   aj = a->j;
1479b434eb95SMatthew G. Knepley   aa = a->a;
1480b434eb95SMatthew G. Knepley   ii = a->i;
1481b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1482b434eb95SMatthew G. Knepley     if (zz != yy) {
1483b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1484b434eb95SMatthew G. Knepley     }
1485b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1486b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1487b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1488b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1489b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1490b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1491b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1492b434eb95SMatthew G. Knepley       sum = y[*ridx];
1493b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1494b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1495b434eb95SMatthew G. Knepley     }
1496b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1497b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1498b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1499b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1500b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1501b434eb95SMatthew G. Knepley       sum = y[i];
1502b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1503b434eb95SMatthew G. Knepley       z[i] = sum;
1504b434eb95SMatthew G. Knepley     }
1505b434eb95SMatthew G. Knepley   }
1506b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1507b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1508b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1509b434eb95SMatthew G. Knepley   if (zz != yy) {
1510b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1511b434eb95SMatthew G. Knepley   }
1512b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1513b434eb95SMatthew G. Knepley }
1514b434eb95SMatthew G. Knepley 
1515c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
15164a2ae208SSatish Balay #undef __FUNCT__
15174a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1518dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
151917ab2063SBarry Smith {
1520416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1521f15663dcSBarry Smith   PetscScalar       *y,*z;
1522f15663dcSBarry Smith   const PetscScalar *x;
152354f21887SBarry Smith   const MatScalar   *aa;
1524dfbe8321SBarry Smith   PetscErrorCode    ierr;
1525d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
15260298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1527362ced78SSatish Balay   PetscScalar       sum;
1528ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
15299ea0dfa2SSatish Balay 
15303a40ed3dSBarry Smith   PetscFunctionBegin;
1531f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15321ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15332e8a6d31SBarry Smith   if (zz != yy) {
15341ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15352e8a6d31SBarry Smith   } else {
15362e8a6d31SBarry Smith     z = y;
15372e8a6d31SBarry Smith   }
1538bfeeae90SHong Zhang 
153997952fefSHong Zhang   aj = a->j;
154097952fefSHong Zhang   aa = a->a;
1541cddf8d76SBarry Smith   ii = a->i;
15424eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15434eb6d288SHong Zhang     if (zz != yy) {
15444eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15454eb6d288SHong Zhang     }
154697952fefSHong Zhang     m    = a->compressedrow.nrows;
154797952fefSHong Zhang     ii   = a->compressedrow.i;
154897952fefSHong Zhang     ridx = a->compressedrow.rindex;
154997952fefSHong Zhang     for (i=0; i<m; i++) {
155097952fefSHong Zhang       n   = ii[i+1] - ii[i];
155197952fefSHong Zhang       aj  = a->j + ii[i];
155297952fefSHong Zhang       aa  = a->a + ii[i];
155397952fefSHong Zhang       sum = y[*ridx];
1554f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
155597952fefSHong Zhang       z[*ridx++] = sum;
155697952fefSHong Zhang     }
155797952fefSHong Zhang   } else { /* do not use compressed row format */
1558f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1559f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1560f15663dcSBarry Smith #else
156117ab2063SBarry Smith     for (i=0; i<m; i++) {
1562f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1563f15663dcSBarry Smith       aj  = a->j + ii[i];
1564f15663dcSBarry Smith       aa  = a->a + ii[i];
156517ab2063SBarry Smith       sum = y[i];
1566f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
156717ab2063SBarry Smith       z[i] = sum;
156817ab2063SBarry Smith     }
156902ab625aSSatish Balay #endif
1570f15663dcSBarry Smith   }
1571dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1572f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15731ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15742e8a6d31SBarry Smith   if (zz != yy) {
15751ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15762e8a6d31SBarry Smith   }
15778154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15786b375ea7SVictor Minden   /*
1579918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1580918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1581918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15826b375ea7SVictor Minden   */
1583918e98c3SVictor Minden #endif
15843a40ed3dSBarry Smith   PetscFunctionReturn(0);
158517ab2063SBarry Smith }
158617ab2063SBarry Smith 
158717ab2063SBarry Smith /*
158817ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
158917ab2063SBarry Smith */
15904a2ae208SSatish Balay #undef __FUNCT__
15914a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1592dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
159317ab2063SBarry Smith {
1594416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15956849ba73SBarry Smith   PetscErrorCode ierr;
1596d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
159717ab2063SBarry Smith 
15983a40ed3dSBarry Smith   PetscFunctionBegin;
159909f38230SBarry Smith   if (!a->diag) {
1600785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
16013bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
160209f38230SBarry Smith   }
1603d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
160409f38230SBarry Smith     a->diag[i] = a->i[i+1];
1605bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1606bfeeae90SHong Zhang       if (a->j[j] == i) {
160709f38230SBarry Smith         a->diag[i] = j;
160817ab2063SBarry Smith         break;
160917ab2063SBarry Smith       }
161017ab2063SBarry Smith     }
161117ab2063SBarry Smith   }
16123a40ed3dSBarry Smith   PetscFunctionReturn(0);
161317ab2063SBarry Smith }
161417ab2063SBarry Smith 
1615be5855fcSBarry Smith /*
1616be5855fcSBarry Smith      Checks for missing diagonals
1617be5855fcSBarry Smith */
16184a2ae208SSatish Balay #undef __FUNCT__
16194a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1620ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1621be5855fcSBarry Smith {
1622be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
162397f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1624be5855fcSBarry Smith 
1625be5855fcSBarry Smith   PetscFunctionBegin;
162609f38230SBarry Smith   *missing = PETSC_FALSE;
1627d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
162809f38230SBarry Smith     *missing = PETSC_TRUE;
162909f38230SBarry Smith     if (d) *d = 0;
1630358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
163109f38230SBarry Smith   } else {
1632f1e2ffcdSBarry Smith     diag = a->diag;
1633d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1634bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
163509f38230SBarry Smith         *missing = PETSC_TRUE;
163609f38230SBarry Smith         if (d) *d = i;
163709f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1638358d2f5dSShri Abhyankar         break;
163909f38230SBarry Smith       }
1640be5855fcSBarry Smith     }
1641be5855fcSBarry Smith   }
1642be5855fcSBarry Smith   PetscFunctionReturn(0);
1643be5855fcSBarry Smith }
1644be5855fcSBarry Smith 
164571f1c65dSBarry Smith #undef __FUNCT__
164671f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16477087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
164871f1c65dSBarry Smith {
164971f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
165071f1c65dSBarry Smith   PetscErrorCode ierr;
1651d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
165254f21887SBarry Smith   MatScalar      *v = a->a;
165354f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
165471f1c65dSBarry Smith 
165571f1c65dSBarry Smith   PetscFunctionBegin;
165671f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
165771f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
165871f1c65dSBarry Smith   diag = a->diag;
165971f1c65dSBarry Smith   if (!a->idiag) {
1660dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
16613bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
166271f1c65dSBarry Smith     v    = a->a;
166371f1c65dSBarry Smith   }
166471f1c65dSBarry Smith   mdiag = a->mdiag;
166571f1c65dSBarry Smith   idiag = a->idiag;
166671f1c65dSBarry Smith 
1667028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
166871f1c65dSBarry Smith     for (i=0; i<m; i++) {
166971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1670e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
167171f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
167271f1c65dSBarry Smith     }
167371f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
167471f1c65dSBarry Smith   } else {
167571f1c65dSBarry Smith     for (i=0; i<m; i++) {
167671f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
167771f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
167871f1c65dSBarry Smith     }
1679dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
168071f1c65dSBarry Smith   }
168171f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
168271f1c65dSBarry Smith   PetscFunctionReturn(0);
168371f1c65dSBarry Smith }
168471f1c65dSBarry Smith 
1685c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16864a2ae208SSatish Balay #undef __FUNCT__
168741f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
168841f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
168917ab2063SBarry Smith {
1690416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1691e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1692e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
169354f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1694dfbe8321SBarry Smith   PetscErrorCode    ierr;
1695d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
169697f1f81fSBarry Smith   const PetscInt    *idx,*diag;
169717ab2063SBarry Smith 
16983a40ed3dSBarry Smith   PetscFunctionBegin;
1699b965ef7fSBarry Smith   its = its*lits;
170091723122SBarry Smith 
170171f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
170271f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
170371f1c65dSBarry Smith   a->fshift = fshift;
170471f1c65dSBarry Smith   a->omega  = omega;
1705ed480e8bSBarry Smith 
170671f1c65dSBarry Smith   diag  = a->diag;
170771f1c65dSBarry Smith   t     = a->ssor_work;
1708ed480e8bSBarry Smith   idiag = a->idiag;
170971f1c65dSBarry Smith   mdiag = a->mdiag;
1710ed480e8bSBarry Smith 
17111ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
17123649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1713ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
171417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
171517ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1716ed480e8bSBarry Smith     bs = b;
171717ab2063SBarry Smith     for (i=0; i<m; i++) {
171871f1c65dSBarry Smith       d   = fshift + mdiag[i];
1719416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1720ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1721ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
172217ab2063SBarry Smith       sum = b[i]*d/omega;
1723003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
172417ab2063SBarry Smith       x[i] = sum;
172517ab2063SBarry Smith     }
17261ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17273649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1728efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17293a40ed3dSBarry Smith     PetscFunctionReturn(0);
173017ab2063SBarry Smith   }
1731c783ea89SBarry Smith 
17322205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17332205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
173417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1735887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
173617ab2063SBarry Smith 
173717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
173817ab2063SBarry Smith 
1739887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
174017ab2063SBarry Smith     */
174117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
174217ab2063SBarry Smith 
174317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
174417ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1745416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1746ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1747ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
174817ab2063SBarry Smith       sum = b[i];
1749e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1750ed480e8bSBarry Smith       x[i] = sum*idiag[i];
175117ab2063SBarry Smith     }
175217ab2063SBarry Smith 
175317ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1754416022c9SBarry Smith     v = a->a;
17552205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
175617ab2063SBarry Smith 
175717ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1758ed480e8bSBarry Smith     ts   = t;
1759416022c9SBarry Smith     diag = a->diag;
176017ab2063SBarry Smith     for (i=0; i<m; i++) {
1761416022c9SBarry Smith       n   = diag[i] - a->i[i];
1762ed480e8bSBarry Smith       idx = a->j + a->i[i];
1763ed480e8bSBarry Smith       v   = a->a + a->i[i];
176417ab2063SBarry Smith       sum = t[i];
1765003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1766ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1767733d66baSBarry Smith       /*  x = x + t */
1768733d66baSBarry Smith       x[i] += t[i];
176917ab2063SBarry Smith     }
177017ab2063SBarry Smith 
1771dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17721ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17733649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17743a40ed3dSBarry Smith     PetscFunctionReturn(0);
177517ab2063SBarry Smith   }
177617ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
177717ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
177817ab2063SBarry Smith       for (i=0; i<m; i++) {
1779416022c9SBarry Smith         n   = diag[i] - a->i[i];
1780ed480e8bSBarry Smith         idx = a->j + a->i[i];
1781ed480e8bSBarry Smith         v   = a->a + a->i[i];
178217ab2063SBarry Smith         sum = b[i];
1783e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17845c99c7daSBarry Smith         t[i] = sum;
1785ed480e8bSBarry Smith         x[i] = sum*idiag[i];
178617ab2063SBarry Smith       }
17875c99c7daSBarry Smith       xb   = t;
1788efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17893a40ed3dSBarry Smith     } else xb = b;
179017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
179117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1792416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1793ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1794ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
179517ab2063SBarry Smith         sum = xb[i];
1796e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17975c99c7daSBarry Smith         if (xb == b) {
1798ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17995c99c7daSBarry Smith         } else {
1800b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
180117ab2063SBarry Smith         }
18025c99c7daSBarry Smith       }
1803b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
180417ab2063SBarry Smith     }
180517ab2063SBarry Smith     its--;
180617ab2063SBarry Smith   }
180717ab2063SBarry Smith   while (its--) {
180817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
180917ab2063SBarry Smith       for (i=0; i<m; i++) {
1810b19a5dc2SMark Adams         /* lower */
1811b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1812ed480e8bSBarry Smith         idx = a->j + a->i[i];
1813ed480e8bSBarry Smith         v   = a->a + a->i[i];
181417ab2063SBarry Smith         sum = b[i];
1815e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1816b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1817b19a5dc2SMark Adams         /* upper */
1818b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1819b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1820b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1821b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1822b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
182317ab2063SBarry Smith       }
1824b19a5dc2SMark Adams       xb   = t;
18259f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1826b19a5dc2SMark Adams     } else xb = b;
182717ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
182817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1829b19a5dc2SMark Adams         sum = xb[i];
1830b19a5dc2SMark Adams         if (xb == b) {
1831b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1832416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1833ed480e8bSBarry Smith           idx = a->j + a->i[i];
1834ed480e8bSBarry Smith           v   = a->a + a->i[i];
1835e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1836ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1837b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1838b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1839b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1840b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1841b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1842b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
184317ab2063SBarry Smith         }
1844b19a5dc2SMark Adams       }
1845b19a5dc2SMark Adams       if (xb == b) {
18469f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1847b19a5dc2SMark Adams       } else {
1848b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1849b19a5dc2SMark Adams       }
185017ab2063SBarry Smith     }
185117ab2063SBarry Smith   }
18521ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18533649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1854365a8a9eSBarry Smith   PetscFunctionReturn(0);
185517ab2063SBarry Smith }
185617ab2063SBarry Smith 
18572af78befSBarry Smith 
18584a2ae208SSatish Balay #undef __FUNCT__
18594a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1860dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
186117ab2063SBarry Smith {
1862416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18634e220ebcSLois Curfman McInnes 
18643a40ed3dSBarry Smith   PetscFunctionBegin;
18654e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18664e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18674e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18684e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18694e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18708e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18717adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1872d5f3da31SBarry Smith   if (A->factortype) {
18734e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18744e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18754e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18764e220ebcSLois Curfman McInnes   } else {
18774e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18784e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18794e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18804e220ebcSLois Curfman McInnes   }
18813a40ed3dSBarry Smith   PetscFunctionReturn(0);
188217ab2063SBarry Smith }
188317ab2063SBarry Smith 
18844a2ae208SSatish Balay #undef __FUNCT__
18854a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18862b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
188717ab2063SBarry Smith {
1888416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18893b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18906849ba73SBarry Smith   PetscErrorCode    ierr;
189197b48c8fSBarry Smith   const PetscScalar *xx;
189297b48c8fSBarry Smith   PetscScalar       *bb;
1893ace3abfcSBarry Smith   PetscBool         missing;
189417ab2063SBarry Smith 
18953a40ed3dSBarry Smith   PetscFunctionBegin;
189697b48c8fSBarry Smith   if (x && b) {
189797b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
189897b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
189997b48c8fSBarry Smith     for (i=0; i<N; i++) {
190097b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
190197b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
190297b48c8fSBarry Smith     }
190397b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
190497b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
190597b48c8fSBarry Smith   }
190697b48c8fSBarry Smith 
1907a9817697SBarry Smith   if (a->keepnonzeropattern) {
1908f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1909e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1910bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1911f1e2ffcdSBarry Smith     }
1912f4df32b1SMatthew Knepley     if (diag != 0.0) {
191309f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1914e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1915f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1916f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1917f1e2ffcdSBarry Smith       }
1918f1e2ffcdSBarry Smith     }
191988e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1920f1e2ffcdSBarry Smith   } else {
1921f4df32b1SMatthew Knepley     if (diag != 0.0) {
192217ab2063SBarry Smith       for (i=0; i<N; i++) {
1923e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19247ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1925416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1926f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1927bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
19287ae801bdSBarry Smith         } else { /* in case row was completely empty */
1929f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
193017ab2063SBarry Smith         }
193117ab2063SBarry Smith       }
19323a40ed3dSBarry Smith     } else {
193317ab2063SBarry Smith       for (i=0; i<N; i++) {
1934e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1935416022c9SBarry Smith         a->ilen[rows[i]] = 0;
193617ab2063SBarry Smith       }
193717ab2063SBarry Smith     }
193888e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1939f1e2ffcdSBarry Smith   }
194043a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19413a40ed3dSBarry Smith   PetscFunctionReturn(0);
194217ab2063SBarry Smith }
194317ab2063SBarry Smith 
19444a2ae208SSatish Balay #undef __FUNCT__
19456e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19466e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19476e169961SBarry Smith {
19486e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19496e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19506e169961SBarry Smith   PetscErrorCode    ierr;
19512b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19526e169961SBarry Smith   const PetscScalar *xx;
19536e169961SBarry Smith   PetscScalar       *bb;
19546e169961SBarry Smith 
19556e169961SBarry Smith   PetscFunctionBegin;
19566e169961SBarry Smith   if (x && b) {
19576e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19586e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19592b40b63fSBarry Smith     vecs = PETSC_TRUE;
19606e169961SBarry Smith   }
19611795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
19626e169961SBarry Smith   for (i=0; i<N; i++) {
19636e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19646e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19652205254eSKarl Rupp 
19666e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19676e169961SBarry Smith   }
19686e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19696e169961SBarry Smith     if (!zeroed[i]) {
19706e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19716e169961SBarry Smith         if (zeroed[a->j[j]]) {
19722b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19736e169961SBarry Smith           a->a[j] = 0.0;
19746e169961SBarry Smith         }
19756e169961SBarry Smith       }
19762b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19776e169961SBarry Smith   }
19786e169961SBarry Smith   if (x && b) {
19796e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19806e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19816e169961SBarry Smith   }
19826e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19836e169961SBarry Smith   if (diag != 0.0) {
19846e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19856e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19866e169961SBarry Smith     for (i=0; i<N; i++) {
19876e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19886e169961SBarry Smith     }
19896e169961SBarry Smith   }
19906e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19916e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19926e169961SBarry Smith   PetscFunctionReturn(0);
19936e169961SBarry Smith }
19946e169961SBarry Smith 
19956e169961SBarry Smith #undef __FUNCT__
19964a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1997a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
199817ab2063SBarry Smith {
1999416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
200097f1f81fSBarry Smith   PetscInt   *itmp;
200117ab2063SBarry Smith 
20023a40ed3dSBarry Smith   PetscFunctionBegin;
2003e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
200417ab2063SBarry Smith 
2005416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
2006bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
200717ab2063SBarry Smith   if (idx) {
2008bfeeae90SHong Zhang     itmp = a->j + a->i[row];
200926fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
201017ab2063SBarry Smith     else *idx = 0;
201117ab2063SBarry Smith   }
20123a40ed3dSBarry Smith   PetscFunctionReturn(0);
201317ab2063SBarry Smith }
201417ab2063SBarry Smith 
2015bfeeae90SHong Zhang /* remove this function? */
20164a2ae208SSatish Balay #undef __FUNCT__
20174a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
2018a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
201917ab2063SBarry Smith {
20203a40ed3dSBarry Smith   PetscFunctionBegin;
20213a40ed3dSBarry Smith   PetscFunctionReturn(0);
202217ab2063SBarry Smith }
202317ab2063SBarry Smith 
20244a2ae208SSatish Balay #undef __FUNCT__
20254a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
2026dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
202717ab2063SBarry Smith {
2028416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
202954f21887SBarry Smith   MatScalar      *v  = a->a;
203036db0b34SBarry Smith   PetscReal      sum = 0.0;
20316849ba73SBarry Smith   PetscErrorCode ierr;
203297f1f81fSBarry Smith   PetscInt       i,j;
203317ab2063SBarry Smith 
20343a40ed3dSBarry Smith   PetscFunctionBegin;
203517ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2036416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
203736db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
203817ab2063SBarry Smith     }
20398f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20403a40ed3dSBarry Smith   } else if (type == NORM_1) {
204136db0b34SBarry Smith     PetscReal *tmp;
204297f1f81fSBarry Smith     PetscInt  *jj = a->j;
20431795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2044064f8208SBarry Smith     *nrm = 0.0;
2045416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2046bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
204717ab2063SBarry Smith     }
2048d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2049064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
205017ab2063SBarry Smith     }
2051606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20523a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2053064f8208SBarry Smith     *nrm = 0.0;
2054d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2055bfeeae90SHong Zhang       v   = a->a + a->i[j];
205617ab2063SBarry Smith       sum = 0.0;
2057416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2058cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
205917ab2063SBarry Smith       }
2060064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
206117ab2063SBarry Smith     }
2062f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20633a40ed3dSBarry Smith   PetscFunctionReturn(0);
206417ab2063SBarry Smith }
206517ab2063SBarry Smith 
20664e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20674e938277SHong Zhang #undef __FUNCT__
20684e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20694e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20704e938277SHong Zhang {
20714e938277SHong Zhang   PetscErrorCode ierr;
20724e938277SHong Zhang   PetscInt       i,j,anzj;
20734e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20744e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20754e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20764e938277SHong Zhang 
20774e938277SHong Zhang   PetscFunctionBegin;
20784e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20791795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2080785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2081785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
20824e938277SHong Zhang 
20834e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20844e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
208526fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20864e938277SHong Zhang   /* Form ati for csr format of A^T. */
208726fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20884e938277SHong Zhang 
20894e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20904e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20914e938277SHong Zhang 
20924e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20934e938277SHong Zhang   for (i=0;i<am;i++) {
20944e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20954e938277SHong Zhang     for (j=0;j<anzj;j++) {
20964e938277SHong Zhang       atj[atfill[*aj]] = i;
20974e938277SHong Zhang       atfill[*aj++]   += 1;
20984e938277SHong Zhang     }
20994e938277SHong Zhang   }
21004e938277SHong Zhang 
21014e938277SHong Zhang   /* Clean up temporary space and complete requests. */
21024e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2103ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
21042205254eSKarl Rupp 
2105a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2106a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2107a2f3521dSMark F. Adams 
21084e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
21094e938277SHong Zhang   b->free_a  = PETSC_FALSE;
21104e938277SHong Zhang   b->free_ij = PETSC_TRUE;
21114e938277SHong Zhang   b->nonew   = 0;
21124e938277SHong Zhang   PetscFunctionReturn(0);
21134e938277SHong Zhang }
21144e938277SHong Zhang 
21154a2ae208SSatish Balay #undef __FUNCT__
21164a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2117fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
211817ab2063SBarry Smith {
2119416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2120416022c9SBarry Smith   Mat            C;
21216849ba73SBarry Smith   PetscErrorCode ierr;
2122d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
212354f21887SBarry Smith   MatScalar      *array = a->a;
212417ab2063SBarry Smith 
21253a40ed3dSBarry Smith   PetscFunctionBegin;
2126e32f2f54SBarry 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");
2127fc4dec0aSBarry Smith 
2128fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
21291795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2130bfeeae90SHong Zhang 
2131bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2132ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2133d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2134a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21357adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2136ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2137606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2138a541d17aSBarry Smith   } else {
2139a541d17aSBarry Smith     C = *B;
2140a541d17aSBarry Smith   }
2141a541d17aSBarry Smith 
214217ab2063SBarry Smith   for (i=0; i<m; i++) {
214317ab2063SBarry Smith     len    = ai[i+1]-ai[i];
214487d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2145b9b97703SBarry Smith     array += len;
2146b9b97703SBarry Smith     aj    += len;
214717ab2063SBarry Smith   }
21486d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21496d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
215017ab2063SBarry Smith 
2151815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2152416022c9SBarry Smith     *B = C;
215317ab2063SBarry Smith   } else {
2154eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
215517ab2063SBarry Smith   }
21563a40ed3dSBarry Smith   PetscFunctionReturn(0);
215717ab2063SBarry Smith }
215817ab2063SBarry Smith 
2159cd0d46ebSvictorle #undef __FUNCT__
21605fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21617087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2162cd0d46ebSvictorle {
2163cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
216454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
216554f21887SBarry Smith   MatScalar      *va,*vb;
21666849ba73SBarry Smith   PetscErrorCode ierr;
216797f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2168cd0d46ebSvictorle 
2169cd0d46ebSvictorle   PetscFunctionBegin;
2170cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2171cd0d46ebSvictorle 
2172cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2173cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21745485867bSBarry Smith   if (ma!=nb || na!=mb) {
21755485867bSBarry Smith     *f = PETSC_FALSE;
21765485867bSBarry Smith     PetscFunctionReturn(0);
21775485867bSBarry Smith   }
2178cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2179cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2180cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2181785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2182785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2183cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2184cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2185cd0d46ebSvictorle 
2186cd0d46ebSvictorle   *f = PETSC_TRUE;
2187cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2188cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
218997f1f81fSBarry Smith       PetscInt    idc,idr;
21905485867bSBarry Smith       PetscScalar vc,vr;
2191cd0d46ebSvictorle       /* column/row index/value */
21925485867bSBarry Smith       idc = adx[aptr[i]];
21935485867bSBarry Smith       idr = bdx[bptr[idc]];
21945485867bSBarry Smith       vc  = va[aptr[i]];
21955485867bSBarry Smith       vr  = vb[bptr[idc]];
21965485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21975485867bSBarry Smith         *f = PETSC_FALSE;
21985485867bSBarry Smith         goto done;
2199cd0d46ebSvictorle       } else {
22005485867bSBarry Smith         aptr[i]++;
22015485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2202cd0d46ebSvictorle       }
2203cd0d46ebSvictorle     }
2204cd0d46ebSvictorle   }
2205cd0d46ebSvictorle done:
2206cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
22073aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2208cd0d46ebSvictorle   PetscFunctionReturn(0);
2209cd0d46ebSvictorle }
2210cd0d46ebSvictorle 
22111cbb95d3SBarry Smith #undef __FUNCT__
22121cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
22137087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
22141cbb95d3SBarry Smith {
22151cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
221654f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
221754f21887SBarry Smith   MatScalar      *va,*vb;
22181cbb95d3SBarry Smith   PetscErrorCode ierr;
22191cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
22201cbb95d3SBarry Smith 
22211cbb95d3SBarry Smith   PetscFunctionBegin;
22221cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
22231cbb95d3SBarry Smith 
22241cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
22251cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22261cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
22271cbb95d3SBarry Smith     *f = PETSC_FALSE;
22281cbb95d3SBarry Smith     PetscFunctionReturn(0);
22291cbb95d3SBarry Smith   }
22301cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22311cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22321cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2233785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2234785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
22351cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22361cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22371cbb95d3SBarry Smith 
22381cbb95d3SBarry Smith   *f = PETSC_TRUE;
22391cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22401cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22411cbb95d3SBarry Smith       PetscInt    idc,idr;
22421cbb95d3SBarry Smith       PetscScalar vc,vr;
22431cbb95d3SBarry Smith       /* column/row index/value */
22441cbb95d3SBarry Smith       idc = adx[aptr[i]];
22451cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22461cbb95d3SBarry Smith       vc  = va[aptr[i]];
22471cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22481cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22491cbb95d3SBarry Smith         *f = PETSC_FALSE;
22501cbb95d3SBarry Smith         goto done;
22511cbb95d3SBarry Smith       } else {
22521cbb95d3SBarry Smith         aptr[i]++;
22531cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22541cbb95d3SBarry Smith       }
22551cbb95d3SBarry Smith     }
22561cbb95d3SBarry Smith   }
22571cbb95d3SBarry Smith done:
22581cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22591cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22601cbb95d3SBarry Smith   PetscFunctionReturn(0);
22611cbb95d3SBarry Smith }
22621cbb95d3SBarry Smith 
22639e29f15eSvictorle #undef __FUNCT__
22649e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2265ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22669e29f15eSvictorle {
2267dfbe8321SBarry Smith   PetscErrorCode ierr;
22686e111a19SKarl Rupp 
22699e29f15eSvictorle   PetscFunctionBegin;
22705485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22719e29f15eSvictorle   PetscFunctionReturn(0);
22729e29f15eSvictorle }
22739e29f15eSvictorle 
22744a2ae208SSatish Balay #undef __FUNCT__
22751cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2276ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22771cbb95d3SBarry Smith {
22781cbb95d3SBarry Smith   PetscErrorCode ierr;
22796e111a19SKarl Rupp 
22801cbb95d3SBarry Smith   PetscFunctionBegin;
22811cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22821cbb95d3SBarry Smith   PetscFunctionReturn(0);
22831cbb95d3SBarry Smith }
22841cbb95d3SBarry Smith 
22851cbb95d3SBarry Smith #undef __FUNCT__
22864a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2287dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
228817ab2063SBarry Smith {
2289416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
229054f21887SBarry Smith   PetscScalar    *l,*r,x;
229154f21887SBarry Smith   MatScalar      *v;
2292dfbe8321SBarry Smith   PetscErrorCode ierr;
2293d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
229417ab2063SBarry Smith 
22953a40ed3dSBarry Smith   PetscFunctionBegin;
229617ab2063SBarry Smith   if (ll) {
22973ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22983ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2299e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2300e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
23011ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2302416022c9SBarry Smith     v    = a->a;
230317ab2063SBarry Smith     for (i=0; i<m; i++) {
230417ab2063SBarry Smith       x = l[i];
2305416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
23062205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
230717ab2063SBarry Smith     }
23081ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2309efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
231017ab2063SBarry Smith   }
231117ab2063SBarry Smith   if (rr) {
2312e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2313e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
23141ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2315416022c9SBarry Smith     v    = a->a; jj = a->j;
23162205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
23171ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2318efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
231917ab2063SBarry Smith   }
2320acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
23213a40ed3dSBarry Smith   PetscFunctionReturn(0);
232217ab2063SBarry Smith }
232317ab2063SBarry Smith 
23244a2ae208SSatish Balay #undef __FUNCT__
23254a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
232697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
232717ab2063SBarry Smith {
2328db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23296849ba73SBarry Smith   PetscErrorCode ierr;
2330d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
233197f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23325d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23335d0c19d7SBarry Smith   PetscInt       nrows,ncols;
233497f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
233554f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2336416022c9SBarry Smith   Mat            C;
2337ace3abfcSBarry Smith   PetscBool      stride,sorted;
233817ab2063SBarry Smith 
23393a40ed3dSBarry Smith   PetscFunctionBegin;
234014ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2341e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
234214ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2343e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
234499141d43SSatish Balay 
234517ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2346b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2347b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
234817ab2063SBarry Smith 
2349fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2350251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2351fee21e36SBarry Smith   if (stride && step == 1) {
235202834360SBarry Smith     /* special case of contiguous rows */
2353dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
235402834360SBarry Smith     /* loop over new rows determining lens and starting points */
235502834360SBarry Smith     for (i=0; i<nrows; i++) {
2356bfeeae90SHong Zhang       kstart = ai[irow[i]];
2357a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
235802834360SBarry Smith       for (k=kstart; k<kend; k++) {
2359bfeeae90SHong Zhang         if (aj[k] >= first) {
236002834360SBarry Smith           starts[i] = k;
236102834360SBarry Smith           break;
236202834360SBarry Smith         }
236302834360SBarry Smith       }
2364a2744918SBarry Smith       sum = 0;
236502834360SBarry Smith       while (k < kend) {
2366bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2367a2744918SBarry Smith         sum++;
236802834360SBarry Smith       }
2369a2744918SBarry Smith       lens[i] = sum;
237002834360SBarry Smith     }
237102834360SBarry Smith     /* create submatrix */
2372cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
237397f1f81fSBarry Smith       PetscInt n_cols,n_rows;
237408480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2375e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2376d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
237708480c60SBarry Smith       C    = *B;
23783a40ed3dSBarry Smith     } else {
23793bef6203SJed Brown       PetscInt rbs,cbs;
2380ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2381f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23823bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23833bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23843bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23857adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2386ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
238708480c60SBarry Smith     }
2388db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2389db02288aSLois Curfman McInnes 
239002834360SBarry Smith     /* loop over rows inserting into submatrix */
2391db02288aSLois Curfman McInnes     a_new = c->a;
2392db02288aSLois Curfman McInnes     j_new = c->j;
2393db02288aSLois Curfman McInnes     i_new = c->i;
2394bfeeae90SHong Zhang 
239502834360SBarry Smith     for (i=0; i<nrows; i++) {
2396a2744918SBarry Smith       ii    = starts[i];
2397a2744918SBarry Smith       lensi = lens[i];
2398a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2399a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
240002834360SBarry Smith       }
240187828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2402a2744918SBarry Smith       a_new     += lensi;
2403a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2404a2744918SBarry Smith       c->ilen[i] = lensi;
240502834360SBarry Smith     }
24060e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
24073a40ed3dSBarry Smith   } else {
240802834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
24091795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2410785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
24114dcab191SBarry Smith     for (i=0; i<ncols; i++) {
24124dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
24134dcab191SBarry 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);
24144dcab191SBarry Smith #endif
24154dcab191SBarry Smith       smap[icol[i]] = i+1;
24164dcab191SBarry Smith     }
24174dcab191SBarry Smith 
241802834360SBarry Smith     /* determine lens of each row */
241902834360SBarry Smith     for (i=0; i<nrows; i++) {
2420bfeeae90SHong Zhang       kstart  = ai[irow[i]];
242102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
242202834360SBarry Smith       lens[i] = 0;
242302834360SBarry Smith       for (k=kstart; k<kend; k++) {
2424bfeeae90SHong Zhang         if (smap[aj[k]]) {
242502834360SBarry Smith           lens[i]++;
242602834360SBarry Smith         }
242702834360SBarry Smith       }
242802834360SBarry Smith     }
242917ab2063SBarry Smith     /* Create and fill new matrix */
2430a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2431ace3abfcSBarry Smith       PetscBool equal;
24320f5bd95cSBarry Smith 
243399141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2434e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2435d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2436f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2437d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
243808480c60SBarry Smith       C    = *B;
24393a40ed3dSBarry Smith     } else {
24403bef6203SJed Brown       PetscInt rbs,cbs;
2441ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2442f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24433bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24443bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24453bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24467adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2447ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
244808480c60SBarry Smith     }
244999141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
245017ab2063SBarry Smith     for (i=0; i<nrows; i++) {
245199141d43SSatish Balay       row      = irow[i];
2452bfeeae90SHong Zhang       kstart   = ai[row];
245399141d43SSatish Balay       kend     = kstart + a->ilen[row];
2454bfeeae90SHong Zhang       mat_i    = c->i[i];
245599141d43SSatish Balay       mat_j    = c->j + mat_i;
245699141d43SSatish Balay       mat_a    = c->a + mat_i;
245799141d43SSatish Balay       mat_ilen = c->ilen + i;
245817ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2459bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2460ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
246199141d43SSatish Balay           *mat_a++ = a->a[k];
246299141d43SSatish Balay           (*mat_ilen)++;
246399141d43SSatish Balay 
246417ab2063SBarry Smith         }
246517ab2063SBarry Smith       }
246617ab2063SBarry Smith     }
246702834360SBarry Smith     /* Free work space */
246802834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2469606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2470606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
247102834360SBarry Smith   }
24726d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24736d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
247417ab2063SBarry Smith 
247517ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2476416022c9SBarry Smith   *B   = C;
24773a40ed3dSBarry Smith   PetscFunctionReturn(0);
247817ab2063SBarry Smith }
247917ab2063SBarry Smith 
24801df811f5SHong Zhang #undef __FUNCT__
248182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2482fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
248382d44351SHong Zhang {
248482d44351SHong Zhang   PetscErrorCode ierr;
248582d44351SHong Zhang   Mat            B;
248682d44351SHong Zhang 
248782d44351SHong Zhang   PetscFunctionBegin;
2488c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
248982d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
249082d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2491a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
249282d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
249382d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
249482d44351SHong Zhang     *subMat = B;
2495c2d650bdSHong Zhang   } else {
2496c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2497c2d650bdSHong Zhang   }
249882d44351SHong Zhang   PetscFunctionReturn(0);
249982d44351SHong Zhang }
250082d44351SHong Zhang 
250182d44351SHong Zhang #undef __FUNCT__
25024a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
25030481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2504a871dcd8SBarry Smith {
250563b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2506dfbe8321SBarry Smith   PetscErrorCode ierr;
250763b91edcSBarry Smith   Mat            outA;
2508ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
250963b91edcSBarry Smith 
25103a40ed3dSBarry Smith   PetscFunctionBegin;
2511e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
25121df811f5SHong Zhang 
2513b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2514b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2515a871dcd8SBarry Smith 
251663b91edcSBarry Smith   outA             = inA;
2517d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
25182205254eSKarl Rupp 
2519c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
25206bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
25212205254eSKarl Rupp 
2522c3122656SLisandro Dalcin   a->row = row;
25232205254eSKarl Rupp 
2524c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
25256bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
25262205254eSKarl Rupp 
2527c3122656SLisandro Dalcin   a->col = col;
252863b91edcSBarry Smith 
252936db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
25306bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
25314c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25323bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2533f0ec6fceSSatish Balay 
253494a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2535785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
25363bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
253794a9d846SBarry Smith   }
253863b91edcSBarry Smith 
2539f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2540137fb511SHong Zhang   if (row_identity && col_identity) {
2541ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2542137fb511SHong Zhang   } else {
2543719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2544137fb511SHong Zhang   }
25453a40ed3dSBarry Smith   PetscFunctionReturn(0);
2546a871dcd8SBarry Smith }
2547a871dcd8SBarry Smith 
25484a2ae208SSatish Balay #undef __FUNCT__
25494a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2550f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2551f0b747eeSBarry Smith {
2552f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2553f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2554efee365bSSatish Balay   PetscErrorCode ierr;
2555c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25563a40ed3dSBarry Smith 
25573a40ed3dSBarry Smith   PetscFunctionBegin;
2558c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25598b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2560efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2561acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25623a40ed3dSBarry Smith   PetscFunctionReturn(0);
2563f0b747eeSBarry Smith }
2564f0b747eeSBarry Smith 
25654a2ae208SSatish Balay #undef __FUNCT__
25664a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
256797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2568cddf8d76SBarry Smith {
2569dfbe8321SBarry Smith   PetscErrorCode ierr;
257097f1f81fSBarry Smith   PetscInt       i;
2571cddf8d76SBarry Smith 
25723a40ed3dSBarry Smith   PetscFunctionBegin;
2573cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2574785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2575cddf8d76SBarry Smith   }
2576cddf8d76SBarry Smith 
2577cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25786a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2579cddf8d76SBarry Smith   }
25803a40ed3dSBarry Smith   PetscFunctionReturn(0);
2581cddf8d76SBarry Smith }
2582cddf8d76SBarry Smith 
25834a2ae208SSatish Balay #undef __FUNCT__
25844a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
258597f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25864dcbc457SBarry Smith {
2587e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25886849ba73SBarry Smith   PetscErrorCode ierr;
25895d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25905d0c19d7SBarry Smith   const PetscInt *idx;
259197f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2592f1af5d2fSBarry Smith   PetscBT        table;
2593bbd702dbSSatish Balay 
25943a40ed3dSBarry Smith   PetscFunctionBegin;
2595d0f46423SBarry Smith   m  = A->rmap->n;
2596e4d965acSSatish Balay   ai = a->i;
2597bfeeae90SHong Zhang   aj = a->j;
25988a047759SSatish Balay 
2599e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
260006763907SSatish Balay 
2601785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
260253b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
260306763907SSatish Balay 
2604e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2605b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2606e4d965acSSatish Balay     isz  = 0;
26076831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2608e4d965acSSatish Balay 
2609e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
26104dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2611b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2612e4d965acSSatish Balay 
2613dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2614e4d965acSSatish Balay     for (j=0; j<n; ++j) {
26152205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
26164dcbc457SBarry Smith     }
261706763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
26186bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2619e4d965acSSatish Balay 
262004a348a9SBarry Smith     k = 0;
262104a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
262204a348a9SBarry Smith       n = isz;
262306763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2624e4d965acSSatish Balay         row   = nidx[k];
2625e4d965acSSatish Balay         start = ai[row];
2626e4d965acSSatish Balay         end   = ai[row+1];
262704a348a9SBarry Smith         for (l = start; l<end; l++) {
2628efb16452SHong Zhang           val = aj[l];
26292205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2630e4d965acSSatish Balay         }
2631e4d965acSSatish Balay       }
2632e4d965acSSatish Balay     }
263370b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2634e4d965acSSatish Balay   }
263594bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2636606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26373a40ed3dSBarry Smith   PetscFunctionReturn(0);
26384dcbc457SBarry Smith }
263917ab2063SBarry Smith 
26400513a670SBarry Smith /* -------------------------------------------------------------- */
26414a2ae208SSatish Balay #undef __FUNCT__
26424a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2643dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26440513a670SBarry Smith {
26450513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26466849ba73SBarry Smith   PetscErrorCode ierr;
26473b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26485d0c19d7SBarry Smith   const PetscInt *row,*col;
26495d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
265056cd22aeSBarry Smith   IS             icolp,irowp;
26510298fd71SBarry Smith   PetscInt       *cwork = NULL;
26520298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26530513a670SBarry Smith 
26543a40ed3dSBarry Smith   PetscFunctionBegin;
26554c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
265656cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26574c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
265856cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26590513a670SBarry Smith 
26600513a670SBarry Smith   /* determine lengths of permuted rows */
2661785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
26622205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2663ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2664f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2665a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26667adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2667ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2668606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26690513a670SBarry Smith 
2670785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
26710513a670SBarry Smith   for (i=0; i<m; i++) {
267232ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26732205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2674cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
267532ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26760513a670SBarry Smith   }
2677606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26782205254eSKarl Rupp 
26793c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26802205254eSKarl Rupp 
26810513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26820513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
268356cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
268456cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26856bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26866bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26873a40ed3dSBarry Smith   PetscFunctionReturn(0);
26880513a670SBarry Smith }
26890513a670SBarry Smith 
26904a2ae208SSatish Balay #undef __FUNCT__
26914a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2692dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2693cb5b572fSBarry Smith {
2694dfbe8321SBarry Smith   PetscErrorCode ierr;
2695cb5b572fSBarry Smith 
2696cb5b572fSBarry Smith   PetscFunctionBegin;
269733f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
269833f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2699be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2700be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2701be6bf707SBarry Smith 
2702700c5bfcSBarry 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");
2703d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2704cb5b572fSBarry Smith   } else {
2705cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2706cb5b572fSBarry Smith   }
2707cb5b572fSBarry Smith   PetscFunctionReturn(0);
2708cb5b572fSBarry Smith }
2709cb5b572fSBarry Smith 
27104a2ae208SSatish Balay #undef __FUNCT__
27114994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
27124994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2713273d9f13SBarry Smith {
2714dfbe8321SBarry Smith   PetscErrorCode ierr;
2715273d9f13SBarry Smith 
2716273d9f13SBarry Smith   PetscFunctionBegin;
2717ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2718273d9f13SBarry Smith   PetscFunctionReturn(0);
2719273d9f13SBarry Smith }
2720273d9f13SBarry Smith 
27214a2ae208SSatish Balay #undef __FUNCT__
27228c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
27238c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
27246c0721eeSBarry Smith {
27256c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
27266e111a19SKarl Rupp 
27276c0721eeSBarry Smith   PetscFunctionBegin;
27286c0721eeSBarry Smith   *array = a->a;
27296c0721eeSBarry Smith   PetscFunctionReturn(0);
27306c0721eeSBarry Smith }
27316c0721eeSBarry Smith 
27324a2ae208SSatish Balay #undef __FUNCT__
27338c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27348c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27356c0721eeSBarry Smith {
27366c0721eeSBarry Smith   PetscFunctionBegin;
27376c0721eeSBarry Smith   PetscFunctionReturn(0);
27386c0721eeSBarry Smith }
2739273d9f13SBarry Smith 
27408229c054SShri Abhyankar /*
27418229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
27428229c054SShri Abhyankar    have different nonzero structure.
27438229c054SShri Abhyankar */
2744ac90fabeSBarry Smith #undef __FUNCT__
27458229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
27468229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2747ec7775f6SShri Abhyankar {
27488229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2749ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2750ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2751ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2752ec7775f6SShri Abhyankar 
2753ec7775f6SShri Abhyankar   PetscFunctionBegin;
2754ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2755ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
27568af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
27578af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
27588af7cee1SJed Brown     nnz[i] = 0;
27598af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
27608af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
27618af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
27628af7cee1SJed Brown       nnz[i]++;
27638af7cee1SJed Brown     }
27648af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2765ec7775f6SShri Abhyankar   }
2766ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2767ec7775f6SShri Abhyankar }
2768ec7775f6SShri Abhyankar 
2769ec7775f6SShri Abhyankar #undef __FUNCT__
2770ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2771f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2772ac90fabeSBarry Smith {
2773dfbe8321SBarry Smith   PetscErrorCode ierr;
277497f1f81fSBarry Smith   PetscInt       i;
2775ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2776c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2777ac90fabeSBarry Smith 
2778ac90fabeSBarry Smith   PetscFunctionBegin;
2779c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2780ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2781f4df32b1SMatthew Knepley     PetscScalar alpha = a;
27828b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2783acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2784c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2785a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2786a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
27876bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2788a30b2313SHong Zhang     }
2789a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
27900298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2791a30b2313SHong Zhang       y->XtoY = X;
2792407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2793c537a176SHong Zhang     }
2794f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2795ba0e910bSBarry 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);
2796ac90fabeSBarry Smith   } else {
27978229c054SShri Abhyankar     Mat      B;
27988229c054SShri Abhyankar     PetscInt *nnz;
2799785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2800ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2801bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
28024aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2803a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2804176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
28058229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2806ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2807ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2808ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
28098229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2810ac90fabeSBarry Smith   }
2811ac90fabeSBarry Smith   PetscFunctionReturn(0);
2812ac90fabeSBarry Smith }
2813ac90fabeSBarry Smith 
2814521d7252SBarry Smith #undef __FUNCT__
2815354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
28167087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2817354c94deSBarry Smith {
2818354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2819354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2820354c94deSBarry Smith   PetscInt    i,nz;
2821354c94deSBarry Smith   PetscScalar *a;
2822354c94deSBarry Smith 
2823354c94deSBarry Smith   PetscFunctionBegin;
2824354c94deSBarry Smith   nz = aij->nz;
2825354c94deSBarry Smith   a  = aij->a;
28262205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2827354c94deSBarry Smith #else
2828354c94deSBarry Smith   PetscFunctionBegin;
2829354c94deSBarry Smith #endif
2830354c94deSBarry Smith   PetscFunctionReturn(0);
2831354c94deSBarry Smith }
2832354c94deSBarry Smith 
2833e34fafa9SBarry Smith #undef __FUNCT__
2834985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2835985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2836e34fafa9SBarry Smith {
2837e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2838e34fafa9SBarry Smith   PetscErrorCode ierr;
2839d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2840e34fafa9SBarry Smith   PetscReal      atmp;
2841985db425SBarry Smith   PetscScalar    *x;
2842e34fafa9SBarry Smith   MatScalar      *aa;
2843e34fafa9SBarry Smith 
2844e34fafa9SBarry Smith   PetscFunctionBegin;
2845e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2846e34fafa9SBarry Smith   aa = a->a;
2847e34fafa9SBarry Smith   ai = a->i;
2848e34fafa9SBarry Smith   aj = a->j;
2849e34fafa9SBarry Smith 
2850985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2851e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2852e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2853e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2854e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2855e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
28569189402eSHong Zhang     x[i]  = 0.0;
2857e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2858985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2859985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2860985db425SBarry Smith       aa++; aj++;
2861985db425SBarry Smith     }
2862985db425SBarry Smith   }
2863985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2864985db425SBarry Smith   PetscFunctionReturn(0);
2865985db425SBarry Smith }
2866985db425SBarry Smith 
2867985db425SBarry Smith #undef __FUNCT__
2868985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2869985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2870985db425SBarry Smith {
2871985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2872985db425SBarry Smith   PetscErrorCode ierr;
2873d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2874985db425SBarry Smith   PetscScalar    *x;
2875985db425SBarry Smith   MatScalar      *aa;
2876985db425SBarry Smith 
2877985db425SBarry Smith   PetscFunctionBegin;
2878e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879985db425SBarry Smith   aa = a->a;
2880985db425SBarry Smith   ai = a->i;
2881985db425SBarry Smith   aj = a->j;
2882985db425SBarry Smith 
2883985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2884985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2885985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2886e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2887985db425SBarry Smith   for (i=0; i<m; i++) {
2888985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2889d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2890985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2891985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
2892985db425SBarry Smith       x[i] = 0.0;
2893985db425SBarry Smith       if (idx) {
2894985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2895985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
2896985db425SBarry Smith           if (aj[j] > j) {
2897985db425SBarry Smith             idx[i] = j;
2898985db425SBarry Smith             break;
2899985db425SBarry Smith           }
2900985db425SBarry Smith         }
2901985db425SBarry Smith       }
2902985db425SBarry Smith     }
2903985db425SBarry Smith     for (j=0; j<ncols; j++) {
2904985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2905985db425SBarry Smith       aa++; aj++;
2906985db425SBarry Smith     }
2907985db425SBarry Smith   }
2908985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2909985db425SBarry Smith   PetscFunctionReturn(0);
2910985db425SBarry Smith }
2911985db425SBarry Smith 
2912985db425SBarry Smith #undef __FUNCT__
2913c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
2914c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2915c87e5d42SMatthew Knepley {
2916c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2917c87e5d42SMatthew Knepley   PetscErrorCode ierr;
2918c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2919c87e5d42SMatthew Knepley   PetscReal      atmp;
2920c87e5d42SMatthew Knepley   PetscScalar    *x;
2921c87e5d42SMatthew Knepley   MatScalar      *aa;
2922c87e5d42SMatthew Knepley 
2923c87e5d42SMatthew Knepley   PetscFunctionBegin;
2924e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2925c87e5d42SMatthew Knepley   aa = a->a;
2926c87e5d42SMatthew Knepley   ai = a->i;
2927c87e5d42SMatthew Knepley   aj = a->j;
2928c87e5d42SMatthew Knepley 
2929c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2930c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2931c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
29323bb78c5cSMatthew 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);
2933c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
2934c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
2935289a08f5SMatthew Knepley     if (ncols) {
2936289a08f5SMatthew Knepley       /* Get first nonzero */
2937289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
2938289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
29392205254eSKarl Rupp         if (atmp > 1.0e-12) {
29402205254eSKarl Rupp           x[i] = atmp;
29412205254eSKarl Rupp           if (idx) idx[i] = aj[j];
29422205254eSKarl Rupp           break;
29432205254eSKarl Rupp         }
2944289a08f5SMatthew Knepley       }
294512431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
2946289a08f5SMatthew Knepley     } else {
2947289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
2948289a08f5SMatthew Knepley     }
2949c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
2950c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
2951289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2952c87e5d42SMatthew Knepley       aa++; aj++;
2953c87e5d42SMatthew Knepley     }
2954c87e5d42SMatthew Knepley   }
2955c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2956c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
2957c87e5d42SMatthew Knepley }
2958c87e5d42SMatthew Knepley 
2959c87e5d42SMatthew Knepley #undef __FUNCT__
2960985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
2961985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2962985db425SBarry Smith {
2963985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2964985db425SBarry Smith   PetscErrorCode ierr;
2965d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2966985db425SBarry Smith   PetscScalar    *x;
2967985db425SBarry Smith   MatScalar      *aa;
2968985db425SBarry Smith 
2969985db425SBarry Smith   PetscFunctionBegin;
2970e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2971985db425SBarry Smith   aa = a->a;
2972985db425SBarry Smith   ai = a->i;
2973985db425SBarry Smith   aj = a->j;
2974985db425SBarry Smith 
2975985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2976985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2977985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2978e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2979985db425SBarry Smith   for (i=0; i<m; i++) {
2980985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
2981d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
2982985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
2983985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
2984985db425SBarry Smith       x[i] = 0.0;
2985985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
2986985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
2987985db425SBarry Smith         for (j=0; j<ncols; j++) {
2988985db425SBarry Smith           if (aj[j] > j) {
2989985db425SBarry Smith             idx[i] = j;
2990985db425SBarry Smith             break;
2991985db425SBarry Smith           }
2992985db425SBarry Smith         }
2993985db425SBarry Smith       }
2994985db425SBarry Smith     }
2995985db425SBarry Smith     for (j=0; j<ncols; j++) {
2996985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
2997985db425SBarry Smith       aa++; aj++;
2998e34fafa9SBarry Smith     }
2999e34fafa9SBarry Smith   }
3000e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3001e34fafa9SBarry Smith   PetscFunctionReturn(0);
3002e34fafa9SBarry Smith }
3003bbead8a2SBarry Smith 
3004bbead8a2SBarry Smith #include <petscblaslapack.h>
300506873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
3006bbead8a2SBarry Smith 
3007bbead8a2SBarry Smith #undef __FUNCT__
3008bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
3009713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3010bbead8a2SBarry Smith {
3011bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
3012bbead8a2SBarry Smith   PetscErrorCode ierr;
301334fc4b71SJed 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;
3014bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
3015bbead8a2SBarry Smith   PetscReal      shift = 0.0;
3016bbead8a2SBarry Smith 
3017bbead8a2SBarry Smith   PetscFunctionBegin;
30184a0d0026SBarry Smith   if (a->ibdiagvalid) {
30194a0d0026SBarry Smith     if (values) *values = a->ibdiag;
30204a0d0026SBarry Smith     PetscFunctionReturn(0);
30214a0d0026SBarry Smith   }
3022bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3023bbead8a2SBarry Smith   if (!a->ibdiag) {
3024785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
30253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3026bbead8a2SBarry Smith   }
3027bbead8a2SBarry Smith   diag = a->ibdiag;
3028bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3029bbead8a2SBarry Smith   /* factor and invert each block */
3030bbead8a2SBarry Smith   switch (bs) {
3031bbead8a2SBarry Smith   case 1:
3032bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3033bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3034bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3035bbead8a2SBarry Smith     }
3036bbead8a2SBarry Smith     break;
3037bbead8a2SBarry Smith   case 2:
3038bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3039bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3040bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
304196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
304296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3043bbead8a2SBarry Smith       diag += 4;
3044bbead8a2SBarry Smith     }
3045bbead8a2SBarry Smith     break;
3046bbead8a2SBarry Smith   case 3:
3047bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3048bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3049bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
305096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
305196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3052bbead8a2SBarry Smith       diag += 9;
3053bbead8a2SBarry Smith     }
3054bbead8a2SBarry Smith     break;
3055bbead8a2SBarry Smith   case 4:
3056bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3057bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3058bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
305996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
306096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3061bbead8a2SBarry Smith       diag += 16;
3062bbead8a2SBarry Smith     }
3063bbead8a2SBarry Smith     break;
3064bbead8a2SBarry Smith   case 5:
3065bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3066bbead8a2SBarry 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;
3067bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
306896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
306996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3070bbead8a2SBarry Smith       diag += 25;
3071bbead8a2SBarry Smith     }
3072bbead8a2SBarry Smith     break;
3073bbead8a2SBarry Smith   case 6:
3074bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3075bbead8a2SBarry 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;
3076bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
307796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
307896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3079bbead8a2SBarry Smith       diag += 36;
3080bbead8a2SBarry Smith     }
3081bbead8a2SBarry Smith     break;
3082bbead8a2SBarry Smith   case 7:
3083bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3084bbead8a2SBarry 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;
3085bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
308696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
308796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3088bbead8a2SBarry Smith       diag += 49;
3089bbead8a2SBarry Smith     }
3090bbead8a2SBarry Smith     break;
3091bbead8a2SBarry Smith   default:
3092dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3093bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3094bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3095bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3096bbead8a2SBarry Smith       }
3097bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
309896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
309996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3100bbead8a2SBarry Smith       diag += bs2;
3101bbead8a2SBarry Smith     }
3102bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3103bbead8a2SBarry Smith   }
3104bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3105bbead8a2SBarry Smith   PetscFunctionReturn(0);
3106bbead8a2SBarry Smith }
3107bbead8a2SBarry Smith 
310873a71a0fSBarry Smith #undef __FUNCT__
310973a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
311073a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
311173a71a0fSBarry Smith {
311273a71a0fSBarry Smith   PetscErrorCode ierr;
311373a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
311473a71a0fSBarry Smith   PetscScalar    a;
311573a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
311673a71a0fSBarry Smith 
311773a71a0fSBarry Smith   PetscFunctionBegin;
311873a71a0fSBarry Smith   if (!x->assembled) {
311973a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
312073a71a0fSBarry Smith     for (i=0; i<m; i++) {
312173a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
312273a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
312373a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
312473a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
312573a71a0fSBarry Smith       }
312673a71a0fSBarry Smith     }
312773a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
312873a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
312973a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
313073a71a0fSBarry Smith   PetscFunctionReturn(0);
313173a71a0fSBarry Smith }
313273a71a0fSBarry Smith 
3133682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
31340a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3135cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3136cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3137cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
313897304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
31397c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
31407c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3141db4efbfdSBarry Smith                                         0,
3142db4efbfdSBarry Smith                                         0,
3143db4efbfdSBarry Smith                                         0,
3144db4efbfdSBarry Smith                                 /* 10*/ 0,
3145cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3146cb5b572fSBarry Smith                                         0,
314741f059aeSBarry Smith                                         MatSOR_SeqAIJ,
314817ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
314997304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3150cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3151cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3152cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3153cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
315497304618SKris Buschelman                                 /* 20*/ 0,
3155cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3156cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3157cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3158d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3159db4efbfdSBarry Smith                                         0,
3160db4efbfdSBarry Smith                                         0,
3161db4efbfdSBarry Smith                                         0,
3162db4efbfdSBarry Smith                                         0,
31634994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3164db4efbfdSBarry Smith                                         0,
3165db4efbfdSBarry Smith                                         0,
31668c778c55SBarry Smith                                         0,
31678c778c55SBarry Smith                                         0,
3168d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3169cb5b572fSBarry Smith                                         0,
3170cb5b572fSBarry Smith                                         0,
3171cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3172cb5b572fSBarry Smith                                         0,
3173d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3174cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3175cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3176cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3177cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3178d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3179cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3180cb5b572fSBarry Smith                                         0,
318179299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
31826e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
318373a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
31843b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
31853b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
31863b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3187a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
318893dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3189b9617806SBarry Smith                                         0,
31900513a670SBarry Smith                                         0,
3191cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3192cda55fadSBarry Smith                                         0,
3193d519adbfSMatthew Knepley                                 /* 59*/ 0,
3194b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3195b9b97703SBarry Smith                                         MatView_SeqAIJ,
3196357abbc8SBarry Smith                                         0,
3197321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3198321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3199321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3200ee4f033dSBarry Smith                                         0,
3201ee4f033dSBarry Smith                                         0,
3202ee4f033dSBarry Smith                                         0,
3203d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3204c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3205ee4f033dSBarry Smith                                         0,
3206ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3207dcf5cc72SBarry Smith                                         0,
3208d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
32093acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
321097304618SKris Buschelman                                         0,
321197304618SKris Buschelman                                         0,
321297304618SKris Buschelman                                         0,
32136ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
321497304618SKris Buschelman                                         0,
321597304618SKris Buschelman                                         0,
321697304618SKris Buschelman                                         0,
3217bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3218d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
32191cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
32206284ec50SHong Zhang                                         0,
32216284ec50SHong Zhang                                         0,
3222bc011b1eSHong Zhang                                         0,
3223d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
322426be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
322526be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
322665e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
32274a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
322865e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
32296fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
32306fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
32316fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
32322121bac1SHong Zhang                                         0,
32332121bac1SHong Zhang                                 /* 99*/ 0,
3234609c6c4dSKris Buschelman                                         0,
3235609c6c4dSKris Buschelman                                         0,
323687d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
323787d4246cSBarry Smith                                         0,
3238d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
323999cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3240f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3241f5edf698SHong Zhang                                         0,
32422bebee5dSHong Zhang                                         0,
3243cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3244985db425SBarry Smith                                         0,
32452af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
32462af78befSBarry Smith                                         0,
3247599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3248d519adbfSMatthew Knepley                                 /*114*/ 0,
3249599ef60dSHong Zhang                                         0,
32503c2a7987SHong Zhang                                         0,
3251fe97e370SBarry Smith                                         0,
3252fbdbba38SShri Abhyankar                                         0,
3253fbdbba38SShri Abhyankar                                 /*119*/ 0,
3254fbdbba38SShri Abhyankar                                         0,
3255fbdbba38SShri Abhyankar                                         0,
325682d44351SHong Zhang                                         0,
3257b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
32580716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3259bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
326037868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
326137868618SMatthew G Knepley                                         0,
326237868618SMatthew G Knepley                                         0,
32635df89d91SHong Zhang                                 /*129*/ 0,
326475648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
326575648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
326675648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3267b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3268b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
32692b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
32702b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
32712b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
32723964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
32733964eb88SJed Brown                                  /*139*/0,
3274f9426fe0SMark Adams                                         0,
32751919a2e2SJed Brown                                         0,
3276*3a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
3277*3a062f41SBarry Smith                                         MatFindOffBlockDiagonalEntries_SeqAIJ
32789e29f15eSvictorle };
327917ab2063SBarry Smith 
32804a2ae208SSatish Balay #undef __FUNCT__
32814a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
32827087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3283bef8e0ddSBarry Smith {
3284bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
328597f1f81fSBarry Smith   PetscInt   i,nz,n;
3286bef8e0ddSBarry Smith 
3287bef8e0ddSBarry Smith   PetscFunctionBegin;
3288bef8e0ddSBarry Smith   nz = aij->maxnz;
3289d0f46423SBarry Smith   n  = mat->rmap->n;
3290bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3291bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3292bef8e0ddSBarry Smith   }
3293bef8e0ddSBarry Smith   aij->nz = nz;
3294bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3295bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3296bef8e0ddSBarry Smith   }
3297bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3298bef8e0ddSBarry Smith }
3299bef8e0ddSBarry Smith 
33004a2ae208SSatish Balay #undef __FUNCT__
33014a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3302bef8e0ddSBarry Smith /*@
3303bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3304bef8e0ddSBarry Smith        in the matrix.
3305bef8e0ddSBarry Smith 
3306bef8e0ddSBarry Smith   Input Parameters:
3307bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3308bef8e0ddSBarry Smith -  indices - the column indices
3309bef8e0ddSBarry Smith 
331015091d37SBarry Smith   Level: advanced
331115091d37SBarry Smith 
3312bef8e0ddSBarry Smith   Notes:
3313bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3314bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3315bef8e0ddSBarry Smith   of the MatSetValues() operation.
3316bef8e0ddSBarry Smith 
3317bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3318d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3319bef8e0ddSBarry Smith 
3320bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3321bef8e0ddSBarry Smith 
3322b9617806SBarry Smith     The indices should start with zero, not one.
3323b9617806SBarry Smith 
3324bef8e0ddSBarry Smith @*/
33257087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3326bef8e0ddSBarry Smith {
33274ac538c5SBarry Smith   PetscErrorCode ierr;
3328bef8e0ddSBarry Smith 
3329bef8e0ddSBarry Smith   PetscFunctionBegin;
33300700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
33314482741eSBarry Smith   PetscValidPointer(indices,2);
33324ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3333bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3334bef8e0ddSBarry Smith }
3335bef8e0ddSBarry Smith 
3336be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3337be6bf707SBarry Smith 
33384a2ae208SSatish Balay #undef __FUNCT__
33394a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
33407087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3341be6bf707SBarry Smith {
3342be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
33436849ba73SBarry Smith   PetscErrorCode ierr;
3344d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3345be6bf707SBarry Smith 
3346be6bf707SBarry Smith   PetscFunctionBegin;
3347f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3348be6bf707SBarry Smith 
3349be6bf707SBarry Smith   /* allocate space for values if not already there */
3350be6bf707SBarry Smith   if (!aij->saved_values) {
3351785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
33523bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3353be6bf707SBarry Smith   }
3354be6bf707SBarry Smith 
3355be6bf707SBarry Smith   /* copy values over */
335687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3357be6bf707SBarry Smith   PetscFunctionReturn(0);
3358be6bf707SBarry Smith }
3359be6bf707SBarry Smith 
33604a2ae208SSatish Balay #undef __FUNCT__
3361b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3362be6bf707SBarry Smith /*@
3363be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3364be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3365be6bf707SBarry Smith        nonlinear portion.
3366be6bf707SBarry Smith 
3367be6bf707SBarry Smith    Collect on Mat
3368be6bf707SBarry Smith 
3369be6bf707SBarry Smith   Input Parameters:
33700e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3371be6bf707SBarry Smith 
337215091d37SBarry Smith   Level: advanced
337315091d37SBarry Smith 
3374be6bf707SBarry Smith   Common Usage, with SNESSolve():
3375be6bf707SBarry Smith $    Create Jacobian matrix
3376be6bf707SBarry Smith $    Set linear terms into matrix
3377be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3378be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3379be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3380512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3381be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3382be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3383be6bf707SBarry Smith $    In your Jacobian routine
3384be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3385be6bf707SBarry Smith $      Set nonlinear terms in matrix
3386be6bf707SBarry Smith 
3387be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3388be6bf707SBarry Smith $    // build linear portion of Jacobian
3389512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3390be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3391be6bf707SBarry Smith $    loop over nonlinear iterations
3392be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3393be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3394be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3395be6bf707SBarry Smith $       Solve linear system with Jacobian
3396be6bf707SBarry Smith $    endloop
3397be6bf707SBarry Smith 
3398be6bf707SBarry Smith   Notes:
3399be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3400512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3401be6bf707SBarry Smith     calling this routine.
3402be6bf707SBarry Smith 
34030c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
34040c468ba9SBarry Smith     and does not allocated additional space.
34050c468ba9SBarry Smith 
3406be6bf707SBarry Smith .seealso: MatRetrieveValues()
3407be6bf707SBarry Smith 
3408be6bf707SBarry Smith @*/
34097087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3410be6bf707SBarry Smith {
34114ac538c5SBarry Smith   PetscErrorCode ierr;
3412be6bf707SBarry Smith 
3413be6bf707SBarry Smith   PetscFunctionBegin;
34140700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3415e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3416e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34174ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3418be6bf707SBarry Smith   PetscFunctionReturn(0);
3419be6bf707SBarry Smith }
3420be6bf707SBarry Smith 
34214a2ae208SSatish Balay #undef __FUNCT__
34224a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
34237087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3424be6bf707SBarry Smith {
3425be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
34266849ba73SBarry Smith   PetscErrorCode ierr;
3427d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3428be6bf707SBarry Smith 
3429be6bf707SBarry Smith   PetscFunctionBegin;
3430f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3431f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3432be6bf707SBarry Smith   /* copy values over */
343387828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3434be6bf707SBarry Smith   PetscFunctionReturn(0);
3435be6bf707SBarry Smith }
3436be6bf707SBarry Smith 
34374a2ae208SSatish Balay #undef __FUNCT__
34384a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3439be6bf707SBarry Smith /*@
3440be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3441be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3442be6bf707SBarry Smith        nonlinear portion.
3443be6bf707SBarry Smith 
3444be6bf707SBarry Smith    Collect on Mat
3445be6bf707SBarry Smith 
3446be6bf707SBarry Smith   Input Parameters:
3447be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3448be6bf707SBarry Smith 
344915091d37SBarry Smith   Level: advanced
345015091d37SBarry Smith 
3451be6bf707SBarry Smith .seealso: MatStoreValues()
3452be6bf707SBarry Smith 
3453be6bf707SBarry Smith @*/
34547087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3455be6bf707SBarry Smith {
34564ac538c5SBarry Smith   PetscErrorCode ierr;
3457be6bf707SBarry Smith 
3458be6bf707SBarry Smith   PetscFunctionBegin;
34590700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3460e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3461e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
34624ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3463be6bf707SBarry Smith   PetscFunctionReturn(0);
3464be6bf707SBarry Smith }
3465be6bf707SBarry Smith 
3466f83d6046SBarry Smith 
3467be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
34684a2ae208SSatish Balay #undef __FUNCT__
34694a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
347017ab2063SBarry Smith /*@C
3471682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
34720d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
34736e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
347451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
34752bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
347617ab2063SBarry Smith 
3477db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3478db81eaa0SLois Curfman McInnes 
347917ab2063SBarry Smith    Input Parameters:
3480db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
348117ab2063SBarry Smith .  m - number of rows
348217ab2063SBarry Smith .  n - number of columns
348317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
348451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
34850298fd71SBarry Smith          (possibly different for each row) or NULL
348617ab2063SBarry Smith 
348717ab2063SBarry Smith    Output Parameter:
3488416022c9SBarry Smith .  A - the matrix
348917ab2063SBarry Smith 
3490175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3491ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3492175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3493175b88e8SBarry Smith 
3494b259b22eSLois Curfman McInnes    Notes:
349549a6f317SBarry Smith    If nnz is given then nz is ignored
349649a6f317SBarry Smith 
349717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
349817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
34990002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
350044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
350117ab2063SBarry Smith 
350217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35030298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
35043d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
35056da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
350617ab2063SBarry Smith 
3507682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
35084fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3509682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
35106c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
35116c7ebb05SLois Curfman McInnes 
35126c7ebb05SLois Curfman McInnes    Options Database Keys:
3513698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
35149db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
351517ab2063SBarry Smith 
3516027ccd11SLois Curfman McInnes    Level: intermediate
3517027ccd11SLois Curfman McInnes 
351869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
351936db0b34SBarry Smith 
352017ab2063SBarry Smith @*/
35217087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
352217ab2063SBarry Smith {
3523dfbe8321SBarry Smith   PetscErrorCode ierr;
35246945ee14SBarry Smith 
35253a40ed3dSBarry Smith   PetscFunctionBegin;
3526f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3527117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3528c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3529d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3530273d9f13SBarry Smith   PetscFunctionReturn(0);
3531273d9f13SBarry Smith }
3532273d9f13SBarry Smith 
35334a2ae208SSatish Balay #undef __FUNCT__
35344a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3535273d9f13SBarry Smith /*@C
3536273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3537273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3538273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3539273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3540273d9f13SBarry Smith 
3541273d9f13SBarry Smith    Collective on MPI_Comm
3542273d9f13SBarry Smith 
3543273d9f13SBarry Smith    Input Parameters:
3544117016b1SBarry Smith +  B - The matrix-free
3545273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3546273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35470298fd71SBarry Smith          (possibly different for each row) or NULL
3548273d9f13SBarry Smith 
3549273d9f13SBarry Smith    Notes:
355049a6f317SBarry Smith      If nnz is given then nz is ignored
355149a6f317SBarry Smith 
3552273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3553273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3554273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3555273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3556273d9f13SBarry Smith 
3557273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
35580298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3559273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3560273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3561273d9f13SBarry Smith 
3562aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3563aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3564aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3565aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3566aa95bbe8SBarry Smith 
3567a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3568a96a251dSBarry Smith    entries or columns indices
3569a96a251dSBarry Smith 
3570273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3571273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3572273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3573273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3574273d9f13SBarry Smith 
3575273d9f13SBarry Smith    Options Database Keys:
3576698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3577698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3578273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3579273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3580273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3581273d9f13SBarry Smith 
3582273d9f13SBarry Smith    Level: intermediate
3583273d9f13SBarry Smith 
358469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3585273d9f13SBarry Smith 
3586273d9f13SBarry Smith @*/
35877087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3588273d9f13SBarry Smith {
35894ac538c5SBarry Smith   PetscErrorCode ierr;
3590a23d5eceSKris Buschelman 
3591a23d5eceSKris Buschelman   PetscFunctionBegin;
35926ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
35936ba663aaSJed Brown   PetscValidType(B,1);
35944ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3595a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3596a23d5eceSKris Buschelman }
3597a23d5eceSKris Buschelman 
3598a23d5eceSKris Buschelman #undef __FUNCT__
3599a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
36007087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3601a23d5eceSKris Buschelman {
3602273d9f13SBarry Smith   Mat_SeqAIJ     *b;
36032576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
36046849ba73SBarry Smith   PetscErrorCode ierr;
360597f1f81fSBarry Smith   PetscInt       i;
3606273d9f13SBarry Smith 
3607273d9f13SBarry Smith   PetscFunctionBegin;
36082576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3609a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3610c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3611c461c341SBarry Smith     nz             = 0;
3612c461c341SBarry Smith   }
3613c461c341SBarry Smith 
361426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
361526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3616899cda47SBarry Smith 
3617435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3618e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3619b73539f3SBarry Smith   if (nnz) {
3620d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3621e32f2f54SBarry 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]);
3622e32f2f54SBarry 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);
3623b73539f3SBarry Smith     }
3624b73539f3SBarry Smith   }
3625b73539f3SBarry Smith 
3626273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
36272205254eSKarl Rupp 
3628273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3629273d9f13SBarry Smith 
3630ab93d7beSBarry Smith   if (!skipallocation) {
36312ee49352SLisandro Dalcin     if (!b->imax) {
3632dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
36333bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
36342ee49352SLisandro Dalcin     }
3635273d9f13SBarry Smith     if (!nnz) {
3636435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3637c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3638d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3639d0f46423SBarry Smith       nz = nz*B->rmap->n;
3640273d9f13SBarry Smith     } else {
3641273d9f13SBarry Smith       nz = 0;
3642d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3643273d9f13SBarry Smith     }
3644ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
36452205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3646ab93d7beSBarry Smith 
3647273d9f13SBarry Smith     /* allocate the matrix space */
36482ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3649dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
36503bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3651bfeeae90SHong Zhang     b->i[0] = 0;
3652d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
36535da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
36545da197adSKris Buschelman     }
3655273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3656e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3657e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3658b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3659b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3660b31eba2aSShri Abhyankar #endif
3661c461c341SBarry Smith   } else {
3662e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3663e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3664c461c341SBarry Smith   }
3665273d9f13SBarry Smith 
3666273d9f13SBarry Smith   b->nz               = 0;
3667273d9f13SBarry Smith   b->maxnz            = nz;
3668273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
36692205254eSKarl Rupp   if (realalloc) {
36702205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
36712205254eSKarl Rupp   }
3672273d9f13SBarry Smith   PetscFunctionReturn(0);
3673273d9f13SBarry Smith }
3674273d9f13SBarry Smith 
3675a1661176SMatthew Knepley #undef  __FUNCT__
3676a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
367758d36128SBarry Smith /*@
3678a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3679a1661176SMatthew Knepley 
3680a1661176SMatthew Knepley    Input Parameters:
3681a1661176SMatthew Knepley +  B - the matrix
3682a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3683a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3684a1661176SMatthew Knepley -  v - optional values in the matrix
3685a1661176SMatthew Knepley 
3686a1661176SMatthew Knepley    Level: developer
3687a1661176SMatthew Knepley 
368858d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
368958d36128SBarry Smith 
3690a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3691a1661176SMatthew Knepley 
3692a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3693a1661176SMatthew Knepley @*/
3694a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3695a1661176SMatthew Knepley {
3696a1661176SMatthew Knepley   PetscErrorCode ierr;
3697a1661176SMatthew Knepley 
3698a1661176SMatthew Knepley   PetscFunctionBegin;
36990700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
37006ba663aaSJed Brown   PetscValidType(B,1);
37014ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3702a1661176SMatthew Knepley   PetscFunctionReturn(0);
3703a1661176SMatthew Knepley }
3704a1661176SMatthew Knepley 
3705a1661176SMatthew Knepley #undef  __FUNCT__
3706a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
37077087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3708a1661176SMatthew Knepley {
3709a1661176SMatthew Knepley   PetscInt       i;
3710a1661176SMatthew Knepley   PetscInt       m,n;
3711a1661176SMatthew Knepley   PetscInt       nz;
3712a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3713a1661176SMatthew Knepley   PetscScalar    *values;
3714a1661176SMatthew Knepley   PetscErrorCode ierr;
3715a1661176SMatthew Knepley 
3716a1661176SMatthew Knepley   PetscFunctionBegin;
371765e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3718779a8d59SSatish Balay 
3719779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3720779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3721779a8d59SSatish Balay 
3722779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3723785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3724a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3725b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3726a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
372765e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3728a1661176SMatthew Knepley     nnz[i] = nz;
3729a1661176SMatthew Knepley   }
3730a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3731a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3732a1661176SMatthew Knepley 
3733a1661176SMatthew Knepley   if (v) {
3734a1661176SMatthew Knepley     values = (PetscScalar*) v;
3735a1661176SMatthew Knepley   } else {
37361795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3737a1661176SMatthew Knepley   }
3738a1661176SMatthew Knepley 
3739a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3740b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3741b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3742a1661176SMatthew Knepley   }
3743a1661176SMatthew Knepley 
3744a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3745a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3746a1661176SMatthew Knepley 
3747a1661176SMatthew Knepley   if (!v) {
3748a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3749a1661176SMatthew Knepley   }
37507827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3751a1661176SMatthew Knepley   PetscFunctionReturn(0);
3752a1661176SMatthew Knepley }
3753a1661176SMatthew Knepley 
3754c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
375506873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3756170fe5c8SBarry Smith 
3757170fe5c8SBarry Smith #undef __FUNCT__
3758170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3759170fe5c8SBarry Smith /*
3760170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3761170fe5c8SBarry Smith 
3762170fe5c8SBarry Smith                n                       p                          p
3763170fe5c8SBarry Smith         (              )       (              )         (                  )
3764170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3765170fe5c8SBarry Smith         (              )       (              )         (                  )
3766170fe5c8SBarry Smith 
3767170fe5c8SBarry Smith */
3768170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3769170fe5c8SBarry Smith {
3770170fe5c8SBarry Smith   PetscErrorCode    ierr;
3771170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3772170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3773170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
37741de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3775170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3776170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3777170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3778170fe5c8SBarry Smith 
3779170fe5c8SBarry Smith   PetscFunctionBegin;
3780d0f46423SBarry Smith   m    = A->rmap->n;
3781d0f46423SBarry Smith   n    = A->cmap->n;
3782d0f46423SBarry Smith   p    = B->cmap->n;
3783170fe5c8SBarry Smith   a    = sub_a->v;
3784170fe5c8SBarry Smith   b    = sub_b->a;
3785170fe5c8SBarry Smith   c    = sub_c->v;
3786170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3787170fe5c8SBarry Smith 
3788170fe5c8SBarry Smith   ii  = sub_b->i;
3789170fe5c8SBarry Smith   idx = sub_b->j;
3790170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3791170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3792170fe5c8SBarry Smith     while (q-->0) {
3793170fe5c8SBarry Smith       c_q = c + m*(*idx);
3794170fe5c8SBarry Smith       a_q = a + m*i;
3795854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3796170fe5c8SBarry Smith       idx++;
3797170fe5c8SBarry Smith       b++;
3798170fe5c8SBarry Smith     }
3799170fe5c8SBarry Smith   }
3800170fe5c8SBarry Smith   PetscFunctionReturn(0);
3801170fe5c8SBarry Smith }
3802170fe5c8SBarry Smith 
3803170fe5c8SBarry Smith #undef __FUNCT__
3804170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3805170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3806170fe5c8SBarry Smith {
3807170fe5c8SBarry Smith   PetscErrorCode ierr;
3808d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3809170fe5c8SBarry Smith   Mat            Cmat;
3810170fe5c8SBarry Smith 
3811170fe5c8SBarry Smith   PetscFunctionBegin;
3812e32f2f54SBarry 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);
3813ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3814170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3815a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3816170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
38170298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3818d73949e8SHong Zhang 
3819d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
38202205254eSKarl Rupp 
3821170fe5c8SBarry Smith   *C = Cmat;
3822170fe5c8SBarry Smith   PetscFunctionReturn(0);
3823170fe5c8SBarry Smith }
3824170fe5c8SBarry Smith 
3825170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3826170fe5c8SBarry Smith #undef __FUNCT__
3827170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3828170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3829170fe5c8SBarry Smith {
3830170fe5c8SBarry Smith   PetscErrorCode ierr;
3831170fe5c8SBarry Smith 
3832170fe5c8SBarry Smith   PetscFunctionBegin;
3833170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
38343ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3835170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
38363ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3837170fe5c8SBarry Smith   }
38383ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3839170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
38403ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3841170fe5c8SBarry Smith   PetscFunctionReturn(0);
3842170fe5c8SBarry Smith }
3843170fe5c8SBarry Smith 
3844170fe5c8SBarry Smith 
38450bad9183SKris Buschelman /*MC
3846fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
38470bad9183SKris Buschelman    based on compressed sparse row format.
38480bad9183SKris Buschelman 
38490bad9183SKris Buschelman    Options Database Keys:
38500bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
38510bad9183SKris Buschelman 
38520bad9183SKris Buschelman   Level: beginner
38530bad9183SKris Buschelman 
3854f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
38550bad9183SKris Buschelman M*/
38560bad9183SKris Buschelman 
3857ccd284c7SBarry Smith /*MC
3858ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3859ccd284c7SBarry Smith 
3860ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3861ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3862ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3863ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3864ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3865ccd284c7SBarry Smith 
3866ccd284c7SBarry Smith    Options Database Keys:
3867ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3868ccd284c7SBarry Smith 
3869ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3870ccd284c7SBarry Smith    enough exist.
3871ccd284c7SBarry Smith 
3872ccd284c7SBarry Smith   Level: beginner
3873ccd284c7SBarry Smith 
3874ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3875ccd284c7SBarry Smith M*/
3876ccd284c7SBarry Smith 
3877ccd284c7SBarry Smith /*MC
3878ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3879ccd284c7SBarry Smith 
3880ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3881ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3882ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3883ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3884ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3885ccd284c7SBarry Smith 
3886ccd284c7SBarry Smith    Options Database Keys:
3887ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
3888ccd284c7SBarry Smith 
3889ccd284c7SBarry Smith   Level: beginner
3890ccd284c7SBarry Smith 
3891ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
3892ccd284c7SBarry Smith M*/
3893ccd284c7SBarry Smith 
3894b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
38958cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
3896b5e56a35SBarry Smith #endif
3897ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
38988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
3899af1023dbSSatish Balay #endif
39008cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
39018cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
39028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
39037087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
3904611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
39058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
3906611f576cSBarry Smith #endif
3907611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
39088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
3909611f576cSBarry Smith #endif
3910f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
39118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
3912f3c0ef26SHong Zhang #endif
3913eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
39148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
3915eb3b5408SSatish Balay #endif
3916586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
39178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
3918586621ddSJed Brown #endif
3919719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
39208cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
3921719d5645SBarry Smith #endif
3922b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
39238cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
39247087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
39257087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
3926b3866ffcSBarry Smith #endif
392717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
39288cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
392917f1a0eaSHong Zhang #endif
393017667f90SBarry Smith 
3931c0c8ee5eSDmitry Karpeev 
39328c778c55SBarry Smith #undef __FUNCT__
39338c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
39348c778c55SBarry Smith /*@C
39358c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
39368c778c55SBarry Smith 
39378c778c55SBarry Smith    Not Collective
39388c778c55SBarry Smith 
39398c778c55SBarry Smith    Input Parameter:
39408c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39418c778c55SBarry Smith 
39428c778c55SBarry Smith    Output Parameter:
39438c778c55SBarry Smith .   array - pointer to the data
39448c778c55SBarry Smith 
39458c778c55SBarry Smith    Level: intermediate
39468c778c55SBarry Smith 
3947774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
39488c778c55SBarry Smith @*/
39498c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
39508c778c55SBarry Smith {
39518c778c55SBarry Smith   PetscErrorCode ierr;
39528c778c55SBarry Smith 
39538c778c55SBarry Smith   PetscFunctionBegin;
39548c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39558c778c55SBarry Smith   PetscFunctionReturn(0);
39568c778c55SBarry Smith }
39578c778c55SBarry Smith 
39588c778c55SBarry Smith #undef __FUNCT__
39598c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
39608c778c55SBarry Smith /*@C
39618c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
39628c778c55SBarry Smith 
39638c778c55SBarry Smith    Not Collective
39648c778c55SBarry Smith 
39658c778c55SBarry Smith    Input Parameters:
39668c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
39678c778c55SBarry Smith .  array - pointer to the data
39688c778c55SBarry Smith 
39698c778c55SBarry Smith    Level: intermediate
39708c778c55SBarry Smith 
3971774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
39728c778c55SBarry Smith @*/
39738c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
39748c778c55SBarry Smith {
39758c778c55SBarry Smith   PetscErrorCode ierr;
39768c778c55SBarry Smith 
39778c778c55SBarry Smith   PetscFunctionBegin;
39788c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
39798c778c55SBarry Smith   PetscFunctionReturn(0);
39808c778c55SBarry Smith }
39818c778c55SBarry Smith 
39824a2ae208SSatish Balay #undef __FUNCT__
39834a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
39848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
3985273d9f13SBarry Smith {
3986273d9f13SBarry Smith   Mat_SeqAIJ     *b;
3987dfbe8321SBarry Smith   PetscErrorCode ierr;
398838baddfdSBarry Smith   PetscMPIInt    size;
3989273d9f13SBarry Smith 
3990273d9f13SBarry Smith   PetscFunctionBegin;
3991ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3992e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
3993273d9f13SBarry Smith 
3994b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
39952205254eSKarl Rupp 
3996b0a32e0cSBarry Smith   B->data = (void*)b;
39972205254eSKarl Rupp 
3998549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
39992205254eSKarl Rupp 
4000416022c9SBarry Smith   b->row                = 0;
4001416022c9SBarry Smith   b->col                = 0;
400282bf6240SBarry Smith   b->icol               = 0;
4003b810aeb4SBarry Smith   b->reallocs           = 0;
400436db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4005f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4006416022c9SBarry Smith   b->nonew              = 0;
4007416022c9SBarry Smith   b->diag               = 0;
4008416022c9SBarry Smith   b->solve_work         = 0;
40092a1b7f2aSHong Zhang   B->spptr              = 0;
4010be6bf707SBarry Smith   b->saved_values       = 0;
4011d7f994e1SBarry Smith   b->idiag              = 0;
401271f1c65dSBarry Smith   b->mdiag              = 0;
401371f1c65dSBarry Smith   b->ssor_work          = 0;
401471f1c65dSBarry Smith   b->omega              = 1.0;
401571f1c65dSBarry Smith   b->fshift             = 0.0;
401671f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4017bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4018a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
4019a30b2313SHong Zhang   b->xtoy               = 0;
4020a30b2313SHong Zhang   b->XtoY               = 0;
402188e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
402217ab2063SBarry Smith 
402335d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4024bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
40268c778c55SBarry Smith 
4027b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4028bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4031b3866ffcSBarry Smith #endif
4032b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4033bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4034b5e56a35SBarry Smith #endif
4035ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4036bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4037719d5645SBarry Smith #endif
4038611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4040611f576cSBarry Smith #endif
4041f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4043f3c0ef26SHong Zhang #endif
4044611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4045bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4046611f576cSBarry Smith #endif
4047eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4048bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4049eb3b5408SSatish Balay #endif
4050586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4052586621ddSJed Brown #endif
4053719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4055719d5645SBarry Smith #endif
405617f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
405817f1a0eaSHong Zhang #endif
405917f1a0eaSHong Zhang 
4060bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4061bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4062bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4063bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4064bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4065bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4066bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4067bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4068bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4069bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4070bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4071bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4072bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4073bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4074bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4075bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4076bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4077bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
40784108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
407917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
40803a40ed3dSBarry Smith   PetscFunctionReturn(0);
408117ab2063SBarry Smith }
408217ab2063SBarry Smith 
40834a2ae208SSatish Balay #undef __FUNCT__
4084b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4085b24902e0SBarry Smith /*
4086b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4087b24902e0SBarry Smith */
4088ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
408917ab2063SBarry Smith {
4090416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
40916849ba73SBarry Smith   PetscErrorCode ierr;
4092d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
409317ab2063SBarry Smith 
40943a40ed3dSBarry Smith   PetscFunctionBegin;
4095273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4096273d9f13SBarry Smith 
4097d5f3da31SBarry Smith   C->factortype = A->factortype;
4098416022c9SBarry Smith   c->row        = 0;
4099416022c9SBarry Smith   c->col        = 0;
410082bf6240SBarry Smith   c->icol       = 0;
41016ad4291fSHong Zhang   c->reallocs   = 0;
410217ab2063SBarry Smith 
41036ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
410417ab2063SBarry Smith 
4105aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4106aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4107eec197d1SBarry Smith 
4108dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
41093bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
411017ab2063SBarry Smith   for (i=0; i<m; i++) {
4111416022c9SBarry Smith     c->imax[i] = a->imax[i];
4112416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
411317ab2063SBarry Smith   }
411417ab2063SBarry Smith 
411517ab2063SBarry Smith   /* allocate the matrix space */
4116f77e22a1SHong Zhang   if (mallocmatspace) {
4117dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
41183bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
41192205254eSKarl Rupp 
4120f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
41212205254eSKarl Rupp 
412297f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
412317ab2063SBarry Smith     if (m > 0) {
412497f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4125be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4126bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4127be6bf707SBarry Smith       } else {
4128bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
412917ab2063SBarry Smith       }
413008480c60SBarry Smith     }
4131f77e22a1SHong Zhang   }
413217ab2063SBarry Smith 
41336ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4134416022c9SBarry Smith   c->roworiented       = a->roworiented;
4135416022c9SBarry Smith   c->nonew             = a->nonew;
4136416022c9SBarry Smith   if (a->diag) {
4137785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
41383bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
413917ab2063SBarry Smith     for (i=0; i<m; i++) {
4140416022c9SBarry Smith       c->diag[i] = a->diag[i];
414117ab2063SBarry Smith     }
41423a40ed3dSBarry Smith   } else c->diag = 0;
41432205254eSKarl Rupp 
41446ad4291fSHong Zhang   c->solve_work         = 0;
41456ad4291fSHong Zhang   c->saved_values       = 0;
41466ad4291fSHong Zhang   c->idiag              = 0;
414771f1c65dSBarry Smith   c->ssor_work          = 0;
4148a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4149e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4150e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
41516ad4291fSHong Zhang   c->xtoy               = 0;
41526ad4291fSHong Zhang   c->XtoY               = 0;
41536ad4291fSHong Zhang 
4154893ad86cSHong Zhang   c->rmax         = a->rmax;
4155416022c9SBarry Smith   c->nz           = a->nz;
41568ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4157273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4158754ec7b1SSatish Balay 
41596ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
41606ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4161cd6b891eSBarry Smith   if (a->compressedrow.use) {
41626ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4163dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
41646ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
41656ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
416627ea64f8SHong Zhang   } else {
416727ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
41680298fd71SBarry Smith     c->compressedrow.i      = NULL;
41690298fd71SBarry Smith     c->compressedrow.rindex = NULL;
41706ad4291fSHong Zhang   }
417188e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
41724846f1f5SKris Buschelman 
41732205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4174140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
41753a40ed3dSBarry Smith   PetscFunctionReturn(0);
417617ab2063SBarry Smith }
417717ab2063SBarry Smith 
41784a2ae208SSatish Balay #undef __FUNCT__
4179b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4180b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4181b24902e0SBarry Smith {
4182b24902e0SBarry Smith   PetscErrorCode ierr;
4183b24902e0SBarry Smith 
4184b24902e0SBarry Smith   PetscFunctionBegin;
4185ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
41864b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4187cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
4188a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4189cfd3f464SBarry Smith   }
4190a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4191f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4192b24902e0SBarry Smith   PetscFunctionReturn(0);
4193b24902e0SBarry Smith }
4194b24902e0SBarry Smith 
4195b24902e0SBarry Smith #undef __FUNCT__
41964a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4197112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4198fbdbba38SShri Abhyankar {
4199fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4200fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4201fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4202fbdbba38SShri Abhyankar   int            fd;
4203fbdbba38SShri Abhyankar   PetscMPIInt    size;
4204fbdbba38SShri Abhyankar   MPI_Comm       comm;
4205bbead8a2SBarry Smith   PetscInt       bs = 1;
4206fbdbba38SShri Abhyankar 
4207fbdbba38SShri Abhyankar   PetscFunctionBegin;
4208fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4209fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4210fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4211bbead8a2SBarry Smith 
42120298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
42130298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4214bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
42151814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4216bbead8a2SBarry Smith 
4217fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4218fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4219fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4220fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4221fbdbba38SShri Abhyankar 
4222bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4223fbdbba38SShri Abhyankar 
4224fbdbba38SShri Abhyankar   /* read in row lengths */
4225785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4226fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4227fbdbba38SShri Abhyankar 
4228fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4229fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4230fbdbba38SShri 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);
4231fbdbba38SShri Abhyankar 
4232fbdbba38SShri Abhyankar   /* set global size if not set already*/
4233f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4234fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4235aabbc4fbSShri Abhyankar   } else {
4236fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4237fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
42384c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
42394c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
42404c5b953cSHong Zhang     }
4241f501eaabSShri 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);
4242aabbc4fbSShri Abhyankar   }
4243fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4244fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4245fbdbba38SShri Abhyankar 
4246fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4247fbdbba38SShri Abhyankar 
4248fbdbba38SShri Abhyankar   /* read in nonzero values */
4249fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4250fbdbba38SShri Abhyankar 
4251fbdbba38SShri Abhyankar   /* set matrix "i" values */
4252fbdbba38SShri Abhyankar   a->i[0] = 0;
4253fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4254fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4255fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4256fbdbba38SShri Abhyankar   }
4257fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4258fbdbba38SShri Abhyankar 
4259fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4260fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4261fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4262fbdbba38SShri Abhyankar }
4263fbdbba38SShri Abhyankar 
4264fbdbba38SShri Abhyankar #undef __FUNCT__
4265b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4266ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
42677264ac53SSatish Balay {
42687264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4269dfbe8321SBarry Smith   PetscErrorCode ierr;
4270eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4271eeffb40dSHong Zhang   PetscInt k;
4272eeffb40dSHong Zhang #endif
42737264ac53SSatish Balay 
42743a40ed3dSBarry Smith   PetscFunctionBegin;
4275bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4276d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4277ca44d042SBarry Smith     *flg = PETSC_FALSE;
4278ca44d042SBarry Smith     PetscFunctionReturn(0);
4279bcd2baecSBarry Smith   }
42807264ac53SSatish Balay 
42817264ac53SSatish Balay   /* if the a->i are the same */
4282d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4283abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
42847264ac53SSatish Balay 
42857264ac53SSatish Balay   /* if a->j are the same */
428697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4287abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4288bcd2baecSBarry Smith 
4289bcd2baecSBarry Smith   /* if a->a are the same */
4290eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4291eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4292eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4293eeffb40dSHong Zhang       *flg = PETSC_FALSE;
42943a40ed3dSBarry Smith       PetscFunctionReturn(0);
4295eeffb40dSHong Zhang     }
4296eeffb40dSHong Zhang   }
4297eeffb40dSHong Zhang #else
4298eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4299eeffb40dSHong Zhang #endif
4300eeffb40dSHong Zhang   PetscFunctionReturn(0);
43017264ac53SSatish Balay }
430236db0b34SBarry Smith 
43034a2ae208SSatish Balay #undef __FUNCT__
43044a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
430505869f15SSatish Balay /*@
430636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
430736db0b34SBarry Smith               provided by the user.
430836db0b34SBarry Smith 
4309c75a6043SHong Zhang       Collective on MPI_Comm
431036db0b34SBarry Smith 
431136db0b34SBarry Smith    Input Parameters:
431236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
431336db0b34SBarry Smith .   m - number of rows
431436db0b34SBarry Smith .   n - number of columns
431536db0b34SBarry Smith .   i - row indices
431636db0b34SBarry Smith .   j - column indices
431736db0b34SBarry Smith -   a - matrix values
431836db0b34SBarry Smith 
431936db0b34SBarry Smith    Output Parameter:
432036db0b34SBarry Smith .   mat - the matrix
432136db0b34SBarry Smith 
432236db0b34SBarry Smith    Level: intermediate
432336db0b34SBarry Smith 
432436db0b34SBarry Smith    Notes:
43250551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4326292fb18eSBarry Smith     once the matrix is destroyed and not before
432736db0b34SBarry Smith 
432836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
432936db0b34SBarry Smith 
4330bfeeae90SHong Zhang        The i and j indices are 0 based
433136db0b34SBarry Smith 
4332a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4333a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4334a4552177SSatish Balay     as shown:
4335a4552177SSatish Balay 
4336a4552177SSatish Balay         1 0 0
4337a4552177SSatish Balay         2 0 3
4338a4552177SSatish Balay         4 5 6
4339a4552177SSatish Balay 
4340a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
43419985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4342a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4343a4552177SSatish Balay 
43449985e31cSBarry Smith 
434569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
434636db0b34SBarry Smith 
434736db0b34SBarry Smith @*/
43487087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
434936db0b34SBarry Smith {
4350dfbe8321SBarry Smith   PetscErrorCode ierr;
4351cbcfb4deSHong Zhang   PetscInt       ii;
435236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4353cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4354cbcfb4deSHong Zhang   PetscInt jj;
4355cbcfb4deSHong Zhang #endif
435636db0b34SBarry Smith 
435736db0b34SBarry Smith   PetscFunctionBegin;
4358f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4359f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4360f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4361a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4362ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4363ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4364ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4365dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4366ab93d7beSBarry Smith 
436736db0b34SBarry Smith   aij->i            = i;
436836db0b34SBarry Smith   aij->j            = j;
436936db0b34SBarry Smith   aij->a            = a;
437036db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
437136db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4372e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4373e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
437436db0b34SBarry Smith 
437536db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
437636db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
43772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4378e32f2f54SBarry 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]);
43799985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4380e32f2f54SBarry 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);
4381e32f2f54SBarry 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);
43829985e31cSBarry Smith     }
438336db0b34SBarry Smith #endif
438436db0b34SBarry Smith   }
43852515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
438636db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4387e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4388e32f2f54SBarry 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]);
438936db0b34SBarry Smith   }
439036db0b34SBarry Smith #endif
439136db0b34SBarry Smith 
4392b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4393b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
439436db0b34SBarry Smith   PetscFunctionReturn(0);
439536db0b34SBarry Smith }
43968a0b0e6bSVictor Minden #undef __FUNCT__
43978a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
439880ef6e79SMatthew G Knepley /*@C
4399d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
44008a0b0e6bSVictor Minden               provided by the user.
44018a0b0e6bSVictor Minden 
44028a0b0e6bSVictor Minden       Collective on MPI_Comm
44038a0b0e6bSVictor Minden 
44048a0b0e6bSVictor Minden    Input Parameters:
44058a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
44068a0b0e6bSVictor Minden .   m   - number of rows
44078a0b0e6bSVictor Minden .   n   - number of columns
44088a0b0e6bSVictor Minden .   i   - row indices
44098a0b0e6bSVictor Minden .   j   - column indices
44101230e6d1SVictor Minden .   a   - matrix values
44111230e6d1SVictor Minden .   nz  - number of nonzeros
44121230e6d1SVictor Minden -   idx - 0 or 1 based
44138a0b0e6bSVictor Minden 
44148a0b0e6bSVictor Minden    Output Parameter:
44158a0b0e6bSVictor Minden .   mat - the matrix
44168a0b0e6bSVictor Minden 
44178a0b0e6bSVictor Minden    Level: intermediate
44188a0b0e6bSVictor Minden 
44198a0b0e6bSVictor Minden    Notes:
44208a0b0e6bSVictor Minden        The i and j indices are 0 based
44218a0b0e6bSVictor Minden 
44228a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
44238a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
44248a0b0e6bSVictor Minden     as shown:
44258a0b0e6bSVictor Minden 
44268a0b0e6bSVictor Minden         1 0 0
44278a0b0e6bSVictor Minden         2 0 3
44288a0b0e6bSVictor Minden         4 5 6
44298a0b0e6bSVictor Minden 
44308a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
44318a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
44328a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
44338a0b0e6bSVictor Minden 
44348a0b0e6bSVictor Minden 
443569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
44368a0b0e6bSVictor Minden 
44378a0b0e6bSVictor Minden @*/
44381230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
44398a0b0e6bSVictor Minden {
44408a0b0e6bSVictor Minden   PetscErrorCode ierr;
4441d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
44428a0b0e6bSVictor Minden 
44438a0b0e6bSVictor Minden 
44448a0b0e6bSVictor Minden   PetscFunctionBegin;
44451795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
44461230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4447c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
44481230e6d1SVictor Minden   }
44498a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
44508a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
44518a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
44521230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
44531230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
44541230e6d1SVictor Minden     if (idx) {
44551230e6d1SVictor Minden       row = i[ii] - 1;
44561230e6d1SVictor Minden       col = j[ii] - 1;
44571230e6d1SVictor Minden     } else {
44581230e6d1SVictor Minden       row = i[ii];
44591230e6d1SVictor Minden       col = j[ii];
44608a0b0e6bSVictor Minden     }
44611230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
44628a0b0e6bSVictor Minden   }
44638a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
44648a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4465d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
44668a0b0e6bSVictor Minden   PetscFunctionReturn(0);
44678a0b0e6bSVictor Minden }
446836db0b34SBarry Smith 
4469cc8ba8e1SBarry Smith #undef __FUNCT__
4470ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4471dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4472cc8ba8e1SBarry Smith {
4473dfbe8321SBarry Smith   PetscErrorCode ierr;
4474cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
447536db0b34SBarry Smith 
4476cc8ba8e1SBarry Smith   PetscFunctionBegin;
44778ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4478cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4479cc8ba8e1SBarry Smith     a->coloring = coloring;
448012c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
448197f1f81fSBarry Smith     PetscInt        i,*larray;
448212c595b3SBarry Smith     ISColoring      ocoloring;
448308b6dcc0SBarry Smith     ISColoringValue *colors;
448412c595b3SBarry Smith 
448512c595b3SBarry Smith     /* set coloring for diagonal portion */
4486785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
44872205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
44880298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4489785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
44902205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
449112c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4492d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
449312c595b3SBarry Smith     a->coloring = ocoloring;
449412c595b3SBarry Smith   }
4495cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4496cc8ba8e1SBarry Smith }
4497cc8ba8e1SBarry Smith 
4498ee4f033dSBarry Smith #undef __FUNCT__
4499ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
450097f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4501ee4f033dSBarry Smith {
4502ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4503d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
450454f21887SBarry Smith   MatScalar       *v      = a->a;
450554f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
450608b6dcc0SBarry Smith   ISColoringValue *color;
4507ee4f033dSBarry Smith 
4508ee4f033dSBarry Smith   PetscFunctionBegin;
4509e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4510ee4f033dSBarry Smith   color = a->coloring->colors;
4511ee4f033dSBarry Smith   /* loop over rows */
4512ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4513ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4514ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
45152205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4516ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4517cc8ba8e1SBarry Smith   }
4518cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4519cc8ba8e1SBarry Smith }
452036db0b34SBarry Smith 
4521acf2f550SJed Brown #undef __FUNCT__
4522acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4523acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4524acf2f550SJed Brown {
4525acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4526acf2f550SJed Brown   PetscErrorCode ierr;
4527acf2f550SJed Brown 
4528acf2f550SJed Brown   PetscFunctionBegin;
4529acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4530acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
45312205254eSKarl Rupp 
4532acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4533acf2f550SJed Brown   PetscFunctionReturn(0);
4534acf2f550SJed Brown }
4535acf2f550SJed Brown 
453681824310SBarry Smith /*
453781824310SBarry Smith     Special version for direct calls from Fortran
453881824310SBarry Smith */
4539b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
454081824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
454181824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
454281824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
454381824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
454481824310SBarry Smith #endif
454581824310SBarry Smith 
454681824310SBarry Smith /* Change these macros so can be used in void function */
454781824310SBarry Smith #undef CHKERRQ
4548ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
454981824310SBarry Smith #undef SETERRQ2
4550e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
45514994cf47SJed Brown #undef SETERRQ3
45524994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
455381824310SBarry Smith 
455481824310SBarry Smith #undef __FUNCT__
455581824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
45568cc058d9SJed 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)
455781824310SBarry Smith {
455881824310SBarry Smith   Mat            A  = *AA;
455981824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
456081824310SBarry Smith   InsertMode     is = *isis;
456181824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
456281824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
456381824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
456481824310SBarry Smith   PetscErrorCode ierr;
456581824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
456654f21887SBarry Smith   MatScalar      *ap,value,*aa;
4567ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4568ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
456981824310SBarry Smith 
457081824310SBarry Smith   PetscFunctionBegin;
45714994cf47SJed Brown   MatCheckPreallocated(A,1);
457281824310SBarry Smith   imax  = a->imax;
457381824310SBarry Smith   ai    = a->i;
457481824310SBarry Smith   ailen = a->ilen;
457581824310SBarry Smith   aj    = a->j;
457681824310SBarry Smith   aa    = a->a;
457781824310SBarry Smith 
457881824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
457981824310SBarry Smith     row = im[k];
458081824310SBarry Smith     if (row < 0) continue;
458181824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4582ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
458381824310SBarry Smith #endif
458481824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
458581824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
458681824310SBarry Smith     low  = 0;
458781824310SBarry Smith     high = nrow;
458881824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
458981824310SBarry Smith       if (in[l] < 0) continue;
459081824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4591ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
459281824310SBarry Smith #endif
459381824310SBarry Smith       col = in[l];
45942205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
45952205254eSKarl Rupp       else value = v[k + l*m];
45962205254eSKarl Rupp 
459781824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
459881824310SBarry Smith 
45992205254eSKarl Rupp       if (col <= lastcol) low = 0;
46002205254eSKarl Rupp       else high = nrow;
460181824310SBarry Smith       lastcol = col;
460281824310SBarry Smith       while (high-low > 5) {
460381824310SBarry Smith         t = (low+high)/2;
460481824310SBarry Smith         if (rp[t] > col) high = t;
460581824310SBarry Smith         else             low  = t;
460681824310SBarry Smith       }
460781824310SBarry Smith       for (i=low; i<high; i++) {
460881824310SBarry Smith         if (rp[i] > col) break;
460981824310SBarry Smith         if (rp[i] == col) {
461081824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
461181824310SBarry Smith           else                  ap[i] = value;
461281824310SBarry Smith           goto noinsert;
461381824310SBarry Smith         }
461481824310SBarry Smith       }
461581824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
461681824310SBarry Smith       if (nonew == 1) goto noinsert;
4617ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4618fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
461981824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
462081824310SBarry Smith       /* shift up all the later entries in this row */
462181824310SBarry Smith       for (ii=N; ii>=i; ii--) {
462281824310SBarry Smith         rp[ii+1] = rp[ii];
462381824310SBarry Smith         ap[ii+1] = ap[ii];
462481824310SBarry Smith       }
462581824310SBarry Smith       rp[i] = col;
462681824310SBarry Smith       ap[i] = value;
462781824310SBarry Smith noinsert:;
462881824310SBarry Smith       low = i + 1;
462981824310SBarry Smith     }
463081824310SBarry Smith     ailen[row] = nrow;
463181824310SBarry Smith   }
463281824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
463381824310SBarry Smith   PetscFunctionReturnVoid();
463481824310SBarry Smith }
46359f7953f8SBarry Smith 
463662298a1eSBarry Smith 
4637