xref: /petsc/src/mat/impls/aij/seq/aij.c (revision f38dd0b868460da6d675826b02be25a07dcbce12)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
1106873bf2SBarry Smith #include <petsc-private/kernels/blocktranspose.h>
1278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1378b84d54SShri Abhyankar #include <petscthreadcomm.h>
1478b84d54SShri Abhyankar #endif
150716a85fSBarry Smith 
160716a85fSBarry Smith #undef __FUNCT__
170716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
180716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
190716a85fSBarry Smith {
200716a85fSBarry Smith   PetscErrorCode ierr;
210716a85fSBarry Smith   PetscInt       i,m,n;
220716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
230716a85fSBarry Smith 
240716a85fSBarry Smith   PetscFunctionBegin;
250716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
260716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
270716a85fSBarry Smith   if (type == NORM_2) {
280716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
290716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
300716a85fSBarry Smith     }
310716a85fSBarry Smith   } else if (type == NORM_1) {
320716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
330716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
340716a85fSBarry Smith     }
350716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
360716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
370716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
380716a85fSBarry Smith     }
390716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
400716a85fSBarry Smith 
410716a85fSBarry Smith   if (type == NORM_2) {
428f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
430716a85fSBarry Smith   }
440716a85fSBarry Smith   PetscFunctionReturn(0);
450716a85fSBarry Smith }
460716a85fSBarry Smith 
474a2ae208SSatish Balay #undef __FUNCT__
483a062f41SBarry Smith #define __FUNCT__ "MatFindOffBlockDiagonalEntries_SeqAIJ"
493a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
503a062f41SBarry Smith {
513a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
523a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
533a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
543a062f41SBarry Smith   PetscInt        *rows;
553a062f41SBarry Smith   PetscErrorCode  ierr;
563a062f41SBarry Smith 
573a062f41SBarry Smith   PetscFunctionBegin;
583a062f41SBarry Smith   for (i=0; i<m; i++) {
593a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
603a062f41SBarry Smith       cnt++;
613a062f41SBarry Smith     }
623a062f41SBarry Smith   }
633a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
643a062f41SBarry Smith   cnt  = 0;
653a062f41SBarry Smith   for (i=0; i<m; i++) {
663a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
673a062f41SBarry Smith       rows[cnt] = i;
683a062f41SBarry Smith       cnt++;
693a062f41SBarry Smith     }
703a062f41SBarry Smith   }
713a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
723a062f41SBarry Smith   PetscFunctionReturn(0);
733a062f41SBarry Smith }
743a062f41SBarry Smith 
753a062f41SBarry Smith #undef __FUNCT__
76f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
77f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
786ce1633cSBarry Smith {
796ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
806ce1633cSBarry Smith   const MatScalar *aa = a->a;
816ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
826ce1633cSBarry Smith   const PetscInt  *jj = a->j,*diag;
836ce1633cSBarry Smith   PetscInt        *rows;
846ce1633cSBarry Smith   PetscErrorCode  ierr;
856ce1633cSBarry Smith 
866ce1633cSBarry Smith   PetscFunctionBegin;
876ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
886ce1633cSBarry Smith   diag = a->diag;
896ce1633cSBarry Smith   for (i=0; i<m; i++) {
906ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
916ce1633cSBarry Smith       cnt++;
926ce1633cSBarry Smith     }
936ce1633cSBarry Smith   }
94785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
956ce1633cSBarry Smith   cnt  = 0;
966ce1633cSBarry Smith   for (i=0; i<m; i++) {
976ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
986ce1633cSBarry Smith       rows[cnt++] = i;
996ce1633cSBarry Smith     }
1006ce1633cSBarry Smith   }
101f1f41ecbSJed Brown   *nrows = cnt;
102f1f41ecbSJed Brown   *zrows = rows;
103f1f41ecbSJed Brown   PetscFunctionReturn(0);
104f1f41ecbSJed Brown }
105f1f41ecbSJed Brown 
106f1f41ecbSJed Brown #undef __FUNCT__
107f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
108f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
109f1f41ecbSJed Brown {
110f1f41ecbSJed Brown   PetscInt       nrows,*rows;
111f1f41ecbSJed Brown   PetscErrorCode ierr;
112f1f41ecbSJed Brown 
113f1f41ecbSJed Brown   PetscFunctionBegin;
1140298fd71SBarry Smith   *zrows = NULL;
115f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
116ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1176ce1633cSBarry Smith   PetscFunctionReturn(0);
1186ce1633cSBarry Smith }
1196ce1633cSBarry Smith 
1206ce1633cSBarry Smith #undef __FUNCT__
121b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
122b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
123b3a44c85SBarry Smith {
124b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
125b3a44c85SBarry Smith   const MatScalar *aa;
126b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
127b3a44c85SBarry Smith   const PetscInt  *ii;
128b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
129b3a44c85SBarry Smith   PetscErrorCode  ierr;
130b3a44c85SBarry Smith 
131b3a44c85SBarry Smith   PetscFunctionBegin;
132b3a44c85SBarry Smith   *keptrows = 0;
133b3a44c85SBarry Smith   ii        = a->i;
134b3a44c85SBarry Smith   for (i=0; i<m; i++) {
135b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
136b3a44c85SBarry Smith     if (!n) {
137b3a44c85SBarry Smith       cnt++;
138b3a44c85SBarry Smith       goto ok1;
139b3a44c85SBarry Smith     }
140b3a44c85SBarry Smith     aa = a->a + ii[i];
141b3a44c85SBarry Smith     for (j=0; j<n; j++) {
142b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
143b3a44c85SBarry Smith     }
144b3a44c85SBarry Smith     cnt++;
145b3a44c85SBarry Smith ok1:;
146b3a44c85SBarry Smith   }
147b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
148785e854fSJed Brown   ierr = PetscMalloc1((A->rmap->n-cnt),&rows);CHKERRQ(ierr);
149b3a44c85SBarry Smith   cnt  = 0;
150b3a44c85SBarry Smith   for (i=0; i<m; i++) {
151b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
152b3a44c85SBarry Smith     if (!n) continue;
153b3a44c85SBarry Smith     aa = a->a + ii[i];
154b3a44c85SBarry Smith     for (j=0; j<n; j++) {
155b3a44c85SBarry Smith       if (aa[j] != 0.0) {
156b3a44c85SBarry Smith         rows[cnt++] = i;
157b3a44c85SBarry Smith         break;
158b3a44c85SBarry Smith       }
159b3a44c85SBarry Smith     }
160b3a44c85SBarry Smith   }
161b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
162b3a44c85SBarry Smith   PetscFunctionReturn(0);
163b3a44c85SBarry Smith }
164b3a44c85SBarry Smith 
165b3a44c85SBarry Smith #undef __FUNCT__
16679299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1677087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
16879299369SBarry Smith {
16979299369SBarry Smith   PetscErrorCode ierr;
17079299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
171d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
17254f21887SBarry Smith   MatScalar      *aa = aij->a;
17354f21887SBarry Smith   PetscScalar    *v;
174ace3abfcSBarry Smith   PetscBool      missing;
17579299369SBarry Smith 
17679299369SBarry Smith   PetscFunctionBegin;
17709f38230SBarry Smith   if (Y->assembled) {
1780298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
17909f38230SBarry Smith     if (!missing) {
18079299369SBarry Smith       diag = aij->diag;
18179299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
18279299369SBarry Smith       if (is == INSERT_VALUES) {
18379299369SBarry Smith         for (i=0; i<m; i++) {
18479299369SBarry Smith           aa[diag[i]] = v[i];
18579299369SBarry Smith         }
18679299369SBarry Smith       } else {
18779299369SBarry Smith         for (i=0; i<m; i++) {
18879299369SBarry Smith           aa[diag[i]] += v[i];
18979299369SBarry Smith         }
19079299369SBarry Smith       }
19179299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
19279299369SBarry Smith       PetscFunctionReturn(0);
19379299369SBarry Smith     }
194acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
19509f38230SBarry Smith   }
19609f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
19709f38230SBarry Smith   PetscFunctionReturn(0);
19809f38230SBarry Smith }
19979299369SBarry Smith 
20079299369SBarry Smith #undef __FUNCT__
2014a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
2021a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
20317ab2063SBarry Smith {
204416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
205dfbe8321SBarry Smith   PetscErrorCode ierr;
20697f1f81fSBarry Smith   PetscInt       i,ishift;
20717ab2063SBarry Smith 
2083a40ed3dSBarry Smith   PetscFunctionBegin;
209d0f46423SBarry Smith   *m = A->rmap->n;
2103a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
211bfeeae90SHong Zhang   ishift = 0;
21253e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
2131a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
214bfeeae90SHong Zhang   } else if (oshift == 1) {
2151a83f524SJed Brown     PetscInt *tia;
216d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2173b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
218785e854fSJed Brown     ierr = PetscMalloc1((A->rmap->n+1),&tia);CHKERRQ(ierr);
2191a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2201a83f524SJed Brown     *ia = tia;
221ecc77c7aSBarry Smith     if (ja) {
2221a83f524SJed Brown       PetscInt *tja;
223785e854fSJed Brown       ierr = PetscMalloc1((nz+1),&tja);CHKERRQ(ierr);
2241a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2251a83f524SJed Brown       *ja = tja;
226ecc77c7aSBarry Smith     }
2276945ee14SBarry Smith   } else {
228ecc77c7aSBarry Smith     *ia = a->i;
229ecc77c7aSBarry Smith     if (ja) *ja = a->j;
230a2ce50c7SBarry Smith   }
2313a40ed3dSBarry Smith   PetscFunctionReturn(0);
232a2744918SBarry Smith }
233a2744918SBarry Smith 
2344a2ae208SSatish Balay #undef __FUNCT__
2354a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
2361a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2376945ee14SBarry Smith {
238dfbe8321SBarry Smith   PetscErrorCode ierr;
2396945ee14SBarry Smith 
2403a40ed3dSBarry Smith   PetscFunctionBegin;
2413a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
242bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
243606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
244ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
245bcd2baecSBarry Smith   }
2463a40ed3dSBarry Smith   PetscFunctionReturn(0);
24717ab2063SBarry Smith }
24817ab2063SBarry Smith 
2494a2ae208SSatish Balay #undef __FUNCT__
2504a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
2511a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2523b2fbd54SBarry Smith {
2533b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
254dfbe8321SBarry Smith   PetscErrorCode ierr;
255d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
25697f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2573b2fbd54SBarry Smith 
2583a40ed3dSBarry Smith   PetscFunctionBegin;
259899cda47SBarry Smith   *nn = n;
2603a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2613b2fbd54SBarry Smith   if (symmetric) {
2621a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2633b2fbd54SBarry Smith   } else {
2641795a4d1SJed Brown     ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
265785e854fSJed Brown     ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
266785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
2673b2fbd54SBarry Smith     jj   = a->j;
2683b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
269bfeeae90SHong Zhang       collengths[jj[i]]++;
2703b2fbd54SBarry Smith     }
2713b2fbd54SBarry Smith     cia[0] = oshift;
2723b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2733b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2743b2fbd54SBarry Smith     }
27597f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2763b2fbd54SBarry Smith     jj   = a->j;
277a93ec695SBarry Smith     for (row=0; row<m; row++) {
278a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
279a93ec695SBarry Smith       for (i=0; i<mr; i++) {
280bfeeae90SHong Zhang         col = *jj++;
2812205254eSKarl Rupp 
2823b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2833b2fbd54SBarry Smith       }
2843b2fbd54SBarry Smith     }
285606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2863b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2873b2fbd54SBarry Smith   }
2883a40ed3dSBarry Smith   PetscFunctionReturn(0);
2893b2fbd54SBarry Smith }
2903b2fbd54SBarry Smith 
2914a2ae208SSatish Balay #undef __FUNCT__
2924a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2931a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2943b2fbd54SBarry Smith {
295dfbe8321SBarry Smith   PetscErrorCode ierr;
296606d414cSSatish Balay 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
2983a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2993b2fbd54SBarry Smith 
300606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
301606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
3023a40ed3dSBarry Smith   PetscFunctionReturn(0);
3033b2fbd54SBarry Smith }
3043b2fbd54SBarry Smith 
3057cee066cSHong Zhang /*
3067cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
3077cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
308040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
3097cee066cSHong Zhang */
3107cee066cSHong Zhang #undef __FUNCT__
3117cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
3127cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3137cee066cSHong Zhang {
3147cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3157cee066cSHong Zhang   PetscErrorCode ierr;
3167cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
3177cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
3187cee066cSHong Zhang   PetscInt       *cspidx;
3197cee066cSHong Zhang 
3207cee066cSHong Zhang   PetscFunctionBegin;
3217cee066cSHong Zhang   *nn = n;
3227cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
323625f6d37SHong Zhang 
3241795a4d1SJed Brown   ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr);
325785e854fSJed Brown   ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr);
326785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr);
327785e854fSJed Brown   ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr);
3287cee066cSHong Zhang   jj   = a->j;
3297cee066cSHong Zhang   for (i=0; i<nz; i++) {
3307cee066cSHong Zhang     collengths[jj[i]]++;
3317cee066cSHong Zhang   }
3327cee066cSHong Zhang   cia[0] = oshift;
3337cee066cSHong Zhang   for (i=0; i<n; i++) {
3347cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3357cee066cSHong Zhang   }
3367cee066cSHong Zhang   ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
3377cee066cSHong Zhang   jj   = a->j;
3387cee066cSHong Zhang   for (row=0; row<m; row++) {
3397cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3407cee066cSHong Zhang     for (i=0; i<mr; i++) {
3417cee066cSHong Zhang       col = *jj++;
3427cee066cSHong Zhang       cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
3437cee066cSHong Zhang       cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
3447cee066cSHong Zhang     }
3457cee066cSHong Zhang   }
3467cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
3477cee066cSHong Zhang   *ia    = cia; *ja = cja;
3487cee066cSHong Zhang   *spidx = cspidx;
3497cee066cSHong Zhang   PetscFunctionReturn(0);
3507cee066cSHong Zhang }
3517cee066cSHong Zhang 
3527cee066cSHong Zhang #undef __FUNCT__
3537cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
3547cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool  *done)
3557cee066cSHong Zhang {
3567cee066cSHong Zhang   PetscErrorCode ierr;
3577cee066cSHong Zhang 
3587cee066cSHong Zhang   PetscFunctionBegin;
3595243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3607cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3617cee066cSHong Zhang   PetscFunctionReturn(0);
3627cee066cSHong Zhang }
3637cee066cSHong Zhang 
36487d4246cSBarry Smith #undef __FUNCT__
36587d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
36687d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
36787d4246cSBarry Smith {
36887d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
36987d4246cSBarry Smith   PetscInt       *ai = a->i;
37087d4246cSBarry Smith   PetscErrorCode ierr;
37187d4246cSBarry Smith 
37287d4246cSBarry Smith   PetscFunctionBegin;
37387d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
37487d4246cSBarry Smith   PetscFunctionReturn(0);
37587d4246cSBarry Smith }
37687d4246cSBarry Smith 
3774a2ae208SSatish Balay #undef __FUNCT__
378bd04181cSBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast"
379bd04181cSBarry Smith /*
380bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
381bd04181cSBarry Smith 
382bd04181cSBarry Smith       -   a single row of values is set with each call
383bd04181cSBarry Smith       -   the local to global mapping is the identity
384bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
385bd04181cSBarry Smith       -   the values are always added to the matrix, not set
386bd04181cSBarry Smith       -   the columns indices on each call are sorted
387bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
388bd04181cSBarry Smith 
389bd04181cSBarry Smith */
390189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFastold(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
391bd04181cSBarry Smith {
392bd04181cSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
393bd04181cSBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
394bd04181cSBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen;
395bd04181cSBarry Smith   const PetscInt *aj = a->j;
396bd04181cSBarry Smith   MatScalar      *ap,*aa = a->a;
397bd04181cSBarry Smith PetscBool      found;
398bd04181cSBarry Smith 
399bd04181cSBarry Smith   PetscFunctionBegin;
400bd04181cSBarry Smith if (m >1) printf("trouble1\n");
401bd04181cSBarry Smith   row = im[0];
402bd04181cSBarry Smith   rp   = aj + ai[row];
403bd04181cSBarry Smith   ap   = aa + ai[row];
404bd04181cSBarry Smith   nrow = ailen[row];
405189e4007SBarry Smith   printf("row %d nrow %d\n",row,nrow);
406189e4007SBarry Smith   if (!nrow) printf("trouble4 %d\n",row);
407bd04181cSBarry Smith   low  = 0;
408bd04181cSBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
409bd04181cSBarry Smith     col = in[l];
410bd04181cSBarry Smith     high = nrow;
411bd04181cSBarry Smith found = PETSC_FALSE;
412189e4007SBarry Smith //printf("%d %d %d %d %d %d\n",l,low,high-1,rp[low],rp[high-1],col);
413bd04181cSBarry Smith if (l > 0 && in[l] < in[l-1]) printf("trouble3 %d %d\n",in[l-1],in[l]);
414bd04181cSBarry Smith     while (high-low > 5) {
415bd04181cSBarry Smith       t = (low+high)/2;
416bd04181cSBarry Smith       if (rp[t] > col) high = t;
417bd04181cSBarry Smith       else low = t;
418bd04181cSBarry Smith     }
419bd04181cSBarry Smith     for (i=low; i<high; i++) {
420bd04181cSBarry Smith       if (rp[i] == col) {
421bd04181cSBarry Smith         ap[i] += v[l];
422bd04181cSBarry Smith         low = i + 1;
423bd04181cSBarry Smith found = PETSC_TRUE;
424bd04181cSBarry Smith         break;
425bd04181cSBarry Smith       }
426bd04181cSBarry Smith     }
427189e4007SBarry Smith     if (!found) printf("trouble2 row %d  %d %d %d %d %d   %d %d\n",row,low,high-1,rp[low],rp[high-1],col,rp[0],rp[nrow-1]);
428bd04181cSBarry Smith   }
429bd04181cSBarry Smith   PetscFunctionReturn(0);
430bd04181cSBarry Smith }
431bd04181cSBarry Smith 
432189e4007SBarry Smith #include <petsc-private/isimpl.h>
433189e4007SBarry Smith #undef __FUNCT__
434189e4007SBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast"
435189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
436189e4007SBarry Smith {
437189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
438*f38dd0b8SBarry Smith   PetscInt       *rp,low,high,t,ii,row,nrow,i,col,l,rmax,N;
439189e4007SBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
440189e4007SBarry Smith   PetscErrorCode ierr;
441189e4007SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
442189e4007SBarry Smith   MatScalar      *ap,value,*aa = a->a;
443189e4007SBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
444189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
445189e4007SBarry Smith 
446*f38dd0b8SBarry Smith   row = ridx[im[0]];
447189e4007SBarry Smith   rp   = aj + ai[row]; ap = aa + ai[row];
448189e4007SBarry Smith   rmax = imax[row]; nrow = ailen[row];
449189e4007SBarry Smith   low  = 0;
450189e4007SBarry Smith   high = nrow;
451189e4007SBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
452189e4007SBarry Smith     col = cidx[in[l]];
453*f38dd0b8SBarry Smith     value = v[l];
454189e4007SBarry Smith 
455189e4007SBarry Smith     if (col <= lastcol) low = 0;
456189e4007SBarry Smith     else high = nrow;
457189e4007SBarry Smith     lastcol = col;
458189e4007SBarry Smith     while (high-low > 5) {
459189e4007SBarry Smith       t = (low+high)/2;
460189e4007SBarry Smith       if (rp[t] > col) high = t;
461189e4007SBarry Smith       else low = t;
462189e4007SBarry Smith     }
463189e4007SBarry Smith     for (i=low; i<high; i++) {
464189e4007SBarry Smith       if (rp[i] > col) break;
465189e4007SBarry Smith       if (rp[i] == col) {
466189e4007SBarry Smith         if (is == ADD_VALUES) ap[i] += value;
467189e4007SBarry Smith         else ap[i] = value;
468189e4007SBarry Smith         low = i + 1;
469189e4007SBarry Smith         goto noinsert;
470189e4007SBarry Smith       }
471189e4007SBarry Smith     }
472189e4007SBarry Smith     if (value == 0.0 && ignorezeroentries) goto noinsert;
473189e4007SBarry Smith     if (nonew == 1) goto noinsert;
474189e4007SBarry Smith     if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
475189e4007SBarry Smith     MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
476189e4007SBarry Smith     N = nrow++ - 1; a->nz++; high++;
477189e4007SBarry Smith     /* shift up all the later entries in this row */
478189e4007SBarry Smith     for (ii=N; ii>=i; ii--) {
479189e4007SBarry Smith       rp[ii+1] = rp[ii];
480189e4007SBarry Smith       ap[ii+1] = ap[ii];
481189e4007SBarry Smith     }
482189e4007SBarry Smith     rp[i] = col;
483189e4007SBarry Smith     ap[i] = value;
484189e4007SBarry Smith     low   = i + 1;
485189e4007SBarry Smith     noinsert:;
486189e4007SBarry Smith   }
487*f38dd0b8SBarry Smith   return 0;
488189e4007SBarry Smith }
489189e4007SBarry Smith 
490bd04181cSBarry Smith #undef __FUNCT__
4914a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
49297f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
49317ab2063SBarry Smith {
494416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
495e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
49697f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
4976849ba73SBarry Smith   PetscErrorCode ierr;
498e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
49954f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
500ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
501ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
50217ab2063SBarry Smith 
5033a40ed3dSBarry Smith   PetscFunctionBegin;
50471fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
50517ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
506416022c9SBarry Smith     row = im[k];
5075ef9f2a5SBarry Smith     if (row < 0) continue;
5082515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
509e32f2f54SBarry 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);
5103b2fbd54SBarry Smith #endif
511bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
51217ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
513416022c9SBarry Smith     low  = 0;
514c71e6ed7SBarry Smith     high = nrow;
51517ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
5165ef9f2a5SBarry Smith       if (in[l] < 0) continue;
5172515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
518e32f2f54SBarry 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);
5193b2fbd54SBarry Smith #endif
520bfeeae90SHong Zhang       col = in[l];
52116371a99SBarry Smith       if (v) {
5224b0e389bSBarry Smith         if (roworiented) {
5235ef9f2a5SBarry Smith           value = v[l + k*n];
524bef8e0ddSBarry Smith         } else {
5254b0e389bSBarry Smith           value = v[k + l*m];
5264b0e389bSBarry Smith         }
52716371a99SBarry Smith       } else {
52875567043SBarry Smith         value = 0.;
52916371a99SBarry Smith       }
53033b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
53136db0b34SBarry Smith 
5322205254eSKarl Rupp       if (col <= lastcol) low = 0;
5332205254eSKarl Rupp       else high = nrow;
534e2ee6c50SBarry Smith       lastcol = col;
535416022c9SBarry Smith       while (high-low > 5) {
536416022c9SBarry Smith         t = (low+high)/2;
537416022c9SBarry Smith         if (rp[t] > col) high = t;
538416022c9SBarry Smith         else low = t;
53917ab2063SBarry Smith       }
540416022c9SBarry Smith       for (i=low; i<high; i++) {
54117ab2063SBarry Smith         if (rp[i] > col) break;
54217ab2063SBarry Smith         if (rp[i] == col) {
543416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
54417ab2063SBarry Smith           else ap[i] = value;
545e44c0bd4SBarry Smith           low = i + 1;
54617ab2063SBarry Smith           goto noinsert;
54717ab2063SBarry Smith         }
54817ab2063SBarry Smith       }
549abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
550c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
551e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
552fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
553c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
554416022c9SBarry Smith       /* shift up all the later entries in this row */
555416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
55617ab2063SBarry Smith         rp[ii+1] = rp[ii];
55717ab2063SBarry Smith         ap[ii+1] = ap[ii];
55817ab2063SBarry Smith       }
55917ab2063SBarry Smith       rp[i] = col;
56017ab2063SBarry Smith       ap[i] = value;
561416022c9SBarry Smith       low   = i + 1;
562e44c0bd4SBarry Smith noinsert:;
56317ab2063SBarry Smith     }
56417ab2063SBarry Smith     ailen[row] = nrow;
56517ab2063SBarry Smith   }
56688e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
5673a40ed3dSBarry Smith   PetscFunctionReturn(0);
56817ab2063SBarry Smith }
56917ab2063SBarry Smith 
57081824310SBarry Smith 
5714a2ae208SSatish Balay #undef __FUNCT__
5724a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
573a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
5747eb43aa7SLois Curfman McInnes {
5757eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
57697f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
57797f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
57854f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
5797eb43aa7SLois Curfman McInnes 
5803a40ed3dSBarry Smith   PetscFunctionBegin;
5817eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
5827eb43aa7SLois Curfman McInnes     row = im[k];
583e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
584e32f2f54SBarry 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);
585bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
5867eb43aa7SLois Curfman McInnes     nrow = ailen[row];
5877eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
588e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
589e32f2f54SBarry 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);
590bfeeae90SHong Zhang       col  = in[l];
5917eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
5927eb43aa7SLois Curfman McInnes       while (high-low > 5) {
5937eb43aa7SLois Curfman McInnes         t = (low+high)/2;
5947eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
5957eb43aa7SLois Curfman McInnes         else low = t;
5967eb43aa7SLois Curfman McInnes       }
5977eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
5987eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
5997eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
600b49de8d1SLois Curfman McInnes           *v++ = ap[i];
6017eb43aa7SLois Curfman McInnes           goto finished;
6027eb43aa7SLois Curfman McInnes         }
6037eb43aa7SLois Curfman McInnes       }
60497e567efSBarry Smith       *v++ = 0.0;
6057eb43aa7SLois Curfman McInnes finished:;
6067eb43aa7SLois Curfman McInnes     }
6077eb43aa7SLois Curfman McInnes   }
6083a40ed3dSBarry Smith   PetscFunctionReturn(0);
6097eb43aa7SLois Curfman McInnes }
6107eb43aa7SLois Curfman McInnes 
61117ab2063SBarry Smith 
6124a2ae208SSatish Balay #undef __FUNCT__
6134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
614dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
61517ab2063SBarry Smith {
616416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
6176849ba73SBarry Smith   PetscErrorCode ierr;
6186f69ff64SBarry Smith   PetscInt       i,*col_lens;
6196f69ff64SBarry Smith   int            fd;
620b37d52dbSMark F. Adams   FILE           *file;
62117ab2063SBarry Smith 
6223a40ed3dSBarry Smith   PetscFunctionBegin;
623b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
624785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
6252205254eSKarl Rupp 
6260700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
627d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
628d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
629416022c9SBarry Smith   col_lens[3] = a->nz;
630416022c9SBarry Smith 
631416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
632d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
633416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
63417ab2063SBarry Smith   }
635d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
636606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
637416022c9SBarry Smith 
638416022c9SBarry Smith   /* store column indices (zero start index) */
6396f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
640416022c9SBarry Smith 
641416022c9SBarry Smith   /* store nonzero values */
6426f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
643b37d52dbSMark F. Adams 
644b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
645b37d52dbSMark F. Adams   if (file) {
646b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
647b37d52dbSMark F. Adams   }
6483a40ed3dSBarry Smith   PetscFunctionReturn(0);
64917ab2063SBarry Smith }
650416022c9SBarry Smith 
65109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
652cd155464SBarry Smith 
6534a2ae208SSatish Balay #undef __FUNCT__
6544a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
655dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
656416022c9SBarry Smith {
657416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
658dfbe8321SBarry Smith   PetscErrorCode    ierr;
659d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
660e060cb09SBarry Smith   const char        *name;
661f3ef73ceSBarry Smith   PetscViewerFormat format;
66217ab2063SBarry Smith 
6633a40ed3dSBarry Smith   PetscFunctionBegin;
664b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
66571c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
66697f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
667014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
668d00d2cf4SBarry Smith       nofinalvalue = 1;
669d00d2cf4SBarry Smith     }
670d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
671d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
67277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
67377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
674b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
67517ab2063SBarry Smith 
67617ab2063SBarry Smith     for (i=0; i<m; i++) {
677416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
678aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
67977431f27SBarry 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);
68017ab2063SBarry Smith #else
68177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
68217ab2063SBarry Smith #endif
68317ab2063SBarry Smith       }
68417ab2063SBarry Smith     }
685d00d2cf4SBarry Smith     if (nofinalvalue) {
686d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
687d00d2cf4SBarry Smith     }
688317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
689fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
690d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
69168369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
692cd155464SBarry Smith     PetscFunctionReturn(0);
693fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
694d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
695dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
69644cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
69777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
69844cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
699aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70036db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
701ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
70236db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
703ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
70436db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
705ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
7066831982aSBarry Smith         }
70744cd7ae7SLois Curfman McInnes #else
708ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
70944cd7ae7SLois Curfman McInnes #endif
71044cd7ae7SLois Curfman McInnes       }
711b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
71244cd7ae7SLois Curfman McInnes     }
713d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
714fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
71597f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
716d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
717dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
718785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
719496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
720496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
721496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
722496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
723aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
72436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
725496be53dSLois Curfman McInnes #else
726496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
727496be53dSLois Curfman McInnes #endif
728496be53dSLois Curfman McInnes         }
729496be53dSLois Curfman McInnes       }
730496be53dSLois Curfman McInnes     }
7312e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
73277431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
7332e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
7342205254eSKarl Rupp       if (i+4<m) {
7352205254eSKarl 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);
7362205254eSKarl Rupp       } else if (i+3<m) {
7372205254eSKarl 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);
7382205254eSKarl Rupp       } else if (i+2<m) {
7392205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
7402205254eSKarl Rupp       } else if (i+1<m) {
7412205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
7422205254eSKarl Rupp       } else if (i<m) {
7432205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
7442205254eSKarl Rupp       } else {
7452205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
7462205254eSKarl Rupp       }
747496be53dSLois Curfman McInnes     }
748b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
749606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
750496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
751496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
75277431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
753496be53dSLois Curfman McInnes       }
754b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
755496be53dSLois Curfman McInnes     }
756b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
757496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
758496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
759496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
760aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
76136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
762b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7636831982aSBarry Smith           }
764496be53dSLois Curfman McInnes #else
765b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
766496be53dSLois Curfman McInnes #endif
767496be53dSLois Curfman McInnes         }
768496be53dSLois Curfman McInnes       }
769b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
770496be53dSLois Curfman McInnes     }
771d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
772fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
77397f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
77487828ca2SBarry Smith     PetscScalar value;
77568f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
77668f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
77768f1ed48SBarry Smith 
77868f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
77968f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
78068f1ed48SBarry Smith         realonly = PETSC_FALSE;
78168f1ed48SBarry Smith         break;
78268f1ed48SBarry Smith       }
78368f1ed48SBarry Smith     }
78468f1ed48SBarry Smith #endif
78502594712SBarry Smith 
786d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
787dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
78802594712SBarry Smith     for (i=0; i<m; i++) {
78902594712SBarry Smith       jcnt = 0;
790d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
791e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
79202594712SBarry Smith           value = a->a[cnt++];
793e24b481bSBarry Smith           jcnt++;
79402594712SBarry Smith         } else {
79502594712SBarry Smith           value = 0.0;
79602594712SBarry Smith         }
797aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
79868f1ed48SBarry Smith         if (realonly) {
79968f1ed48SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",PetscRealPart(value));CHKERRQ(ierr);
80068f1ed48SBarry Smith         } else {
801b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
80268f1ed48SBarry Smith         }
80302594712SBarry Smith #else
804b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
80502594712SBarry Smith #endif
80602594712SBarry Smith       }
807b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
80802594712SBarry Smith     }
809d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
8103c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
811150b93efSMatthew G. Knepley     PetscInt fshift=1;
812d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
8133c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
8143c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
8153c215bfdSMatthew Knepley #else
8163c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
8173c215bfdSMatthew Knepley #endif
818d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
8193c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
8203c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
8213c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
8223c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
823150b93efSMatthew 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);
8243c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
825150b93efSMatthew 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);
8263c215bfdSMatthew Knepley         } else {
827150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
8283c215bfdSMatthew Knepley         }
8293c215bfdSMatthew Knepley #else
830150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
8313c215bfdSMatthew Knepley #endif
8323c215bfdSMatthew Knepley       }
8333c215bfdSMatthew Knepley     }
834d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
8353a40ed3dSBarry Smith   } else {
836d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
837dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
838d5f3da31SBarry Smith     if (A->factortype) {
83916cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
84016cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
84116cd7e1dSShri Abhyankar         /* L part */
84216cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
84316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
84416cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
845ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
84616cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
847ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
84816cd7e1dSShri Abhyankar           } else {
849ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
85016cd7e1dSShri Abhyankar           }
85116cd7e1dSShri Abhyankar #else
852ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
85316cd7e1dSShri Abhyankar #endif
85416cd7e1dSShri Abhyankar         }
85516cd7e1dSShri Abhyankar         /* diagonal */
85616cd7e1dSShri Abhyankar         j = a->diag[i];
85716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
85816cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
859ba0e910bSBarry 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);
86016cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
861ba0e910bSBarry 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);
86216cd7e1dSShri Abhyankar         } else {
863ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
86416cd7e1dSShri Abhyankar         }
86516cd7e1dSShri Abhyankar #else
866ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
86716cd7e1dSShri Abhyankar #endif
86816cd7e1dSShri Abhyankar 
86916cd7e1dSShri Abhyankar         /* U part */
87016cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
87116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
87216cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
873ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
87416cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
875ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
87616cd7e1dSShri Abhyankar           } else {
877ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
87816cd7e1dSShri Abhyankar           }
87916cd7e1dSShri Abhyankar #else
880ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
88116cd7e1dSShri Abhyankar #endif
88216cd7e1dSShri Abhyankar         }
88316cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
88416cd7e1dSShri Abhyankar       }
88516cd7e1dSShri Abhyankar     } else {
88617ab2063SBarry Smith       for (i=0; i<m; i++) {
88777431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
888416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
889aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
89036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
891ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
89236db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
893ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8943a40ed3dSBarry Smith           } else {
895ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
89617ab2063SBarry Smith           }
89717ab2063SBarry Smith #else
898ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
89917ab2063SBarry Smith #endif
90017ab2063SBarry Smith         }
901b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
90217ab2063SBarry Smith       }
90316cd7e1dSShri Abhyankar     }
904d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
90517ab2063SBarry Smith   }
906b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
9073a40ed3dSBarry Smith   PetscFunctionReturn(0);
908416022c9SBarry Smith }
909416022c9SBarry Smith 
9109804daf3SBarry Smith #include <petscdraw.h>
9114a2ae208SSatish Balay #undef __FUNCT__
9124a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
913dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
914416022c9SBarry Smith {
915480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
916416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
917dfbe8321SBarry Smith   PetscErrorCode    ierr;
918d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
91936db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
920b0a32e0cSBarry Smith   PetscViewer       viewer;
921f3ef73ceSBarry Smith   PetscViewerFormat format;
922cddf8d76SBarry Smith 
9233a40ed3dSBarry Smith   PetscFunctionBegin;
924480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
925b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
92619bcc07fSBarry Smith 
927b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
928416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
9290513a670SBarry Smith 
930fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
9310513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
932b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
933416022c9SBarry Smith     for (i=0; i<m; i++) {
934cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
935bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
936bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
93736db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
938b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
939cddf8d76SBarry Smith       }
940cddf8d76SBarry Smith     }
941b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
942cddf8d76SBarry Smith     for (i=0; i<m; i++) {
943cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
944bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
945bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
946cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
947b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
948cddf8d76SBarry Smith       }
949cddf8d76SBarry Smith     }
950b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
951cddf8d76SBarry Smith     for (i=0; i<m; i++) {
952cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
953bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
954bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
95536db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
956b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
957416022c9SBarry Smith       }
958416022c9SBarry Smith     }
9590513a670SBarry Smith   } else {
9600513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
9610513a670SBarry Smith     /* first determine max of all nonzero values */
96297f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
963b0a32e0cSBarry Smith     PetscDraw popup;
96436db0b34SBarry Smith     PetscReal scale;
9650513a670SBarry Smith 
9660513a670SBarry Smith     for (i=0; i<nz; i++) {
9670513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
9680513a670SBarry Smith     }
969b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
970b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
9712205254eSKarl Rupp     if (popup) {
9722205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
9732205254eSKarl Rupp     }
9740513a670SBarry Smith     count = 0;
9750513a670SBarry Smith     for (i=0; i<m; i++) {
9760513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
977bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
978bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
97997f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
980b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
9810513a670SBarry Smith         count++;
9820513a670SBarry Smith       }
9830513a670SBarry Smith     }
9840513a670SBarry Smith   }
985480ef9eaSBarry Smith   PetscFunctionReturn(0);
986480ef9eaSBarry Smith }
987cddf8d76SBarry Smith 
9889804daf3SBarry Smith #include <petscdraw.h>
9894a2ae208SSatish Balay #undef __FUNCT__
9904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
991dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
992480ef9eaSBarry Smith {
993dfbe8321SBarry Smith   PetscErrorCode ierr;
994b0a32e0cSBarry Smith   PetscDraw      draw;
99536db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
996ace3abfcSBarry Smith   PetscBool      isnull;
997480ef9eaSBarry Smith 
998480ef9eaSBarry Smith   PetscFunctionBegin;
999b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1000b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1001480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
1002480ef9eaSBarry Smith 
1003480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1004d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1005480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
1006b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1007b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
10080298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
10093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1010416022c9SBarry Smith }
1011416022c9SBarry Smith 
10124a2ae208SSatish Balay #undef __FUNCT__
10134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
1014dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
1015416022c9SBarry Smith {
1016dfbe8321SBarry Smith   PetscErrorCode ierr;
1017ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1018416022c9SBarry Smith 
10193a40ed3dSBarry Smith   PetscFunctionBegin;
1020251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1021251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1022251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1023c45a1595SBarry Smith   if (iascii) {
10243a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
10250f5bd95cSBarry Smith   } else if (isbinary) {
10263a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
10270f5bd95cSBarry Smith   } else if (isdraw) {
10283a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
102911aeaf0aSBarry Smith   }
10304108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
10313a40ed3dSBarry Smith   PetscFunctionReturn(0);
103217ab2063SBarry Smith }
103319bcc07fSBarry Smith 
10344a2ae208SSatish Balay #undef __FUNCT__
10354a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
1036dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
103717ab2063SBarry Smith {
1038416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10396849ba73SBarry Smith   PetscErrorCode ierr;
104097f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
1041d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
104254f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
10433447b6efSHong Zhang   PetscReal      ratio  = 0.6;
104417ab2063SBarry Smith 
10453a40ed3dSBarry Smith   PetscFunctionBegin;
10463a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
104717ab2063SBarry Smith 
104843ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
104917ab2063SBarry Smith   for (i=1; i<m; i++) {
1050416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
105117ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
105294a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
105317ab2063SBarry Smith     if (fshift) {
1054bfeeae90SHong Zhang       ip = aj + ai[i];
1055bfeeae90SHong Zhang       ap = aa + ai[i];
105617ab2063SBarry Smith       N  = ailen[i];
105717ab2063SBarry Smith       for (j=0; j<N; j++) {
105817ab2063SBarry Smith         ip[j-fshift] = ip[j];
105917ab2063SBarry Smith         ap[j-fshift] = ap[j];
106017ab2063SBarry Smith       }
106117ab2063SBarry Smith     }
106217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
106317ab2063SBarry Smith   }
106417ab2063SBarry Smith   if (m) {
106517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
106617ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
106717ab2063SBarry Smith   }
10687b083b7cSBarry Smith 
106917ab2063SBarry Smith   /* reset ilen and imax for each row */
10707b083b7cSBarry Smith   a->nonzerorowcnt = 0;
107117ab2063SBarry Smith   for (i=0; i<m; i++) {
107217ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
10737b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
107417ab2063SBarry Smith   }
1075bfeeae90SHong Zhang   a->nz = ai[m];
107665e19b50SBarry 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);
107717ab2063SBarry Smith 
107809f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1079d0f46423SBarry 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);
1080ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
1081ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
10822205254eSKarl Rupp 
10838e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1084dd5f02e7SSatish Balay   a->reallocs         = 0;
10854e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
108636db0b34SBarry Smith   a->rmax             = rmax;
10874e220ebcSLois Curfman McInnes 
108811e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
10892205254eSKarl Rupp 
109088e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
109171c2f376SKris Buschelman 
10924108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
109371f1c65dSBarry Smith 
1094acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10953a40ed3dSBarry Smith   PetscFunctionReturn(0);
109617ab2063SBarry Smith }
109717ab2063SBarry Smith 
10984a2ae208SSatish Balay #undef __FUNCT__
109999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
110099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
110199cafbc1SBarry Smith {
110299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
110399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
110454f21887SBarry Smith   MatScalar      *aa = a->a;
1105acf2f550SJed Brown   PetscErrorCode ierr;
110699cafbc1SBarry Smith 
110799cafbc1SBarry Smith   PetscFunctionBegin;
110899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1109acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
111099cafbc1SBarry Smith   PetscFunctionReturn(0);
111199cafbc1SBarry Smith }
111299cafbc1SBarry Smith 
111399cafbc1SBarry Smith #undef __FUNCT__
111499cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
111599cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
111699cafbc1SBarry Smith {
111799cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
111899cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
111954f21887SBarry Smith   MatScalar      *aa = a->a;
1120acf2f550SJed Brown   PetscErrorCode ierr;
112199cafbc1SBarry Smith 
112299cafbc1SBarry Smith   PetscFunctionBegin;
112399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1124acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
112599cafbc1SBarry Smith   PetscFunctionReturn(0);
112699cafbc1SBarry Smith }
112799cafbc1SBarry Smith 
112878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
112978b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
113078b84d54SShri Abhyankar {
113178b84d54SShri Abhyankar   PetscErrorCode ierr;
113278b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
113378b84d54SShri Abhyankar   PetscInt       n,start,end;
113478b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
113578b84d54SShri Abhyankar 
113678b84d54SShri Abhyankar   start = trstarts[thread_id];
113778b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
113819baf141SJed Brown   n     = a->i[end] - a->i[start];
113919baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
114078b84d54SShri Abhyankar   return 0;
114178b84d54SShri Abhyankar }
114278b84d54SShri Abhyankar 
114378b84d54SShri Abhyankar #undef __FUNCT__
114478b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
114578b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
114678b84d54SShri Abhyankar {
114778b84d54SShri Abhyankar   PetscErrorCode ierr;
114878b84d54SShri Abhyankar 
114978b84d54SShri Abhyankar   PetscFunctionBegin;
1150ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1151acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
115278b84d54SShri Abhyankar   PetscFunctionReturn(0);
115378b84d54SShri Abhyankar }
115478b84d54SShri Abhyankar #else
115599cafbc1SBarry Smith #undef __FUNCT__
11564a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1157dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
115817ab2063SBarry Smith {
1159416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1160dfbe8321SBarry Smith   PetscErrorCode ierr;
11613a40ed3dSBarry Smith 
11623a40ed3dSBarry Smith   PetscFunctionBegin;
1163d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1164acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
11653a40ed3dSBarry Smith   PetscFunctionReturn(0);
116617ab2063SBarry Smith }
116778b84d54SShri Abhyankar #endif
1168416022c9SBarry Smith 
11694a2ae208SSatish Balay #undef __FUNCT__
11704a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1171dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
117217ab2063SBarry Smith {
1173416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1174dfbe8321SBarry Smith   PetscErrorCode ierr;
1175d5d45c9bSBarry Smith 
11763a40ed3dSBarry Smith   PetscFunctionBegin;
1177aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1178d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
117917ab2063SBarry Smith #endif
1180e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
11816bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
11826bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
118305b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1184d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
118505b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
118671f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
118705b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
11886bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
118905b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
11906bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
119105b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
11926bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1193cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
11940b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1195a30b2313SHong Zhang 
11964108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1197bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1198901853e0SKris Buschelman 
1199dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1200bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1201bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1202bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1203bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1204bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1205bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1206bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1207bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1208bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1209bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
12103a40ed3dSBarry Smith   PetscFunctionReturn(0);
121117ab2063SBarry Smith }
121217ab2063SBarry Smith 
12134a2ae208SSatish Balay #undef __FUNCT__
12144a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1215ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
121617ab2063SBarry Smith {
1217416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12184846f1f5SKris Buschelman   PetscErrorCode ierr;
12193a40ed3dSBarry Smith 
12203a40ed3dSBarry Smith   PetscFunctionBegin;
1221a65d3064SKris Buschelman   switch (op) {
1222a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
12234e0d8c25SBarry Smith     a->roworiented = flg;
1224a65d3064SKris Buschelman     break;
1225a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1226a9817697SBarry Smith     a->keepnonzeropattern = flg;
1227a65d3064SKris Buschelman     break;
1228512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1229512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1230a65d3064SKris Buschelman     break;
1231a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
12324e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1233a65d3064SKris Buschelman     break;
1234a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
12354e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1236a65d3064SKris Buschelman     break;
123728b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
123828b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
123928b2fa4aSMatthew Knepley     break;
1240a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
12414e0d8c25SBarry Smith     a->ignorezeroentries = flg;
12420df259c2SBarry Smith     break;
12433d472b54SHong Zhang   case MAT_SPD:
1244b1646e73SJed Brown   case MAT_SYMMETRIC:
1245b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1246b1646e73SJed Brown   case MAT_HERMITIAN:
1247b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
12485021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
12495021d80fSJed Brown     break;
12504e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1251a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1252a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1253290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1254a65d3064SKris Buschelman     break;
1255b87ac2d8SJed Brown   case MAT_USE_INODES:
1256b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1257b87ac2d8SJed Brown     break;
1258a65d3064SKris Buschelman   default:
1259e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1260a65d3064SKris Buschelman   }
12614108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
12623a40ed3dSBarry Smith   PetscFunctionReturn(0);
126317ab2063SBarry Smith }
126417ab2063SBarry Smith 
12654a2ae208SSatish Balay #undef __FUNCT__
12664a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1267dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
126817ab2063SBarry Smith {
1269416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12706849ba73SBarry Smith   PetscErrorCode ierr;
1271d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
127235e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
127317ab2063SBarry Smith 
12743a40ed3dSBarry Smith   PetscFunctionBegin;
1275d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1276e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
127735e7444dSHong Zhang 
1278d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1279d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
128035e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
12812c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
128235e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
128335e7444dSHong Zhang     PetscFunctionReturn(0);
128435e7444dSHong Zhang   }
128535e7444dSHong Zhang 
12862dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
12871ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
128835e7444dSHong Zhang   for (i=0; i<n; i++) {
128935e7444dSHong Zhang     nz = ai[i+1] - ai[i];
12902f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
129135e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
129235e7444dSHong Zhang       if (aj[j] == i) {
129335e7444dSHong Zhang         x[i] = aa[j];
129417ab2063SBarry Smith         break;
129517ab2063SBarry Smith       }
129617ab2063SBarry Smith     }
129717ab2063SBarry Smith   }
12981ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
12993a40ed3dSBarry Smith   PetscFunctionReturn(0);
130017ab2063SBarry Smith }
130117ab2063SBarry Smith 
1302c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
13034a2ae208SSatish Balay #undef __FUNCT__
13044a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1305dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
130617ab2063SBarry Smith {
1307416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
13085c897100SBarry Smith   PetscScalar    *x,*y;
1309dfbe8321SBarry Smith   PetscErrorCode ierr;
1310d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
13115c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1312a77337e4SBarry Smith   MatScalar         *v;
1313a77337e4SBarry Smith   PetscScalar       alpha;
13140298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
13153447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1316ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
13175c897100SBarry Smith #endif
131817ab2063SBarry Smith 
13193a40ed3dSBarry Smith   PetscFunctionBegin;
13202e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
13211ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
13221ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
13235c897100SBarry Smith 
13245c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1325bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
13265c897100SBarry Smith #else
13273447b6efSHong Zhang   if (usecprow) {
13283447b6efSHong Zhang     m    = cprow.nrows;
13293447b6efSHong Zhang     ii   = cprow.i;
13307b2bb3b9SHong Zhang     ridx = cprow.rindex;
13313447b6efSHong Zhang   } else {
13323447b6efSHong Zhang     ii = a->i;
13333447b6efSHong Zhang   }
133417ab2063SBarry Smith   for (i=0; i<m; i++) {
13353447b6efSHong Zhang     idx = a->j + ii[i];
13363447b6efSHong Zhang     v   = a->a + ii[i];
13373447b6efSHong Zhang     n   = ii[i+1] - ii[i];
13383447b6efSHong Zhang     if (usecprow) {
13397b2bb3b9SHong Zhang       alpha = x[ridx[i]];
13403447b6efSHong Zhang     } else {
134117ab2063SBarry Smith       alpha = x[i];
13423447b6efSHong Zhang     }
134304fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
134417ab2063SBarry Smith   }
13455c897100SBarry Smith #endif
1346dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
13471ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13481ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13493a40ed3dSBarry Smith   PetscFunctionReturn(0);
135017ab2063SBarry Smith }
135117ab2063SBarry Smith 
13524a2ae208SSatish Balay #undef __FUNCT__
13535c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1354dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
13555c897100SBarry Smith {
1356dfbe8321SBarry Smith   PetscErrorCode ierr;
13575c897100SBarry Smith 
13585c897100SBarry Smith   PetscFunctionBegin;
1359170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
13605c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
13615c897100SBarry Smith   PetscFunctionReturn(0);
13625c897100SBarry Smith }
13635c897100SBarry Smith 
1364c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
136578b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
136678b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
136778b84d54SShri Abhyankar {
136878b84d54SShri Abhyankar   PetscErrorCode    ierr;
136978b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
137078b84d54SShri Abhyankar   PetscScalar       *y;
137178b84d54SShri Abhyankar   const PetscScalar *x;
137278b84d54SShri Abhyankar   const MatScalar   *aa;
137378b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
137478b84d54SShri Abhyankar   PetscInt          n,start,end,i;
137578b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
137678b84d54SShri Abhyankar   PetscScalar       sum;
137778b84d54SShri Abhyankar 
137878b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
137978b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
138078b84d54SShri Abhyankar   start = trstarts[thread_id];
138178b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
138278b84d54SShri Abhyankar   aj    = a->j;
138378b84d54SShri Abhyankar   aa    = a->a;
138478b84d54SShri Abhyankar   ai    = a->i;
138578b84d54SShri Abhyankar   for (i=start; i<end; i++) {
138678b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
138778b84d54SShri Abhyankar     aj  = a->j + ai[i];
138878b84d54SShri Abhyankar     aa  = a->a + ai[i];
138978b84d54SShri Abhyankar     sum = 0.0;
139078b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
139178b84d54SShri Abhyankar     y[i] = sum;
139278b84d54SShri Abhyankar   }
139378b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
139478b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
139578b84d54SShri Abhyankar   return 0;
139678b84d54SShri Abhyankar }
139778b84d54SShri Abhyankar 
139878b84d54SShri Abhyankar #undef __FUNCT__
139978b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
140078b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
140178b84d54SShri Abhyankar {
140278b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
140378b84d54SShri Abhyankar   PetscScalar       *y;
140478b84d54SShri Abhyankar   const PetscScalar *x;
140578b84d54SShri Abhyankar   const MatScalar   *aa;
140678b84d54SShri Abhyankar   PetscErrorCode    ierr;
140778b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
14080298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14097b083b7cSBarry Smith   PetscInt          n,i;
141078b84d54SShri Abhyankar   PetscScalar       sum;
141178b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
141278b84d54SShri Abhyankar 
141378b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
141478b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
141578b84d54SShri Abhyankar #endif
141678b84d54SShri Abhyankar 
141778b84d54SShri Abhyankar   PetscFunctionBegin;
141878b84d54SShri Abhyankar   aj = a->j;
141978b84d54SShri Abhyankar   aa = a->a;
142078b84d54SShri Abhyankar   ii = a->i;
142178b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
142278b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
142378b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
142478b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
142578b84d54SShri Abhyankar     ii   = a->compressedrow.i;
142678b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
142778b84d54SShri Abhyankar     for (i=0; i<m; i++) {
142878b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
142978b84d54SShri Abhyankar       aj          = a->j + ii[i];
143078b84d54SShri Abhyankar       aa          = a->a + ii[i];
143178b84d54SShri Abhyankar       sum         = 0.0;
143278b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
143378b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
143478b84d54SShri Abhyankar       y[*ridx++] = sum;
143578b84d54SShri Abhyankar     }
143678b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
143778b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
143878b84d54SShri Abhyankar   } else { /* do not use compressed row format */
143978b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
144078b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
144178b84d54SShri Abhyankar #else
1442ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
144378b84d54SShri Abhyankar #endif
144478b84d54SShri Abhyankar   }
14457b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
144678b84d54SShri Abhyankar   PetscFunctionReturn(0);
144778b84d54SShri Abhyankar }
144878b84d54SShri Abhyankar #else
14495c897100SBarry Smith #undef __FUNCT__
14504a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1451dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
145217ab2063SBarry Smith {
1453416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1454d9fead3dSBarry Smith   PetscScalar       *y;
145554f21887SBarry Smith   const PetscScalar *x;
145654f21887SBarry Smith   const MatScalar   *aa;
1457dfbe8321SBarry Smith   PetscErrorCode    ierr;
1458003131ecSBarry Smith   PetscInt          m=A->rmap->n;
14590298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14607b083b7cSBarry Smith   PetscInt          n,i;
1461362ced78SSatish Balay   PetscScalar       sum;
1462ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
146317ab2063SBarry Smith 
1464b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
146597952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1466fee21e36SBarry Smith #endif
1467fee21e36SBarry Smith 
14683a40ed3dSBarry Smith   PetscFunctionBegin;
14693649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14701ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
147197952fefSHong Zhang   aj   = a->j;
147297952fefSHong Zhang   aa   = a->a;
1473416022c9SBarry Smith   ii   = a->i;
14744eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
147597952fefSHong Zhang     m    = a->compressedrow.nrows;
147697952fefSHong Zhang     ii   = a->compressedrow.i;
147797952fefSHong Zhang     ridx = a->compressedrow.rindex;
147897952fefSHong Zhang     for (i=0; i<m; i++) {
147997952fefSHong Zhang       n           = ii[i+1] - ii[i];
148097952fefSHong Zhang       aj          = a->j + ii[i];
148197952fefSHong Zhang       aa          = a->a + ii[i];
148297952fefSHong Zhang       sum         = 0.0;
1483003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1484003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
148597952fefSHong Zhang       y[*ridx++] = sum;
148697952fefSHong Zhang     }
148797952fefSHong Zhang   } else { /* do not use compressed row format */
1488b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1489b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1490b05257ddSBarry Smith #else
149178b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1492ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
149378b84d54SShri Abhyankar #else
149417ab2063SBarry Smith     for (i=0; i<m; i++) {
1495003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1496003131ecSBarry Smith       aj          = a->j + ii[i];
1497003131ecSBarry Smith       aa          = a->a + ii[i];
149817ab2063SBarry Smith       sum         = 0.0;
1499003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
150017ab2063SBarry Smith       y[i] = sum;
150117ab2063SBarry Smith     }
15028d195f9aSBarry Smith #endif
150378b84d54SShri Abhyankar #endif
1504b05257ddSBarry Smith   }
15057b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
15063649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15071ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15083a40ed3dSBarry Smith   PetscFunctionReturn(0);
150917ab2063SBarry Smith }
151078b84d54SShri Abhyankar #endif
151117ab2063SBarry Smith 
1512b434eb95SMatthew G. Knepley #undef __FUNCT__
1513b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1514b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1515b434eb95SMatthew G. Knepley {
1516b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1517b434eb95SMatthew G. Knepley   PetscScalar       *y;
1518b434eb95SMatthew G. Knepley   const PetscScalar *x;
1519b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1520b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1521b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1522b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1523b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1524b434eb95SMatthew G. Knepley   PetscScalar       sum;
1525b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1526b434eb95SMatthew G. Knepley 
1527b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1528b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1529b434eb95SMatthew G. Knepley #endif
1530b434eb95SMatthew G. Knepley 
1531b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1532b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1533b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1534b434eb95SMatthew G. Knepley   aj   = a->j;
1535b434eb95SMatthew G. Knepley   aa   = a->a;
1536b434eb95SMatthew G. Knepley   ii   = a->i;
1537b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1538b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1539b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1540b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1541b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1542b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1543b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1544b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1545b434eb95SMatthew G. Knepley       sum         = 0.0;
1546b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1547b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1548b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1549b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1550b434eb95SMatthew G. Knepley     }
1551b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1552b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1553b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1554b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1555b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1556b434eb95SMatthew G. Knepley       sum         = 0.0;
1557b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1558b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1559b434eb95SMatthew G. Knepley       y[i] = sum;
1560b434eb95SMatthew G. Knepley     }
1561b434eb95SMatthew G. Knepley   }
1562b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1563b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1564b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1565b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1566b434eb95SMatthew G. Knepley }
1567b434eb95SMatthew G. Knepley 
1568b434eb95SMatthew G. Knepley #undef __FUNCT__
1569b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1570b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1571b434eb95SMatthew G. Knepley {
1572b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1573b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1574b434eb95SMatthew G. Knepley   const PetscScalar *x;
1575b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1576b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1577b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1578b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1579b434eb95SMatthew G. Knepley   PetscScalar       sum;
1580b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1581b434eb95SMatthew G. Knepley 
1582b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1583b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1584b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1585b434eb95SMatthew G. Knepley   if (zz != yy) {
1586b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1587b434eb95SMatthew G. Knepley   } else {
1588b434eb95SMatthew G. Knepley     z = y;
1589b434eb95SMatthew G. Knepley   }
1590b434eb95SMatthew G. Knepley 
1591b434eb95SMatthew G. Knepley   aj = a->j;
1592b434eb95SMatthew G. Knepley   aa = a->a;
1593b434eb95SMatthew G. Knepley   ii = a->i;
1594b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1595b434eb95SMatthew G. Knepley     if (zz != yy) {
1596b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1597b434eb95SMatthew G. Knepley     }
1598b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1599b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1600b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1601b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1602b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1603b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1604b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1605b434eb95SMatthew G. Knepley       sum = y[*ridx];
1606b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1607b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1608b434eb95SMatthew G. Knepley     }
1609b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1610b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1611b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1612b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1613b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1614b434eb95SMatthew G. Knepley       sum = y[i];
1615b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1616b434eb95SMatthew G. Knepley       z[i] = sum;
1617b434eb95SMatthew G. Knepley     }
1618b434eb95SMatthew G. Knepley   }
1619b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1620b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1621b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1622b434eb95SMatthew G. Knepley   if (zz != yy) {
1623b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1624b434eb95SMatthew G. Knepley   }
1625b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1626b434eb95SMatthew G. Knepley }
1627b434eb95SMatthew G. Knepley 
1628c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
16294a2ae208SSatish Balay #undef __FUNCT__
16304a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1631dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
163217ab2063SBarry Smith {
1633416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1634f15663dcSBarry Smith   PetscScalar       *y,*z;
1635f15663dcSBarry Smith   const PetscScalar *x;
163654f21887SBarry Smith   const MatScalar   *aa;
1637dfbe8321SBarry Smith   PetscErrorCode    ierr;
1638d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
16390298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1640362ced78SSatish Balay   PetscScalar       sum;
1641ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
16429ea0dfa2SSatish Balay 
16433a40ed3dSBarry Smith   PetscFunctionBegin;
1644f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
16451ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
16462e8a6d31SBarry Smith   if (zz != yy) {
16471ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
16482e8a6d31SBarry Smith   } else {
16492e8a6d31SBarry Smith     z = y;
16502e8a6d31SBarry Smith   }
1651bfeeae90SHong Zhang 
165297952fefSHong Zhang   aj = a->j;
165397952fefSHong Zhang   aa = a->a;
1654cddf8d76SBarry Smith   ii = a->i;
16554eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
16564eb6d288SHong Zhang     if (zz != yy) {
16574eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
16584eb6d288SHong Zhang     }
165997952fefSHong Zhang     m    = a->compressedrow.nrows;
166097952fefSHong Zhang     ii   = a->compressedrow.i;
166197952fefSHong Zhang     ridx = a->compressedrow.rindex;
166297952fefSHong Zhang     for (i=0; i<m; i++) {
166397952fefSHong Zhang       n   = ii[i+1] - ii[i];
166497952fefSHong Zhang       aj  = a->j + ii[i];
166597952fefSHong Zhang       aa  = a->a + ii[i];
166697952fefSHong Zhang       sum = y[*ridx];
1667f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
166897952fefSHong Zhang       z[*ridx++] = sum;
166997952fefSHong Zhang     }
167097952fefSHong Zhang   } else { /* do not use compressed row format */
1671f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1672f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1673f15663dcSBarry Smith #else
167417ab2063SBarry Smith     for (i=0; i<m; i++) {
1675f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1676f15663dcSBarry Smith       aj  = a->j + ii[i];
1677f15663dcSBarry Smith       aa  = a->a + ii[i];
167817ab2063SBarry Smith       sum = y[i];
1679f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
168017ab2063SBarry Smith       z[i] = sum;
168117ab2063SBarry Smith     }
168202ab625aSSatish Balay #endif
1683f15663dcSBarry Smith   }
1684dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1685f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
16861ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
16872e8a6d31SBarry Smith   if (zz != yy) {
16881ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
16892e8a6d31SBarry Smith   }
16908154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
16916b375ea7SVictor Minden   /*
1692918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1693918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1694918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
16956b375ea7SVictor Minden   */
1696918e98c3SVictor Minden #endif
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
169817ab2063SBarry Smith }
169917ab2063SBarry Smith 
170017ab2063SBarry Smith /*
170117ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
170217ab2063SBarry Smith */
17034a2ae208SSatish Balay #undef __FUNCT__
17044a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1705dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
170617ab2063SBarry Smith {
1707416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
17086849ba73SBarry Smith   PetscErrorCode ierr;
1709d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
171017ab2063SBarry Smith 
17113a40ed3dSBarry Smith   PetscFunctionBegin;
171209f38230SBarry Smith   if (!a->diag) {
1713785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
17143bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
171509f38230SBarry Smith   }
1716d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
171709f38230SBarry Smith     a->diag[i] = a->i[i+1];
1718bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1719bfeeae90SHong Zhang       if (a->j[j] == i) {
172009f38230SBarry Smith         a->diag[i] = j;
172117ab2063SBarry Smith         break;
172217ab2063SBarry Smith       }
172317ab2063SBarry Smith     }
172417ab2063SBarry Smith   }
17253a40ed3dSBarry Smith   PetscFunctionReturn(0);
172617ab2063SBarry Smith }
172717ab2063SBarry Smith 
1728be5855fcSBarry Smith /*
1729be5855fcSBarry Smith      Checks for missing diagonals
1730be5855fcSBarry Smith */
17314a2ae208SSatish Balay #undef __FUNCT__
17324a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1733ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1734be5855fcSBarry Smith {
1735be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
173697f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1737be5855fcSBarry Smith 
1738be5855fcSBarry Smith   PetscFunctionBegin;
173909f38230SBarry Smith   *missing = PETSC_FALSE;
1740d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
174109f38230SBarry Smith     *missing = PETSC_TRUE;
174209f38230SBarry Smith     if (d) *d = 0;
1743358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
174409f38230SBarry Smith   } else {
1745f1e2ffcdSBarry Smith     diag = a->diag;
1746d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1747bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
174809f38230SBarry Smith         *missing = PETSC_TRUE;
174909f38230SBarry Smith         if (d) *d = i;
175009f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1751358d2f5dSShri Abhyankar         break;
175209f38230SBarry Smith       }
1753be5855fcSBarry Smith     }
1754be5855fcSBarry Smith   }
1755be5855fcSBarry Smith   PetscFunctionReturn(0);
1756be5855fcSBarry Smith }
1757be5855fcSBarry Smith 
175871f1c65dSBarry Smith #undef __FUNCT__
175971f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
17607087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
176171f1c65dSBarry Smith {
176271f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
176371f1c65dSBarry Smith   PetscErrorCode ierr;
1764d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
176554f21887SBarry Smith   MatScalar      *v = a->a;
176654f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
176771f1c65dSBarry Smith 
176871f1c65dSBarry Smith   PetscFunctionBegin;
176971f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
177071f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
177171f1c65dSBarry Smith   diag = a->diag;
177271f1c65dSBarry Smith   if (!a->idiag) {
1773dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
17743bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
177571f1c65dSBarry Smith     v    = a->a;
177671f1c65dSBarry Smith   }
177771f1c65dSBarry Smith   mdiag = a->mdiag;
177871f1c65dSBarry Smith   idiag = a->idiag;
177971f1c65dSBarry Smith 
1780028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
178171f1c65dSBarry Smith     for (i=0; i<m; i++) {
178271f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1783e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
178471f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
178571f1c65dSBarry Smith     }
178671f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
178771f1c65dSBarry Smith   } else {
178871f1c65dSBarry Smith     for (i=0; i<m; i++) {
178971f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
179071f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
179171f1c65dSBarry Smith     }
1792dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
179371f1c65dSBarry Smith   }
179471f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
179571f1c65dSBarry Smith   PetscFunctionReturn(0);
179671f1c65dSBarry Smith }
179771f1c65dSBarry Smith 
1798c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
17994a2ae208SSatish Balay #undef __FUNCT__
180041f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
180141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
180217ab2063SBarry Smith {
1803416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1804e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1805e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
180654f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1807dfbe8321SBarry Smith   PetscErrorCode    ierr;
1808d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
180997f1f81fSBarry Smith   const PetscInt    *idx,*diag;
181017ab2063SBarry Smith 
18113a40ed3dSBarry Smith   PetscFunctionBegin;
1812b965ef7fSBarry Smith   its = its*lits;
181391723122SBarry Smith 
181471f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
181571f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
181671f1c65dSBarry Smith   a->fshift = fshift;
181771f1c65dSBarry Smith   a->omega  = omega;
1818ed480e8bSBarry Smith 
181971f1c65dSBarry Smith   diag  = a->diag;
182071f1c65dSBarry Smith   t     = a->ssor_work;
1821ed480e8bSBarry Smith   idiag = a->idiag;
182271f1c65dSBarry Smith   mdiag = a->mdiag;
1823ed480e8bSBarry Smith 
18241ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
18253649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1826ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
182717ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
182817ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1829ed480e8bSBarry Smith     bs = b;
183017ab2063SBarry Smith     for (i=0; i<m; i++) {
183171f1c65dSBarry Smith       d   = fshift + mdiag[i];
1832416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1833ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1834ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
183517ab2063SBarry Smith       sum = b[i]*d/omega;
1836003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
183717ab2063SBarry Smith       x[i] = sum;
183817ab2063SBarry Smith     }
18391ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18403649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1841efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
18423a40ed3dSBarry Smith     PetscFunctionReturn(0);
184317ab2063SBarry Smith   }
1844c783ea89SBarry Smith 
18452205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
18462205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
184717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1848887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
184917ab2063SBarry Smith 
185017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
185117ab2063SBarry Smith 
1852887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
185317ab2063SBarry Smith     */
185417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
185517ab2063SBarry Smith 
185617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
185717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1858416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1859ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1860ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
186117ab2063SBarry Smith       sum = b[i];
1862e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1863ed480e8bSBarry Smith       x[i] = sum*idiag[i];
186417ab2063SBarry Smith     }
186517ab2063SBarry Smith 
186617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1867416022c9SBarry Smith     v = a->a;
18682205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
186917ab2063SBarry Smith 
187017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1871ed480e8bSBarry Smith     ts   = t;
1872416022c9SBarry Smith     diag = a->diag;
187317ab2063SBarry Smith     for (i=0; i<m; i++) {
1874416022c9SBarry Smith       n   = diag[i] - a->i[i];
1875ed480e8bSBarry Smith       idx = a->j + a->i[i];
1876ed480e8bSBarry Smith       v   = a->a + a->i[i];
187717ab2063SBarry Smith       sum = t[i];
1878003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1879ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1880733d66baSBarry Smith       /*  x = x + t */
1881733d66baSBarry Smith       x[i] += t[i];
188217ab2063SBarry Smith     }
188317ab2063SBarry Smith 
1884dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
18851ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18863649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
18873a40ed3dSBarry Smith     PetscFunctionReturn(0);
188817ab2063SBarry Smith   }
188917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
189017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
189117ab2063SBarry Smith       for (i=0; i<m; i++) {
1892416022c9SBarry Smith         n   = diag[i] - a->i[i];
1893ed480e8bSBarry Smith         idx = a->j + a->i[i];
1894ed480e8bSBarry Smith         v   = a->a + a->i[i];
189517ab2063SBarry Smith         sum = b[i];
1896e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
18975c99c7daSBarry Smith         t[i] = sum;
1898ed480e8bSBarry Smith         x[i] = sum*idiag[i];
189917ab2063SBarry Smith       }
19005c99c7daSBarry Smith       xb   = t;
1901efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
19023a40ed3dSBarry Smith     } else xb = b;
190317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
190417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1905416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1906ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1907ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
190817ab2063SBarry Smith         sum = xb[i];
1909e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
19105c99c7daSBarry Smith         if (xb == b) {
1911ed480e8bSBarry Smith           x[i] = sum*idiag[i];
19125c99c7daSBarry Smith         } else {
1913b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
191417ab2063SBarry Smith         }
19155c99c7daSBarry Smith       }
1916b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
191717ab2063SBarry Smith     }
191817ab2063SBarry Smith     its--;
191917ab2063SBarry Smith   }
192017ab2063SBarry Smith   while (its--) {
192117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
192217ab2063SBarry Smith       for (i=0; i<m; i++) {
1923b19a5dc2SMark Adams         /* lower */
1924b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1925ed480e8bSBarry Smith         idx = a->j + a->i[i];
1926ed480e8bSBarry Smith         v   = a->a + a->i[i];
192717ab2063SBarry Smith         sum = b[i];
1928e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1929b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1930b19a5dc2SMark Adams         /* upper */
1931b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1932b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1933b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1934b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1935b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
193617ab2063SBarry Smith       }
1937b19a5dc2SMark Adams       xb   = t;
19389f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1939b19a5dc2SMark Adams     } else xb = b;
194017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
194117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1942b19a5dc2SMark Adams         sum = xb[i];
1943b19a5dc2SMark Adams         if (xb == b) {
1944b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1945416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1946ed480e8bSBarry Smith           idx = a->j + a->i[i];
1947ed480e8bSBarry Smith           v   = a->a + a->i[i];
1948e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1949ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1950b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1951b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1952b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1953b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1954b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1955b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
195617ab2063SBarry Smith         }
1957b19a5dc2SMark Adams       }
1958b19a5dc2SMark Adams       if (xb == b) {
19599f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1960b19a5dc2SMark Adams       } else {
1961b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1962b19a5dc2SMark Adams       }
196317ab2063SBarry Smith     }
196417ab2063SBarry Smith   }
19651ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
19663649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1967365a8a9eSBarry Smith   PetscFunctionReturn(0);
196817ab2063SBarry Smith }
196917ab2063SBarry Smith 
19702af78befSBarry Smith 
19714a2ae208SSatish Balay #undef __FUNCT__
19724a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1973dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
197417ab2063SBarry Smith {
1975416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19764e220ebcSLois Curfman McInnes 
19773a40ed3dSBarry Smith   PetscFunctionBegin;
19784e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
19794e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
19804e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
19814e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
19824e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
19838e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
19847adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1985d5f3da31SBarry Smith   if (A->factortype) {
19864e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
19874e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
19884e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
19894e220ebcSLois Curfman McInnes   } else {
19904e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
19914e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
19924e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
19934e220ebcSLois Curfman McInnes   }
19943a40ed3dSBarry Smith   PetscFunctionReturn(0);
199517ab2063SBarry Smith }
199617ab2063SBarry Smith 
19974a2ae208SSatish Balay #undef __FUNCT__
19984a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
19992b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
200017ab2063SBarry Smith {
2001416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
20023b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
20036849ba73SBarry Smith   PetscErrorCode    ierr;
200497b48c8fSBarry Smith   const PetscScalar *xx;
200597b48c8fSBarry Smith   PetscScalar       *bb;
2006ace3abfcSBarry Smith   PetscBool         missing;
200717ab2063SBarry Smith 
20083a40ed3dSBarry Smith   PetscFunctionBegin;
200997b48c8fSBarry Smith   if (x && b) {
201097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
201197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
201297b48c8fSBarry Smith     for (i=0; i<N; i++) {
201397b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
201497b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
201597b48c8fSBarry Smith     }
201697b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
201797b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
201897b48c8fSBarry Smith   }
201997b48c8fSBarry Smith 
2020a9817697SBarry Smith   if (a->keepnonzeropattern) {
2021f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
2022e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
2023bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
2024f1e2ffcdSBarry Smith     }
2025f4df32b1SMatthew Knepley     if (diag != 0.0) {
202609f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
2027e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
2028f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
2029f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
2030f1e2ffcdSBarry Smith       }
2031f1e2ffcdSBarry Smith     }
203288e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
2033f1e2ffcdSBarry Smith   } else {
2034f4df32b1SMatthew Knepley     if (diag != 0.0) {
203517ab2063SBarry Smith       for (i=0; i<N; i++) {
2036e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
20377ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
2038416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
2039f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
2040bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
20417ae801bdSBarry Smith         } else { /* in case row was completely empty */
2042f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
204317ab2063SBarry Smith         }
204417ab2063SBarry Smith       }
20453a40ed3dSBarry Smith     } else {
204617ab2063SBarry Smith       for (i=0; i<N; i++) {
2047e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
2048416022c9SBarry Smith         a->ilen[rows[i]] = 0;
204917ab2063SBarry Smith       }
205017ab2063SBarry Smith     }
205188e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
2052f1e2ffcdSBarry Smith   }
205343a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20543a40ed3dSBarry Smith   PetscFunctionReturn(0);
205517ab2063SBarry Smith }
205617ab2063SBarry Smith 
20574a2ae208SSatish Balay #undef __FUNCT__
20586e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
20596e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20606e169961SBarry Smith {
20616e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
20626e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
20636e169961SBarry Smith   PetscErrorCode    ierr;
20642b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
20656e169961SBarry Smith   const PetscScalar *xx;
20666e169961SBarry Smith   PetscScalar       *bb;
20676e169961SBarry Smith 
20686e169961SBarry Smith   PetscFunctionBegin;
20696e169961SBarry Smith   if (x && b) {
20706e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
20716e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
20722b40b63fSBarry Smith     vecs = PETSC_TRUE;
20736e169961SBarry Smith   }
20741795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
20756e169961SBarry Smith   for (i=0; i<N; i++) {
20766e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
20776e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
20782205254eSKarl Rupp 
20796e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
20806e169961SBarry Smith   }
20816e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
20826e169961SBarry Smith     if (!zeroed[i]) {
20836e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
20846e169961SBarry Smith         if (zeroed[a->j[j]]) {
20852b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
20866e169961SBarry Smith           a->a[j] = 0.0;
20876e169961SBarry Smith         }
20886e169961SBarry Smith       }
20892b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
20906e169961SBarry Smith   }
20916e169961SBarry Smith   if (x && b) {
20926e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
20936e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
20946e169961SBarry Smith   }
20956e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
20966e169961SBarry Smith   if (diag != 0.0) {
20976e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
20986e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
20996e169961SBarry Smith     for (i=0; i<N; i++) {
21006e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
21016e169961SBarry Smith     }
21026e169961SBarry Smith   }
21036e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
21046e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21056e169961SBarry Smith   PetscFunctionReturn(0);
21066e169961SBarry Smith }
21076e169961SBarry Smith 
21086e169961SBarry Smith #undef __FUNCT__
21094a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
2110a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
211117ab2063SBarry Smith {
2112416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
211397f1f81fSBarry Smith   PetscInt   *itmp;
211417ab2063SBarry Smith 
21153a40ed3dSBarry Smith   PetscFunctionBegin;
2116e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
211717ab2063SBarry Smith 
2118416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
2119bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
212017ab2063SBarry Smith   if (idx) {
2121bfeeae90SHong Zhang     itmp = a->j + a->i[row];
212226fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
212317ab2063SBarry Smith     else *idx = 0;
212417ab2063SBarry Smith   }
21253a40ed3dSBarry Smith   PetscFunctionReturn(0);
212617ab2063SBarry Smith }
212717ab2063SBarry Smith 
2128bfeeae90SHong Zhang /* remove this function? */
21294a2ae208SSatish Balay #undef __FUNCT__
21304a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
2131a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
213217ab2063SBarry Smith {
21333a40ed3dSBarry Smith   PetscFunctionBegin;
21343a40ed3dSBarry Smith   PetscFunctionReturn(0);
213517ab2063SBarry Smith }
213617ab2063SBarry Smith 
21374a2ae208SSatish Balay #undef __FUNCT__
21384a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
2139dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
214017ab2063SBarry Smith {
2141416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
214254f21887SBarry Smith   MatScalar      *v  = a->a;
214336db0b34SBarry Smith   PetscReal      sum = 0.0;
21446849ba73SBarry Smith   PetscErrorCode ierr;
214597f1f81fSBarry Smith   PetscInt       i,j;
214617ab2063SBarry Smith 
21473a40ed3dSBarry Smith   PetscFunctionBegin;
214817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2149416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
215036db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
215117ab2063SBarry Smith     }
21528f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
21533a40ed3dSBarry Smith   } else if (type == NORM_1) {
215436db0b34SBarry Smith     PetscReal *tmp;
215597f1f81fSBarry Smith     PetscInt  *jj = a->j;
21561795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2157064f8208SBarry Smith     *nrm = 0.0;
2158416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2159bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
216017ab2063SBarry Smith     }
2161d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2162064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
216317ab2063SBarry Smith     }
2164606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
21653a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2166064f8208SBarry Smith     *nrm = 0.0;
2167d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2168bfeeae90SHong Zhang       v   = a->a + a->i[j];
216917ab2063SBarry Smith       sum = 0.0;
2170416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2171cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
217217ab2063SBarry Smith       }
2173064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
217417ab2063SBarry Smith     }
2175f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
21763a40ed3dSBarry Smith   PetscFunctionReturn(0);
217717ab2063SBarry Smith }
217817ab2063SBarry Smith 
21794e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
21804e938277SHong Zhang #undef __FUNCT__
21814e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
21824e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
21834e938277SHong Zhang {
21844e938277SHong Zhang   PetscErrorCode ierr;
21854e938277SHong Zhang   PetscInt       i,j,anzj;
21864e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
21874e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
21884e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
21894e938277SHong Zhang 
21904e938277SHong Zhang   PetscFunctionBegin;
21914e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
21921795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2193785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2194785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
21954e938277SHong Zhang 
21964e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
21974e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
219826fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
21994e938277SHong Zhang   /* Form ati for csr format of A^T. */
220026fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
22014e938277SHong Zhang 
22024e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
22034e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
22044e938277SHong Zhang 
22054e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
22064e938277SHong Zhang   for (i=0;i<am;i++) {
22074e938277SHong Zhang     anzj = ai[i+1] - ai[i];
22084e938277SHong Zhang     for (j=0;j<anzj;j++) {
22094e938277SHong Zhang       atj[atfill[*aj]] = i;
22104e938277SHong Zhang       atfill[*aj++]   += 1;
22114e938277SHong Zhang     }
22124e938277SHong Zhang   }
22134e938277SHong Zhang 
22144e938277SHong Zhang   /* Clean up temporary space and complete requests. */
22154e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2216ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
22172205254eSKarl Rupp 
2218a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2219a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2220a2f3521dSMark F. Adams 
22214e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
22224e938277SHong Zhang   b->free_a  = PETSC_FALSE;
22234e938277SHong Zhang   b->free_ij = PETSC_TRUE;
22244e938277SHong Zhang   b->nonew   = 0;
22254e938277SHong Zhang   PetscFunctionReturn(0);
22264e938277SHong Zhang }
22274e938277SHong Zhang 
22284a2ae208SSatish Balay #undef __FUNCT__
22294a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2230fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
223117ab2063SBarry Smith {
2232416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2233416022c9SBarry Smith   Mat            C;
22346849ba73SBarry Smith   PetscErrorCode ierr;
2235d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
223654f21887SBarry Smith   MatScalar      *array = a->a;
223717ab2063SBarry Smith 
22383a40ed3dSBarry Smith   PetscFunctionBegin;
2239e32f2f54SBarry 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");
2240fc4dec0aSBarry Smith 
2241fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
22421795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2243bfeeae90SHong Zhang 
2244bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2245ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2246d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2247a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
22487adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2249ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2250606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2251a541d17aSBarry Smith   } else {
2252a541d17aSBarry Smith     C = *B;
2253a541d17aSBarry Smith   }
2254a541d17aSBarry Smith 
225517ab2063SBarry Smith   for (i=0; i<m; i++) {
225617ab2063SBarry Smith     len    = ai[i+1]-ai[i];
225787d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2258b9b97703SBarry Smith     array += len;
2259b9b97703SBarry Smith     aj    += len;
226017ab2063SBarry Smith   }
22616d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22626d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
226317ab2063SBarry Smith 
2264815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2265416022c9SBarry Smith     *B = C;
226617ab2063SBarry Smith   } else {
2267eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
226817ab2063SBarry Smith   }
22693a40ed3dSBarry Smith   PetscFunctionReturn(0);
227017ab2063SBarry Smith }
227117ab2063SBarry Smith 
2272cd0d46ebSvictorle #undef __FUNCT__
22735fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
22747087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2275cd0d46ebSvictorle {
2276cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
227754f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
227854f21887SBarry Smith   MatScalar      *va,*vb;
22796849ba73SBarry Smith   PetscErrorCode ierr;
228097f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2281cd0d46ebSvictorle 
2282cd0d46ebSvictorle   PetscFunctionBegin;
2283cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2284cd0d46ebSvictorle 
2285cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2286cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22875485867bSBarry Smith   if (ma!=nb || na!=mb) {
22885485867bSBarry Smith     *f = PETSC_FALSE;
22895485867bSBarry Smith     PetscFunctionReturn(0);
22905485867bSBarry Smith   }
2291cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2292cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2293cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2294785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2295785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2296cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2297cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2298cd0d46ebSvictorle 
2299cd0d46ebSvictorle   *f = PETSC_TRUE;
2300cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2301cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
230297f1f81fSBarry Smith       PetscInt    idc,idr;
23035485867bSBarry Smith       PetscScalar vc,vr;
2304cd0d46ebSvictorle       /* column/row index/value */
23055485867bSBarry Smith       idc = adx[aptr[i]];
23065485867bSBarry Smith       idr = bdx[bptr[idc]];
23075485867bSBarry Smith       vc  = va[aptr[i]];
23085485867bSBarry Smith       vr  = vb[bptr[idc]];
23095485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
23105485867bSBarry Smith         *f = PETSC_FALSE;
23115485867bSBarry Smith         goto done;
2312cd0d46ebSvictorle       } else {
23135485867bSBarry Smith         aptr[i]++;
23145485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2315cd0d46ebSvictorle       }
2316cd0d46ebSvictorle     }
2317cd0d46ebSvictorle   }
2318cd0d46ebSvictorle done:
2319cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
23203aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2321cd0d46ebSvictorle   PetscFunctionReturn(0);
2322cd0d46ebSvictorle }
2323cd0d46ebSvictorle 
23241cbb95d3SBarry Smith #undef __FUNCT__
23251cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
23267087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
23271cbb95d3SBarry Smith {
23281cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
232954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
233054f21887SBarry Smith   MatScalar      *va,*vb;
23311cbb95d3SBarry Smith   PetscErrorCode ierr;
23321cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
23331cbb95d3SBarry Smith 
23341cbb95d3SBarry Smith   PetscFunctionBegin;
23351cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
23361cbb95d3SBarry Smith 
23371cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
23381cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
23391cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
23401cbb95d3SBarry Smith     *f = PETSC_FALSE;
23411cbb95d3SBarry Smith     PetscFunctionReturn(0);
23421cbb95d3SBarry Smith   }
23431cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
23441cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
23451cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2346785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2347785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
23481cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
23491cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
23501cbb95d3SBarry Smith 
23511cbb95d3SBarry Smith   *f = PETSC_TRUE;
23521cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
23531cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
23541cbb95d3SBarry Smith       PetscInt    idc,idr;
23551cbb95d3SBarry Smith       PetscScalar vc,vr;
23561cbb95d3SBarry Smith       /* column/row index/value */
23571cbb95d3SBarry Smith       idc = adx[aptr[i]];
23581cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
23591cbb95d3SBarry Smith       vc  = va[aptr[i]];
23601cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
23611cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
23621cbb95d3SBarry Smith         *f = PETSC_FALSE;
23631cbb95d3SBarry Smith         goto done;
23641cbb95d3SBarry Smith       } else {
23651cbb95d3SBarry Smith         aptr[i]++;
23661cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
23671cbb95d3SBarry Smith       }
23681cbb95d3SBarry Smith     }
23691cbb95d3SBarry Smith   }
23701cbb95d3SBarry Smith done:
23711cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
23721cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
23731cbb95d3SBarry Smith   PetscFunctionReturn(0);
23741cbb95d3SBarry Smith }
23751cbb95d3SBarry Smith 
23769e29f15eSvictorle #undef __FUNCT__
23779e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2378ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
23799e29f15eSvictorle {
2380dfbe8321SBarry Smith   PetscErrorCode ierr;
23816e111a19SKarl Rupp 
23829e29f15eSvictorle   PetscFunctionBegin;
23835485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
23849e29f15eSvictorle   PetscFunctionReturn(0);
23859e29f15eSvictorle }
23869e29f15eSvictorle 
23874a2ae208SSatish Balay #undef __FUNCT__
23881cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2389ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
23901cbb95d3SBarry Smith {
23911cbb95d3SBarry Smith   PetscErrorCode ierr;
23926e111a19SKarl Rupp 
23931cbb95d3SBarry Smith   PetscFunctionBegin;
23941cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
23951cbb95d3SBarry Smith   PetscFunctionReturn(0);
23961cbb95d3SBarry Smith }
23971cbb95d3SBarry Smith 
23981cbb95d3SBarry Smith #undef __FUNCT__
23994a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2400dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
240117ab2063SBarry Smith {
2402416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
240354f21887SBarry Smith   PetscScalar    *l,*r,x;
240454f21887SBarry Smith   MatScalar      *v;
2405dfbe8321SBarry Smith   PetscErrorCode ierr;
2406d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
240717ab2063SBarry Smith 
24083a40ed3dSBarry Smith   PetscFunctionBegin;
240917ab2063SBarry Smith   if (ll) {
24103ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
24113ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2412e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2413e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
24141ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2415416022c9SBarry Smith     v    = a->a;
241617ab2063SBarry Smith     for (i=0; i<m; i++) {
241717ab2063SBarry Smith       x = l[i];
2418416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
24192205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
242017ab2063SBarry Smith     }
24211ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2422efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
242317ab2063SBarry Smith   }
242417ab2063SBarry Smith   if (rr) {
2425e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2426e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
24271ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2428416022c9SBarry Smith     v    = a->a; jj = a->j;
24292205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
24301ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2431efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
243217ab2063SBarry Smith   }
2433acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
24343a40ed3dSBarry Smith   PetscFunctionReturn(0);
243517ab2063SBarry Smith }
243617ab2063SBarry Smith 
24374a2ae208SSatish Balay #undef __FUNCT__
24384a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
243997f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
244017ab2063SBarry Smith {
2441db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
24426849ba73SBarry Smith   PetscErrorCode ierr;
2443d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
244497f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
24455d0c19d7SBarry Smith   const PetscInt *irow,*icol;
24465d0c19d7SBarry Smith   PetscInt       nrows,ncols;
244797f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
244854f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2449416022c9SBarry Smith   Mat            C;
2450ace3abfcSBarry Smith   PetscBool      stride,sorted;
245117ab2063SBarry Smith 
24523a40ed3dSBarry Smith   PetscFunctionBegin;
245314ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2454e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
245514ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2456e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
245799141d43SSatish Balay 
245817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2459b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2460b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
246117ab2063SBarry Smith 
2462fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2463251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2464fee21e36SBarry Smith   if (stride && step == 1) {
246502834360SBarry Smith     /* special case of contiguous rows */
2466dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
246702834360SBarry Smith     /* loop over new rows determining lens and starting points */
246802834360SBarry Smith     for (i=0; i<nrows; i++) {
2469bfeeae90SHong Zhang       kstart = ai[irow[i]];
2470a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
247102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2472bfeeae90SHong Zhang         if (aj[k] >= first) {
247302834360SBarry Smith           starts[i] = k;
247402834360SBarry Smith           break;
247502834360SBarry Smith         }
247602834360SBarry Smith       }
2477a2744918SBarry Smith       sum = 0;
247802834360SBarry Smith       while (k < kend) {
2479bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2480a2744918SBarry Smith         sum++;
248102834360SBarry Smith       }
2482a2744918SBarry Smith       lens[i] = sum;
248302834360SBarry Smith     }
248402834360SBarry Smith     /* create submatrix */
2485cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
248697f1f81fSBarry Smith       PetscInt n_cols,n_rows;
248708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2488e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2489d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
249008480c60SBarry Smith       C    = *B;
24913a40ed3dSBarry Smith     } else {
24923bef6203SJed Brown       PetscInt rbs,cbs;
2493ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2494f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24953bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24963bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24973bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24987adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2499ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
250008480c60SBarry Smith     }
2501db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2502db02288aSLois Curfman McInnes 
250302834360SBarry Smith     /* loop over rows inserting into submatrix */
2504db02288aSLois Curfman McInnes     a_new = c->a;
2505db02288aSLois Curfman McInnes     j_new = c->j;
2506db02288aSLois Curfman McInnes     i_new = c->i;
2507bfeeae90SHong Zhang 
250802834360SBarry Smith     for (i=0; i<nrows; i++) {
2509a2744918SBarry Smith       ii    = starts[i];
2510a2744918SBarry Smith       lensi = lens[i];
2511a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2512a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
251302834360SBarry Smith       }
251487828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2515a2744918SBarry Smith       a_new     += lensi;
2516a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2517a2744918SBarry Smith       c->ilen[i] = lensi;
251802834360SBarry Smith     }
25190e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
25203a40ed3dSBarry Smith   } else {
252102834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
25221795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2523785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
25244dcab191SBarry Smith     for (i=0; i<ncols; i++) {
25254dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
25264dcab191SBarry 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);
25274dcab191SBarry Smith #endif
25284dcab191SBarry Smith       smap[icol[i]] = i+1;
25294dcab191SBarry Smith     }
25304dcab191SBarry Smith 
253102834360SBarry Smith     /* determine lens of each row */
253202834360SBarry Smith     for (i=0; i<nrows; i++) {
2533bfeeae90SHong Zhang       kstart  = ai[irow[i]];
253402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
253502834360SBarry Smith       lens[i] = 0;
253602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2537bfeeae90SHong Zhang         if (smap[aj[k]]) {
253802834360SBarry Smith           lens[i]++;
253902834360SBarry Smith         }
254002834360SBarry Smith       }
254102834360SBarry Smith     }
254217ab2063SBarry Smith     /* Create and fill new matrix */
2543a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2544ace3abfcSBarry Smith       PetscBool equal;
25450f5bd95cSBarry Smith 
254699141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2547e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2548d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2549f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2550d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
255108480c60SBarry Smith       C    = *B;
25523a40ed3dSBarry Smith     } else {
25533bef6203SJed Brown       PetscInt rbs,cbs;
2554ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2555f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
25563bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
25573bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
25583bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
25597adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2560ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
256108480c60SBarry Smith     }
256299141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
256317ab2063SBarry Smith     for (i=0; i<nrows; i++) {
256499141d43SSatish Balay       row      = irow[i];
2565bfeeae90SHong Zhang       kstart   = ai[row];
256699141d43SSatish Balay       kend     = kstart + a->ilen[row];
2567bfeeae90SHong Zhang       mat_i    = c->i[i];
256899141d43SSatish Balay       mat_j    = c->j + mat_i;
256999141d43SSatish Balay       mat_a    = c->a + mat_i;
257099141d43SSatish Balay       mat_ilen = c->ilen + i;
257117ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2572bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2573ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
257499141d43SSatish Balay           *mat_a++ = a->a[k];
257599141d43SSatish Balay           (*mat_ilen)++;
257699141d43SSatish Balay 
257717ab2063SBarry Smith         }
257817ab2063SBarry Smith       }
257917ab2063SBarry Smith     }
258002834360SBarry Smith     /* Free work space */
258102834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2582606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2583606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
258402834360SBarry Smith   }
25856d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
25866d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
258717ab2063SBarry Smith 
258817ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2589416022c9SBarry Smith   *B   = C;
25903a40ed3dSBarry Smith   PetscFunctionReturn(0);
259117ab2063SBarry Smith }
259217ab2063SBarry Smith 
25931df811f5SHong Zhang #undef __FUNCT__
259482d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2595fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
259682d44351SHong Zhang {
259782d44351SHong Zhang   PetscErrorCode ierr;
259882d44351SHong Zhang   Mat            B;
259982d44351SHong Zhang 
260082d44351SHong Zhang   PetscFunctionBegin;
2601c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
260282d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
260382d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2604a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
260582d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
260682d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
260782d44351SHong Zhang     *subMat = B;
2608c2d650bdSHong Zhang   } else {
2609c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2610c2d650bdSHong Zhang   }
261182d44351SHong Zhang   PetscFunctionReturn(0);
261282d44351SHong Zhang }
261382d44351SHong Zhang 
261482d44351SHong Zhang #undef __FUNCT__
26154a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
26160481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2617a871dcd8SBarry Smith {
261863b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2619dfbe8321SBarry Smith   PetscErrorCode ierr;
262063b91edcSBarry Smith   Mat            outA;
2621ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
262263b91edcSBarry Smith 
26233a40ed3dSBarry Smith   PetscFunctionBegin;
2624e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
26251df811f5SHong Zhang 
2626b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2627b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2628a871dcd8SBarry Smith 
262963b91edcSBarry Smith   outA             = inA;
2630d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
26312205254eSKarl Rupp 
2632c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
26336bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
26342205254eSKarl Rupp 
2635c3122656SLisandro Dalcin   a->row = row;
26362205254eSKarl Rupp 
2637c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
26386bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
26392205254eSKarl Rupp 
2640c3122656SLisandro Dalcin   a->col = col;
264163b91edcSBarry Smith 
264236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
26436bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
26444c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
26453bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2646f0ec6fceSSatish Balay 
264794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2648785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
26493bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
265094a9d846SBarry Smith   }
265163b91edcSBarry Smith 
2652f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2653137fb511SHong Zhang   if (row_identity && col_identity) {
2654ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2655137fb511SHong Zhang   } else {
2656719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2657137fb511SHong Zhang   }
26583a40ed3dSBarry Smith   PetscFunctionReturn(0);
2659a871dcd8SBarry Smith }
2660a871dcd8SBarry Smith 
26614a2ae208SSatish Balay #undef __FUNCT__
26624a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2663f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2664f0b747eeSBarry Smith {
2665f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2666f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2667efee365bSSatish Balay   PetscErrorCode ierr;
2668c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
26693a40ed3dSBarry Smith 
26703a40ed3dSBarry Smith   PetscFunctionBegin;
2671c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
26728b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2673efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2674acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
26753a40ed3dSBarry Smith   PetscFunctionReturn(0);
2676f0b747eeSBarry Smith }
2677f0b747eeSBarry Smith 
26784a2ae208SSatish Balay #undef __FUNCT__
26794a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
268097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2681cddf8d76SBarry Smith {
2682dfbe8321SBarry Smith   PetscErrorCode ierr;
268397f1f81fSBarry Smith   PetscInt       i;
2684cddf8d76SBarry Smith 
26853a40ed3dSBarry Smith   PetscFunctionBegin;
2686cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2687785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2688cddf8d76SBarry Smith   }
2689cddf8d76SBarry Smith 
2690cddf8d76SBarry Smith   for (i=0; i<n; i++) {
26916a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2692cddf8d76SBarry Smith   }
26933a40ed3dSBarry Smith   PetscFunctionReturn(0);
2694cddf8d76SBarry Smith }
2695cddf8d76SBarry Smith 
26964a2ae208SSatish Balay #undef __FUNCT__
26974a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
269897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
26994dcbc457SBarry Smith {
2700e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
27016849ba73SBarry Smith   PetscErrorCode ierr;
27025d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
27035d0c19d7SBarry Smith   const PetscInt *idx;
270497f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2705f1af5d2fSBarry Smith   PetscBT        table;
2706bbd702dbSSatish Balay 
27073a40ed3dSBarry Smith   PetscFunctionBegin;
2708d0f46423SBarry Smith   m  = A->rmap->n;
2709e4d965acSSatish Balay   ai = a->i;
2710bfeeae90SHong Zhang   aj = a->j;
27118a047759SSatish Balay 
2712e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
271306763907SSatish Balay 
2714785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
271553b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
271606763907SSatish Balay 
2717e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2718b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2719e4d965acSSatish Balay     isz  = 0;
27206831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2721e4d965acSSatish Balay 
2722e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
27234dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2724b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2725e4d965acSSatish Balay 
2726dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2727e4d965acSSatish Balay     for (j=0; j<n; ++j) {
27282205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
27294dcbc457SBarry Smith     }
273006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
27316bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2732e4d965acSSatish Balay 
273304a348a9SBarry Smith     k = 0;
273404a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
273504a348a9SBarry Smith       n = isz;
273606763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2737e4d965acSSatish Balay         row   = nidx[k];
2738e4d965acSSatish Balay         start = ai[row];
2739e4d965acSSatish Balay         end   = ai[row+1];
274004a348a9SBarry Smith         for (l = start; l<end; l++) {
2741efb16452SHong Zhang           val = aj[l];
27422205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2743e4d965acSSatish Balay         }
2744e4d965acSSatish Balay       }
2745e4d965acSSatish Balay     }
274670b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2747e4d965acSSatish Balay   }
274894bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2749606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
27503a40ed3dSBarry Smith   PetscFunctionReturn(0);
27514dcbc457SBarry Smith }
275217ab2063SBarry Smith 
27530513a670SBarry Smith /* -------------------------------------------------------------- */
27544a2ae208SSatish Balay #undef __FUNCT__
27554a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2756dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
27570513a670SBarry Smith {
27580513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
27596849ba73SBarry Smith   PetscErrorCode ierr;
27603b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
27615d0c19d7SBarry Smith   const PetscInt *row,*col;
27625d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
276356cd22aeSBarry Smith   IS             icolp,irowp;
27640298fd71SBarry Smith   PetscInt       *cwork = NULL;
27650298fd71SBarry Smith   PetscScalar    *vwork = NULL;
27660513a670SBarry Smith 
27673a40ed3dSBarry Smith   PetscFunctionBegin;
27684c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
276956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
27704c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
277156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
27720513a670SBarry Smith 
27730513a670SBarry Smith   /* determine lengths of permuted rows */
2774785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
27752205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2776ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2777f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2778a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
27797adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2780ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2781606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
27820513a670SBarry Smith 
2783785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
27840513a670SBarry Smith   for (i=0; i<m; i++) {
278532ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
27862205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2787cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
278832ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
27890513a670SBarry Smith   }
2790606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
27912205254eSKarl Rupp 
27923c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
27932205254eSKarl Rupp 
27940513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
27950513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
279656cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
279756cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
27986bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
27996bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
28003a40ed3dSBarry Smith   PetscFunctionReturn(0);
28010513a670SBarry Smith }
28020513a670SBarry Smith 
28034a2ae208SSatish Balay #undef __FUNCT__
28044a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2805dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2806cb5b572fSBarry Smith {
2807dfbe8321SBarry Smith   PetscErrorCode ierr;
2808cb5b572fSBarry Smith 
2809cb5b572fSBarry Smith   PetscFunctionBegin;
281033f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
281133f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2812be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2813be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2814be6bf707SBarry Smith 
2815700c5bfcSBarry 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");
2816d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2817cb5b572fSBarry Smith   } else {
2818cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2819cb5b572fSBarry Smith   }
2820cb5b572fSBarry Smith   PetscFunctionReturn(0);
2821cb5b572fSBarry Smith }
2822cb5b572fSBarry Smith 
28234a2ae208SSatish Balay #undef __FUNCT__
28244994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
28254994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2826273d9f13SBarry Smith {
2827dfbe8321SBarry Smith   PetscErrorCode ierr;
2828273d9f13SBarry Smith 
2829273d9f13SBarry Smith   PetscFunctionBegin;
2830ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2831273d9f13SBarry Smith   PetscFunctionReturn(0);
2832273d9f13SBarry Smith }
2833273d9f13SBarry Smith 
28344a2ae208SSatish Balay #undef __FUNCT__
28358c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
28368c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
28376c0721eeSBarry Smith {
28386c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
28396e111a19SKarl Rupp 
28406c0721eeSBarry Smith   PetscFunctionBegin;
28416c0721eeSBarry Smith   *array = a->a;
28426c0721eeSBarry Smith   PetscFunctionReturn(0);
28436c0721eeSBarry Smith }
28446c0721eeSBarry Smith 
28454a2ae208SSatish Balay #undef __FUNCT__
28468c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
28478c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
28486c0721eeSBarry Smith {
28496c0721eeSBarry Smith   PetscFunctionBegin;
28506c0721eeSBarry Smith   PetscFunctionReturn(0);
28516c0721eeSBarry Smith }
2852273d9f13SBarry Smith 
28538229c054SShri Abhyankar /*
28548229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
28558229c054SShri Abhyankar    have different nonzero structure.
28568229c054SShri Abhyankar */
2857ac90fabeSBarry Smith #undef __FUNCT__
28588229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
28598229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2860ec7775f6SShri Abhyankar {
28618229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2862ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2863ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2864ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2865ec7775f6SShri Abhyankar 
2866ec7775f6SShri Abhyankar   PetscFunctionBegin;
2867ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2868ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
28698af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
28708af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
28718af7cee1SJed Brown     nnz[i] = 0;
28728af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
28738af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
28748af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
28758af7cee1SJed Brown       nnz[i]++;
28768af7cee1SJed Brown     }
28778af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2878ec7775f6SShri Abhyankar   }
2879ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2880ec7775f6SShri Abhyankar }
2881ec7775f6SShri Abhyankar 
2882ec7775f6SShri Abhyankar #undef __FUNCT__
2883ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2884f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2885ac90fabeSBarry Smith {
2886dfbe8321SBarry Smith   PetscErrorCode ierr;
288797f1f81fSBarry Smith   PetscInt       i;
2888ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2889c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2890ac90fabeSBarry Smith 
2891ac90fabeSBarry Smith   PetscFunctionBegin;
2892c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2893ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2894f4df32b1SMatthew Knepley     PetscScalar alpha = a;
28958b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2896acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2897c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2898a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2899a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
29006bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2901a30b2313SHong Zhang     }
2902a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
29030298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2904a30b2313SHong Zhang       y->XtoY = X;
2905407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2906c537a176SHong Zhang     }
2907f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2908ba0e910bSBarry 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);
2909ac90fabeSBarry Smith   } else {
29108229c054SShri Abhyankar     Mat      B;
29118229c054SShri Abhyankar     PetscInt *nnz;
2912785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2913ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2914bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
29154aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2916a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2917176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
29188229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2919ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2920ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2921ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
29228229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2923ac90fabeSBarry Smith   }
2924ac90fabeSBarry Smith   PetscFunctionReturn(0);
2925ac90fabeSBarry Smith }
2926ac90fabeSBarry Smith 
2927521d7252SBarry Smith #undef __FUNCT__
2928354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
29297087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2930354c94deSBarry Smith {
2931354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2932354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2933354c94deSBarry Smith   PetscInt    i,nz;
2934354c94deSBarry Smith   PetscScalar *a;
2935354c94deSBarry Smith 
2936354c94deSBarry Smith   PetscFunctionBegin;
2937354c94deSBarry Smith   nz = aij->nz;
2938354c94deSBarry Smith   a  = aij->a;
29392205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2940354c94deSBarry Smith #else
2941354c94deSBarry Smith   PetscFunctionBegin;
2942354c94deSBarry Smith #endif
2943354c94deSBarry Smith   PetscFunctionReturn(0);
2944354c94deSBarry Smith }
2945354c94deSBarry Smith 
2946e34fafa9SBarry Smith #undef __FUNCT__
2947985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2948985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2949e34fafa9SBarry Smith {
2950e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2951e34fafa9SBarry Smith   PetscErrorCode ierr;
2952d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2953e34fafa9SBarry Smith   PetscReal      atmp;
2954985db425SBarry Smith   PetscScalar    *x;
2955e34fafa9SBarry Smith   MatScalar      *aa;
2956e34fafa9SBarry Smith 
2957e34fafa9SBarry Smith   PetscFunctionBegin;
2958e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2959e34fafa9SBarry Smith   aa = a->a;
2960e34fafa9SBarry Smith   ai = a->i;
2961e34fafa9SBarry Smith   aj = a->j;
2962e34fafa9SBarry Smith 
2963985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2964e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2965e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2966e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2967e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2968e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
29699189402eSHong Zhang     x[i]  = 0.0;
2970e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2971985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2972985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2973985db425SBarry Smith       aa++; aj++;
2974985db425SBarry Smith     }
2975985db425SBarry Smith   }
2976985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2977985db425SBarry Smith   PetscFunctionReturn(0);
2978985db425SBarry Smith }
2979985db425SBarry Smith 
2980985db425SBarry Smith #undef __FUNCT__
2981985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
2982985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2983985db425SBarry Smith {
2984985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2985985db425SBarry Smith   PetscErrorCode ierr;
2986d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2987985db425SBarry Smith   PetscScalar    *x;
2988985db425SBarry Smith   MatScalar      *aa;
2989985db425SBarry Smith 
2990985db425SBarry Smith   PetscFunctionBegin;
2991e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2992985db425SBarry Smith   aa = a->a;
2993985db425SBarry Smith   ai = a->i;
2994985db425SBarry Smith   aj = a->j;
2995985db425SBarry Smith 
2996985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2997985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2998985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2999e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3000985db425SBarry Smith   for (i=0; i<m; i++) {
3001985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3002d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3003985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3004985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
3005985db425SBarry Smith       x[i] = 0.0;
3006985db425SBarry Smith       if (idx) {
3007985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3008985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
3009985db425SBarry Smith           if (aj[j] > j) {
3010985db425SBarry Smith             idx[i] = j;
3011985db425SBarry Smith             break;
3012985db425SBarry Smith           }
3013985db425SBarry Smith         }
3014985db425SBarry Smith       }
3015985db425SBarry Smith     }
3016985db425SBarry Smith     for (j=0; j<ncols; j++) {
3017985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3018985db425SBarry Smith       aa++; aj++;
3019985db425SBarry Smith     }
3020985db425SBarry Smith   }
3021985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3022985db425SBarry Smith   PetscFunctionReturn(0);
3023985db425SBarry Smith }
3024985db425SBarry Smith 
3025985db425SBarry Smith #undef __FUNCT__
3026c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
3027c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3028c87e5d42SMatthew Knepley {
3029c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3030c87e5d42SMatthew Knepley   PetscErrorCode ierr;
3031c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3032c87e5d42SMatthew Knepley   PetscReal      atmp;
3033c87e5d42SMatthew Knepley   PetscScalar    *x;
3034c87e5d42SMatthew Knepley   MatScalar      *aa;
3035c87e5d42SMatthew Knepley 
3036c87e5d42SMatthew Knepley   PetscFunctionBegin;
3037e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3038c87e5d42SMatthew Knepley   aa = a->a;
3039c87e5d42SMatthew Knepley   ai = a->i;
3040c87e5d42SMatthew Knepley   aj = a->j;
3041c87e5d42SMatthew Knepley 
3042c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3043c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3044c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
30453bb78c5cSMatthew 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);
3046c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
3047c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
3048289a08f5SMatthew Knepley     if (ncols) {
3049289a08f5SMatthew Knepley       /* Get first nonzero */
3050289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
3051289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
30522205254eSKarl Rupp         if (atmp > 1.0e-12) {
30532205254eSKarl Rupp           x[i] = atmp;
30542205254eSKarl Rupp           if (idx) idx[i] = aj[j];
30552205254eSKarl Rupp           break;
30562205254eSKarl Rupp         }
3057289a08f5SMatthew Knepley       }
305812431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
3059289a08f5SMatthew Knepley     } else {
3060289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
3061289a08f5SMatthew Knepley     }
3062c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
3063c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
3064289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3065c87e5d42SMatthew Knepley       aa++; aj++;
3066c87e5d42SMatthew Knepley     }
3067c87e5d42SMatthew Knepley   }
3068c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3069c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
3070c87e5d42SMatthew Knepley }
3071c87e5d42SMatthew Knepley 
3072c87e5d42SMatthew Knepley #undef __FUNCT__
3073985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
3074985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3075985db425SBarry Smith {
3076985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3077985db425SBarry Smith   PetscErrorCode ierr;
3078d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3079985db425SBarry Smith   PetscScalar    *x;
3080985db425SBarry Smith   MatScalar      *aa;
3081985db425SBarry Smith 
3082985db425SBarry Smith   PetscFunctionBegin;
3083e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3084985db425SBarry Smith   aa = a->a;
3085985db425SBarry Smith   ai = a->i;
3086985db425SBarry Smith   aj = a->j;
3087985db425SBarry Smith 
3088985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3089985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3090985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3091e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3092985db425SBarry Smith   for (i=0; i<m; i++) {
3093985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3094d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3095985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3096985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
3097985db425SBarry Smith       x[i] = 0.0;
3098985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
3099985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3100985db425SBarry Smith         for (j=0; j<ncols; j++) {
3101985db425SBarry Smith           if (aj[j] > j) {
3102985db425SBarry Smith             idx[i] = j;
3103985db425SBarry Smith             break;
3104985db425SBarry Smith           }
3105985db425SBarry Smith         }
3106985db425SBarry Smith       }
3107985db425SBarry Smith     }
3108985db425SBarry Smith     for (j=0; j<ncols; j++) {
3109985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3110985db425SBarry Smith       aa++; aj++;
3111e34fafa9SBarry Smith     }
3112e34fafa9SBarry Smith   }
3113e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3114e34fafa9SBarry Smith   PetscFunctionReturn(0);
3115e34fafa9SBarry Smith }
3116bbead8a2SBarry Smith 
3117bbead8a2SBarry Smith #include <petscblaslapack.h>
311806873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
3119bbead8a2SBarry Smith 
3120bbead8a2SBarry Smith #undef __FUNCT__
3121bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
3122713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3123bbead8a2SBarry Smith {
3124bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
3125bbead8a2SBarry Smith   PetscErrorCode ierr;
312634fc4b71SJed 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;
3127bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
3128bbead8a2SBarry Smith   PetscReal      shift = 0.0;
3129bbead8a2SBarry Smith 
3130bbead8a2SBarry Smith   PetscFunctionBegin;
31314a0d0026SBarry Smith   if (a->ibdiagvalid) {
31324a0d0026SBarry Smith     if (values) *values = a->ibdiag;
31334a0d0026SBarry Smith     PetscFunctionReturn(0);
31344a0d0026SBarry Smith   }
3135bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3136bbead8a2SBarry Smith   if (!a->ibdiag) {
3137785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
31383bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3139bbead8a2SBarry Smith   }
3140bbead8a2SBarry Smith   diag = a->ibdiag;
3141bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3142bbead8a2SBarry Smith   /* factor and invert each block */
3143bbead8a2SBarry Smith   switch (bs) {
3144bbead8a2SBarry Smith   case 1:
3145bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3146bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3147bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3148bbead8a2SBarry Smith     }
3149bbead8a2SBarry Smith     break;
3150bbead8a2SBarry Smith   case 2:
3151bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3152bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3153bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
315496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
315596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3156bbead8a2SBarry Smith       diag += 4;
3157bbead8a2SBarry Smith     }
3158bbead8a2SBarry Smith     break;
3159bbead8a2SBarry Smith   case 3:
3160bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3161bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3162bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
316396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
316496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3165bbead8a2SBarry Smith       diag += 9;
3166bbead8a2SBarry Smith     }
3167bbead8a2SBarry Smith     break;
3168bbead8a2SBarry Smith   case 4:
3169bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3170bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3171bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
317296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
317396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3174bbead8a2SBarry Smith       diag += 16;
3175bbead8a2SBarry Smith     }
3176bbead8a2SBarry Smith     break;
3177bbead8a2SBarry Smith   case 5:
3178bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3179bbead8a2SBarry 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;
3180bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
318196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
318296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3183bbead8a2SBarry Smith       diag += 25;
3184bbead8a2SBarry Smith     }
3185bbead8a2SBarry Smith     break;
3186bbead8a2SBarry Smith   case 6:
3187bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3188bbead8a2SBarry 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;
3189bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
319096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
319196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3192bbead8a2SBarry Smith       diag += 36;
3193bbead8a2SBarry Smith     }
3194bbead8a2SBarry Smith     break;
3195bbead8a2SBarry Smith   case 7:
3196bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3197bbead8a2SBarry 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;
3198bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
319996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
320096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3201bbead8a2SBarry Smith       diag += 49;
3202bbead8a2SBarry Smith     }
3203bbead8a2SBarry Smith     break;
3204bbead8a2SBarry Smith   default:
3205dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3206bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3207bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3208bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3209bbead8a2SBarry Smith       }
3210bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
321196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
321296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3213bbead8a2SBarry Smith       diag += bs2;
3214bbead8a2SBarry Smith     }
3215bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3216bbead8a2SBarry Smith   }
3217bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3218bbead8a2SBarry Smith   PetscFunctionReturn(0);
3219bbead8a2SBarry Smith }
3220bbead8a2SBarry Smith 
322173a71a0fSBarry Smith #undef __FUNCT__
322273a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
322373a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
322473a71a0fSBarry Smith {
322573a71a0fSBarry Smith   PetscErrorCode ierr;
322673a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
322773a71a0fSBarry Smith   PetscScalar    a;
322873a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
322973a71a0fSBarry Smith 
323073a71a0fSBarry Smith   PetscFunctionBegin;
323173a71a0fSBarry Smith   if (!x->assembled) {
323273a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
323373a71a0fSBarry Smith     for (i=0; i<m; i++) {
323473a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
323573a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
323673a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
323773a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
323873a71a0fSBarry Smith       }
323973a71a0fSBarry Smith     }
324073a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
324173a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
324273a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
324373a71a0fSBarry Smith   PetscFunctionReturn(0);
324473a71a0fSBarry Smith }
324573a71a0fSBarry Smith 
3246682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
32470a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3248cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3249cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3250cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
325197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
32527c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
32537c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3254db4efbfdSBarry Smith                                         0,
3255db4efbfdSBarry Smith                                         0,
3256db4efbfdSBarry Smith                                         0,
3257db4efbfdSBarry Smith                                 /* 10*/ 0,
3258cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3259cb5b572fSBarry Smith                                         0,
326041f059aeSBarry Smith                                         MatSOR_SeqAIJ,
326117ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
326297304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3263cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3264cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3265cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3266cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
326797304618SKris Buschelman                                 /* 20*/ 0,
3268cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3269cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3270cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3271d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3272db4efbfdSBarry Smith                                         0,
3273db4efbfdSBarry Smith                                         0,
3274db4efbfdSBarry Smith                                         0,
3275db4efbfdSBarry Smith                                         0,
32764994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3277db4efbfdSBarry Smith                                         0,
3278db4efbfdSBarry Smith                                         0,
32798c778c55SBarry Smith                                         0,
32808c778c55SBarry Smith                                         0,
3281d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3282cb5b572fSBarry Smith                                         0,
3283cb5b572fSBarry Smith                                         0,
3284cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3285cb5b572fSBarry Smith                                         0,
3286d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3287cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3288cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3289cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3290cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3291d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3292cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3293cb5b572fSBarry Smith                                         0,
329479299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
32956e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
329673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
32973b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
32983b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
32993b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3300a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
330193dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3302b9617806SBarry Smith                                         0,
33030513a670SBarry Smith                                         0,
3304cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3305cda55fadSBarry Smith                                         0,
3306d519adbfSMatthew Knepley                                 /* 59*/ 0,
3307b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3308b9b97703SBarry Smith                                         MatView_SeqAIJ,
3309357abbc8SBarry Smith                                         0,
3310321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3311321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3312321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3313ee4f033dSBarry Smith                                         0,
3314ee4f033dSBarry Smith                                         0,
3315ee4f033dSBarry Smith                                         0,
3316d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3317c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3318ee4f033dSBarry Smith                                         0,
3319ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3320dcf5cc72SBarry Smith                                         0,
3321d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
33223acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
332397304618SKris Buschelman                                         0,
332497304618SKris Buschelman                                         0,
332597304618SKris Buschelman                                         0,
33266ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
332797304618SKris Buschelman                                         0,
332897304618SKris Buschelman                                         0,
332997304618SKris Buschelman                                         0,
3330bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3331d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
33321cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
33336284ec50SHong Zhang                                         0,
33346284ec50SHong Zhang                                         0,
3335bc011b1eSHong Zhang                                         0,
3336d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
333726be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
333826be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
333965e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
33404a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
334165e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
33426fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
33436fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
33446fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
33452121bac1SHong Zhang                                         0,
33462121bac1SHong Zhang                                 /* 99*/ 0,
3347609c6c4dSKris Buschelman                                         0,
3348609c6c4dSKris Buschelman                                         0,
334987d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
335087d4246cSBarry Smith                                         0,
3351d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
335299cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3353f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3354f5edf698SHong Zhang                                         0,
33552bebee5dSHong Zhang                                         0,
3356cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3357985db425SBarry Smith                                         0,
33582af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
33592af78befSBarry Smith                                         0,
3360599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3361d519adbfSMatthew Knepley                                 /*114*/ 0,
3362599ef60dSHong Zhang                                         0,
33633c2a7987SHong Zhang                                         0,
3364fe97e370SBarry Smith                                         0,
3365fbdbba38SShri Abhyankar                                         0,
3366fbdbba38SShri Abhyankar                                 /*119*/ 0,
3367fbdbba38SShri Abhyankar                                         0,
3368fbdbba38SShri Abhyankar                                         0,
336982d44351SHong Zhang                                         0,
3370b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
33710716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3372bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
337337868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
337437868618SMatthew G Knepley                                         0,
337537868618SMatthew G Knepley                                         0,
33765df89d91SHong Zhang                                 /*129*/ 0,
337775648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
337875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
337975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3380b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3381b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
33822b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
33832b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
33842b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
33853964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
33863964eb88SJed Brown                                  /*139*/0,
3387f9426fe0SMark Adams                                         0,
33881919a2e2SJed Brown                                         0,
33893a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
33903a062f41SBarry Smith                                         MatFindOffBlockDiagonalEntries_SeqAIJ
33919e29f15eSvictorle };
339217ab2063SBarry Smith 
33934a2ae208SSatish Balay #undef __FUNCT__
33944a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
33957087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3396bef8e0ddSBarry Smith {
3397bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
339897f1f81fSBarry Smith   PetscInt   i,nz,n;
3399bef8e0ddSBarry Smith 
3400bef8e0ddSBarry Smith   PetscFunctionBegin;
3401bef8e0ddSBarry Smith   nz = aij->maxnz;
3402d0f46423SBarry Smith   n  = mat->rmap->n;
3403bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3404bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3405bef8e0ddSBarry Smith   }
3406bef8e0ddSBarry Smith   aij->nz = nz;
3407bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3408bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3409bef8e0ddSBarry Smith   }
3410bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3411bef8e0ddSBarry Smith }
3412bef8e0ddSBarry Smith 
34134a2ae208SSatish Balay #undef __FUNCT__
34144a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3415bef8e0ddSBarry Smith /*@
3416bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3417bef8e0ddSBarry Smith        in the matrix.
3418bef8e0ddSBarry Smith 
3419bef8e0ddSBarry Smith   Input Parameters:
3420bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3421bef8e0ddSBarry Smith -  indices - the column indices
3422bef8e0ddSBarry Smith 
342315091d37SBarry Smith   Level: advanced
342415091d37SBarry Smith 
3425bef8e0ddSBarry Smith   Notes:
3426bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3427bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3428bef8e0ddSBarry Smith   of the MatSetValues() operation.
3429bef8e0ddSBarry Smith 
3430bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3431d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3432bef8e0ddSBarry Smith 
3433bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3434bef8e0ddSBarry Smith 
3435b9617806SBarry Smith     The indices should start with zero, not one.
3436b9617806SBarry Smith 
3437bef8e0ddSBarry Smith @*/
34387087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3439bef8e0ddSBarry Smith {
34404ac538c5SBarry Smith   PetscErrorCode ierr;
3441bef8e0ddSBarry Smith 
3442bef8e0ddSBarry Smith   PetscFunctionBegin;
34430700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
34444482741eSBarry Smith   PetscValidPointer(indices,2);
34454ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3446bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3447bef8e0ddSBarry Smith }
3448bef8e0ddSBarry Smith 
3449be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3450be6bf707SBarry Smith 
34514a2ae208SSatish Balay #undef __FUNCT__
34524a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
34537087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3454be6bf707SBarry Smith {
3455be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
34566849ba73SBarry Smith   PetscErrorCode ierr;
3457d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3458be6bf707SBarry Smith 
3459be6bf707SBarry Smith   PetscFunctionBegin;
3460169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3461be6bf707SBarry Smith 
3462be6bf707SBarry Smith   /* allocate space for values if not already there */
3463be6bf707SBarry Smith   if (!aij->saved_values) {
3464785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
34653bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3466be6bf707SBarry Smith   }
3467be6bf707SBarry Smith 
3468be6bf707SBarry Smith   /* copy values over */
346987828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3470be6bf707SBarry Smith   PetscFunctionReturn(0);
3471be6bf707SBarry Smith }
3472be6bf707SBarry Smith 
34734a2ae208SSatish Balay #undef __FUNCT__
3474b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3475be6bf707SBarry Smith /*@
3476be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3477be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3478be6bf707SBarry Smith        nonlinear portion.
3479be6bf707SBarry Smith 
3480be6bf707SBarry Smith    Collect on Mat
3481be6bf707SBarry Smith 
3482be6bf707SBarry Smith   Input Parameters:
34830e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3484be6bf707SBarry Smith 
348515091d37SBarry Smith   Level: advanced
348615091d37SBarry Smith 
3487be6bf707SBarry Smith   Common Usage, with SNESSolve():
3488be6bf707SBarry Smith $    Create Jacobian matrix
3489be6bf707SBarry Smith $    Set linear terms into matrix
3490be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3491be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3492be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3493512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3494be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3495be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3496be6bf707SBarry Smith $    In your Jacobian routine
3497be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3498be6bf707SBarry Smith $      Set nonlinear terms in matrix
3499be6bf707SBarry Smith 
3500be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3501be6bf707SBarry Smith $    // build linear portion of Jacobian
3502512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3503be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3504be6bf707SBarry Smith $    loop over nonlinear iterations
3505be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3506be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3507be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3508be6bf707SBarry Smith $       Solve linear system with Jacobian
3509be6bf707SBarry Smith $    endloop
3510be6bf707SBarry Smith 
3511be6bf707SBarry Smith   Notes:
3512be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3513512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3514be6bf707SBarry Smith     calling this routine.
3515be6bf707SBarry Smith 
35160c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
35170c468ba9SBarry Smith     and does not allocated additional space.
35180c468ba9SBarry Smith 
3519be6bf707SBarry Smith .seealso: MatRetrieveValues()
3520be6bf707SBarry Smith 
3521be6bf707SBarry Smith @*/
35227087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3523be6bf707SBarry Smith {
35244ac538c5SBarry Smith   PetscErrorCode ierr;
3525be6bf707SBarry Smith 
3526be6bf707SBarry Smith   PetscFunctionBegin;
35270700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3528e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3529e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
35304ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3531be6bf707SBarry Smith   PetscFunctionReturn(0);
3532be6bf707SBarry Smith }
3533be6bf707SBarry Smith 
35344a2ae208SSatish Balay #undef __FUNCT__
35354a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
35367087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3537be6bf707SBarry Smith {
3538be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
35396849ba73SBarry Smith   PetscErrorCode ierr;
3540d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3541be6bf707SBarry Smith 
3542be6bf707SBarry Smith   PetscFunctionBegin;
3543169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3544f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3545be6bf707SBarry Smith   /* copy values over */
354687828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3547be6bf707SBarry Smith   PetscFunctionReturn(0);
3548be6bf707SBarry Smith }
3549be6bf707SBarry Smith 
35504a2ae208SSatish Balay #undef __FUNCT__
35514a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3552be6bf707SBarry Smith /*@
3553be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3554be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3555be6bf707SBarry Smith        nonlinear portion.
3556be6bf707SBarry Smith 
3557be6bf707SBarry Smith    Collect on Mat
3558be6bf707SBarry Smith 
3559be6bf707SBarry Smith   Input Parameters:
3560be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3561be6bf707SBarry Smith 
356215091d37SBarry Smith   Level: advanced
356315091d37SBarry Smith 
3564be6bf707SBarry Smith .seealso: MatStoreValues()
3565be6bf707SBarry Smith 
3566be6bf707SBarry Smith @*/
35677087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3568be6bf707SBarry Smith {
35694ac538c5SBarry Smith   PetscErrorCode ierr;
3570be6bf707SBarry Smith 
3571be6bf707SBarry Smith   PetscFunctionBegin;
35720700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3573e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3574e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
35754ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3576be6bf707SBarry Smith   PetscFunctionReturn(0);
3577be6bf707SBarry Smith }
3578be6bf707SBarry Smith 
3579f83d6046SBarry Smith 
3580be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
35814a2ae208SSatish Balay #undef __FUNCT__
35824a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
358317ab2063SBarry Smith /*@C
3584682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
35850d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
35866e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
358751c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
35882bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
358917ab2063SBarry Smith 
3590db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3591db81eaa0SLois Curfman McInnes 
359217ab2063SBarry Smith    Input Parameters:
3593db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
359417ab2063SBarry Smith .  m - number of rows
359517ab2063SBarry Smith .  n - number of columns
359617ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
359751c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
35980298fd71SBarry Smith          (possibly different for each row) or NULL
359917ab2063SBarry Smith 
360017ab2063SBarry Smith    Output Parameter:
3601416022c9SBarry Smith .  A - the matrix
360217ab2063SBarry Smith 
3603175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3604ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3605175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3606175b88e8SBarry Smith 
3607b259b22eSLois Curfman McInnes    Notes:
360849a6f317SBarry Smith    If nnz is given then nz is ignored
360949a6f317SBarry Smith 
361017ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
361117ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
36120002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
361344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
361417ab2063SBarry Smith 
361517ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
36160298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
36173d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
36186da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
361917ab2063SBarry Smith 
3620682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
36214fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3622682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
36236c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
36246c7ebb05SLois Curfman McInnes 
36256c7ebb05SLois Curfman McInnes    Options Database Keys:
3626698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
36279db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
362817ab2063SBarry Smith 
3629027ccd11SLois Curfman McInnes    Level: intermediate
3630027ccd11SLois Curfman McInnes 
363169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
363236db0b34SBarry Smith 
363317ab2063SBarry Smith @*/
36347087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
363517ab2063SBarry Smith {
3636dfbe8321SBarry Smith   PetscErrorCode ierr;
36376945ee14SBarry Smith 
36383a40ed3dSBarry Smith   PetscFunctionBegin;
3639f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3640117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3641c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3642d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3643273d9f13SBarry Smith   PetscFunctionReturn(0);
3644273d9f13SBarry Smith }
3645273d9f13SBarry Smith 
36464a2ae208SSatish Balay #undef __FUNCT__
36474a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3648273d9f13SBarry Smith /*@C
3649273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3650273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3651273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3652273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3653273d9f13SBarry Smith 
3654273d9f13SBarry Smith    Collective on MPI_Comm
3655273d9f13SBarry Smith 
3656273d9f13SBarry Smith    Input Parameters:
3657117016b1SBarry Smith +  B - The matrix-free
3658273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3659273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
36600298fd71SBarry Smith          (possibly different for each row) or NULL
3661273d9f13SBarry Smith 
3662273d9f13SBarry Smith    Notes:
366349a6f317SBarry Smith      If nnz is given then nz is ignored
366449a6f317SBarry Smith 
3665273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3666273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3667273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3668273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3669273d9f13SBarry Smith 
3670273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
36710298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3672273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3673273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3674273d9f13SBarry Smith 
3675aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3676aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3677aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3678aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3679aa95bbe8SBarry Smith 
3680a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3681a96a251dSBarry Smith    entries or columns indices
3682a96a251dSBarry Smith 
3683273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3684273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3685273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3686273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3687273d9f13SBarry Smith 
3688273d9f13SBarry Smith    Options Database Keys:
3689698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3690698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3691273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3692273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3693273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3694273d9f13SBarry Smith 
3695273d9f13SBarry Smith    Level: intermediate
3696273d9f13SBarry Smith 
369769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3698273d9f13SBarry Smith 
3699273d9f13SBarry Smith @*/
37007087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3701273d9f13SBarry Smith {
37024ac538c5SBarry Smith   PetscErrorCode ierr;
3703a23d5eceSKris Buschelman 
3704a23d5eceSKris Buschelman   PetscFunctionBegin;
37056ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
37066ba663aaSJed Brown   PetscValidType(B,1);
37074ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3708a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3709a23d5eceSKris Buschelman }
3710a23d5eceSKris Buschelman 
3711a23d5eceSKris Buschelman #undef __FUNCT__
3712a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
37137087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3714a23d5eceSKris Buschelman {
3715273d9f13SBarry Smith   Mat_SeqAIJ     *b;
37162576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
37176849ba73SBarry Smith   PetscErrorCode ierr;
371897f1f81fSBarry Smith   PetscInt       i;
3719273d9f13SBarry Smith 
3720273d9f13SBarry Smith   PetscFunctionBegin;
37212576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3722a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3723c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3724c461c341SBarry Smith     nz             = 0;
3725c461c341SBarry Smith   }
3726c461c341SBarry Smith 
372726283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
372826283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3729899cda47SBarry Smith 
3730435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3731e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3732b73539f3SBarry Smith   if (nnz) {
3733d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3734e32f2f54SBarry 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]);
3735e32f2f54SBarry 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);
3736b73539f3SBarry Smith     }
3737b73539f3SBarry Smith   }
3738b73539f3SBarry Smith 
3739273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
37402205254eSKarl Rupp 
3741273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3742273d9f13SBarry Smith 
3743ab93d7beSBarry Smith   if (!skipallocation) {
37442ee49352SLisandro Dalcin     if (!b->imax) {
3745dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
37463bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
37472ee49352SLisandro Dalcin     }
3748273d9f13SBarry Smith     if (!nnz) {
3749435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3750c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3751d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3752d0f46423SBarry Smith       nz = nz*B->rmap->n;
3753273d9f13SBarry Smith     } else {
3754273d9f13SBarry Smith       nz = 0;
3755d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3756273d9f13SBarry Smith     }
3757ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
37582205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3759ab93d7beSBarry Smith 
3760273d9f13SBarry Smith     /* allocate the matrix space */
37612ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3762dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
37633bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3764bfeeae90SHong Zhang     b->i[0] = 0;
3765d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
37665da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
37675da197adSKris Buschelman     }
3768273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3769e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3770e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3771b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3772b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3773b31eba2aSShri Abhyankar #endif
3774c461c341SBarry Smith   } else {
3775e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3776e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3777c461c341SBarry Smith   }
3778273d9f13SBarry Smith 
3779273d9f13SBarry Smith   b->nz               = 0;
3780273d9f13SBarry Smith   b->maxnz            = nz;
3781273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
37822205254eSKarl Rupp   if (realalloc) {
37832205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
37842205254eSKarl Rupp   }
3785273d9f13SBarry Smith   PetscFunctionReturn(0);
3786273d9f13SBarry Smith }
3787273d9f13SBarry Smith 
3788a1661176SMatthew Knepley #undef  __FUNCT__
3789a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
379058d36128SBarry Smith /*@
3791a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3792a1661176SMatthew Knepley 
3793a1661176SMatthew Knepley    Input Parameters:
3794a1661176SMatthew Knepley +  B - the matrix
3795a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3796a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3797a1661176SMatthew Knepley -  v - optional values in the matrix
3798a1661176SMatthew Knepley 
3799a1661176SMatthew Knepley    Level: developer
3800a1661176SMatthew Knepley 
380158d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
380258d36128SBarry Smith 
3803a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3804a1661176SMatthew Knepley 
3805a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3806a1661176SMatthew Knepley @*/
3807a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3808a1661176SMatthew Knepley {
3809a1661176SMatthew Knepley   PetscErrorCode ierr;
3810a1661176SMatthew Knepley 
3811a1661176SMatthew Knepley   PetscFunctionBegin;
38120700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
38136ba663aaSJed Brown   PetscValidType(B,1);
38144ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3815a1661176SMatthew Knepley   PetscFunctionReturn(0);
3816a1661176SMatthew Knepley }
3817a1661176SMatthew Knepley 
3818a1661176SMatthew Knepley #undef  __FUNCT__
3819a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
38207087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3821a1661176SMatthew Knepley {
3822a1661176SMatthew Knepley   PetscInt       i;
3823a1661176SMatthew Knepley   PetscInt       m,n;
3824a1661176SMatthew Knepley   PetscInt       nz;
3825a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3826a1661176SMatthew Knepley   PetscScalar    *values;
3827a1661176SMatthew Knepley   PetscErrorCode ierr;
3828a1661176SMatthew Knepley 
3829a1661176SMatthew Knepley   PetscFunctionBegin;
383065e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3831779a8d59SSatish Balay 
3832779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3833779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3834779a8d59SSatish Balay 
3835779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3836785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3837a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3838b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3839a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
384065e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3841a1661176SMatthew Knepley     nnz[i] = nz;
3842a1661176SMatthew Knepley   }
3843a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3844a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3845a1661176SMatthew Knepley 
3846a1661176SMatthew Knepley   if (v) {
3847a1661176SMatthew Knepley     values = (PetscScalar*) v;
3848a1661176SMatthew Knepley   } else {
38491795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3850a1661176SMatthew Knepley   }
3851a1661176SMatthew Knepley 
3852a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3853b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3854b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3855a1661176SMatthew Knepley   }
3856a1661176SMatthew Knepley 
3857a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3858a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3859a1661176SMatthew Knepley 
3860a1661176SMatthew Knepley   if (!v) {
3861a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3862a1661176SMatthew Knepley   }
38637827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3864a1661176SMatthew Knepley   PetscFunctionReturn(0);
3865a1661176SMatthew Knepley }
3866a1661176SMatthew Knepley 
3867c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
386806873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3869170fe5c8SBarry Smith 
3870170fe5c8SBarry Smith #undef __FUNCT__
3871170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3872170fe5c8SBarry Smith /*
3873170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3874170fe5c8SBarry Smith 
3875170fe5c8SBarry Smith                n                       p                          p
3876170fe5c8SBarry Smith         (              )       (              )         (                  )
3877170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3878170fe5c8SBarry Smith         (              )       (              )         (                  )
3879170fe5c8SBarry Smith 
3880170fe5c8SBarry Smith */
3881170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3882170fe5c8SBarry Smith {
3883170fe5c8SBarry Smith   PetscErrorCode    ierr;
3884170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3885170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3886170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
38871de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3888170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3889170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3890170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3891170fe5c8SBarry Smith 
3892170fe5c8SBarry Smith   PetscFunctionBegin;
3893d0f46423SBarry Smith   m    = A->rmap->n;
3894d0f46423SBarry Smith   n    = A->cmap->n;
3895d0f46423SBarry Smith   p    = B->cmap->n;
3896170fe5c8SBarry Smith   a    = sub_a->v;
3897170fe5c8SBarry Smith   b    = sub_b->a;
3898170fe5c8SBarry Smith   c    = sub_c->v;
3899170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3900170fe5c8SBarry Smith 
3901170fe5c8SBarry Smith   ii  = sub_b->i;
3902170fe5c8SBarry Smith   idx = sub_b->j;
3903170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3904170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3905170fe5c8SBarry Smith     while (q-->0) {
3906170fe5c8SBarry Smith       c_q = c + m*(*idx);
3907170fe5c8SBarry Smith       a_q = a + m*i;
3908854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3909170fe5c8SBarry Smith       idx++;
3910170fe5c8SBarry Smith       b++;
3911170fe5c8SBarry Smith     }
3912170fe5c8SBarry Smith   }
3913170fe5c8SBarry Smith   PetscFunctionReturn(0);
3914170fe5c8SBarry Smith }
3915170fe5c8SBarry Smith 
3916170fe5c8SBarry Smith #undef __FUNCT__
3917170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3918170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3919170fe5c8SBarry Smith {
3920170fe5c8SBarry Smith   PetscErrorCode ierr;
3921d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3922170fe5c8SBarry Smith   Mat            Cmat;
3923170fe5c8SBarry Smith 
3924170fe5c8SBarry Smith   PetscFunctionBegin;
3925e32f2f54SBarry 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);
3926ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3927170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3928a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3929170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
39300298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3931d73949e8SHong Zhang 
3932d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
39332205254eSKarl Rupp 
3934170fe5c8SBarry Smith   *C = Cmat;
3935170fe5c8SBarry Smith   PetscFunctionReturn(0);
3936170fe5c8SBarry Smith }
3937170fe5c8SBarry Smith 
3938170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3939170fe5c8SBarry Smith #undef __FUNCT__
3940170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3941170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3942170fe5c8SBarry Smith {
3943170fe5c8SBarry Smith   PetscErrorCode ierr;
3944170fe5c8SBarry Smith 
3945170fe5c8SBarry Smith   PetscFunctionBegin;
3946170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
39473ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3948170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
39493ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3950170fe5c8SBarry Smith   }
39513ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3952170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
39533ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3954170fe5c8SBarry Smith   PetscFunctionReturn(0);
3955170fe5c8SBarry Smith }
3956170fe5c8SBarry Smith 
3957170fe5c8SBarry Smith 
39580bad9183SKris Buschelman /*MC
3959fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
39600bad9183SKris Buschelman    based on compressed sparse row format.
39610bad9183SKris Buschelman 
39620bad9183SKris Buschelman    Options Database Keys:
39630bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
39640bad9183SKris Buschelman 
39650bad9183SKris Buschelman   Level: beginner
39660bad9183SKris Buschelman 
3967f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
39680bad9183SKris Buschelman M*/
39690bad9183SKris Buschelman 
3970ccd284c7SBarry Smith /*MC
3971ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3972ccd284c7SBarry Smith 
3973ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3974ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
3975ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
3976ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3977ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3978ccd284c7SBarry Smith 
3979ccd284c7SBarry Smith    Options Database Keys:
3980ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
3981ccd284c7SBarry Smith 
3982ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
3983ccd284c7SBarry Smith    enough exist.
3984ccd284c7SBarry Smith 
3985ccd284c7SBarry Smith   Level: beginner
3986ccd284c7SBarry Smith 
3987ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
3988ccd284c7SBarry Smith M*/
3989ccd284c7SBarry Smith 
3990ccd284c7SBarry Smith /*MC
3991ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
3992ccd284c7SBarry Smith 
3993ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
3994ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
3995ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
3996ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
3997ccd284c7SBarry Smith   the above preallocation routines for simplicity.
3998ccd284c7SBarry Smith 
3999ccd284c7SBarry Smith    Options Database Keys:
4000ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
4001ccd284c7SBarry Smith 
4002ccd284c7SBarry Smith   Level: beginner
4003ccd284c7SBarry Smith 
4004ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
4005ccd284c7SBarry Smith M*/
4006ccd284c7SBarry Smith 
4007b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
40088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
4009b5e56a35SBarry Smith #endif
4010ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
40118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
4012af1023dbSSatish Balay #endif
40138cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
40148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
40158cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
40167087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
4017611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
40188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
4019611f576cSBarry Smith #endif
4020611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
40218cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
4022611f576cSBarry Smith #endif
4023f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
40248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
4025f3c0ef26SHong Zhang #endif
4026eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
40278cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
4028eb3b5408SSatish Balay #endif
4029586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
40308cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
4031586621ddSJed Brown #endif
4032719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
40338cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
4034719d5645SBarry Smith #endif
4035b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
40368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
40377087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
40387087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
4039b3866ffcSBarry Smith #endif
404017f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
40418cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
404217f1a0eaSHong Zhang #endif
404317667f90SBarry Smith 
4044c0c8ee5eSDmitry Karpeev 
40458c778c55SBarry Smith #undef __FUNCT__
40468c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
40478c778c55SBarry Smith /*@C
40488c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
40498c778c55SBarry Smith 
40508c778c55SBarry Smith    Not Collective
40518c778c55SBarry Smith 
40528c778c55SBarry Smith    Input Parameter:
40538c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
40548c778c55SBarry Smith 
40558c778c55SBarry Smith    Output Parameter:
40568c778c55SBarry Smith .   array - pointer to the data
40578c778c55SBarry Smith 
40588c778c55SBarry Smith    Level: intermediate
40598c778c55SBarry Smith 
4060774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
40618c778c55SBarry Smith @*/
40628c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
40638c778c55SBarry Smith {
40648c778c55SBarry Smith   PetscErrorCode ierr;
40658c778c55SBarry Smith 
40668c778c55SBarry Smith   PetscFunctionBegin;
40678c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
40688c778c55SBarry Smith   PetscFunctionReturn(0);
40698c778c55SBarry Smith }
40708c778c55SBarry Smith 
40718c778c55SBarry Smith #undef __FUNCT__
40728c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
40738c778c55SBarry Smith /*@C
40748c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
40758c778c55SBarry Smith 
40768c778c55SBarry Smith    Not Collective
40778c778c55SBarry Smith 
40788c778c55SBarry Smith    Input Parameters:
40798c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
40808c778c55SBarry Smith .  array - pointer to the data
40818c778c55SBarry Smith 
40828c778c55SBarry Smith    Level: intermediate
40838c778c55SBarry Smith 
4084774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
40858c778c55SBarry Smith @*/
40868c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
40878c778c55SBarry Smith {
40888c778c55SBarry Smith   PetscErrorCode ierr;
40898c778c55SBarry Smith 
40908c778c55SBarry Smith   PetscFunctionBegin;
40918c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
40928c778c55SBarry Smith   PetscFunctionReturn(0);
40938c778c55SBarry Smith }
40948c778c55SBarry Smith 
40954a2ae208SSatish Balay #undef __FUNCT__
40964a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
40978cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
4098273d9f13SBarry Smith {
4099273d9f13SBarry Smith   Mat_SeqAIJ     *b;
4100dfbe8321SBarry Smith   PetscErrorCode ierr;
410138baddfdSBarry Smith   PetscMPIInt    size;
4102273d9f13SBarry Smith 
4103273d9f13SBarry Smith   PetscFunctionBegin;
4104ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
4105e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
4106273d9f13SBarry Smith 
4107b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
41082205254eSKarl Rupp 
4109b0a32e0cSBarry Smith   B->data = (void*)b;
41102205254eSKarl Rupp 
4111549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
41122205254eSKarl Rupp 
4113416022c9SBarry Smith   b->row                = 0;
4114416022c9SBarry Smith   b->col                = 0;
411582bf6240SBarry Smith   b->icol               = 0;
4116b810aeb4SBarry Smith   b->reallocs           = 0;
411736db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4118f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4119416022c9SBarry Smith   b->nonew              = 0;
4120416022c9SBarry Smith   b->diag               = 0;
4121416022c9SBarry Smith   b->solve_work         = 0;
41222a1b7f2aSHong Zhang   B->spptr              = 0;
4123be6bf707SBarry Smith   b->saved_values       = 0;
4124d7f994e1SBarry Smith   b->idiag              = 0;
412571f1c65dSBarry Smith   b->mdiag              = 0;
412671f1c65dSBarry Smith   b->ssor_work          = 0;
412771f1c65dSBarry Smith   b->omega              = 1.0;
412871f1c65dSBarry Smith   b->fshift             = 0.0;
412971f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4130bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4131a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
4132a30b2313SHong Zhang   b->xtoy               = 0;
4133a30b2313SHong Zhang   b->XtoY               = 0;
413488e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
413517ab2063SBarry Smith 
413635d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4137bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4138bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
41398c778c55SBarry Smith 
4140b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4141bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4142bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4143bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4144b3866ffcSBarry Smith #endif
4145b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4146bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4147b5e56a35SBarry Smith #endif
4148ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4149bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4150719d5645SBarry Smith #endif
4151611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4152bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4153611f576cSBarry Smith #endif
4154f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4155bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4156f3c0ef26SHong Zhang #endif
4157611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4158bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4159611f576cSBarry Smith #endif
4160eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4161bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4162eb3b5408SSatish Balay #endif
4163586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4164bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4165586621ddSJed Brown #endif
4166719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4167bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4168719d5645SBarry Smith #endif
416917f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4170bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
417117f1a0eaSHong Zhang #endif
417217f1a0eaSHong Zhang 
4173bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4174bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4175bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4176bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4177bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4178bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4179bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4180bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4181bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4182bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4183bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4184bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4185bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4186bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4187bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4188bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4189bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4190bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
41914108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
419217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
41933a40ed3dSBarry Smith   PetscFunctionReturn(0);
419417ab2063SBarry Smith }
419517ab2063SBarry Smith 
41964a2ae208SSatish Balay #undef __FUNCT__
4197b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4198b24902e0SBarry Smith /*
4199b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4200b24902e0SBarry Smith */
4201ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
420217ab2063SBarry Smith {
4203416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
42046849ba73SBarry Smith   PetscErrorCode ierr;
4205d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
420617ab2063SBarry Smith 
42073a40ed3dSBarry Smith   PetscFunctionBegin;
4208273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4209273d9f13SBarry Smith 
4210d5f3da31SBarry Smith   C->factortype = A->factortype;
4211416022c9SBarry Smith   c->row        = 0;
4212416022c9SBarry Smith   c->col        = 0;
421382bf6240SBarry Smith   c->icol       = 0;
42146ad4291fSHong Zhang   c->reallocs   = 0;
421517ab2063SBarry Smith 
42166ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
421717ab2063SBarry Smith 
4218aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4219aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4220eec197d1SBarry Smith 
4221dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
42223bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
422317ab2063SBarry Smith   for (i=0; i<m; i++) {
4224416022c9SBarry Smith     c->imax[i] = a->imax[i];
4225416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
422617ab2063SBarry Smith   }
422717ab2063SBarry Smith 
422817ab2063SBarry Smith   /* allocate the matrix space */
4229f77e22a1SHong Zhang   if (mallocmatspace) {
4230dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
42313bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
42322205254eSKarl Rupp 
4233f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
42342205254eSKarl Rupp 
423597f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
423617ab2063SBarry Smith     if (m > 0) {
423797f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4238be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4239bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4240be6bf707SBarry Smith       } else {
4241bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
424217ab2063SBarry Smith       }
424308480c60SBarry Smith     }
4244f77e22a1SHong Zhang   }
424517ab2063SBarry Smith 
42466ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4247416022c9SBarry Smith   c->roworiented       = a->roworiented;
4248416022c9SBarry Smith   c->nonew             = a->nonew;
4249416022c9SBarry Smith   if (a->diag) {
4250785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
42513bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
425217ab2063SBarry Smith     for (i=0; i<m; i++) {
4253416022c9SBarry Smith       c->diag[i] = a->diag[i];
425417ab2063SBarry Smith     }
42553a40ed3dSBarry Smith   } else c->diag = 0;
42562205254eSKarl Rupp 
42576ad4291fSHong Zhang   c->solve_work         = 0;
42586ad4291fSHong Zhang   c->saved_values       = 0;
42596ad4291fSHong Zhang   c->idiag              = 0;
426071f1c65dSBarry Smith   c->ssor_work          = 0;
4261a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4262e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4263e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
42646ad4291fSHong Zhang   c->xtoy               = 0;
42656ad4291fSHong Zhang   c->XtoY               = 0;
42666ad4291fSHong Zhang 
4267893ad86cSHong Zhang   c->rmax         = a->rmax;
4268416022c9SBarry Smith   c->nz           = a->nz;
42698ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4270273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4271754ec7b1SSatish Balay 
42726ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
42736ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4274cd6b891eSBarry Smith   if (a->compressedrow.use) {
42756ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4276dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
42776ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
42786ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
427927ea64f8SHong Zhang   } else {
428027ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
42810298fd71SBarry Smith     c->compressedrow.i      = NULL;
42820298fd71SBarry Smith     c->compressedrow.rindex = NULL;
42836ad4291fSHong Zhang   }
428488e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
42854846f1f5SKris Buschelman 
42862205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4287140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
42883a40ed3dSBarry Smith   PetscFunctionReturn(0);
428917ab2063SBarry Smith }
429017ab2063SBarry Smith 
42914a2ae208SSatish Balay #undef __FUNCT__
4292b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4293b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4294b24902e0SBarry Smith {
4295b24902e0SBarry Smith   PetscErrorCode ierr;
4296b24902e0SBarry Smith 
4297b24902e0SBarry Smith   PetscFunctionBegin;
4298ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
42994b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4300cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
4301a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4302cfd3f464SBarry Smith   }
4303a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4304f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4305b24902e0SBarry Smith   PetscFunctionReturn(0);
4306b24902e0SBarry Smith }
4307b24902e0SBarry Smith 
4308b24902e0SBarry Smith #undef __FUNCT__
43094a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4310112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4311fbdbba38SShri Abhyankar {
4312fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4313fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4314fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4315fbdbba38SShri Abhyankar   int            fd;
4316fbdbba38SShri Abhyankar   PetscMPIInt    size;
4317fbdbba38SShri Abhyankar   MPI_Comm       comm;
4318bbead8a2SBarry Smith   PetscInt       bs = 1;
4319fbdbba38SShri Abhyankar 
4320fbdbba38SShri Abhyankar   PetscFunctionBegin;
4321fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4322fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4323fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4324bbead8a2SBarry Smith 
43250298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
43260298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4327bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
43281814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4329bbead8a2SBarry Smith 
4330fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4331fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4332fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4333fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4334fbdbba38SShri Abhyankar 
4335bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4336fbdbba38SShri Abhyankar 
4337fbdbba38SShri Abhyankar   /* read in row lengths */
4338785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4339fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4340fbdbba38SShri Abhyankar 
4341fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4342fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4343fbdbba38SShri 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);
4344fbdbba38SShri Abhyankar 
4345fbdbba38SShri Abhyankar   /* set global size if not set already*/
4346f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4347fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4348aabbc4fbSShri Abhyankar   } else {
4349fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4350fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
43514c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
43524c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
43534c5b953cSHong Zhang     }
4354f501eaabSShri 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);
4355aabbc4fbSShri Abhyankar   }
4356fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4357fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4358fbdbba38SShri Abhyankar 
4359fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4360fbdbba38SShri Abhyankar 
4361fbdbba38SShri Abhyankar   /* read in nonzero values */
4362fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4363fbdbba38SShri Abhyankar 
4364fbdbba38SShri Abhyankar   /* set matrix "i" values */
4365fbdbba38SShri Abhyankar   a->i[0] = 0;
4366fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4367fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4368fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4369fbdbba38SShri Abhyankar   }
4370fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4371fbdbba38SShri Abhyankar 
4372fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4373fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4374fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4375fbdbba38SShri Abhyankar }
4376fbdbba38SShri Abhyankar 
4377fbdbba38SShri Abhyankar #undef __FUNCT__
4378b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4379ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
43807264ac53SSatish Balay {
43817264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4382dfbe8321SBarry Smith   PetscErrorCode ierr;
4383eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4384eeffb40dSHong Zhang   PetscInt k;
4385eeffb40dSHong Zhang #endif
43867264ac53SSatish Balay 
43873a40ed3dSBarry Smith   PetscFunctionBegin;
4388bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4389d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4390ca44d042SBarry Smith     *flg = PETSC_FALSE;
4391ca44d042SBarry Smith     PetscFunctionReturn(0);
4392bcd2baecSBarry Smith   }
43937264ac53SSatish Balay 
43947264ac53SSatish Balay   /* if the a->i are the same */
4395d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4396abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
43977264ac53SSatish Balay 
43987264ac53SSatish Balay   /* if a->j are the same */
439997f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4400abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4401bcd2baecSBarry Smith 
4402bcd2baecSBarry Smith   /* if a->a are the same */
4403eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4404eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4405eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4406eeffb40dSHong Zhang       *flg = PETSC_FALSE;
44073a40ed3dSBarry Smith       PetscFunctionReturn(0);
4408eeffb40dSHong Zhang     }
4409eeffb40dSHong Zhang   }
4410eeffb40dSHong Zhang #else
4411eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4412eeffb40dSHong Zhang #endif
4413eeffb40dSHong Zhang   PetscFunctionReturn(0);
44147264ac53SSatish Balay }
441536db0b34SBarry Smith 
44164a2ae208SSatish Balay #undef __FUNCT__
44174a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
441805869f15SSatish Balay /*@
441936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
442036db0b34SBarry Smith               provided by the user.
442136db0b34SBarry Smith 
4422c75a6043SHong Zhang       Collective on MPI_Comm
442336db0b34SBarry Smith 
442436db0b34SBarry Smith    Input Parameters:
442536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
442636db0b34SBarry Smith .   m - number of rows
442736db0b34SBarry Smith .   n - number of columns
442836db0b34SBarry Smith .   i - row indices
442936db0b34SBarry Smith .   j - column indices
443036db0b34SBarry Smith -   a - matrix values
443136db0b34SBarry Smith 
443236db0b34SBarry Smith    Output Parameter:
443336db0b34SBarry Smith .   mat - the matrix
443436db0b34SBarry Smith 
443536db0b34SBarry Smith    Level: intermediate
443636db0b34SBarry Smith 
443736db0b34SBarry Smith    Notes:
44380551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4439292fb18eSBarry Smith     once the matrix is destroyed and not before
444036db0b34SBarry Smith 
444136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
444236db0b34SBarry Smith 
4443bfeeae90SHong Zhang        The i and j indices are 0 based
444436db0b34SBarry Smith 
4445a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4446a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4447a4552177SSatish Balay     as shown:
4448a4552177SSatish Balay 
4449a4552177SSatish Balay         1 0 0
4450a4552177SSatish Balay         2 0 3
4451a4552177SSatish Balay         4 5 6
4452a4552177SSatish Balay 
4453a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
44549985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4455a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4456a4552177SSatish Balay 
44579985e31cSBarry Smith 
445869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
445936db0b34SBarry Smith 
446036db0b34SBarry Smith @*/
44617087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
446236db0b34SBarry Smith {
4463dfbe8321SBarry Smith   PetscErrorCode ierr;
4464cbcfb4deSHong Zhang   PetscInt       ii;
446536db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4466cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4467cbcfb4deSHong Zhang   PetscInt jj;
4468cbcfb4deSHong Zhang #endif
446936db0b34SBarry Smith 
447036db0b34SBarry Smith   PetscFunctionBegin;
4471f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4472f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4473f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4474a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4475ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4476ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4477ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4478dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4479ab93d7beSBarry Smith 
448036db0b34SBarry Smith   aij->i            = i;
448136db0b34SBarry Smith   aij->j            = j;
448236db0b34SBarry Smith   aij->a            = a;
448336db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
448436db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4485e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4486e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
448736db0b34SBarry Smith 
448836db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
448936db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
44902515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4491e32f2f54SBarry 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]);
44929985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4493e32f2f54SBarry 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);
4494e32f2f54SBarry 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);
44959985e31cSBarry Smith     }
449636db0b34SBarry Smith #endif
449736db0b34SBarry Smith   }
44982515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
449936db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4500e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4501e32f2f54SBarry 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]);
450236db0b34SBarry Smith   }
450336db0b34SBarry Smith #endif
450436db0b34SBarry Smith 
4505b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4506b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
450736db0b34SBarry Smith   PetscFunctionReturn(0);
450836db0b34SBarry Smith }
45098a0b0e6bSVictor Minden #undef __FUNCT__
45108a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
451180ef6e79SMatthew G Knepley /*@C
4512d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
45138a0b0e6bSVictor Minden               provided by the user.
45148a0b0e6bSVictor Minden 
45158a0b0e6bSVictor Minden       Collective on MPI_Comm
45168a0b0e6bSVictor Minden 
45178a0b0e6bSVictor Minden    Input Parameters:
45188a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
45198a0b0e6bSVictor Minden .   m   - number of rows
45208a0b0e6bSVictor Minden .   n   - number of columns
45218a0b0e6bSVictor Minden .   i   - row indices
45228a0b0e6bSVictor Minden .   j   - column indices
45231230e6d1SVictor Minden .   a   - matrix values
45241230e6d1SVictor Minden .   nz  - number of nonzeros
45251230e6d1SVictor Minden -   idx - 0 or 1 based
45268a0b0e6bSVictor Minden 
45278a0b0e6bSVictor Minden    Output Parameter:
45288a0b0e6bSVictor Minden .   mat - the matrix
45298a0b0e6bSVictor Minden 
45308a0b0e6bSVictor Minden    Level: intermediate
45318a0b0e6bSVictor Minden 
45328a0b0e6bSVictor Minden    Notes:
45338a0b0e6bSVictor Minden        The i and j indices are 0 based
45348a0b0e6bSVictor Minden 
45358a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
45368a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
45378a0b0e6bSVictor Minden     as shown:
45388a0b0e6bSVictor Minden 
45398a0b0e6bSVictor Minden         1 0 0
45408a0b0e6bSVictor Minden         2 0 3
45418a0b0e6bSVictor Minden         4 5 6
45428a0b0e6bSVictor Minden 
45438a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
45448a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
45458a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
45468a0b0e6bSVictor Minden 
45478a0b0e6bSVictor Minden 
454869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
45498a0b0e6bSVictor Minden 
45508a0b0e6bSVictor Minden @*/
45511230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
45528a0b0e6bSVictor Minden {
45538a0b0e6bSVictor Minden   PetscErrorCode ierr;
4554d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
45558a0b0e6bSVictor Minden 
45568a0b0e6bSVictor Minden 
45578a0b0e6bSVictor Minden   PetscFunctionBegin;
45581795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
45591230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4560c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
45611230e6d1SVictor Minden   }
45628a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
45638a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
45648a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
45651230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
45661230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
45671230e6d1SVictor Minden     if (idx) {
45681230e6d1SVictor Minden       row = i[ii] - 1;
45691230e6d1SVictor Minden       col = j[ii] - 1;
45701230e6d1SVictor Minden     } else {
45711230e6d1SVictor Minden       row = i[ii];
45721230e6d1SVictor Minden       col = j[ii];
45738a0b0e6bSVictor Minden     }
45741230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
45758a0b0e6bSVictor Minden   }
45768a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
45778a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4578d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
45798a0b0e6bSVictor Minden   PetscFunctionReturn(0);
45808a0b0e6bSVictor Minden }
458136db0b34SBarry Smith 
4582cc8ba8e1SBarry Smith #undef __FUNCT__
4583ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4584dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4585cc8ba8e1SBarry Smith {
4586dfbe8321SBarry Smith   PetscErrorCode ierr;
4587cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
458836db0b34SBarry Smith 
4589cc8ba8e1SBarry Smith   PetscFunctionBegin;
45908ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4591cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4592cc8ba8e1SBarry Smith     a->coloring = coloring;
459312c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
459497f1f81fSBarry Smith     PetscInt        i,*larray;
459512c595b3SBarry Smith     ISColoring      ocoloring;
459608b6dcc0SBarry Smith     ISColoringValue *colors;
459712c595b3SBarry Smith 
459812c595b3SBarry Smith     /* set coloring for diagonal portion */
4599785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
46002205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
46010298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4602785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
46032205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
460412c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4605d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
460612c595b3SBarry Smith     a->coloring = ocoloring;
460712c595b3SBarry Smith   }
4608cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4609cc8ba8e1SBarry Smith }
4610cc8ba8e1SBarry Smith 
4611ee4f033dSBarry Smith #undef __FUNCT__
4612ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
461397f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4614ee4f033dSBarry Smith {
4615ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4616d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
461754f21887SBarry Smith   MatScalar       *v      = a->a;
461854f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
461908b6dcc0SBarry Smith   ISColoringValue *color;
4620ee4f033dSBarry Smith 
4621ee4f033dSBarry Smith   PetscFunctionBegin;
4622e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4623ee4f033dSBarry Smith   color = a->coloring->colors;
4624ee4f033dSBarry Smith   /* loop over rows */
4625ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4626ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4627ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
46282205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4629ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4630cc8ba8e1SBarry Smith   }
4631cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4632cc8ba8e1SBarry Smith }
463336db0b34SBarry Smith 
4634acf2f550SJed Brown #undef __FUNCT__
4635acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4636acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4637acf2f550SJed Brown {
4638acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4639acf2f550SJed Brown   PetscErrorCode ierr;
4640acf2f550SJed Brown 
4641acf2f550SJed Brown   PetscFunctionBegin;
4642acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4643acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
46442205254eSKarl Rupp 
4645acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4646acf2f550SJed Brown   PetscFunctionReturn(0);
4647acf2f550SJed Brown }
4648acf2f550SJed Brown 
464981824310SBarry Smith /*
465081824310SBarry Smith     Special version for direct calls from Fortran
465181824310SBarry Smith */
4652b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
465381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
465481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
465581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
465681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
465781824310SBarry Smith #endif
465881824310SBarry Smith 
465981824310SBarry Smith /* Change these macros so can be used in void function */
466081824310SBarry Smith #undef CHKERRQ
4661ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
466281824310SBarry Smith #undef SETERRQ2
4663e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
46644994cf47SJed Brown #undef SETERRQ3
46654994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
466681824310SBarry Smith 
466781824310SBarry Smith #undef __FUNCT__
466881824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
46698cc058d9SJed 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)
467081824310SBarry Smith {
467181824310SBarry Smith   Mat            A  = *AA;
467281824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
467381824310SBarry Smith   InsertMode     is = *isis;
467481824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
467581824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
467681824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
467781824310SBarry Smith   PetscErrorCode ierr;
467881824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
467954f21887SBarry Smith   MatScalar      *ap,value,*aa;
4680ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4681ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
468281824310SBarry Smith 
468381824310SBarry Smith   PetscFunctionBegin;
46844994cf47SJed Brown   MatCheckPreallocated(A,1);
468581824310SBarry Smith   imax  = a->imax;
468681824310SBarry Smith   ai    = a->i;
468781824310SBarry Smith   ailen = a->ilen;
468881824310SBarry Smith   aj    = a->j;
468981824310SBarry Smith   aa    = a->a;
469081824310SBarry Smith 
469181824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
469281824310SBarry Smith     row = im[k];
469381824310SBarry Smith     if (row < 0) continue;
469481824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4695ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
469681824310SBarry Smith #endif
469781824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
469881824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
469981824310SBarry Smith     low  = 0;
470081824310SBarry Smith     high = nrow;
470181824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
470281824310SBarry Smith       if (in[l] < 0) continue;
470381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4704ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
470581824310SBarry Smith #endif
470681824310SBarry Smith       col = in[l];
47072205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
47082205254eSKarl Rupp       else value = v[k + l*m];
47092205254eSKarl Rupp 
471081824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
471181824310SBarry Smith 
47122205254eSKarl Rupp       if (col <= lastcol) low = 0;
47132205254eSKarl Rupp       else high = nrow;
471481824310SBarry Smith       lastcol = col;
471581824310SBarry Smith       while (high-low > 5) {
471681824310SBarry Smith         t = (low+high)/2;
471781824310SBarry Smith         if (rp[t] > col) high = t;
471881824310SBarry Smith         else             low  = t;
471981824310SBarry Smith       }
472081824310SBarry Smith       for (i=low; i<high; i++) {
472181824310SBarry Smith         if (rp[i] > col) break;
472281824310SBarry Smith         if (rp[i] == col) {
472381824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
472481824310SBarry Smith           else                  ap[i] = value;
472581824310SBarry Smith           goto noinsert;
472681824310SBarry Smith         }
472781824310SBarry Smith       }
472881824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
472981824310SBarry Smith       if (nonew == 1) goto noinsert;
4730ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4731fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
473281824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
473381824310SBarry Smith       /* shift up all the later entries in this row */
473481824310SBarry Smith       for (ii=N; ii>=i; ii--) {
473581824310SBarry Smith         rp[ii+1] = rp[ii];
473681824310SBarry Smith         ap[ii+1] = ap[ii];
473781824310SBarry Smith       }
473881824310SBarry Smith       rp[i] = col;
473981824310SBarry Smith       ap[i] = value;
474081824310SBarry Smith noinsert:;
474181824310SBarry Smith       low = i + 1;
474281824310SBarry Smith     }
474381824310SBarry Smith     ailen[row] = nrow;
474481824310SBarry Smith   }
474581824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
474681824310SBarry Smith   PetscFunctionReturnVoid();
474781824310SBarry Smith }
47489f7953f8SBarry Smith 
474962298a1eSBarry Smith 
4750