xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 189e400751ee4871736b65bb4c939eb6a95690c9)
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 */
390*189e4007SBarry 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];
405*189e4007SBarry Smith   printf("row %d nrow %d\n",row,nrow);
406*189e4007SBarry 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;
412*189e4007SBarry 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     }
427*189e4007SBarry 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 
432*189e4007SBarry Smith #include <petsc-private/isimpl.h>
433*189e4007SBarry Smith #undef __FUNCT__
434*189e4007SBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast"
435*189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
436*189e4007SBarry Smith {
437*189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
438*189e4007SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
439*189e4007SBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
440*189e4007SBarry Smith   PetscErrorCode ierr;
441*189e4007SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
442*189e4007SBarry Smith   MatScalar      *ap,value,*aa = a->a;
443*189e4007SBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
444*189e4007SBarry Smith   PetscBool      roworiented       = a->roworiented;
445*189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
446*189e4007SBarry Smith 
447*189e4007SBarry Smith   PetscFunctionBegin;
448*189e4007SBarry Smith   if (v) PetscValidScalarPointer(v,6);
449*189e4007SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
450*189e4007SBarry Smith     row = ridx[im[k]];
451*189e4007SBarry Smith     if (row < 0) continue;
452*189e4007SBarry Smith #if defined(PETSC_USE_DEBUG)
453*189e4007SBarry 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);
454*189e4007SBarry Smith #endif
455*189e4007SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
456*189e4007SBarry Smith     rmax = imax[row]; nrow = ailen[row];
457*189e4007SBarry Smith     low  = 0;
458*189e4007SBarry Smith     high = nrow;
459*189e4007SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
460*189e4007SBarry Smith       col = cidx[in[l]];
461*189e4007SBarry Smith       if (col < 0) continue;
462*189e4007SBarry Smith #if defined(PETSC_USE_DEBUG)
463*189e4007SBarry Smith       if (col >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",col,A->cmap->n-1);
464*189e4007SBarry Smith #endif
465*189e4007SBarry Smith 
466*189e4007SBarry Smith       if (v) {
467*189e4007SBarry Smith         if (roworiented) {
468*189e4007SBarry Smith           value = v[l + k*n];
469*189e4007SBarry Smith         } else {
470*189e4007SBarry Smith           value = v[k + l*m];
471*189e4007SBarry Smith         }
472*189e4007SBarry Smith       } else {
473*189e4007SBarry Smith         value = 0.;
474*189e4007SBarry Smith       }
475*189e4007SBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
476*189e4007SBarry Smith 
477*189e4007SBarry Smith       if (col <= lastcol) low = 0;
478*189e4007SBarry Smith       else high = nrow;
479*189e4007SBarry Smith       lastcol = col;
480*189e4007SBarry Smith       while (high-low > 5) {
481*189e4007SBarry Smith         t = (low+high)/2;
482*189e4007SBarry Smith         if (rp[t] > col) high = t;
483*189e4007SBarry Smith         else low = t;
484*189e4007SBarry Smith       }
485*189e4007SBarry Smith       for (i=low; i<high; i++) {
486*189e4007SBarry Smith         if (rp[i] > col) break;
487*189e4007SBarry Smith         if (rp[i] == col) {
488*189e4007SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
489*189e4007SBarry Smith           else ap[i] = value;
490*189e4007SBarry Smith           low = i + 1;
491*189e4007SBarry Smith           goto noinsert;
492*189e4007SBarry Smith         }
493*189e4007SBarry Smith       }
494*189e4007SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
495*189e4007SBarry Smith       if (nonew == 1) goto noinsert;
496*189e4007SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
497*189e4007SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
498*189e4007SBarry Smith       N = nrow++ - 1; a->nz++; high++;
499*189e4007SBarry Smith       /* shift up all the later entries in this row */
500*189e4007SBarry Smith       for (ii=N; ii>=i; ii--) {
501*189e4007SBarry Smith         rp[ii+1] = rp[ii];
502*189e4007SBarry Smith         ap[ii+1] = ap[ii];
503*189e4007SBarry Smith       }
504*189e4007SBarry Smith       rp[i] = col;
505*189e4007SBarry Smith       ap[i] = value;
506*189e4007SBarry Smith       low   = i + 1;
507*189e4007SBarry Smith noinsert:;
508*189e4007SBarry Smith     }
509*189e4007SBarry Smith     ailen[row] = nrow;
510*189e4007SBarry Smith   }
511*189e4007SBarry Smith   A->same_nonzero = PETSC_FALSE;
512*189e4007SBarry Smith   PetscFunctionReturn(0);
513*189e4007SBarry Smith }
514*189e4007SBarry Smith 
515bd04181cSBarry Smith #undef __FUNCT__
5164a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
51797f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
51817ab2063SBarry Smith {
519416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
520e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
52197f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
5226849ba73SBarry Smith   PetscErrorCode ierr;
523e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
52454f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
525ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
526ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
52717ab2063SBarry Smith 
5283a40ed3dSBarry Smith   PetscFunctionBegin;
52971fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
53017ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
531416022c9SBarry Smith     row = im[k];
5325ef9f2a5SBarry Smith     if (row < 0) continue;
5332515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
534e32f2f54SBarry 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);
5353b2fbd54SBarry Smith #endif
536bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
53717ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
538416022c9SBarry Smith     low  = 0;
539c71e6ed7SBarry Smith     high = nrow;
54017ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
5415ef9f2a5SBarry Smith       if (in[l] < 0) continue;
5422515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
543e32f2f54SBarry 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);
5443b2fbd54SBarry Smith #endif
545bfeeae90SHong Zhang       col = in[l];
54616371a99SBarry Smith       if (v) {
5474b0e389bSBarry Smith         if (roworiented) {
5485ef9f2a5SBarry Smith           value = v[l + k*n];
549bef8e0ddSBarry Smith         } else {
5504b0e389bSBarry Smith           value = v[k + l*m];
5514b0e389bSBarry Smith         }
55216371a99SBarry Smith       } else {
55375567043SBarry Smith         value = 0.;
55416371a99SBarry Smith       }
55533b2b78bSBarry Smith       if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue;
55636db0b34SBarry Smith 
5572205254eSKarl Rupp       if (col <= lastcol) low = 0;
5582205254eSKarl Rupp       else high = nrow;
559e2ee6c50SBarry Smith       lastcol = col;
560416022c9SBarry Smith       while (high-low > 5) {
561416022c9SBarry Smith         t = (low+high)/2;
562416022c9SBarry Smith         if (rp[t] > col) high = t;
563416022c9SBarry Smith         else low = t;
56417ab2063SBarry Smith       }
565416022c9SBarry Smith       for (i=low; i<high; i++) {
56617ab2063SBarry Smith         if (rp[i] > col) break;
56717ab2063SBarry Smith         if (rp[i] == col) {
568416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
56917ab2063SBarry Smith           else ap[i] = value;
570e44c0bd4SBarry Smith           low = i + 1;
57117ab2063SBarry Smith           goto noinsert;
57217ab2063SBarry Smith         }
57317ab2063SBarry Smith       }
574abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
575c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
576e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
577fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
578c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
579416022c9SBarry Smith       /* shift up all the later entries in this row */
580416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
58117ab2063SBarry Smith         rp[ii+1] = rp[ii];
58217ab2063SBarry Smith         ap[ii+1] = ap[ii];
58317ab2063SBarry Smith       }
58417ab2063SBarry Smith       rp[i] = col;
58517ab2063SBarry Smith       ap[i] = value;
586416022c9SBarry Smith       low   = i + 1;
587e44c0bd4SBarry Smith noinsert:;
58817ab2063SBarry Smith     }
58917ab2063SBarry Smith     ailen[row] = nrow;
59017ab2063SBarry Smith   }
59188e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
5923a40ed3dSBarry Smith   PetscFunctionReturn(0);
59317ab2063SBarry Smith }
59417ab2063SBarry Smith 
59581824310SBarry Smith 
5964a2ae208SSatish Balay #undef __FUNCT__
5974a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
598a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
5997eb43aa7SLois Curfman McInnes {
6007eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
60197f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
60297f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
60354f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
6047eb43aa7SLois Curfman McInnes 
6053a40ed3dSBarry Smith   PetscFunctionBegin;
6067eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
6077eb43aa7SLois Curfman McInnes     row = im[k];
608e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
609e32f2f54SBarry 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);
610bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
6117eb43aa7SLois Curfman McInnes     nrow = ailen[row];
6127eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
613e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
614e32f2f54SBarry 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);
615bfeeae90SHong Zhang       col  = in[l];
6167eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
6177eb43aa7SLois Curfman McInnes       while (high-low > 5) {
6187eb43aa7SLois Curfman McInnes         t = (low+high)/2;
6197eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
6207eb43aa7SLois Curfman McInnes         else low = t;
6217eb43aa7SLois Curfman McInnes       }
6227eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
6237eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
6247eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
625b49de8d1SLois Curfman McInnes           *v++ = ap[i];
6267eb43aa7SLois Curfman McInnes           goto finished;
6277eb43aa7SLois Curfman McInnes         }
6287eb43aa7SLois Curfman McInnes       }
62997e567efSBarry Smith       *v++ = 0.0;
6307eb43aa7SLois Curfman McInnes finished:;
6317eb43aa7SLois Curfman McInnes     }
6327eb43aa7SLois Curfman McInnes   }
6333a40ed3dSBarry Smith   PetscFunctionReturn(0);
6347eb43aa7SLois Curfman McInnes }
6357eb43aa7SLois Curfman McInnes 
63617ab2063SBarry Smith 
6374a2ae208SSatish Balay #undef __FUNCT__
6384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
639dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
64017ab2063SBarry Smith {
641416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
6426849ba73SBarry Smith   PetscErrorCode ierr;
6436f69ff64SBarry Smith   PetscInt       i,*col_lens;
6446f69ff64SBarry Smith   int            fd;
645b37d52dbSMark F. Adams   FILE           *file;
64617ab2063SBarry Smith 
6473a40ed3dSBarry Smith   PetscFunctionBegin;
648b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
649785e854fSJed Brown   ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr);
6502205254eSKarl Rupp 
6510700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
652d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
653d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
654416022c9SBarry Smith   col_lens[3] = a->nz;
655416022c9SBarry Smith 
656416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
657d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
658416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
65917ab2063SBarry Smith   }
660d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
661606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
662416022c9SBarry Smith 
663416022c9SBarry Smith   /* store column indices (zero start index) */
6646f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
665416022c9SBarry Smith 
666416022c9SBarry Smith   /* store nonzero values */
6676f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
668b37d52dbSMark F. Adams 
669b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
670b37d52dbSMark F. Adams   if (file) {
671b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
672b37d52dbSMark F. Adams   }
6733a40ed3dSBarry Smith   PetscFunctionReturn(0);
67417ab2063SBarry Smith }
675416022c9SBarry Smith 
67609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
677cd155464SBarry Smith 
6784a2ae208SSatish Balay #undef __FUNCT__
6794a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
680dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
681416022c9SBarry Smith {
682416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
683dfbe8321SBarry Smith   PetscErrorCode    ierr;
684d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
685e060cb09SBarry Smith   const char        *name;
686f3ef73ceSBarry Smith   PetscViewerFormat format;
68717ab2063SBarry Smith 
6883a40ed3dSBarry Smith   PetscFunctionBegin;
689b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
69071c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
69197f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
692014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
693d00d2cf4SBarry Smith       nofinalvalue = 1;
694d00d2cf4SBarry Smith     }
695d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
696d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
69777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
69877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
699b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
70017ab2063SBarry Smith 
70117ab2063SBarry Smith     for (i=0; i<m; i++) {
702416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
703aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
70477431f27SBarry 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);
70517ab2063SBarry Smith #else
70677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
70717ab2063SBarry Smith #endif
70817ab2063SBarry Smith       }
70917ab2063SBarry Smith     }
710d00d2cf4SBarry Smith     if (nofinalvalue) {
711d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
712d00d2cf4SBarry Smith     }
713317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
714fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
715d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
71668369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
717cd155464SBarry Smith     PetscFunctionReturn(0);
718fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
719d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
720dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
72144cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
72277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
72344cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
724aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
72536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
726ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
728ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72936db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
730ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
7316831982aSBarry Smith         }
73244cd7ae7SLois Curfman McInnes #else
733ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
73444cd7ae7SLois Curfman McInnes #endif
73544cd7ae7SLois Curfman McInnes       }
736b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
73744cd7ae7SLois Curfman McInnes     }
738d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
739fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
74097f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
741d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
742dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
743785e854fSJed Brown     ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr);
744496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
745496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
746496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
747496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
748aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
74936db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
750496be53dSLois Curfman McInnes #else
751496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
752496be53dSLois Curfman McInnes #endif
753496be53dSLois Curfman McInnes         }
754496be53dSLois Curfman McInnes       }
755496be53dSLois Curfman McInnes     }
7562e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
75777431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
7582e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
7592205254eSKarl Rupp       if (i+4<m) {
7602205254eSKarl 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);
7612205254eSKarl Rupp       } else if (i+3<m) {
7622205254eSKarl 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);
7632205254eSKarl Rupp       } else if (i+2<m) {
7642205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
7652205254eSKarl Rupp       } else if (i+1<m) {
7662205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
7672205254eSKarl Rupp       } else if (i<m) {
7682205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
7692205254eSKarl Rupp       } else {
7702205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
7712205254eSKarl Rupp       }
772496be53dSLois Curfman McInnes     }
773b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
774606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
775496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
776496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
77777431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
778496be53dSLois Curfman McInnes       }
779b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
780496be53dSLois Curfman McInnes     }
781b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
782496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
783496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
784496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
785aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
78636db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
787b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7886831982aSBarry Smith           }
789496be53dSLois Curfman McInnes #else
790b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
791496be53dSLois Curfman McInnes #endif
792496be53dSLois Curfman McInnes         }
793496be53dSLois Curfman McInnes       }
794b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
795496be53dSLois Curfman McInnes     }
796d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
797fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
79897f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
79987828ca2SBarry Smith     PetscScalar value;
80068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
80168f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
80268f1ed48SBarry Smith 
80368f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
80468f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
80568f1ed48SBarry Smith         realonly = PETSC_FALSE;
80668f1ed48SBarry Smith         break;
80768f1ed48SBarry Smith       }
80868f1ed48SBarry Smith     }
80968f1ed48SBarry Smith #endif
81002594712SBarry Smith 
811d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
812dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
81302594712SBarry Smith     for (i=0; i<m; i++) {
81402594712SBarry Smith       jcnt = 0;
815d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
816e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
81702594712SBarry Smith           value = a->a[cnt++];
818e24b481bSBarry Smith           jcnt++;
81902594712SBarry Smith         } else {
82002594712SBarry Smith           value = 0.0;
82102594712SBarry Smith         }
822aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
82368f1ed48SBarry Smith         if (realonly) {
82468f1ed48SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",PetscRealPart(value));CHKERRQ(ierr);
82568f1ed48SBarry Smith         } else {
826b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
82768f1ed48SBarry Smith         }
82802594712SBarry Smith #else
829b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
83002594712SBarry Smith #endif
83102594712SBarry Smith       }
832b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
83302594712SBarry Smith     }
834d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
8353c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
836150b93efSMatthew G. Knepley     PetscInt fshift=1;
837d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
8383c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
8393c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
8403c215bfdSMatthew Knepley #else
8413c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
8423c215bfdSMatthew Knepley #endif
843d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
8443c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
8453c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
8463c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
8473c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
848150b93efSMatthew 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);
8493c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
850150b93efSMatthew 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);
8513c215bfdSMatthew Knepley         } else {
852150b93efSMatthew G. Knepley           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
8533c215bfdSMatthew Knepley         }
8543c215bfdSMatthew Knepley #else
855150b93efSMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
8563c215bfdSMatthew Knepley #endif
8573c215bfdSMatthew Knepley       }
8583c215bfdSMatthew Knepley     }
859d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
8603a40ed3dSBarry Smith   } else {
861d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
862dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
863d5f3da31SBarry Smith     if (A->factortype) {
86416cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
86516cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
86616cd7e1dSShri Abhyankar         /* L part */
86716cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
86816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
86916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
870ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
87116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
872ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
87316cd7e1dSShri Abhyankar           } else {
874ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
87516cd7e1dSShri Abhyankar           }
87616cd7e1dSShri Abhyankar #else
877ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
87816cd7e1dSShri Abhyankar #endif
87916cd7e1dSShri Abhyankar         }
88016cd7e1dSShri Abhyankar         /* diagonal */
88116cd7e1dSShri Abhyankar         j = a->diag[i];
88216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
88316cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
884ba0e910bSBarry 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);
88516cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
886ba0e910bSBarry 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);
88716cd7e1dSShri Abhyankar         } else {
888ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
88916cd7e1dSShri Abhyankar         }
89016cd7e1dSShri Abhyankar #else
891ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
89216cd7e1dSShri Abhyankar #endif
89316cd7e1dSShri Abhyankar 
89416cd7e1dSShri Abhyankar         /* U part */
89516cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
89616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
89716cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
898ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
89916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
900ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
90116cd7e1dSShri Abhyankar           } else {
902ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
90316cd7e1dSShri Abhyankar           }
90416cd7e1dSShri Abhyankar #else
905ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
90616cd7e1dSShri Abhyankar #endif
90716cd7e1dSShri Abhyankar         }
90816cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
90916cd7e1dSShri Abhyankar       }
91016cd7e1dSShri Abhyankar     } else {
91117ab2063SBarry Smith       for (i=0; i<m; i++) {
91277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
913416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
914aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
91536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
916ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
91736db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
918ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
9193a40ed3dSBarry Smith           } else {
920ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
92117ab2063SBarry Smith           }
92217ab2063SBarry Smith #else
923ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
92417ab2063SBarry Smith #endif
92517ab2063SBarry Smith         }
926b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
92717ab2063SBarry Smith       }
92816cd7e1dSShri Abhyankar     }
929d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
93017ab2063SBarry Smith   }
931b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
9323a40ed3dSBarry Smith   PetscFunctionReturn(0);
933416022c9SBarry Smith }
934416022c9SBarry Smith 
9359804daf3SBarry Smith #include <petscdraw.h>
9364a2ae208SSatish Balay #undef __FUNCT__
9374a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
938dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
939416022c9SBarry Smith {
940480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
941416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
942dfbe8321SBarry Smith   PetscErrorCode    ierr;
943d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
94436db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
945b0a32e0cSBarry Smith   PetscViewer       viewer;
946f3ef73ceSBarry Smith   PetscViewerFormat format;
947cddf8d76SBarry Smith 
9483a40ed3dSBarry Smith   PetscFunctionBegin;
949480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
950b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
95119bcc07fSBarry Smith 
952b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
953416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
9540513a670SBarry Smith 
955fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
9560513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
957b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
958416022c9SBarry Smith     for (i=0; i<m; i++) {
959cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
960bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
961bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
96236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
963b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
964cddf8d76SBarry Smith       }
965cddf8d76SBarry Smith     }
966b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
967cddf8d76SBarry Smith     for (i=0; i<m; i++) {
968cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
969bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
970bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
971cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
972b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
973cddf8d76SBarry Smith       }
974cddf8d76SBarry Smith     }
975b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
976cddf8d76SBarry Smith     for (i=0; i<m; i++) {
977cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
978bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
979bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
98036db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
981b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
982416022c9SBarry Smith       }
983416022c9SBarry Smith     }
9840513a670SBarry Smith   } else {
9850513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
9860513a670SBarry Smith     /* first determine max of all nonzero values */
98797f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
988b0a32e0cSBarry Smith     PetscDraw popup;
98936db0b34SBarry Smith     PetscReal scale;
9900513a670SBarry Smith 
9910513a670SBarry Smith     for (i=0; i<nz; i++) {
9920513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
9930513a670SBarry Smith     }
994b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
995b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
9962205254eSKarl Rupp     if (popup) {
9972205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
9982205254eSKarl Rupp     }
9990513a670SBarry Smith     count = 0;
10000513a670SBarry Smith     for (i=0; i<m; i++) {
10010513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
1002bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
1003bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
100497f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
1005b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
10060513a670SBarry Smith         count++;
10070513a670SBarry Smith       }
10080513a670SBarry Smith     }
10090513a670SBarry Smith   }
1010480ef9eaSBarry Smith   PetscFunctionReturn(0);
1011480ef9eaSBarry Smith }
1012cddf8d76SBarry Smith 
10139804daf3SBarry Smith #include <petscdraw.h>
10144a2ae208SSatish Balay #undef __FUNCT__
10154a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
1016dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
1017480ef9eaSBarry Smith {
1018dfbe8321SBarry Smith   PetscErrorCode ierr;
1019b0a32e0cSBarry Smith   PetscDraw      draw;
102036db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1021ace3abfcSBarry Smith   PetscBool      isnull;
1022480ef9eaSBarry Smith 
1023480ef9eaSBarry Smith   PetscFunctionBegin;
1024b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1025b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1026480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
1027480ef9eaSBarry Smith 
1028480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1029d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1030480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
1031b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1032b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
10330298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
10343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1035416022c9SBarry Smith }
1036416022c9SBarry Smith 
10374a2ae208SSatish Balay #undef __FUNCT__
10384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
1039dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
1040416022c9SBarry Smith {
1041dfbe8321SBarry Smith   PetscErrorCode ierr;
1042ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1043416022c9SBarry Smith 
10443a40ed3dSBarry Smith   PetscFunctionBegin;
1045251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1046251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1047251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1048c45a1595SBarry Smith   if (iascii) {
10493a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
10500f5bd95cSBarry Smith   } else if (isbinary) {
10513a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
10520f5bd95cSBarry Smith   } else if (isdraw) {
10533a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
105411aeaf0aSBarry Smith   }
10554108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
10563a40ed3dSBarry Smith   PetscFunctionReturn(0);
105717ab2063SBarry Smith }
105819bcc07fSBarry Smith 
10594a2ae208SSatish Balay #undef __FUNCT__
10604a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
1061dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
106217ab2063SBarry Smith {
1063416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10646849ba73SBarry Smith   PetscErrorCode ierr;
106597f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
1066d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
106754f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
10683447b6efSHong Zhang   PetscReal      ratio  = 0.6;
106917ab2063SBarry Smith 
10703a40ed3dSBarry Smith   PetscFunctionBegin;
10713a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
107217ab2063SBarry Smith 
107343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
107417ab2063SBarry Smith   for (i=1; i<m; i++) {
1075416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
107617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
107794a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
107817ab2063SBarry Smith     if (fshift) {
1079bfeeae90SHong Zhang       ip = aj + ai[i];
1080bfeeae90SHong Zhang       ap = aa + ai[i];
108117ab2063SBarry Smith       N  = ailen[i];
108217ab2063SBarry Smith       for (j=0; j<N; j++) {
108317ab2063SBarry Smith         ip[j-fshift] = ip[j];
108417ab2063SBarry Smith         ap[j-fshift] = ap[j];
108517ab2063SBarry Smith       }
108617ab2063SBarry Smith     }
108717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
108817ab2063SBarry Smith   }
108917ab2063SBarry Smith   if (m) {
109017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
109117ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
109217ab2063SBarry Smith   }
10937b083b7cSBarry Smith 
109417ab2063SBarry Smith   /* reset ilen and imax for each row */
10957b083b7cSBarry Smith   a->nonzerorowcnt = 0;
109617ab2063SBarry Smith   for (i=0; i<m; i++) {
109717ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
10987b083b7cSBarry Smith     a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
109917ab2063SBarry Smith   }
1100bfeeae90SHong Zhang   a->nz = ai[m];
110165e19b50SBarry 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);
110217ab2063SBarry Smith 
110309f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1104d0f46423SBarry 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);
1105ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
1106ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
11072205254eSKarl Rupp 
11088e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1109dd5f02e7SSatish Balay   a->reallocs         = 0;
11104e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
111136db0b34SBarry Smith   a->rmax             = rmax;
11124e220ebcSLois Curfman McInnes 
111311e456e1SBarry Smith   ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
11142205254eSKarl Rupp 
111588e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
111671c2f376SKris Buschelman 
11174108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
111871f1c65dSBarry Smith 
1119acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
11203a40ed3dSBarry Smith   PetscFunctionReturn(0);
112117ab2063SBarry Smith }
112217ab2063SBarry Smith 
11234a2ae208SSatish Balay #undef __FUNCT__
112499cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
112599cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
112699cafbc1SBarry Smith {
112799cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
112899cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
112954f21887SBarry Smith   MatScalar      *aa = a->a;
1130acf2f550SJed Brown   PetscErrorCode ierr;
113199cafbc1SBarry Smith 
113299cafbc1SBarry Smith   PetscFunctionBegin;
113399cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1134acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
113599cafbc1SBarry Smith   PetscFunctionReturn(0);
113699cafbc1SBarry Smith }
113799cafbc1SBarry Smith 
113899cafbc1SBarry Smith #undef __FUNCT__
113999cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
114099cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
114199cafbc1SBarry Smith {
114299cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
114399cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
114454f21887SBarry Smith   MatScalar      *aa = a->a;
1145acf2f550SJed Brown   PetscErrorCode ierr;
114699cafbc1SBarry Smith 
114799cafbc1SBarry Smith   PetscFunctionBegin;
114899cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1149acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
115099cafbc1SBarry Smith   PetscFunctionReturn(0);
115199cafbc1SBarry Smith }
115299cafbc1SBarry Smith 
115378b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
115478b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
115578b84d54SShri Abhyankar {
115678b84d54SShri Abhyankar   PetscErrorCode ierr;
115778b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
115878b84d54SShri Abhyankar   PetscInt       n,start,end;
115978b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
116078b84d54SShri Abhyankar 
116178b84d54SShri Abhyankar   start = trstarts[thread_id];
116278b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
116319baf141SJed Brown   n     = a->i[end] - a->i[start];
116419baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
116578b84d54SShri Abhyankar   return 0;
116678b84d54SShri Abhyankar }
116778b84d54SShri Abhyankar 
116878b84d54SShri Abhyankar #undef __FUNCT__
116978b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
117078b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
117178b84d54SShri Abhyankar {
117278b84d54SShri Abhyankar   PetscErrorCode ierr;
117378b84d54SShri Abhyankar 
117478b84d54SShri Abhyankar   PetscFunctionBegin;
1175ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1176acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
117778b84d54SShri Abhyankar   PetscFunctionReturn(0);
117878b84d54SShri Abhyankar }
117978b84d54SShri Abhyankar #else
118099cafbc1SBarry Smith #undef __FUNCT__
11814a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1182dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
118317ab2063SBarry Smith {
1184416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1185dfbe8321SBarry Smith   PetscErrorCode ierr;
11863a40ed3dSBarry Smith 
11873a40ed3dSBarry Smith   PetscFunctionBegin;
1188d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1189acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
11903a40ed3dSBarry Smith   PetscFunctionReturn(0);
119117ab2063SBarry Smith }
119278b84d54SShri Abhyankar #endif
1193416022c9SBarry Smith 
11944a2ae208SSatish Balay #undef __FUNCT__
11954a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1196dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
119717ab2063SBarry Smith {
1198416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1199dfbe8321SBarry Smith   PetscErrorCode ierr;
1200d5d45c9bSBarry Smith 
12013a40ed3dSBarry Smith   PetscFunctionBegin;
1202aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1203d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
120417ab2063SBarry Smith #endif
1205e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
12066bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
12076bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
120805b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1209d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
121005b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
121171f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
121205b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
12136bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
121405b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
12156bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
121605b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
12176bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1218cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
12190b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1220a30b2313SHong Zhang 
12214108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1222bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1223901853e0SKris Buschelman 
1224dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1225bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1226bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1227bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1228bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1229bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1230bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1231bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1232bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1233bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1234bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
12353a40ed3dSBarry Smith   PetscFunctionReturn(0);
123617ab2063SBarry Smith }
123717ab2063SBarry Smith 
12384a2ae208SSatish Balay #undef __FUNCT__
12394a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1240ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
124117ab2063SBarry Smith {
1242416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12434846f1f5SKris Buschelman   PetscErrorCode ierr;
12443a40ed3dSBarry Smith 
12453a40ed3dSBarry Smith   PetscFunctionBegin;
1246a65d3064SKris Buschelman   switch (op) {
1247a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
12484e0d8c25SBarry Smith     a->roworiented = flg;
1249a65d3064SKris Buschelman     break;
1250a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1251a9817697SBarry Smith     a->keepnonzeropattern = flg;
1252a65d3064SKris Buschelman     break;
1253512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1254512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1255a65d3064SKris Buschelman     break;
1256a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
12574e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1258a65d3064SKris Buschelman     break;
1259a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
12604e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1261a65d3064SKris Buschelman     break;
126228b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
126328b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
126428b2fa4aSMatthew Knepley     break;
1265a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
12664e0d8c25SBarry Smith     a->ignorezeroentries = flg;
12670df259c2SBarry Smith     break;
12683d472b54SHong Zhang   case MAT_SPD:
1269b1646e73SJed Brown   case MAT_SYMMETRIC:
1270b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1271b1646e73SJed Brown   case MAT_HERMITIAN:
1272b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
12735021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
12745021d80fSJed Brown     break;
12754e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1276a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1277a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1278290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1279a65d3064SKris Buschelman     break;
1280b87ac2d8SJed Brown   case MAT_USE_INODES:
1281b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1282b87ac2d8SJed Brown     break;
1283a65d3064SKris Buschelman   default:
1284e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1285a65d3064SKris Buschelman   }
12864108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
12873a40ed3dSBarry Smith   PetscFunctionReturn(0);
128817ab2063SBarry Smith }
128917ab2063SBarry Smith 
12904a2ae208SSatish Balay #undef __FUNCT__
12914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1292dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
129317ab2063SBarry Smith {
1294416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
12956849ba73SBarry Smith   PetscErrorCode ierr;
1296d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
129735e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
129817ab2063SBarry Smith 
12993a40ed3dSBarry Smith   PetscFunctionBegin;
1300d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1301e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
130235e7444dSHong Zhang 
1303d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1304d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
130535e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
13062c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
130735e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
130835e7444dSHong Zhang     PetscFunctionReturn(0);
130935e7444dSHong Zhang   }
131035e7444dSHong Zhang 
13112dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
13121ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
131335e7444dSHong Zhang   for (i=0; i<n; i++) {
131435e7444dSHong Zhang     nz = ai[i+1] - ai[i];
13152f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
131635e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
131735e7444dSHong Zhang       if (aj[j] == i) {
131835e7444dSHong Zhang         x[i] = aa[j];
131917ab2063SBarry Smith         break;
132017ab2063SBarry Smith       }
132117ab2063SBarry Smith     }
132217ab2063SBarry Smith   }
13231ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
13243a40ed3dSBarry Smith   PetscFunctionReturn(0);
132517ab2063SBarry Smith }
132617ab2063SBarry Smith 
1327c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
13284a2ae208SSatish Balay #undef __FUNCT__
13294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1330dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
133117ab2063SBarry Smith {
1332416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
13335c897100SBarry Smith   PetscScalar    *x,*y;
1334dfbe8321SBarry Smith   PetscErrorCode ierr;
1335d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
13365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1337a77337e4SBarry Smith   MatScalar         *v;
1338a77337e4SBarry Smith   PetscScalar       alpha;
13390298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
13403447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1341ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
13425c897100SBarry Smith #endif
134317ab2063SBarry Smith 
13443a40ed3dSBarry Smith   PetscFunctionBegin;
13452e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
13461ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
13471ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
13485c897100SBarry Smith 
13495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1350bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
13515c897100SBarry Smith #else
13523447b6efSHong Zhang   if (usecprow) {
13533447b6efSHong Zhang     m    = cprow.nrows;
13543447b6efSHong Zhang     ii   = cprow.i;
13557b2bb3b9SHong Zhang     ridx = cprow.rindex;
13563447b6efSHong Zhang   } else {
13573447b6efSHong Zhang     ii = a->i;
13583447b6efSHong Zhang   }
135917ab2063SBarry Smith   for (i=0; i<m; i++) {
13603447b6efSHong Zhang     idx = a->j + ii[i];
13613447b6efSHong Zhang     v   = a->a + ii[i];
13623447b6efSHong Zhang     n   = ii[i+1] - ii[i];
13633447b6efSHong Zhang     if (usecprow) {
13647b2bb3b9SHong Zhang       alpha = x[ridx[i]];
13653447b6efSHong Zhang     } else {
136617ab2063SBarry Smith       alpha = x[i];
13673447b6efSHong Zhang     }
136804fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
136917ab2063SBarry Smith   }
13705c897100SBarry Smith #endif
1371dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
13721ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
13731ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13743a40ed3dSBarry Smith   PetscFunctionReturn(0);
137517ab2063SBarry Smith }
137617ab2063SBarry Smith 
13774a2ae208SSatish Balay #undef __FUNCT__
13785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1379dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
13805c897100SBarry Smith {
1381dfbe8321SBarry Smith   PetscErrorCode ierr;
13825c897100SBarry Smith 
13835c897100SBarry Smith   PetscFunctionBegin;
1384170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
13855c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
13865c897100SBarry Smith   PetscFunctionReturn(0);
13875c897100SBarry Smith }
13885c897100SBarry Smith 
1389c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
139078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
139178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
139278b84d54SShri Abhyankar {
139378b84d54SShri Abhyankar   PetscErrorCode    ierr;
139478b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
139578b84d54SShri Abhyankar   PetscScalar       *y;
139678b84d54SShri Abhyankar   const PetscScalar *x;
139778b84d54SShri Abhyankar   const MatScalar   *aa;
139878b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
139978b84d54SShri Abhyankar   PetscInt          n,start,end,i;
140078b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
140178b84d54SShri Abhyankar   PetscScalar       sum;
140278b84d54SShri Abhyankar 
140378b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
140478b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
140578b84d54SShri Abhyankar   start = trstarts[thread_id];
140678b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
140778b84d54SShri Abhyankar   aj    = a->j;
140878b84d54SShri Abhyankar   aa    = a->a;
140978b84d54SShri Abhyankar   ai    = a->i;
141078b84d54SShri Abhyankar   for (i=start; i<end; i++) {
141178b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
141278b84d54SShri Abhyankar     aj  = a->j + ai[i];
141378b84d54SShri Abhyankar     aa  = a->a + ai[i];
141478b84d54SShri Abhyankar     sum = 0.0;
141578b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
141678b84d54SShri Abhyankar     y[i] = sum;
141778b84d54SShri Abhyankar   }
141878b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
141978b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
142078b84d54SShri Abhyankar   return 0;
142178b84d54SShri Abhyankar }
142278b84d54SShri Abhyankar 
142378b84d54SShri Abhyankar #undef __FUNCT__
142478b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
142578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
142678b84d54SShri Abhyankar {
142778b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
142878b84d54SShri Abhyankar   PetscScalar       *y;
142978b84d54SShri Abhyankar   const PetscScalar *x;
143078b84d54SShri Abhyankar   const MatScalar   *aa;
143178b84d54SShri Abhyankar   PetscErrorCode    ierr;
143278b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
14330298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14347b083b7cSBarry Smith   PetscInt          n,i;
143578b84d54SShri Abhyankar   PetscScalar       sum;
143678b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
143778b84d54SShri Abhyankar 
143878b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
143978b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
144078b84d54SShri Abhyankar #endif
144178b84d54SShri Abhyankar 
144278b84d54SShri Abhyankar   PetscFunctionBegin;
144378b84d54SShri Abhyankar   aj = a->j;
144478b84d54SShri Abhyankar   aa = a->a;
144578b84d54SShri Abhyankar   ii = a->i;
144678b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
144778b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
144878b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
144978b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
145078b84d54SShri Abhyankar     ii   = a->compressedrow.i;
145178b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
145278b84d54SShri Abhyankar     for (i=0; i<m; i++) {
145378b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
145478b84d54SShri Abhyankar       aj          = a->j + ii[i];
145578b84d54SShri Abhyankar       aa          = a->a + ii[i];
145678b84d54SShri Abhyankar       sum         = 0.0;
145778b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
145878b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
145978b84d54SShri Abhyankar       y[*ridx++] = sum;
146078b84d54SShri Abhyankar     }
146178b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
146278b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
146378b84d54SShri Abhyankar   } else { /* do not use compressed row format */
146478b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
146578b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
146678b84d54SShri Abhyankar #else
1467ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
146878b84d54SShri Abhyankar #endif
146978b84d54SShri Abhyankar   }
14707b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
147178b84d54SShri Abhyankar   PetscFunctionReturn(0);
147278b84d54SShri Abhyankar }
147378b84d54SShri Abhyankar #else
14745c897100SBarry Smith #undef __FUNCT__
14754a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1476dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
147717ab2063SBarry Smith {
1478416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1479d9fead3dSBarry Smith   PetscScalar       *y;
148054f21887SBarry Smith   const PetscScalar *x;
148154f21887SBarry Smith   const MatScalar   *aa;
1482dfbe8321SBarry Smith   PetscErrorCode    ierr;
1483003131ecSBarry Smith   PetscInt          m=A->rmap->n;
14840298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14857b083b7cSBarry Smith   PetscInt          n,i;
1486362ced78SSatish Balay   PetscScalar       sum;
1487ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
148817ab2063SBarry Smith 
1489b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
149097952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1491fee21e36SBarry Smith #endif
1492fee21e36SBarry Smith 
14933a40ed3dSBarry Smith   PetscFunctionBegin;
14943649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14951ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
149697952fefSHong Zhang   aj   = a->j;
149797952fefSHong Zhang   aa   = a->a;
1498416022c9SBarry Smith   ii   = a->i;
14994eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
150097952fefSHong Zhang     m    = a->compressedrow.nrows;
150197952fefSHong Zhang     ii   = a->compressedrow.i;
150297952fefSHong Zhang     ridx = a->compressedrow.rindex;
150397952fefSHong Zhang     for (i=0; i<m; i++) {
150497952fefSHong Zhang       n           = ii[i+1] - ii[i];
150597952fefSHong Zhang       aj          = a->j + ii[i];
150697952fefSHong Zhang       aa          = a->a + ii[i];
150797952fefSHong Zhang       sum         = 0.0;
1508003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1509003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
151097952fefSHong Zhang       y[*ridx++] = sum;
151197952fefSHong Zhang     }
151297952fefSHong Zhang   } else { /* do not use compressed row format */
1513b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1514b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1515b05257ddSBarry Smith #else
151678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1517ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
151878b84d54SShri Abhyankar #else
151917ab2063SBarry Smith     for (i=0; i<m; i++) {
1520003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1521003131ecSBarry Smith       aj          = a->j + ii[i];
1522003131ecSBarry Smith       aa          = a->a + ii[i];
152317ab2063SBarry Smith       sum         = 0.0;
1524003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152517ab2063SBarry Smith       y[i] = sum;
152617ab2063SBarry Smith     }
15278d195f9aSBarry Smith #endif
152878b84d54SShri Abhyankar #endif
1529b05257ddSBarry Smith   }
15307b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
15313649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15321ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15333a40ed3dSBarry Smith   PetscFunctionReturn(0);
153417ab2063SBarry Smith }
153578b84d54SShri Abhyankar #endif
153617ab2063SBarry Smith 
1537b434eb95SMatthew G. Knepley #undef __FUNCT__
1538b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1539b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1540b434eb95SMatthew G. Knepley {
1541b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1542b434eb95SMatthew G. Knepley   PetscScalar       *y;
1543b434eb95SMatthew G. Knepley   const PetscScalar *x;
1544b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1545b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1546b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1547b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1548b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1549b434eb95SMatthew G. Knepley   PetscScalar       sum;
1550b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1551b434eb95SMatthew G. Knepley 
1552b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1553b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1554b434eb95SMatthew G. Knepley #endif
1555b434eb95SMatthew G. Knepley 
1556b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1557b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1558b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1559b434eb95SMatthew G. Knepley   aj   = a->j;
1560b434eb95SMatthew G. Knepley   aa   = a->a;
1561b434eb95SMatthew G. Knepley   ii   = a->i;
1562b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1563b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1564b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1565b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1566b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1567b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1568b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1569b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1570b434eb95SMatthew G. Knepley       sum         = 0.0;
1571b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1572b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1573b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1574b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1575b434eb95SMatthew G. Knepley     }
1576b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1577b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1578b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1579b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1580b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1581b434eb95SMatthew G. Knepley       sum         = 0.0;
1582b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1583b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1584b434eb95SMatthew G. Knepley       y[i] = sum;
1585b434eb95SMatthew G. Knepley     }
1586b434eb95SMatthew G. Knepley   }
1587b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1588b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1589b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1590b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1591b434eb95SMatthew G. Knepley }
1592b434eb95SMatthew G. Knepley 
1593b434eb95SMatthew G. Knepley #undef __FUNCT__
1594b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1595b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1596b434eb95SMatthew G. Knepley {
1597b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1598b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1599b434eb95SMatthew G. Knepley   const PetscScalar *x;
1600b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1601b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1602b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1603b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1604b434eb95SMatthew G. Knepley   PetscScalar       sum;
1605b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1606b434eb95SMatthew G. Knepley 
1607b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1608b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1609b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1610b434eb95SMatthew G. Knepley   if (zz != yy) {
1611b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1612b434eb95SMatthew G. Knepley   } else {
1613b434eb95SMatthew G. Knepley     z = y;
1614b434eb95SMatthew G. Knepley   }
1615b434eb95SMatthew G. Knepley 
1616b434eb95SMatthew G. Knepley   aj = a->j;
1617b434eb95SMatthew G. Knepley   aa = a->a;
1618b434eb95SMatthew G. Knepley   ii = a->i;
1619b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1620b434eb95SMatthew G. Knepley     if (zz != yy) {
1621b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1622b434eb95SMatthew G. Knepley     }
1623b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1624b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1625b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1626b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1627b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1628b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1629b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1630b434eb95SMatthew G. Knepley       sum = y[*ridx];
1631b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1632b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1633b434eb95SMatthew G. Knepley     }
1634b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1635b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1636b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1637b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1638b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1639b434eb95SMatthew G. Knepley       sum = y[i];
1640b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1641b434eb95SMatthew G. Knepley       z[i] = sum;
1642b434eb95SMatthew G. Knepley     }
1643b434eb95SMatthew G. Knepley   }
1644b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1645b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1646b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1647b434eb95SMatthew G. Knepley   if (zz != yy) {
1648b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1649b434eb95SMatthew G. Knepley   }
1650b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1651b434eb95SMatthew G. Knepley }
1652b434eb95SMatthew G. Knepley 
1653c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
16544a2ae208SSatish Balay #undef __FUNCT__
16554a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1656dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
165717ab2063SBarry Smith {
1658416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1659f15663dcSBarry Smith   PetscScalar       *y,*z;
1660f15663dcSBarry Smith   const PetscScalar *x;
166154f21887SBarry Smith   const MatScalar   *aa;
1662dfbe8321SBarry Smith   PetscErrorCode    ierr;
1663d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
16640298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1665362ced78SSatish Balay   PetscScalar       sum;
1666ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
16679ea0dfa2SSatish Balay 
16683a40ed3dSBarry Smith   PetscFunctionBegin;
1669f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
16701ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
16712e8a6d31SBarry Smith   if (zz != yy) {
16721ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
16732e8a6d31SBarry Smith   } else {
16742e8a6d31SBarry Smith     z = y;
16752e8a6d31SBarry Smith   }
1676bfeeae90SHong Zhang 
167797952fefSHong Zhang   aj = a->j;
167897952fefSHong Zhang   aa = a->a;
1679cddf8d76SBarry Smith   ii = a->i;
16804eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
16814eb6d288SHong Zhang     if (zz != yy) {
16824eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
16834eb6d288SHong Zhang     }
168497952fefSHong Zhang     m    = a->compressedrow.nrows;
168597952fefSHong Zhang     ii   = a->compressedrow.i;
168697952fefSHong Zhang     ridx = a->compressedrow.rindex;
168797952fefSHong Zhang     for (i=0; i<m; i++) {
168897952fefSHong Zhang       n   = ii[i+1] - ii[i];
168997952fefSHong Zhang       aj  = a->j + ii[i];
169097952fefSHong Zhang       aa  = a->a + ii[i];
169197952fefSHong Zhang       sum = y[*ridx];
1692f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
169397952fefSHong Zhang       z[*ridx++] = sum;
169497952fefSHong Zhang     }
169597952fefSHong Zhang   } else { /* do not use compressed row format */
1696f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1697f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1698f15663dcSBarry Smith #else
169917ab2063SBarry Smith     for (i=0; i<m; i++) {
1700f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1701f15663dcSBarry Smith       aj  = a->j + ii[i];
1702f15663dcSBarry Smith       aa  = a->a + ii[i];
170317ab2063SBarry Smith       sum = y[i];
1704f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
170517ab2063SBarry Smith       z[i] = sum;
170617ab2063SBarry Smith     }
170702ab625aSSatish Balay #endif
1708f15663dcSBarry Smith   }
1709dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1710f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
17111ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
17122e8a6d31SBarry Smith   if (zz != yy) {
17131ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
17142e8a6d31SBarry Smith   }
17158154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
17166b375ea7SVictor Minden   /*
1717918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1718918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1719918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
17206b375ea7SVictor Minden   */
1721918e98c3SVictor Minden #endif
17223a40ed3dSBarry Smith   PetscFunctionReturn(0);
172317ab2063SBarry Smith }
172417ab2063SBarry Smith 
172517ab2063SBarry Smith /*
172617ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
172717ab2063SBarry Smith */
17284a2ae208SSatish Balay #undef __FUNCT__
17294a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1730dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
173117ab2063SBarry Smith {
1732416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
17336849ba73SBarry Smith   PetscErrorCode ierr;
1734d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
173517ab2063SBarry Smith 
17363a40ed3dSBarry Smith   PetscFunctionBegin;
173709f38230SBarry Smith   if (!a->diag) {
1738785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
17393bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
174009f38230SBarry Smith   }
1741d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
174209f38230SBarry Smith     a->diag[i] = a->i[i+1];
1743bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1744bfeeae90SHong Zhang       if (a->j[j] == i) {
174509f38230SBarry Smith         a->diag[i] = j;
174617ab2063SBarry Smith         break;
174717ab2063SBarry Smith       }
174817ab2063SBarry Smith     }
174917ab2063SBarry Smith   }
17503a40ed3dSBarry Smith   PetscFunctionReturn(0);
175117ab2063SBarry Smith }
175217ab2063SBarry Smith 
1753be5855fcSBarry Smith /*
1754be5855fcSBarry Smith      Checks for missing diagonals
1755be5855fcSBarry Smith */
17564a2ae208SSatish Balay #undef __FUNCT__
17574a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1758ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1759be5855fcSBarry Smith {
1760be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
176197f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1762be5855fcSBarry Smith 
1763be5855fcSBarry Smith   PetscFunctionBegin;
176409f38230SBarry Smith   *missing = PETSC_FALSE;
1765d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
176609f38230SBarry Smith     *missing = PETSC_TRUE;
176709f38230SBarry Smith     if (d) *d = 0;
1768358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
176909f38230SBarry Smith   } else {
1770f1e2ffcdSBarry Smith     diag = a->diag;
1771d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1772bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
177309f38230SBarry Smith         *missing = PETSC_TRUE;
177409f38230SBarry Smith         if (d) *d = i;
177509f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1776358d2f5dSShri Abhyankar         break;
177709f38230SBarry Smith       }
1778be5855fcSBarry Smith     }
1779be5855fcSBarry Smith   }
1780be5855fcSBarry Smith   PetscFunctionReturn(0);
1781be5855fcSBarry Smith }
1782be5855fcSBarry Smith 
178371f1c65dSBarry Smith #undef __FUNCT__
178471f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
17857087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
178671f1c65dSBarry Smith {
178771f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
178871f1c65dSBarry Smith   PetscErrorCode ierr;
1789d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
179054f21887SBarry Smith   MatScalar      *v = a->a;
179154f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
179271f1c65dSBarry Smith 
179371f1c65dSBarry Smith   PetscFunctionBegin;
179471f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
179571f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
179671f1c65dSBarry Smith   diag = a->diag;
179771f1c65dSBarry Smith   if (!a->idiag) {
1798dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
17993bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
180071f1c65dSBarry Smith     v    = a->a;
180171f1c65dSBarry Smith   }
180271f1c65dSBarry Smith   mdiag = a->mdiag;
180371f1c65dSBarry Smith   idiag = a->idiag;
180471f1c65dSBarry Smith 
1805028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
180671f1c65dSBarry Smith     for (i=0; i<m; i++) {
180771f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1808e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
180971f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
181071f1c65dSBarry Smith     }
181171f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
181271f1c65dSBarry Smith   } else {
181371f1c65dSBarry Smith     for (i=0; i<m; i++) {
181471f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
181571f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
181671f1c65dSBarry Smith     }
1817dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
181871f1c65dSBarry Smith   }
181971f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
182071f1c65dSBarry Smith   PetscFunctionReturn(0);
182171f1c65dSBarry Smith }
182271f1c65dSBarry Smith 
1823c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
18244a2ae208SSatish Balay #undef __FUNCT__
182541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
182641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
182717ab2063SBarry Smith {
1828416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1829e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1830e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
183154f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1832dfbe8321SBarry Smith   PetscErrorCode    ierr;
1833d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
183497f1f81fSBarry Smith   const PetscInt    *idx,*diag;
183517ab2063SBarry Smith 
18363a40ed3dSBarry Smith   PetscFunctionBegin;
1837b965ef7fSBarry Smith   its = its*lits;
183891723122SBarry Smith 
183971f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
184071f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
184171f1c65dSBarry Smith   a->fshift = fshift;
184271f1c65dSBarry Smith   a->omega  = omega;
1843ed480e8bSBarry Smith 
184471f1c65dSBarry Smith   diag  = a->diag;
184571f1c65dSBarry Smith   t     = a->ssor_work;
1846ed480e8bSBarry Smith   idiag = a->idiag;
184771f1c65dSBarry Smith   mdiag = a->mdiag;
1848ed480e8bSBarry Smith 
18491ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
18503649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1851ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
185217ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
185317ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1854ed480e8bSBarry Smith     bs = b;
185517ab2063SBarry Smith     for (i=0; i<m; i++) {
185671f1c65dSBarry Smith       d   = fshift + mdiag[i];
1857416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1858ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1859ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
186017ab2063SBarry Smith       sum = b[i]*d/omega;
1861003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
186217ab2063SBarry Smith       x[i] = sum;
186317ab2063SBarry Smith     }
18641ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18653649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1866efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
18673a40ed3dSBarry Smith     PetscFunctionReturn(0);
186817ab2063SBarry Smith   }
1869c783ea89SBarry Smith 
18702205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
18712205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
187217ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1873887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
187417ab2063SBarry Smith 
187517ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
187617ab2063SBarry Smith 
1877887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
187817ab2063SBarry Smith     */
187917ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
188017ab2063SBarry Smith 
188117ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
188217ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1883416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1884ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1885ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
188617ab2063SBarry Smith       sum = b[i];
1887e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1888ed480e8bSBarry Smith       x[i] = sum*idiag[i];
188917ab2063SBarry Smith     }
189017ab2063SBarry Smith 
189117ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1892416022c9SBarry Smith     v = a->a;
18932205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
189417ab2063SBarry Smith 
189517ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1896ed480e8bSBarry Smith     ts   = t;
1897416022c9SBarry Smith     diag = a->diag;
189817ab2063SBarry Smith     for (i=0; i<m; i++) {
1899416022c9SBarry Smith       n   = diag[i] - a->i[i];
1900ed480e8bSBarry Smith       idx = a->j + a->i[i];
1901ed480e8bSBarry Smith       v   = a->a + a->i[i];
190217ab2063SBarry Smith       sum = t[i];
1903003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1904ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1905733d66baSBarry Smith       /*  x = x + t */
1906733d66baSBarry Smith       x[i] += t[i];
190717ab2063SBarry Smith     }
190817ab2063SBarry Smith 
1909dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
19101ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
19113649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
19123a40ed3dSBarry Smith     PetscFunctionReturn(0);
191317ab2063SBarry Smith   }
191417ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
191517ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
191617ab2063SBarry Smith       for (i=0; i<m; i++) {
1917416022c9SBarry Smith         n   = diag[i] - a->i[i];
1918ed480e8bSBarry Smith         idx = a->j + a->i[i];
1919ed480e8bSBarry Smith         v   = a->a + a->i[i];
192017ab2063SBarry Smith         sum = b[i];
1921e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
19225c99c7daSBarry Smith         t[i] = sum;
1923ed480e8bSBarry Smith         x[i] = sum*idiag[i];
192417ab2063SBarry Smith       }
19255c99c7daSBarry Smith       xb   = t;
1926efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
19273a40ed3dSBarry Smith     } else xb = b;
192817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
192917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1930416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1931ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1932ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
193317ab2063SBarry Smith         sum = xb[i];
1934e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
19355c99c7daSBarry Smith         if (xb == b) {
1936ed480e8bSBarry Smith           x[i] = sum*idiag[i];
19375c99c7daSBarry Smith         } else {
1938b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
193917ab2063SBarry Smith         }
19405c99c7daSBarry Smith       }
1941b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
194217ab2063SBarry Smith     }
194317ab2063SBarry Smith     its--;
194417ab2063SBarry Smith   }
194517ab2063SBarry Smith   while (its--) {
194617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
194717ab2063SBarry Smith       for (i=0; i<m; i++) {
1948b19a5dc2SMark Adams         /* lower */
1949b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1950ed480e8bSBarry Smith         idx = a->j + a->i[i];
1951ed480e8bSBarry Smith         v   = a->a + a->i[i];
195217ab2063SBarry Smith         sum = b[i];
1953e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1954b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1955b19a5dc2SMark Adams         /* upper */
1956b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1957b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1958b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1959b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1960b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
196117ab2063SBarry Smith       }
1962b19a5dc2SMark Adams       xb   = t;
19639f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1964b19a5dc2SMark Adams     } else xb = b;
196517ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
196617ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1967b19a5dc2SMark Adams         sum = xb[i];
1968b19a5dc2SMark Adams         if (xb == b) {
1969b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1970416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1971ed480e8bSBarry Smith           idx = a->j + a->i[i];
1972ed480e8bSBarry Smith           v   = a->a + a->i[i];
1973e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1974ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1975b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1976b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1977b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1978b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1979b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1980b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
198117ab2063SBarry Smith         }
1982b19a5dc2SMark Adams       }
1983b19a5dc2SMark Adams       if (xb == b) {
19849f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1985b19a5dc2SMark Adams       } else {
1986b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1987b19a5dc2SMark Adams       }
198817ab2063SBarry Smith     }
198917ab2063SBarry Smith   }
19901ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
19913649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1992365a8a9eSBarry Smith   PetscFunctionReturn(0);
199317ab2063SBarry Smith }
199417ab2063SBarry Smith 
19952af78befSBarry Smith 
19964a2ae208SSatish Balay #undef __FUNCT__
19974a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1998dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
199917ab2063SBarry Smith {
2000416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
20014e220ebcSLois Curfman McInnes 
20023a40ed3dSBarry Smith   PetscFunctionBegin;
20034e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
20044e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
20054e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
20064e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
20074e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
20088e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
20097adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
2010d5f3da31SBarry Smith   if (A->factortype) {
20114e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
20124e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
20134e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
20144e220ebcSLois Curfman McInnes   } else {
20154e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
20164e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
20174e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
20184e220ebcSLois Curfman McInnes   }
20193a40ed3dSBarry Smith   PetscFunctionReturn(0);
202017ab2063SBarry Smith }
202117ab2063SBarry Smith 
20224a2ae208SSatish Balay #undef __FUNCT__
20234a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
20242b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
202517ab2063SBarry Smith {
2026416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
20273b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
20286849ba73SBarry Smith   PetscErrorCode    ierr;
202997b48c8fSBarry Smith   const PetscScalar *xx;
203097b48c8fSBarry Smith   PetscScalar       *bb;
2031ace3abfcSBarry Smith   PetscBool         missing;
203217ab2063SBarry Smith 
20333a40ed3dSBarry Smith   PetscFunctionBegin;
203497b48c8fSBarry Smith   if (x && b) {
203597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
203697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
203797b48c8fSBarry Smith     for (i=0; i<N; i++) {
203897b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
203997b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
204097b48c8fSBarry Smith     }
204197b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
204297b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
204397b48c8fSBarry Smith   }
204497b48c8fSBarry Smith 
2045a9817697SBarry Smith   if (a->keepnonzeropattern) {
2046f1e2ffcdSBarry 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]);
2048bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
2049f1e2ffcdSBarry Smith     }
2050f4df32b1SMatthew Knepley     if (diag != 0.0) {
205109f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
2052e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
2053f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
2054f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
2055f1e2ffcdSBarry Smith       }
2056f1e2ffcdSBarry Smith     }
205788e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
2058f1e2ffcdSBarry Smith   } else {
2059f4df32b1SMatthew Knepley     if (diag != 0.0) {
206017ab2063SBarry Smith       for (i=0; i<N; i++) {
2061e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
20627ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
2063416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
2064f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
2065bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
20667ae801bdSBarry Smith         } else { /* in case row was completely empty */
2067f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
206817ab2063SBarry Smith         }
206917ab2063SBarry Smith       }
20703a40ed3dSBarry Smith     } else {
207117ab2063SBarry Smith       for (i=0; i<N; i++) {
2072e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
2073416022c9SBarry Smith         a->ilen[rows[i]] = 0;
207417ab2063SBarry Smith       }
207517ab2063SBarry Smith     }
207688e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
2077f1e2ffcdSBarry Smith   }
207843a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20793a40ed3dSBarry Smith   PetscFunctionReturn(0);
208017ab2063SBarry Smith }
208117ab2063SBarry Smith 
20824a2ae208SSatish Balay #undef __FUNCT__
20836e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
20846e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20856e169961SBarry Smith {
20866e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
20876e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
20886e169961SBarry Smith   PetscErrorCode    ierr;
20892b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
20906e169961SBarry Smith   const PetscScalar *xx;
20916e169961SBarry Smith   PetscScalar       *bb;
20926e169961SBarry Smith 
20936e169961SBarry Smith   PetscFunctionBegin;
20946e169961SBarry Smith   if (x && b) {
20956e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
20966e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
20972b40b63fSBarry Smith     vecs = PETSC_TRUE;
20986e169961SBarry Smith   }
20991795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
21006e169961SBarry Smith   for (i=0; i<N; i++) {
21016e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
21026e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
21032205254eSKarl Rupp 
21046e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
21056e169961SBarry Smith   }
21066e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
21076e169961SBarry Smith     if (!zeroed[i]) {
21086e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
21096e169961SBarry Smith         if (zeroed[a->j[j]]) {
21102b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
21116e169961SBarry Smith           a->a[j] = 0.0;
21126e169961SBarry Smith         }
21136e169961SBarry Smith       }
21142b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
21156e169961SBarry Smith   }
21166e169961SBarry Smith   if (x && b) {
21176e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
21186e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
21196e169961SBarry Smith   }
21206e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
21216e169961SBarry Smith   if (diag != 0.0) {
21226e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
21236e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
21246e169961SBarry Smith     for (i=0; i<N; i++) {
21256e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
21266e169961SBarry Smith     }
21276e169961SBarry Smith   }
21286e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
21296e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21306e169961SBarry Smith   PetscFunctionReturn(0);
21316e169961SBarry Smith }
21326e169961SBarry Smith 
21336e169961SBarry Smith #undef __FUNCT__
21344a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
2135a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
213617ab2063SBarry Smith {
2137416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
213897f1f81fSBarry Smith   PetscInt   *itmp;
213917ab2063SBarry Smith 
21403a40ed3dSBarry Smith   PetscFunctionBegin;
2141e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
214217ab2063SBarry Smith 
2143416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
2144bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
214517ab2063SBarry Smith   if (idx) {
2146bfeeae90SHong Zhang     itmp = a->j + a->i[row];
214726fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
214817ab2063SBarry Smith     else *idx = 0;
214917ab2063SBarry Smith   }
21503a40ed3dSBarry Smith   PetscFunctionReturn(0);
215117ab2063SBarry Smith }
215217ab2063SBarry Smith 
2153bfeeae90SHong Zhang /* remove this function? */
21544a2ae208SSatish Balay #undef __FUNCT__
21554a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
2156a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
215717ab2063SBarry Smith {
21583a40ed3dSBarry Smith   PetscFunctionBegin;
21593a40ed3dSBarry Smith   PetscFunctionReturn(0);
216017ab2063SBarry Smith }
216117ab2063SBarry Smith 
21624a2ae208SSatish Balay #undef __FUNCT__
21634a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
2164dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
216517ab2063SBarry Smith {
2166416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
216754f21887SBarry Smith   MatScalar      *v  = a->a;
216836db0b34SBarry Smith   PetscReal      sum = 0.0;
21696849ba73SBarry Smith   PetscErrorCode ierr;
217097f1f81fSBarry Smith   PetscInt       i,j;
217117ab2063SBarry Smith 
21723a40ed3dSBarry Smith   PetscFunctionBegin;
217317ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2174416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
217536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
217617ab2063SBarry Smith     }
21778f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
21783a40ed3dSBarry Smith   } else if (type == NORM_1) {
217936db0b34SBarry Smith     PetscReal *tmp;
218097f1f81fSBarry Smith     PetscInt  *jj = a->j;
21811795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2182064f8208SBarry Smith     *nrm = 0.0;
2183416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2184bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
218517ab2063SBarry Smith     }
2186d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2187064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
218817ab2063SBarry Smith     }
2189606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
21903a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2191064f8208SBarry Smith     *nrm = 0.0;
2192d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2193bfeeae90SHong Zhang       v   = a->a + a->i[j];
219417ab2063SBarry Smith       sum = 0.0;
2195416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2196cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
219717ab2063SBarry Smith       }
2198064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
219917ab2063SBarry Smith     }
2200f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
22013a40ed3dSBarry Smith   PetscFunctionReturn(0);
220217ab2063SBarry Smith }
220317ab2063SBarry Smith 
22044e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
22054e938277SHong Zhang #undef __FUNCT__
22064e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
22074e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
22084e938277SHong Zhang {
22094e938277SHong Zhang   PetscErrorCode ierr;
22104e938277SHong Zhang   PetscInt       i,j,anzj;
22114e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
22124e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
22134e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
22144e938277SHong Zhang 
22154e938277SHong Zhang   PetscFunctionBegin;
22164e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
22171795a4d1SJed Brown   ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr);
2218785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2219785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
22204e938277SHong Zhang 
22214e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
22224e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
222326fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
22244e938277SHong Zhang   /* Form ati for csr format of A^T. */
222526fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
22264e938277SHong Zhang 
22274e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
22284e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
22294e938277SHong Zhang 
22304e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
22314e938277SHong Zhang   for (i=0;i<am;i++) {
22324e938277SHong Zhang     anzj = ai[i+1] - ai[i];
22334e938277SHong Zhang     for (j=0;j<anzj;j++) {
22344e938277SHong Zhang       atj[atfill[*aj]] = i;
22354e938277SHong Zhang       atfill[*aj++]   += 1;
22364e938277SHong Zhang     }
22374e938277SHong Zhang   }
22384e938277SHong Zhang 
22394e938277SHong Zhang   /* Clean up temporary space and complete requests. */
22404e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2241ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
22422205254eSKarl Rupp 
2243a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2244a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2245a2f3521dSMark F. Adams 
22464e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
22474e938277SHong Zhang   b->free_a  = PETSC_FALSE;
22484e938277SHong Zhang   b->free_ij = PETSC_TRUE;
22494e938277SHong Zhang   b->nonew   = 0;
22504e938277SHong Zhang   PetscFunctionReturn(0);
22514e938277SHong Zhang }
22524e938277SHong Zhang 
22534a2ae208SSatish Balay #undef __FUNCT__
22544a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2255fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
225617ab2063SBarry Smith {
2257416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2258416022c9SBarry Smith   Mat            C;
22596849ba73SBarry Smith   PetscErrorCode ierr;
2260d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
226154f21887SBarry Smith   MatScalar      *array = a->a;
226217ab2063SBarry Smith 
22633a40ed3dSBarry Smith   PetscFunctionBegin;
2264e32f2f54SBarry 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");
2265fc4dec0aSBarry Smith 
2266fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
22671795a4d1SJed Brown     ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr);
2268bfeeae90SHong Zhang 
2269bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2270ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2271d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2272a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
22737adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2274ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2275606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2276a541d17aSBarry Smith   } else {
2277a541d17aSBarry Smith     C = *B;
2278a541d17aSBarry Smith   }
2279a541d17aSBarry Smith 
228017ab2063SBarry Smith   for (i=0; i<m; i++) {
228117ab2063SBarry Smith     len    = ai[i+1]-ai[i];
228287d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2283b9b97703SBarry Smith     array += len;
2284b9b97703SBarry Smith     aj    += len;
228517ab2063SBarry Smith   }
22866d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22876d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228817ab2063SBarry Smith 
2289815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2290416022c9SBarry Smith     *B = C;
229117ab2063SBarry Smith   } else {
2292eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
229317ab2063SBarry Smith   }
22943a40ed3dSBarry Smith   PetscFunctionReturn(0);
229517ab2063SBarry Smith }
229617ab2063SBarry Smith 
2297cd0d46ebSvictorle #undef __FUNCT__
22985fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
22997087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2300cd0d46ebSvictorle {
2301cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
230254f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
230354f21887SBarry Smith   MatScalar      *va,*vb;
23046849ba73SBarry Smith   PetscErrorCode ierr;
230597f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2306cd0d46ebSvictorle 
2307cd0d46ebSvictorle   PetscFunctionBegin;
2308cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2309cd0d46ebSvictorle 
2310cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2311cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
23125485867bSBarry Smith   if (ma!=nb || na!=mb) {
23135485867bSBarry Smith     *f = PETSC_FALSE;
23145485867bSBarry Smith     PetscFunctionReturn(0);
23155485867bSBarry Smith   }
2316cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2317cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2318cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
2319785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2320785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2321cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2322cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2323cd0d46ebSvictorle 
2324cd0d46ebSvictorle   *f = PETSC_TRUE;
2325cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2326cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
232797f1f81fSBarry Smith       PetscInt    idc,idr;
23285485867bSBarry Smith       PetscScalar vc,vr;
2329cd0d46ebSvictorle       /* column/row index/value */
23305485867bSBarry Smith       idc = adx[aptr[i]];
23315485867bSBarry Smith       idr = bdx[bptr[idc]];
23325485867bSBarry Smith       vc  = va[aptr[i]];
23335485867bSBarry Smith       vr  = vb[bptr[idc]];
23345485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
23355485867bSBarry Smith         *f = PETSC_FALSE;
23365485867bSBarry Smith         goto done;
2337cd0d46ebSvictorle       } else {
23385485867bSBarry Smith         aptr[i]++;
23395485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2340cd0d46ebSvictorle       }
2341cd0d46ebSvictorle     }
2342cd0d46ebSvictorle   }
2343cd0d46ebSvictorle done:
2344cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
23453aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2346cd0d46ebSvictorle   PetscFunctionReturn(0);
2347cd0d46ebSvictorle }
2348cd0d46ebSvictorle 
23491cbb95d3SBarry Smith #undef __FUNCT__
23501cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
23517087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
23521cbb95d3SBarry Smith {
23531cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
235454f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
235554f21887SBarry Smith   MatScalar      *va,*vb;
23561cbb95d3SBarry Smith   PetscErrorCode ierr;
23571cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
23581cbb95d3SBarry Smith 
23591cbb95d3SBarry Smith   PetscFunctionBegin;
23601cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
23611cbb95d3SBarry Smith 
23621cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
23631cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
23641cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
23651cbb95d3SBarry Smith     *f = PETSC_FALSE;
23661cbb95d3SBarry Smith     PetscFunctionReturn(0);
23671cbb95d3SBarry Smith   }
23681cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
23691cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
23701cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2371785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2372785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
23731cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
23741cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
23751cbb95d3SBarry Smith 
23761cbb95d3SBarry Smith   *f = PETSC_TRUE;
23771cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
23781cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
23791cbb95d3SBarry Smith       PetscInt    idc,idr;
23801cbb95d3SBarry Smith       PetscScalar vc,vr;
23811cbb95d3SBarry Smith       /* column/row index/value */
23821cbb95d3SBarry Smith       idc = adx[aptr[i]];
23831cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
23841cbb95d3SBarry Smith       vc  = va[aptr[i]];
23851cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
23861cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
23871cbb95d3SBarry Smith         *f = PETSC_FALSE;
23881cbb95d3SBarry Smith         goto done;
23891cbb95d3SBarry Smith       } else {
23901cbb95d3SBarry Smith         aptr[i]++;
23911cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
23921cbb95d3SBarry Smith       }
23931cbb95d3SBarry Smith     }
23941cbb95d3SBarry Smith   }
23951cbb95d3SBarry Smith done:
23961cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
23971cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
23981cbb95d3SBarry Smith   PetscFunctionReturn(0);
23991cbb95d3SBarry Smith }
24001cbb95d3SBarry Smith 
24019e29f15eSvictorle #undef __FUNCT__
24029e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2403ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
24049e29f15eSvictorle {
2405dfbe8321SBarry Smith   PetscErrorCode ierr;
24066e111a19SKarl Rupp 
24079e29f15eSvictorle   PetscFunctionBegin;
24085485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
24099e29f15eSvictorle   PetscFunctionReturn(0);
24109e29f15eSvictorle }
24119e29f15eSvictorle 
24124a2ae208SSatish Balay #undef __FUNCT__
24131cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2414ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
24151cbb95d3SBarry Smith {
24161cbb95d3SBarry Smith   PetscErrorCode ierr;
24176e111a19SKarl Rupp 
24181cbb95d3SBarry Smith   PetscFunctionBegin;
24191cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
24201cbb95d3SBarry Smith   PetscFunctionReturn(0);
24211cbb95d3SBarry Smith }
24221cbb95d3SBarry Smith 
24231cbb95d3SBarry Smith #undef __FUNCT__
24244a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2425dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
242617ab2063SBarry Smith {
2427416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
242854f21887SBarry Smith   PetscScalar    *l,*r,x;
242954f21887SBarry Smith   MatScalar      *v;
2430dfbe8321SBarry Smith   PetscErrorCode ierr;
2431d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
243217ab2063SBarry Smith 
24333a40ed3dSBarry Smith   PetscFunctionBegin;
243417ab2063SBarry Smith   if (ll) {
24353ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
24363ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2437e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2438e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
24391ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2440416022c9SBarry Smith     v    = a->a;
244117ab2063SBarry Smith     for (i=0; i<m; i++) {
244217ab2063SBarry Smith       x = l[i];
2443416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
24442205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
244517ab2063SBarry Smith     }
24461ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2447efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
244817ab2063SBarry Smith   }
244917ab2063SBarry Smith   if (rr) {
2450e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2451e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
24521ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2453416022c9SBarry Smith     v    = a->a; jj = a->j;
24542205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
24551ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2456efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
245717ab2063SBarry Smith   }
2458acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
24593a40ed3dSBarry Smith   PetscFunctionReturn(0);
246017ab2063SBarry Smith }
246117ab2063SBarry Smith 
24624a2ae208SSatish Balay #undef __FUNCT__
24634a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
246497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
246517ab2063SBarry Smith {
2466db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
24676849ba73SBarry Smith   PetscErrorCode ierr;
2468d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
246997f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
24705d0c19d7SBarry Smith   const PetscInt *irow,*icol;
24715d0c19d7SBarry Smith   PetscInt       nrows,ncols;
247297f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
247354f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2474416022c9SBarry Smith   Mat            C;
2475ace3abfcSBarry Smith   PetscBool      stride,sorted;
247617ab2063SBarry Smith 
24773a40ed3dSBarry Smith   PetscFunctionBegin;
247814ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2479e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
248014ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2481e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
248299141d43SSatish Balay 
248317ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2484b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2485b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
248617ab2063SBarry Smith 
2487fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2488251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2489fee21e36SBarry Smith   if (stride && step == 1) {
249002834360SBarry Smith     /* special case of contiguous rows */
2491dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
249202834360SBarry Smith     /* loop over new rows determining lens and starting points */
249302834360SBarry Smith     for (i=0; i<nrows; i++) {
2494bfeeae90SHong Zhang       kstart = ai[irow[i]];
2495a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
249602834360SBarry Smith       for (k=kstart; k<kend; k++) {
2497bfeeae90SHong Zhang         if (aj[k] >= first) {
249802834360SBarry Smith           starts[i] = k;
249902834360SBarry Smith           break;
250002834360SBarry Smith         }
250102834360SBarry Smith       }
2502a2744918SBarry Smith       sum = 0;
250302834360SBarry Smith       while (k < kend) {
2504bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2505a2744918SBarry Smith         sum++;
250602834360SBarry Smith       }
2507a2744918SBarry Smith       lens[i] = sum;
250802834360SBarry Smith     }
250902834360SBarry Smith     /* create submatrix */
2510cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
251197f1f81fSBarry Smith       PetscInt n_cols,n_rows;
251208480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2513e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2514d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
251508480c60SBarry Smith       C    = *B;
25163a40ed3dSBarry Smith     } else {
25173bef6203SJed Brown       PetscInt rbs,cbs;
2518ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2519f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
25203bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
25213bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
25223bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
25237adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2524ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
252508480c60SBarry Smith     }
2526db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2527db02288aSLois Curfman McInnes 
252802834360SBarry Smith     /* loop over rows inserting into submatrix */
2529db02288aSLois Curfman McInnes     a_new = c->a;
2530db02288aSLois Curfman McInnes     j_new = c->j;
2531db02288aSLois Curfman McInnes     i_new = c->i;
2532bfeeae90SHong Zhang 
253302834360SBarry Smith     for (i=0; i<nrows; i++) {
2534a2744918SBarry Smith       ii    = starts[i];
2535a2744918SBarry Smith       lensi = lens[i];
2536a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2537a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
253802834360SBarry Smith       }
253987828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2540a2744918SBarry Smith       a_new     += lensi;
2541a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2542a2744918SBarry Smith       c->ilen[i] = lensi;
254302834360SBarry Smith     }
25440e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
25453a40ed3dSBarry Smith   } else {
254602834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
25471795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2548785e854fSJed Brown     ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr);
25494dcab191SBarry Smith     for (i=0; i<ncols; i++) {
25504dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
25514dcab191SBarry 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);
25524dcab191SBarry Smith #endif
25534dcab191SBarry Smith       smap[icol[i]] = i+1;
25544dcab191SBarry Smith     }
25554dcab191SBarry Smith 
255602834360SBarry Smith     /* determine lens of each row */
255702834360SBarry Smith     for (i=0; i<nrows; i++) {
2558bfeeae90SHong Zhang       kstart  = ai[irow[i]];
255902834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
256002834360SBarry Smith       lens[i] = 0;
256102834360SBarry Smith       for (k=kstart; k<kend; k++) {
2562bfeeae90SHong Zhang         if (smap[aj[k]]) {
256302834360SBarry Smith           lens[i]++;
256402834360SBarry Smith         }
256502834360SBarry Smith       }
256602834360SBarry Smith     }
256717ab2063SBarry Smith     /* Create and fill new matrix */
2568a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2569ace3abfcSBarry Smith       PetscBool equal;
25700f5bd95cSBarry Smith 
257199141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2572e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2573d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2574f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2575d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
257608480c60SBarry Smith       C    = *B;
25773a40ed3dSBarry Smith     } else {
25783bef6203SJed Brown       PetscInt rbs,cbs;
2579ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2580f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
25813bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
25823bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
25833bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
25847adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2585ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
258608480c60SBarry Smith     }
258799141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
258817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
258999141d43SSatish Balay       row      = irow[i];
2590bfeeae90SHong Zhang       kstart   = ai[row];
259199141d43SSatish Balay       kend     = kstart + a->ilen[row];
2592bfeeae90SHong Zhang       mat_i    = c->i[i];
259399141d43SSatish Balay       mat_j    = c->j + mat_i;
259499141d43SSatish Balay       mat_a    = c->a + mat_i;
259599141d43SSatish Balay       mat_ilen = c->ilen + i;
259617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2597bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2598ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
259999141d43SSatish Balay           *mat_a++ = a->a[k];
260099141d43SSatish Balay           (*mat_ilen)++;
260199141d43SSatish Balay 
260217ab2063SBarry Smith         }
260317ab2063SBarry Smith       }
260417ab2063SBarry Smith     }
260502834360SBarry Smith     /* Free work space */
260602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2607606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2608606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
260902834360SBarry Smith   }
26106d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26116d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
261217ab2063SBarry Smith 
261317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2614416022c9SBarry Smith   *B   = C;
26153a40ed3dSBarry Smith   PetscFunctionReturn(0);
261617ab2063SBarry Smith }
261717ab2063SBarry Smith 
26181df811f5SHong Zhang #undef __FUNCT__
261982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2620fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
262182d44351SHong Zhang {
262282d44351SHong Zhang   PetscErrorCode ierr;
262382d44351SHong Zhang   Mat            B;
262482d44351SHong Zhang 
262582d44351SHong Zhang   PetscFunctionBegin;
2626c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
262782d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
262882d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2629a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
263082d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
263182d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
263282d44351SHong Zhang     *subMat = B;
2633c2d650bdSHong Zhang   } else {
2634c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2635c2d650bdSHong Zhang   }
263682d44351SHong Zhang   PetscFunctionReturn(0);
263782d44351SHong Zhang }
263882d44351SHong Zhang 
263982d44351SHong Zhang #undef __FUNCT__
26404a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
26410481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2642a871dcd8SBarry Smith {
264363b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2644dfbe8321SBarry Smith   PetscErrorCode ierr;
264563b91edcSBarry Smith   Mat            outA;
2646ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
264763b91edcSBarry Smith 
26483a40ed3dSBarry Smith   PetscFunctionBegin;
2649e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
26501df811f5SHong Zhang 
2651b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2652b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2653a871dcd8SBarry Smith 
265463b91edcSBarry Smith   outA             = inA;
2655d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
26562205254eSKarl Rupp 
2657c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
26586bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
26592205254eSKarl Rupp 
2660c3122656SLisandro Dalcin   a->row = row;
26612205254eSKarl Rupp 
2662c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
26636bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
26642205254eSKarl Rupp 
2665c3122656SLisandro Dalcin   a->col = col;
266663b91edcSBarry Smith 
266736db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
26686bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
26694c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
26703bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2671f0ec6fceSSatish Balay 
267294a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2673785e854fSJed Brown     ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr);
26743bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
267594a9d846SBarry Smith   }
267663b91edcSBarry Smith 
2677f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2678137fb511SHong Zhang   if (row_identity && col_identity) {
2679ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2680137fb511SHong Zhang   } else {
2681719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2682137fb511SHong Zhang   }
26833a40ed3dSBarry Smith   PetscFunctionReturn(0);
2684a871dcd8SBarry Smith }
2685a871dcd8SBarry Smith 
26864a2ae208SSatish Balay #undef __FUNCT__
26874a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2688f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2689f0b747eeSBarry Smith {
2690f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2691f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2692efee365bSSatish Balay   PetscErrorCode ierr;
2693c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
26943a40ed3dSBarry Smith 
26953a40ed3dSBarry Smith   PetscFunctionBegin;
2696c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
26978b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2698efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2699acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
27003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2701f0b747eeSBarry Smith }
2702f0b747eeSBarry Smith 
27034a2ae208SSatish Balay #undef __FUNCT__
27044a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
270597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2706cddf8d76SBarry Smith {
2707dfbe8321SBarry Smith   PetscErrorCode ierr;
270897f1f81fSBarry Smith   PetscInt       i;
2709cddf8d76SBarry Smith 
27103a40ed3dSBarry Smith   PetscFunctionBegin;
2711cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2712785e854fSJed Brown     ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr);
2713cddf8d76SBarry Smith   }
2714cddf8d76SBarry Smith 
2715cddf8d76SBarry Smith   for (i=0; i<n; i++) {
27166a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2717cddf8d76SBarry Smith   }
27183a40ed3dSBarry Smith   PetscFunctionReturn(0);
2719cddf8d76SBarry Smith }
2720cddf8d76SBarry Smith 
27214a2ae208SSatish Balay #undef __FUNCT__
27224a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
272397f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
27244dcbc457SBarry Smith {
2725e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
27266849ba73SBarry Smith   PetscErrorCode ierr;
27275d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
27285d0c19d7SBarry Smith   const PetscInt *idx;
272997f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2730f1af5d2fSBarry Smith   PetscBT        table;
2731bbd702dbSSatish Balay 
27323a40ed3dSBarry Smith   PetscFunctionBegin;
2733d0f46423SBarry Smith   m  = A->rmap->n;
2734e4d965acSSatish Balay   ai = a->i;
2735bfeeae90SHong Zhang   aj = a->j;
27368a047759SSatish Balay 
2737e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
273806763907SSatish Balay 
2739785e854fSJed Brown   ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr);
274053b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
274106763907SSatish Balay 
2742e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2743b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2744e4d965acSSatish Balay     isz  = 0;
27456831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2746e4d965acSSatish Balay 
2747e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
27484dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2749b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2750e4d965acSSatish Balay 
2751dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2752e4d965acSSatish Balay     for (j=0; j<n; ++j) {
27532205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
27544dcbc457SBarry Smith     }
275506763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
27566bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2757e4d965acSSatish Balay 
275804a348a9SBarry Smith     k = 0;
275904a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
276004a348a9SBarry Smith       n = isz;
276106763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2762e4d965acSSatish Balay         row   = nidx[k];
2763e4d965acSSatish Balay         start = ai[row];
2764e4d965acSSatish Balay         end   = ai[row+1];
276504a348a9SBarry Smith         for (l = start; l<end; l++) {
2766efb16452SHong Zhang           val = aj[l];
27672205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2768e4d965acSSatish Balay         }
2769e4d965acSSatish Balay       }
2770e4d965acSSatish Balay     }
277170b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2772e4d965acSSatish Balay   }
277394bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2774606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
27753a40ed3dSBarry Smith   PetscFunctionReturn(0);
27764dcbc457SBarry Smith }
277717ab2063SBarry Smith 
27780513a670SBarry Smith /* -------------------------------------------------------------- */
27794a2ae208SSatish Balay #undef __FUNCT__
27804a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2781dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
27820513a670SBarry Smith {
27830513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
27846849ba73SBarry Smith   PetscErrorCode ierr;
27853b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
27865d0c19d7SBarry Smith   const PetscInt *row,*col;
27875d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
278856cd22aeSBarry Smith   IS             icolp,irowp;
27890298fd71SBarry Smith   PetscInt       *cwork = NULL;
27900298fd71SBarry Smith   PetscScalar    *vwork = NULL;
27910513a670SBarry Smith 
27923a40ed3dSBarry Smith   PetscFunctionBegin;
27934c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
279456cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
27954c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
279656cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
27970513a670SBarry Smith 
27980513a670SBarry Smith   /* determine lengths of permuted rows */
2799785e854fSJed Brown   ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr);
28002205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2801ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2802f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2803a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
28047adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2805ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2806606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
28070513a670SBarry Smith 
2808785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
28090513a670SBarry Smith   for (i=0; i<m; i++) {
281032ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
28112205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2812cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
281332ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
28140513a670SBarry Smith   }
2815606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
28162205254eSKarl Rupp 
28173c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
28182205254eSKarl Rupp 
28190513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28200513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
282156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
282256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
28236bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
28246bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
28253a40ed3dSBarry Smith   PetscFunctionReturn(0);
28260513a670SBarry Smith }
28270513a670SBarry Smith 
28284a2ae208SSatish Balay #undef __FUNCT__
28294a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2830dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2831cb5b572fSBarry Smith {
2832dfbe8321SBarry Smith   PetscErrorCode ierr;
2833cb5b572fSBarry Smith 
2834cb5b572fSBarry Smith   PetscFunctionBegin;
283533f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
283633f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2837be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2838be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2839be6bf707SBarry Smith 
2840700c5bfcSBarry 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");
2841d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2842cb5b572fSBarry Smith   } else {
2843cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2844cb5b572fSBarry Smith   }
2845cb5b572fSBarry Smith   PetscFunctionReturn(0);
2846cb5b572fSBarry Smith }
2847cb5b572fSBarry Smith 
28484a2ae208SSatish Balay #undef __FUNCT__
28494994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
28504994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2851273d9f13SBarry Smith {
2852dfbe8321SBarry Smith   PetscErrorCode ierr;
2853273d9f13SBarry Smith 
2854273d9f13SBarry Smith   PetscFunctionBegin;
2855ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2856273d9f13SBarry Smith   PetscFunctionReturn(0);
2857273d9f13SBarry Smith }
2858273d9f13SBarry Smith 
28594a2ae208SSatish Balay #undef __FUNCT__
28608c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
28618c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
28626c0721eeSBarry Smith {
28636c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
28646e111a19SKarl Rupp 
28656c0721eeSBarry Smith   PetscFunctionBegin;
28666c0721eeSBarry Smith   *array = a->a;
28676c0721eeSBarry Smith   PetscFunctionReturn(0);
28686c0721eeSBarry Smith }
28696c0721eeSBarry Smith 
28704a2ae208SSatish Balay #undef __FUNCT__
28718c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
28728c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
28736c0721eeSBarry Smith {
28746c0721eeSBarry Smith   PetscFunctionBegin;
28756c0721eeSBarry Smith   PetscFunctionReturn(0);
28766c0721eeSBarry Smith }
2877273d9f13SBarry Smith 
28788229c054SShri Abhyankar /*
28798229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
28808229c054SShri Abhyankar    have different nonzero structure.
28818229c054SShri Abhyankar */
2882ac90fabeSBarry Smith #undef __FUNCT__
28838229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
28848229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
2885ec7775f6SShri Abhyankar {
28868229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
2887ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
2888ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
2889ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
2890ec7775f6SShri Abhyankar 
2891ec7775f6SShri Abhyankar   PetscFunctionBegin;
2892ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
2893ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
28948af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
28958af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
28968af7cee1SJed Brown     nnz[i] = 0;
28978af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
28988af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
28998af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
29008af7cee1SJed Brown       nnz[i]++;
29018af7cee1SJed Brown     }
29028af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
2903ec7775f6SShri Abhyankar   }
2904ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
2905ec7775f6SShri Abhyankar }
2906ec7775f6SShri Abhyankar 
2907ec7775f6SShri Abhyankar #undef __FUNCT__
2908ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2909f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
2910ac90fabeSBarry Smith {
2911dfbe8321SBarry Smith   PetscErrorCode ierr;
291297f1f81fSBarry Smith   PetscInt       i;
2913ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
2914c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
2915ac90fabeSBarry Smith 
2916ac90fabeSBarry Smith   PetscFunctionBegin;
2917c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
2918ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2919f4df32b1SMatthew Knepley     PetscScalar alpha = a;
29208b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
2921acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
2922c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
2923a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
2924a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
29256bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
2926a30b2313SHong Zhang     }
2927a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
29280298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
2929a30b2313SHong Zhang       y->XtoY = X;
2930407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
2931c537a176SHong Zhang     }
2932f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
2933ba0e910bSBarry 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);
2934ac90fabeSBarry Smith   } else {
29358229c054SShri Abhyankar     Mat      B;
29368229c054SShri Abhyankar     PetscInt *nnz;
2937785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
2938ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
2939bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
29404aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
2941a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
2942176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
29438229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
2944ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
2945ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
2946ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
29478229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
2948ac90fabeSBarry Smith   }
2949ac90fabeSBarry Smith   PetscFunctionReturn(0);
2950ac90fabeSBarry Smith }
2951ac90fabeSBarry Smith 
2952521d7252SBarry Smith #undef __FUNCT__
2953354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
29547087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
2955354c94deSBarry Smith {
2956354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
2957354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
2958354c94deSBarry Smith   PetscInt    i,nz;
2959354c94deSBarry Smith   PetscScalar *a;
2960354c94deSBarry Smith 
2961354c94deSBarry Smith   PetscFunctionBegin;
2962354c94deSBarry Smith   nz = aij->nz;
2963354c94deSBarry Smith   a  = aij->a;
29642205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
2965354c94deSBarry Smith #else
2966354c94deSBarry Smith   PetscFunctionBegin;
2967354c94deSBarry Smith #endif
2968354c94deSBarry Smith   PetscFunctionReturn(0);
2969354c94deSBarry Smith }
2970354c94deSBarry Smith 
2971e34fafa9SBarry Smith #undef __FUNCT__
2972985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
2973985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
2974e34fafa9SBarry Smith {
2975e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2976e34fafa9SBarry Smith   PetscErrorCode ierr;
2977d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
2978e34fafa9SBarry Smith   PetscReal      atmp;
2979985db425SBarry Smith   PetscScalar    *x;
2980e34fafa9SBarry Smith   MatScalar      *aa;
2981e34fafa9SBarry Smith 
2982e34fafa9SBarry Smith   PetscFunctionBegin;
2983e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2984e34fafa9SBarry Smith   aa = a->a;
2985e34fafa9SBarry Smith   ai = a->i;
2986e34fafa9SBarry Smith   aj = a->j;
2987e34fafa9SBarry Smith 
2988985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2989e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2990e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
2991e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2992e34fafa9SBarry Smith   for (i=0; i<m; i++) {
2993e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
29949189402eSHong Zhang     x[i]  = 0.0;
2995e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
2996985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
2997985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
2998985db425SBarry Smith       aa++; aj++;
2999985db425SBarry Smith     }
3000985db425SBarry Smith   }
3001985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3002985db425SBarry Smith   PetscFunctionReturn(0);
3003985db425SBarry Smith }
3004985db425SBarry Smith 
3005985db425SBarry Smith #undef __FUNCT__
3006985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
3007985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3008985db425SBarry Smith {
3009985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3010985db425SBarry Smith   PetscErrorCode ierr;
3011d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3012985db425SBarry Smith   PetscScalar    *x;
3013985db425SBarry Smith   MatScalar      *aa;
3014985db425SBarry Smith 
3015985db425SBarry Smith   PetscFunctionBegin;
3016e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3017985db425SBarry Smith   aa = a->a;
3018985db425SBarry Smith   ai = a->i;
3019985db425SBarry Smith   aj = a->j;
3020985db425SBarry Smith 
3021985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3022985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3023985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3024e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3025985db425SBarry Smith   for (i=0; i<m; i++) {
3026985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3027d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3028985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3029985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
3030985db425SBarry Smith       x[i] = 0.0;
3031985db425SBarry Smith       if (idx) {
3032985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3033985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
3034985db425SBarry Smith           if (aj[j] > j) {
3035985db425SBarry Smith             idx[i] = j;
3036985db425SBarry Smith             break;
3037985db425SBarry Smith           }
3038985db425SBarry Smith         }
3039985db425SBarry Smith       }
3040985db425SBarry Smith     }
3041985db425SBarry Smith     for (j=0; j<ncols; j++) {
3042985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3043985db425SBarry Smith       aa++; aj++;
3044985db425SBarry Smith     }
3045985db425SBarry Smith   }
3046985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3047985db425SBarry Smith   PetscFunctionReturn(0);
3048985db425SBarry Smith }
3049985db425SBarry Smith 
3050985db425SBarry Smith #undef __FUNCT__
3051c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
3052c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3053c87e5d42SMatthew Knepley {
3054c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3055c87e5d42SMatthew Knepley   PetscErrorCode ierr;
3056c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3057c87e5d42SMatthew Knepley   PetscReal      atmp;
3058c87e5d42SMatthew Knepley   PetscScalar    *x;
3059c87e5d42SMatthew Knepley   MatScalar      *aa;
3060c87e5d42SMatthew Knepley 
3061c87e5d42SMatthew Knepley   PetscFunctionBegin;
3062e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3063c87e5d42SMatthew Knepley   aa = a->a;
3064c87e5d42SMatthew Knepley   ai = a->i;
3065c87e5d42SMatthew Knepley   aj = a->j;
3066c87e5d42SMatthew Knepley 
3067c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3068c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3069c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
30703bb78c5cSMatthew 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);
3071c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
3072c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
3073289a08f5SMatthew Knepley     if (ncols) {
3074289a08f5SMatthew Knepley       /* Get first nonzero */
3075289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
3076289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
30772205254eSKarl Rupp         if (atmp > 1.0e-12) {
30782205254eSKarl Rupp           x[i] = atmp;
30792205254eSKarl Rupp           if (idx) idx[i] = aj[j];
30802205254eSKarl Rupp           break;
30812205254eSKarl Rupp         }
3082289a08f5SMatthew Knepley       }
308312431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
3084289a08f5SMatthew Knepley     } else {
3085289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
3086289a08f5SMatthew Knepley     }
3087c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
3088c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
3089289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3090c87e5d42SMatthew Knepley       aa++; aj++;
3091c87e5d42SMatthew Knepley     }
3092c87e5d42SMatthew Knepley   }
3093c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3094c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
3095c87e5d42SMatthew Knepley }
3096c87e5d42SMatthew Knepley 
3097c87e5d42SMatthew Knepley #undef __FUNCT__
3098985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
3099985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3100985db425SBarry Smith {
3101985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3102985db425SBarry Smith   PetscErrorCode ierr;
3103d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3104985db425SBarry Smith   PetscScalar    *x;
3105985db425SBarry Smith   MatScalar      *aa;
3106985db425SBarry Smith 
3107985db425SBarry Smith   PetscFunctionBegin;
3108e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3109985db425SBarry Smith   aa = a->a;
3110985db425SBarry Smith   ai = a->i;
3111985db425SBarry Smith   aj = a->j;
3112985db425SBarry Smith 
3113985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3114985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3115985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3116e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3117985db425SBarry Smith   for (i=0; i<m; i++) {
3118985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3119d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3120985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3121985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
3122985db425SBarry Smith       x[i] = 0.0;
3123985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
3124985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3125985db425SBarry Smith         for (j=0; j<ncols; j++) {
3126985db425SBarry Smith           if (aj[j] > j) {
3127985db425SBarry Smith             idx[i] = j;
3128985db425SBarry Smith             break;
3129985db425SBarry Smith           }
3130985db425SBarry Smith         }
3131985db425SBarry Smith       }
3132985db425SBarry Smith     }
3133985db425SBarry Smith     for (j=0; j<ncols; j++) {
3134985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3135985db425SBarry Smith       aa++; aj++;
3136e34fafa9SBarry Smith     }
3137e34fafa9SBarry Smith   }
3138e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3139e34fafa9SBarry Smith   PetscFunctionReturn(0);
3140e34fafa9SBarry Smith }
3141bbead8a2SBarry Smith 
3142bbead8a2SBarry Smith #include <petscblaslapack.h>
314306873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
3144bbead8a2SBarry Smith 
3145bbead8a2SBarry Smith #undef __FUNCT__
3146bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
3147713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3148bbead8a2SBarry Smith {
3149bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
3150bbead8a2SBarry Smith   PetscErrorCode ierr;
315134fc4b71SJed 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;
3152bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
3153bbead8a2SBarry Smith   PetscReal      shift = 0.0;
3154bbead8a2SBarry Smith 
3155bbead8a2SBarry Smith   PetscFunctionBegin;
31564a0d0026SBarry Smith   if (a->ibdiagvalid) {
31574a0d0026SBarry Smith     if (values) *values = a->ibdiag;
31584a0d0026SBarry Smith     PetscFunctionReturn(0);
31594a0d0026SBarry Smith   }
3160bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3161bbead8a2SBarry Smith   if (!a->ibdiag) {
3162785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
31633bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3164bbead8a2SBarry Smith   }
3165bbead8a2SBarry Smith   diag = a->ibdiag;
3166bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3167bbead8a2SBarry Smith   /* factor and invert each block */
3168bbead8a2SBarry Smith   switch (bs) {
3169bbead8a2SBarry Smith   case 1:
3170bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3171bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3172bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3173bbead8a2SBarry Smith     }
3174bbead8a2SBarry Smith     break;
3175bbead8a2SBarry Smith   case 2:
3176bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3177bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3178bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
317996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
318096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3181bbead8a2SBarry Smith       diag += 4;
3182bbead8a2SBarry Smith     }
3183bbead8a2SBarry Smith     break;
3184bbead8a2SBarry Smith   case 3:
3185bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3186bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3187bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
318896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
318996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3190bbead8a2SBarry Smith       diag += 9;
3191bbead8a2SBarry Smith     }
3192bbead8a2SBarry Smith     break;
3193bbead8a2SBarry Smith   case 4:
3194bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3195bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3196bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
319796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
319896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3199bbead8a2SBarry Smith       diag += 16;
3200bbead8a2SBarry Smith     }
3201bbead8a2SBarry Smith     break;
3202bbead8a2SBarry Smith   case 5:
3203bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3204bbead8a2SBarry 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;
3205bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
320696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
320796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3208bbead8a2SBarry Smith       diag += 25;
3209bbead8a2SBarry Smith     }
3210bbead8a2SBarry Smith     break;
3211bbead8a2SBarry Smith   case 6:
3212bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3213bbead8a2SBarry 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;
3214bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
321596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
321696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3217bbead8a2SBarry Smith       diag += 36;
3218bbead8a2SBarry Smith     }
3219bbead8a2SBarry Smith     break;
3220bbead8a2SBarry Smith   case 7:
3221bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3222bbead8a2SBarry 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;
3223bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
322496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
322596b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3226bbead8a2SBarry Smith       diag += 49;
3227bbead8a2SBarry Smith     }
3228bbead8a2SBarry Smith     break;
3229bbead8a2SBarry Smith   default:
3230dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3231bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3232bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3233bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3234bbead8a2SBarry Smith       }
3235bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
323696b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
323796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3238bbead8a2SBarry Smith       diag += bs2;
3239bbead8a2SBarry Smith     }
3240bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3241bbead8a2SBarry Smith   }
3242bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3243bbead8a2SBarry Smith   PetscFunctionReturn(0);
3244bbead8a2SBarry Smith }
3245bbead8a2SBarry Smith 
324673a71a0fSBarry Smith #undef __FUNCT__
324773a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
324873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
324973a71a0fSBarry Smith {
325073a71a0fSBarry Smith   PetscErrorCode ierr;
325173a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
325273a71a0fSBarry Smith   PetscScalar    a;
325373a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
325473a71a0fSBarry Smith 
325573a71a0fSBarry Smith   PetscFunctionBegin;
325673a71a0fSBarry Smith   if (!x->assembled) {
325773a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
325873a71a0fSBarry Smith     for (i=0; i<m; i++) {
325973a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
326073a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
326173a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
326273a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
326373a71a0fSBarry Smith       }
326473a71a0fSBarry Smith     }
326573a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
326673a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
326773a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
326873a71a0fSBarry Smith   PetscFunctionReturn(0);
326973a71a0fSBarry Smith }
327073a71a0fSBarry Smith 
3271682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
32720a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3273cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3274cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3275cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
327697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
32777c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
32787c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3279db4efbfdSBarry Smith                                         0,
3280db4efbfdSBarry Smith                                         0,
3281db4efbfdSBarry Smith                                         0,
3282db4efbfdSBarry Smith                                 /* 10*/ 0,
3283cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3284cb5b572fSBarry Smith                                         0,
328541f059aeSBarry Smith                                         MatSOR_SeqAIJ,
328617ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
328797304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3288cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3289cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3290cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3291cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
329297304618SKris Buschelman                                 /* 20*/ 0,
3293cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3294cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3295cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3296d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3297db4efbfdSBarry Smith                                         0,
3298db4efbfdSBarry Smith                                         0,
3299db4efbfdSBarry Smith                                         0,
3300db4efbfdSBarry Smith                                         0,
33014994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3302db4efbfdSBarry Smith                                         0,
3303db4efbfdSBarry Smith                                         0,
33048c778c55SBarry Smith                                         0,
33058c778c55SBarry Smith                                         0,
3306d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3307cb5b572fSBarry Smith                                         0,
3308cb5b572fSBarry Smith                                         0,
3309cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3310cb5b572fSBarry Smith                                         0,
3311d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3312cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3313cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3314cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3315cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3316d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3317cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3318cb5b572fSBarry Smith                                         0,
331979299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
33206e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
332173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
33223b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
33233b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
33243b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3325a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
332693dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3327b9617806SBarry Smith                                         0,
33280513a670SBarry Smith                                         0,
3329cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3330cda55fadSBarry Smith                                         0,
3331d519adbfSMatthew Knepley                                 /* 59*/ 0,
3332b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3333b9b97703SBarry Smith                                         MatView_SeqAIJ,
3334357abbc8SBarry Smith                                         0,
3335321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3336321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3337321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3338ee4f033dSBarry Smith                                         0,
3339ee4f033dSBarry Smith                                         0,
3340ee4f033dSBarry Smith                                         0,
3341d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3342c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3343ee4f033dSBarry Smith                                         0,
3344ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3345dcf5cc72SBarry Smith                                         0,
3346d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
33473acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
334897304618SKris Buschelman                                         0,
334997304618SKris Buschelman                                         0,
335097304618SKris Buschelman                                         0,
33516ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
335297304618SKris Buschelman                                         0,
335397304618SKris Buschelman                                         0,
335497304618SKris Buschelman                                         0,
3355bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3356d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
33571cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
33586284ec50SHong Zhang                                         0,
33596284ec50SHong Zhang                                         0,
3360bc011b1eSHong Zhang                                         0,
3361d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
336226be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
336326be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
336465e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
33654a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
336665e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
33676fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
33686fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
33696fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
33702121bac1SHong Zhang                                         0,
33712121bac1SHong Zhang                                 /* 99*/ 0,
3372609c6c4dSKris Buschelman                                         0,
3373609c6c4dSKris Buschelman                                         0,
337487d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
337587d4246cSBarry Smith                                         0,
3376d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
337799cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3378f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3379f5edf698SHong Zhang                                         0,
33802bebee5dSHong Zhang                                         0,
3381cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3382985db425SBarry Smith                                         0,
33832af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
33842af78befSBarry Smith                                         0,
3385599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3386d519adbfSMatthew Knepley                                 /*114*/ 0,
3387599ef60dSHong Zhang                                         0,
33883c2a7987SHong Zhang                                         0,
3389fe97e370SBarry Smith                                         0,
3390fbdbba38SShri Abhyankar                                         0,
3391fbdbba38SShri Abhyankar                                 /*119*/ 0,
3392fbdbba38SShri Abhyankar                                         0,
3393fbdbba38SShri Abhyankar                                         0,
339482d44351SHong Zhang                                         0,
3395b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
33960716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3397bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
339837868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
339937868618SMatthew G Knepley                                         0,
340037868618SMatthew G Knepley                                         0,
34015df89d91SHong Zhang                                 /*129*/ 0,
340275648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
340375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
340475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3405b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3406b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
34072b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
34082b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
34092b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
34103964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
34113964eb88SJed Brown                                  /*139*/0,
3412f9426fe0SMark Adams                                         0,
34131919a2e2SJed Brown                                         0,
34143a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
34153a062f41SBarry Smith                                         MatFindOffBlockDiagonalEntries_SeqAIJ
34169e29f15eSvictorle };
341717ab2063SBarry Smith 
34184a2ae208SSatish Balay #undef __FUNCT__
34194a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
34207087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3421bef8e0ddSBarry Smith {
3422bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
342397f1f81fSBarry Smith   PetscInt   i,nz,n;
3424bef8e0ddSBarry Smith 
3425bef8e0ddSBarry Smith   PetscFunctionBegin;
3426bef8e0ddSBarry Smith   nz = aij->maxnz;
3427d0f46423SBarry Smith   n  = mat->rmap->n;
3428bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3429bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3430bef8e0ddSBarry Smith   }
3431bef8e0ddSBarry Smith   aij->nz = nz;
3432bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3433bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3434bef8e0ddSBarry Smith   }
3435bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3436bef8e0ddSBarry Smith }
3437bef8e0ddSBarry Smith 
34384a2ae208SSatish Balay #undef __FUNCT__
34394a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3440bef8e0ddSBarry Smith /*@
3441bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3442bef8e0ddSBarry Smith        in the matrix.
3443bef8e0ddSBarry Smith 
3444bef8e0ddSBarry Smith   Input Parameters:
3445bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3446bef8e0ddSBarry Smith -  indices - the column indices
3447bef8e0ddSBarry Smith 
344815091d37SBarry Smith   Level: advanced
344915091d37SBarry Smith 
3450bef8e0ddSBarry Smith   Notes:
3451bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3452bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3453bef8e0ddSBarry Smith   of the MatSetValues() operation.
3454bef8e0ddSBarry Smith 
3455bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3456d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3457bef8e0ddSBarry Smith 
3458bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3459bef8e0ddSBarry Smith 
3460b9617806SBarry Smith     The indices should start with zero, not one.
3461b9617806SBarry Smith 
3462bef8e0ddSBarry Smith @*/
34637087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3464bef8e0ddSBarry Smith {
34654ac538c5SBarry Smith   PetscErrorCode ierr;
3466bef8e0ddSBarry Smith 
3467bef8e0ddSBarry Smith   PetscFunctionBegin;
34680700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
34694482741eSBarry Smith   PetscValidPointer(indices,2);
34704ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3471bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3472bef8e0ddSBarry Smith }
3473bef8e0ddSBarry Smith 
3474be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3475be6bf707SBarry Smith 
34764a2ae208SSatish Balay #undef __FUNCT__
34774a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
34787087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3479be6bf707SBarry Smith {
3480be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
34816849ba73SBarry Smith   PetscErrorCode ierr;
3482d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3483be6bf707SBarry Smith 
3484be6bf707SBarry Smith   PetscFunctionBegin;
3485169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3486be6bf707SBarry Smith 
3487be6bf707SBarry Smith   /* allocate space for values if not already there */
3488be6bf707SBarry Smith   if (!aij->saved_values) {
3489785e854fSJed Brown     ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr);
34903bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3491be6bf707SBarry Smith   }
3492be6bf707SBarry Smith 
3493be6bf707SBarry Smith   /* copy values over */
349487828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3495be6bf707SBarry Smith   PetscFunctionReturn(0);
3496be6bf707SBarry Smith }
3497be6bf707SBarry Smith 
34984a2ae208SSatish Balay #undef __FUNCT__
3499b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3500be6bf707SBarry Smith /*@
3501be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3502be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3503be6bf707SBarry Smith        nonlinear portion.
3504be6bf707SBarry Smith 
3505be6bf707SBarry Smith    Collect on Mat
3506be6bf707SBarry Smith 
3507be6bf707SBarry Smith   Input Parameters:
35080e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3509be6bf707SBarry Smith 
351015091d37SBarry Smith   Level: advanced
351115091d37SBarry Smith 
3512be6bf707SBarry Smith   Common Usage, with SNESSolve():
3513be6bf707SBarry Smith $    Create Jacobian matrix
3514be6bf707SBarry Smith $    Set linear terms into matrix
3515be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3516be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3517be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3518512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3519be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3520be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3521be6bf707SBarry Smith $    In your Jacobian routine
3522be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3523be6bf707SBarry Smith $      Set nonlinear terms in matrix
3524be6bf707SBarry Smith 
3525be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3526be6bf707SBarry Smith $    // build linear portion of Jacobian
3527512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3528be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3529be6bf707SBarry Smith $    loop over nonlinear iterations
3530be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3531be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3532be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3533be6bf707SBarry Smith $       Solve linear system with Jacobian
3534be6bf707SBarry Smith $    endloop
3535be6bf707SBarry Smith 
3536be6bf707SBarry Smith   Notes:
3537be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3538512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3539be6bf707SBarry Smith     calling this routine.
3540be6bf707SBarry Smith 
35410c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
35420c468ba9SBarry Smith     and does not allocated additional space.
35430c468ba9SBarry Smith 
3544be6bf707SBarry Smith .seealso: MatRetrieveValues()
3545be6bf707SBarry Smith 
3546be6bf707SBarry Smith @*/
35477087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3548be6bf707SBarry Smith {
35494ac538c5SBarry Smith   PetscErrorCode ierr;
3550be6bf707SBarry Smith 
3551be6bf707SBarry Smith   PetscFunctionBegin;
35520700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3553e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3554e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
35554ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3556be6bf707SBarry Smith   PetscFunctionReturn(0);
3557be6bf707SBarry Smith }
3558be6bf707SBarry Smith 
35594a2ae208SSatish Balay #undef __FUNCT__
35604a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
35617087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3562be6bf707SBarry Smith {
3563be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
35646849ba73SBarry Smith   PetscErrorCode ierr;
3565d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3566be6bf707SBarry Smith 
3567be6bf707SBarry Smith   PetscFunctionBegin;
3568169f6850SBarry Smith   if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3569f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3570be6bf707SBarry Smith   /* copy values over */
357187828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3572be6bf707SBarry Smith   PetscFunctionReturn(0);
3573be6bf707SBarry Smith }
3574be6bf707SBarry Smith 
35754a2ae208SSatish Balay #undef __FUNCT__
35764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3577be6bf707SBarry Smith /*@
3578be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3579be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3580be6bf707SBarry Smith        nonlinear portion.
3581be6bf707SBarry Smith 
3582be6bf707SBarry Smith    Collect on Mat
3583be6bf707SBarry Smith 
3584be6bf707SBarry Smith   Input Parameters:
3585be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3586be6bf707SBarry Smith 
358715091d37SBarry Smith   Level: advanced
358815091d37SBarry Smith 
3589be6bf707SBarry Smith .seealso: MatStoreValues()
3590be6bf707SBarry Smith 
3591be6bf707SBarry Smith @*/
35927087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3593be6bf707SBarry Smith {
35944ac538c5SBarry Smith   PetscErrorCode ierr;
3595be6bf707SBarry Smith 
3596be6bf707SBarry Smith   PetscFunctionBegin;
35970700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3598e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3599e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
36004ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3601be6bf707SBarry Smith   PetscFunctionReturn(0);
3602be6bf707SBarry Smith }
3603be6bf707SBarry Smith 
3604f83d6046SBarry Smith 
3605be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
36064a2ae208SSatish Balay #undef __FUNCT__
36074a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
360817ab2063SBarry Smith /*@C
3609682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
36100d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
36116e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
361251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
36132bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
361417ab2063SBarry Smith 
3615db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3616db81eaa0SLois Curfman McInnes 
361717ab2063SBarry Smith    Input Parameters:
3618db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
361917ab2063SBarry Smith .  m - number of rows
362017ab2063SBarry Smith .  n - number of columns
362117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
362251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
36230298fd71SBarry Smith          (possibly different for each row) or NULL
362417ab2063SBarry Smith 
362517ab2063SBarry Smith    Output Parameter:
3626416022c9SBarry Smith .  A - the matrix
362717ab2063SBarry Smith 
3628175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3629ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3630175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3631175b88e8SBarry Smith 
3632b259b22eSLois Curfman McInnes    Notes:
363349a6f317SBarry Smith    If nnz is given then nz is ignored
363449a6f317SBarry Smith 
363517ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
363617ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
36370002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
363844cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
363917ab2063SBarry Smith 
364017ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
36410298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
36423d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
36436da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
364417ab2063SBarry Smith 
3645682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
36464fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3647682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
36486c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
36496c7ebb05SLois Curfman McInnes 
36506c7ebb05SLois Curfman McInnes    Options Database Keys:
3651698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
36529db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
365317ab2063SBarry Smith 
3654027ccd11SLois Curfman McInnes    Level: intermediate
3655027ccd11SLois Curfman McInnes 
365669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
365736db0b34SBarry Smith 
365817ab2063SBarry Smith @*/
36597087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
366017ab2063SBarry Smith {
3661dfbe8321SBarry Smith   PetscErrorCode ierr;
36626945ee14SBarry Smith 
36633a40ed3dSBarry Smith   PetscFunctionBegin;
3664f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3665117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3666c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3667d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3668273d9f13SBarry Smith   PetscFunctionReturn(0);
3669273d9f13SBarry Smith }
3670273d9f13SBarry Smith 
36714a2ae208SSatish Balay #undef __FUNCT__
36724a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3673273d9f13SBarry Smith /*@C
3674273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3675273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3676273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3677273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3678273d9f13SBarry Smith 
3679273d9f13SBarry Smith    Collective on MPI_Comm
3680273d9f13SBarry Smith 
3681273d9f13SBarry Smith    Input Parameters:
3682117016b1SBarry Smith +  B - The matrix-free
3683273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3684273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
36850298fd71SBarry Smith          (possibly different for each row) or NULL
3686273d9f13SBarry Smith 
3687273d9f13SBarry Smith    Notes:
368849a6f317SBarry Smith      If nnz is given then nz is ignored
368949a6f317SBarry Smith 
3690273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3691273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3692273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3693273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3694273d9f13SBarry Smith 
3695273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
36960298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3697273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3698273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3699273d9f13SBarry Smith 
3700aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3701aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3702aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3703aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3704aa95bbe8SBarry Smith 
3705a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3706a96a251dSBarry Smith    entries or columns indices
3707a96a251dSBarry Smith 
3708273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3709273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3710273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3711273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3712273d9f13SBarry Smith 
3713273d9f13SBarry Smith    Options Database Keys:
3714698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3715698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3716273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3717273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3718273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3719273d9f13SBarry Smith 
3720273d9f13SBarry Smith    Level: intermediate
3721273d9f13SBarry Smith 
372269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3723273d9f13SBarry Smith 
3724273d9f13SBarry Smith @*/
37257087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3726273d9f13SBarry Smith {
37274ac538c5SBarry Smith   PetscErrorCode ierr;
3728a23d5eceSKris Buschelman 
3729a23d5eceSKris Buschelman   PetscFunctionBegin;
37306ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
37316ba663aaSJed Brown   PetscValidType(B,1);
37324ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3733a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3734a23d5eceSKris Buschelman }
3735a23d5eceSKris Buschelman 
3736a23d5eceSKris Buschelman #undef __FUNCT__
3737a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
37387087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3739a23d5eceSKris Buschelman {
3740273d9f13SBarry Smith   Mat_SeqAIJ     *b;
37412576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
37426849ba73SBarry Smith   PetscErrorCode ierr;
374397f1f81fSBarry Smith   PetscInt       i;
3744273d9f13SBarry Smith 
3745273d9f13SBarry Smith   PetscFunctionBegin;
37462576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3747a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3748c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3749c461c341SBarry Smith     nz             = 0;
3750c461c341SBarry Smith   }
3751c461c341SBarry Smith 
375226283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
375326283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3754899cda47SBarry Smith 
3755435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3756e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3757b73539f3SBarry Smith   if (nnz) {
3758d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3759e32f2f54SBarry 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]);
3760e32f2f54SBarry 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);
3761b73539f3SBarry Smith     }
3762b73539f3SBarry Smith   }
3763b73539f3SBarry Smith 
3764273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
37652205254eSKarl Rupp 
3766273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3767273d9f13SBarry Smith 
3768ab93d7beSBarry Smith   if (!skipallocation) {
37692ee49352SLisandro Dalcin     if (!b->imax) {
3770dcca6d9dSJed Brown       ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr);
37713bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
37722ee49352SLisandro Dalcin     }
3773273d9f13SBarry Smith     if (!nnz) {
3774435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3775c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3776d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3777d0f46423SBarry Smith       nz = nz*B->rmap->n;
3778273d9f13SBarry Smith     } else {
3779273d9f13SBarry Smith       nz = 0;
3780d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3781273d9f13SBarry Smith     }
3782ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
37832205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3784ab93d7beSBarry Smith 
3785273d9f13SBarry Smith     /* allocate the matrix space */
37862ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3787dcca6d9dSJed Brown     ierr    = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
37883bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3789bfeeae90SHong Zhang     b->i[0] = 0;
3790d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
37915da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
37925da197adSKris Buschelman     }
3793273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3794e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3795e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3796b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3797b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3798b31eba2aSShri Abhyankar #endif
3799c461c341SBarry Smith   } else {
3800e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3801e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3802c461c341SBarry Smith   }
3803273d9f13SBarry Smith 
3804273d9f13SBarry Smith   b->nz               = 0;
3805273d9f13SBarry Smith   b->maxnz            = nz;
3806273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
38072205254eSKarl Rupp   if (realalloc) {
38082205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
38092205254eSKarl Rupp   }
3810273d9f13SBarry Smith   PetscFunctionReturn(0);
3811273d9f13SBarry Smith }
3812273d9f13SBarry Smith 
3813a1661176SMatthew Knepley #undef  __FUNCT__
3814a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
381558d36128SBarry Smith /*@
3816a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3817a1661176SMatthew Knepley 
3818a1661176SMatthew Knepley    Input Parameters:
3819a1661176SMatthew Knepley +  B - the matrix
3820a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3821a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3822a1661176SMatthew Knepley -  v - optional values in the matrix
3823a1661176SMatthew Knepley 
3824a1661176SMatthew Knepley    Level: developer
3825a1661176SMatthew Knepley 
382658d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
382758d36128SBarry Smith 
3828a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3829a1661176SMatthew Knepley 
3830a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3831a1661176SMatthew Knepley @*/
3832a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3833a1661176SMatthew Knepley {
3834a1661176SMatthew Knepley   PetscErrorCode ierr;
3835a1661176SMatthew Knepley 
3836a1661176SMatthew Knepley   PetscFunctionBegin;
38370700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
38386ba663aaSJed Brown   PetscValidType(B,1);
38394ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3840a1661176SMatthew Knepley   PetscFunctionReturn(0);
3841a1661176SMatthew Knepley }
3842a1661176SMatthew Knepley 
3843a1661176SMatthew Knepley #undef  __FUNCT__
3844a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
38457087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3846a1661176SMatthew Knepley {
3847a1661176SMatthew Knepley   PetscInt       i;
3848a1661176SMatthew Knepley   PetscInt       m,n;
3849a1661176SMatthew Knepley   PetscInt       nz;
3850a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
3851a1661176SMatthew Knepley   PetscScalar    *values;
3852a1661176SMatthew Knepley   PetscErrorCode ierr;
3853a1661176SMatthew Knepley 
3854a1661176SMatthew Knepley   PetscFunctionBegin;
385565e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
3856779a8d59SSatish Balay 
3857779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
3858779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3859779a8d59SSatish Balay 
3860779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
3861785e854fSJed Brown   ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr);
3862a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3863b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
3864a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
386565e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
3866a1661176SMatthew Knepley     nnz[i] = nz;
3867a1661176SMatthew Knepley   }
3868a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
3869a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
3870a1661176SMatthew Knepley 
3871a1661176SMatthew Knepley   if (v) {
3872a1661176SMatthew Knepley     values = (PetscScalar*) v;
3873a1661176SMatthew Knepley   } else {
38741795a4d1SJed Brown     ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr);
3875a1661176SMatthew Knepley   }
3876a1661176SMatthew Knepley 
3877a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
3878b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
3879b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
3880a1661176SMatthew Knepley   }
3881a1661176SMatthew Knepley 
3882a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3883a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3884a1661176SMatthew Knepley 
3885a1661176SMatthew Knepley   if (!v) {
3886a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
3887a1661176SMatthew Knepley   }
38887827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
3889a1661176SMatthew Knepley   PetscFunctionReturn(0);
3890a1661176SMatthew Knepley }
3891a1661176SMatthew Knepley 
3892c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
389306873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
3894170fe5c8SBarry Smith 
3895170fe5c8SBarry Smith #undef __FUNCT__
3896170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
3897170fe5c8SBarry Smith /*
3898170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
3899170fe5c8SBarry Smith 
3900170fe5c8SBarry Smith                n                       p                          p
3901170fe5c8SBarry Smith         (              )       (              )         (                  )
3902170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
3903170fe5c8SBarry Smith         (              )       (              )         (                  )
3904170fe5c8SBarry Smith 
3905170fe5c8SBarry Smith */
3906170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
3907170fe5c8SBarry Smith {
3908170fe5c8SBarry Smith   PetscErrorCode    ierr;
3909170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
3910170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
3911170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
39121de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
3913170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
3914170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
3915170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
3916170fe5c8SBarry Smith 
3917170fe5c8SBarry Smith   PetscFunctionBegin;
3918d0f46423SBarry Smith   m    = A->rmap->n;
3919d0f46423SBarry Smith   n    = A->cmap->n;
3920d0f46423SBarry Smith   p    = B->cmap->n;
3921170fe5c8SBarry Smith   a    = sub_a->v;
3922170fe5c8SBarry Smith   b    = sub_b->a;
3923170fe5c8SBarry Smith   c    = sub_c->v;
3924170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
3925170fe5c8SBarry Smith 
3926170fe5c8SBarry Smith   ii  = sub_b->i;
3927170fe5c8SBarry Smith   idx = sub_b->j;
3928170fe5c8SBarry Smith   for (i=0; i<n; i++) {
3929170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
3930170fe5c8SBarry Smith     while (q-->0) {
3931170fe5c8SBarry Smith       c_q = c + m*(*idx);
3932170fe5c8SBarry Smith       a_q = a + m*i;
3933854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
3934170fe5c8SBarry Smith       idx++;
3935170fe5c8SBarry Smith       b++;
3936170fe5c8SBarry Smith     }
3937170fe5c8SBarry Smith   }
3938170fe5c8SBarry Smith   PetscFunctionReturn(0);
3939170fe5c8SBarry Smith }
3940170fe5c8SBarry Smith 
3941170fe5c8SBarry Smith #undef __FUNCT__
3942170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
3943170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
3944170fe5c8SBarry Smith {
3945170fe5c8SBarry Smith   PetscErrorCode ierr;
3946d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
3947170fe5c8SBarry Smith   Mat            Cmat;
3948170fe5c8SBarry Smith 
3949170fe5c8SBarry Smith   PetscFunctionBegin;
3950e32f2f54SBarry 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);
3951ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
3952170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
3953a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
3954170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
39550298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
3956d73949e8SHong Zhang 
3957d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
39582205254eSKarl Rupp 
3959170fe5c8SBarry Smith   *C = Cmat;
3960170fe5c8SBarry Smith   PetscFunctionReturn(0);
3961170fe5c8SBarry Smith }
3962170fe5c8SBarry Smith 
3963170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
3964170fe5c8SBarry Smith #undef __FUNCT__
3965170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
3966170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
3967170fe5c8SBarry Smith {
3968170fe5c8SBarry Smith   PetscErrorCode ierr;
3969170fe5c8SBarry Smith 
3970170fe5c8SBarry Smith   PetscFunctionBegin;
3971170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
39723ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3973170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
39743ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
3975170fe5c8SBarry Smith   }
39763ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3977170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
39783ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
3979170fe5c8SBarry Smith   PetscFunctionReturn(0);
3980170fe5c8SBarry Smith }
3981170fe5c8SBarry Smith 
3982170fe5c8SBarry Smith 
39830bad9183SKris Buschelman /*MC
3984fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
39850bad9183SKris Buschelman    based on compressed sparse row format.
39860bad9183SKris Buschelman 
39870bad9183SKris Buschelman    Options Database Keys:
39880bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
39890bad9183SKris Buschelman 
39900bad9183SKris Buschelman   Level: beginner
39910bad9183SKris Buschelman 
3992f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
39930bad9183SKris Buschelman M*/
39940bad9183SKris Buschelman 
3995ccd284c7SBarry Smith /*MC
3996ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
3997ccd284c7SBarry Smith 
3998ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
3999ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
4000ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
4001ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
4002ccd284c7SBarry Smith   the above preallocation routines for simplicity.
4003ccd284c7SBarry Smith 
4004ccd284c7SBarry Smith    Options Database Keys:
4005ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
4006ccd284c7SBarry Smith 
4007ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
4008ccd284c7SBarry Smith    enough exist.
4009ccd284c7SBarry Smith 
4010ccd284c7SBarry Smith   Level: beginner
4011ccd284c7SBarry Smith 
4012ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
4013ccd284c7SBarry Smith M*/
4014ccd284c7SBarry Smith 
4015ccd284c7SBarry Smith /*MC
4016ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
4017ccd284c7SBarry Smith 
4018ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
4019ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
4020ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
4021ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
4022ccd284c7SBarry Smith   the above preallocation routines for simplicity.
4023ccd284c7SBarry Smith 
4024ccd284c7SBarry Smith    Options Database Keys:
4025ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
4026ccd284c7SBarry Smith 
4027ccd284c7SBarry Smith   Level: beginner
4028ccd284c7SBarry Smith 
4029ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
4030ccd284c7SBarry Smith M*/
4031ccd284c7SBarry Smith 
4032b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
40338cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
4034b5e56a35SBarry Smith #endif
4035ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
40368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
4037af1023dbSSatish Balay #endif
40388cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
40398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
40408cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
40417087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
4042611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
40438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
4044611f576cSBarry Smith #endif
4045611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
40468cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
4047611f576cSBarry Smith #endif
4048f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
40498cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
4050f3c0ef26SHong Zhang #endif
4051eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
40528cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
4053eb3b5408SSatish Balay #endif
4054586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
40558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
4056586621ddSJed Brown #endif
4057719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
40588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
4059719d5645SBarry Smith #endif
4060b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
40618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
40627087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
40637087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
4064b3866ffcSBarry Smith #endif
406517f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
40668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
406717f1a0eaSHong Zhang #endif
406817667f90SBarry Smith 
4069c0c8ee5eSDmitry Karpeev 
40708c778c55SBarry Smith #undef __FUNCT__
40718c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
40728c778c55SBarry Smith /*@C
40738c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
40748c778c55SBarry Smith 
40758c778c55SBarry Smith    Not Collective
40768c778c55SBarry Smith 
40778c778c55SBarry Smith    Input Parameter:
40788c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
40798c778c55SBarry Smith 
40808c778c55SBarry Smith    Output Parameter:
40818c778c55SBarry Smith .   array - pointer to the data
40828c778c55SBarry Smith 
40838c778c55SBarry Smith    Level: intermediate
40848c778c55SBarry Smith 
4085774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
40868c778c55SBarry Smith @*/
40878c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
40888c778c55SBarry Smith {
40898c778c55SBarry Smith   PetscErrorCode ierr;
40908c778c55SBarry Smith 
40918c778c55SBarry Smith   PetscFunctionBegin;
40928c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
40938c778c55SBarry Smith   PetscFunctionReturn(0);
40948c778c55SBarry Smith }
40958c778c55SBarry Smith 
40968c778c55SBarry Smith #undef __FUNCT__
40978c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
40988c778c55SBarry Smith /*@C
40998c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
41008c778c55SBarry Smith 
41018c778c55SBarry Smith    Not Collective
41028c778c55SBarry Smith 
41038c778c55SBarry Smith    Input Parameters:
41048c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
41058c778c55SBarry Smith .  array - pointer to the data
41068c778c55SBarry Smith 
41078c778c55SBarry Smith    Level: intermediate
41088c778c55SBarry Smith 
4109774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
41108c778c55SBarry Smith @*/
41118c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
41128c778c55SBarry Smith {
41138c778c55SBarry Smith   PetscErrorCode ierr;
41148c778c55SBarry Smith 
41158c778c55SBarry Smith   PetscFunctionBegin;
41168c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
41178c778c55SBarry Smith   PetscFunctionReturn(0);
41188c778c55SBarry Smith }
41198c778c55SBarry Smith 
41204a2ae208SSatish Balay #undef __FUNCT__
41214a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
41228cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
4123273d9f13SBarry Smith {
4124273d9f13SBarry Smith   Mat_SeqAIJ     *b;
4125dfbe8321SBarry Smith   PetscErrorCode ierr;
412638baddfdSBarry Smith   PetscMPIInt    size;
4127273d9f13SBarry Smith 
4128273d9f13SBarry Smith   PetscFunctionBegin;
4129ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
4130e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
4131273d9f13SBarry Smith 
4132b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
41332205254eSKarl Rupp 
4134b0a32e0cSBarry Smith   B->data = (void*)b;
41352205254eSKarl Rupp 
4136549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
41372205254eSKarl Rupp 
4138416022c9SBarry Smith   b->row                = 0;
4139416022c9SBarry Smith   b->col                = 0;
414082bf6240SBarry Smith   b->icol               = 0;
4141b810aeb4SBarry Smith   b->reallocs           = 0;
414236db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4143f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4144416022c9SBarry Smith   b->nonew              = 0;
4145416022c9SBarry Smith   b->diag               = 0;
4146416022c9SBarry Smith   b->solve_work         = 0;
41472a1b7f2aSHong Zhang   B->spptr              = 0;
4148be6bf707SBarry Smith   b->saved_values       = 0;
4149d7f994e1SBarry Smith   b->idiag              = 0;
415071f1c65dSBarry Smith   b->mdiag              = 0;
415171f1c65dSBarry Smith   b->ssor_work          = 0;
415271f1c65dSBarry Smith   b->omega              = 1.0;
415371f1c65dSBarry Smith   b->fshift             = 0.0;
415471f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4155bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4156a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
4157a30b2313SHong Zhang   b->xtoy               = 0;
4158a30b2313SHong Zhang   b->XtoY               = 0;
415988e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
416017ab2063SBarry Smith 
416135d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4162bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4163bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
41648c778c55SBarry Smith 
4165b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4166bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4167bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4168bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4169b3866ffcSBarry Smith #endif
4170b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4171bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4172b5e56a35SBarry Smith #endif
4173ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4174bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4175719d5645SBarry Smith #endif
4176611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4177bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4178611f576cSBarry Smith #endif
4179f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4180bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4181f3c0ef26SHong Zhang #endif
4182611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4183bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4184611f576cSBarry Smith #endif
4185eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4186bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4187eb3b5408SSatish Balay #endif
4188586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4189bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4190586621ddSJed Brown #endif
4191719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4192bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4193719d5645SBarry Smith #endif
419417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4195bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
419617f1a0eaSHong Zhang #endif
419717f1a0eaSHong Zhang 
4198bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4199bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4200bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4201bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4202bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4203bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4204bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4205bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4206bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4207bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4208bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4209bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4210bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4211bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4212bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4213bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4214bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4215bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
42164108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
421717667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
42183a40ed3dSBarry Smith   PetscFunctionReturn(0);
421917ab2063SBarry Smith }
422017ab2063SBarry Smith 
42214a2ae208SSatish Balay #undef __FUNCT__
4222b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4223b24902e0SBarry Smith /*
4224b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4225b24902e0SBarry Smith */
4226ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
422717ab2063SBarry Smith {
4228416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
42296849ba73SBarry Smith   PetscErrorCode ierr;
4230d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
423117ab2063SBarry Smith 
42323a40ed3dSBarry Smith   PetscFunctionBegin;
4233273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4234273d9f13SBarry Smith 
4235d5f3da31SBarry Smith   C->factortype = A->factortype;
4236416022c9SBarry Smith   c->row        = 0;
4237416022c9SBarry Smith   c->col        = 0;
423882bf6240SBarry Smith   c->icol       = 0;
42396ad4291fSHong Zhang   c->reallocs   = 0;
424017ab2063SBarry Smith 
42416ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
424217ab2063SBarry Smith 
4243aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4244aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4245eec197d1SBarry Smith 
4246dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr);
42473bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
424817ab2063SBarry Smith   for (i=0; i<m; i++) {
4249416022c9SBarry Smith     c->imax[i] = a->imax[i];
4250416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
425117ab2063SBarry Smith   }
425217ab2063SBarry Smith 
425317ab2063SBarry Smith   /* allocate the matrix space */
4254f77e22a1SHong Zhang   if (mallocmatspace) {
4255dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
42563bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
42572205254eSKarl Rupp 
4258f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
42592205254eSKarl Rupp 
426097f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
426117ab2063SBarry Smith     if (m > 0) {
426297f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4263be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4264bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4265be6bf707SBarry Smith       } else {
4266bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
426717ab2063SBarry Smith       }
426808480c60SBarry Smith     }
4269f77e22a1SHong Zhang   }
427017ab2063SBarry Smith 
42716ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4272416022c9SBarry Smith   c->roworiented       = a->roworiented;
4273416022c9SBarry Smith   c->nonew             = a->nonew;
4274416022c9SBarry Smith   if (a->diag) {
4275785e854fSJed Brown     ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr);
42763bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
427717ab2063SBarry Smith     for (i=0; i<m; i++) {
4278416022c9SBarry Smith       c->diag[i] = a->diag[i];
427917ab2063SBarry Smith     }
42803a40ed3dSBarry Smith   } else c->diag = 0;
42812205254eSKarl Rupp 
42826ad4291fSHong Zhang   c->solve_work         = 0;
42836ad4291fSHong Zhang   c->saved_values       = 0;
42846ad4291fSHong Zhang   c->idiag              = 0;
428571f1c65dSBarry Smith   c->ssor_work          = 0;
4286a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4287e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4288e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
42896ad4291fSHong Zhang   c->xtoy               = 0;
42906ad4291fSHong Zhang   c->XtoY               = 0;
42916ad4291fSHong Zhang 
4292893ad86cSHong Zhang   c->rmax         = a->rmax;
4293416022c9SBarry Smith   c->nz           = a->nz;
42948ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4295273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4296754ec7b1SSatish Balay 
42976ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
42986ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4299cd6b891eSBarry Smith   if (a->compressedrow.use) {
43006ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4301dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
43026ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
43036ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
430427ea64f8SHong Zhang   } else {
430527ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
43060298fd71SBarry Smith     c->compressedrow.i      = NULL;
43070298fd71SBarry Smith     c->compressedrow.rindex = NULL;
43086ad4291fSHong Zhang   }
430988e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
43104846f1f5SKris Buschelman 
43112205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4312140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
43133a40ed3dSBarry Smith   PetscFunctionReturn(0);
431417ab2063SBarry Smith }
431517ab2063SBarry Smith 
43164a2ae208SSatish Balay #undef __FUNCT__
4317b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4318b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4319b24902e0SBarry Smith {
4320b24902e0SBarry Smith   PetscErrorCode ierr;
4321b24902e0SBarry Smith 
4322b24902e0SBarry Smith   PetscFunctionBegin;
4323ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
43244b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4325cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
4326a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4327cfd3f464SBarry Smith   }
4328a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4329f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4330b24902e0SBarry Smith   PetscFunctionReturn(0);
4331b24902e0SBarry Smith }
4332b24902e0SBarry Smith 
4333b24902e0SBarry Smith #undef __FUNCT__
43344a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4335112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4336fbdbba38SShri Abhyankar {
4337fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4338fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4339fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4340fbdbba38SShri Abhyankar   int            fd;
4341fbdbba38SShri Abhyankar   PetscMPIInt    size;
4342fbdbba38SShri Abhyankar   MPI_Comm       comm;
4343bbead8a2SBarry Smith   PetscInt       bs = 1;
4344fbdbba38SShri Abhyankar 
4345fbdbba38SShri Abhyankar   PetscFunctionBegin;
4346fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4347fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4348fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4349bbead8a2SBarry Smith 
43500298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
43510298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4352bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
43531814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4354bbead8a2SBarry Smith 
4355fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4356fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4357fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4358fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4359fbdbba38SShri Abhyankar 
4360bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4361fbdbba38SShri Abhyankar 
4362fbdbba38SShri Abhyankar   /* read in row lengths */
4363785e854fSJed Brown   ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr);
4364fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4365fbdbba38SShri Abhyankar 
4366fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4367fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4368fbdbba38SShri 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);
4369fbdbba38SShri Abhyankar 
4370fbdbba38SShri Abhyankar   /* set global size if not set already*/
4371f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4372fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4373aabbc4fbSShri Abhyankar   } else {
4374fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4375fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
43764c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
43774c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
43784c5b953cSHong Zhang     }
4379f501eaabSShri 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);
4380aabbc4fbSShri Abhyankar   }
4381fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4382fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4383fbdbba38SShri Abhyankar 
4384fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4385fbdbba38SShri Abhyankar 
4386fbdbba38SShri Abhyankar   /* read in nonzero values */
4387fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4388fbdbba38SShri Abhyankar 
4389fbdbba38SShri Abhyankar   /* set matrix "i" values */
4390fbdbba38SShri Abhyankar   a->i[0] = 0;
4391fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4392fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4393fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4394fbdbba38SShri Abhyankar   }
4395fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4396fbdbba38SShri Abhyankar 
4397fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4398fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4399fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4400fbdbba38SShri Abhyankar }
4401fbdbba38SShri Abhyankar 
4402fbdbba38SShri Abhyankar #undef __FUNCT__
4403b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4404ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
44057264ac53SSatish Balay {
44067264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4407dfbe8321SBarry Smith   PetscErrorCode ierr;
4408eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4409eeffb40dSHong Zhang   PetscInt k;
4410eeffb40dSHong Zhang #endif
44117264ac53SSatish Balay 
44123a40ed3dSBarry Smith   PetscFunctionBegin;
4413bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4414d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4415ca44d042SBarry Smith     *flg = PETSC_FALSE;
4416ca44d042SBarry Smith     PetscFunctionReturn(0);
4417bcd2baecSBarry Smith   }
44187264ac53SSatish Balay 
44197264ac53SSatish Balay   /* if the a->i are the same */
4420d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4421abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
44227264ac53SSatish Balay 
44237264ac53SSatish Balay   /* if a->j are the same */
442497f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4425abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4426bcd2baecSBarry Smith 
4427bcd2baecSBarry Smith   /* if a->a are the same */
4428eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4429eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4430eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4431eeffb40dSHong Zhang       *flg = PETSC_FALSE;
44323a40ed3dSBarry Smith       PetscFunctionReturn(0);
4433eeffb40dSHong Zhang     }
4434eeffb40dSHong Zhang   }
4435eeffb40dSHong Zhang #else
4436eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4437eeffb40dSHong Zhang #endif
4438eeffb40dSHong Zhang   PetscFunctionReturn(0);
44397264ac53SSatish Balay }
444036db0b34SBarry Smith 
44414a2ae208SSatish Balay #undef __FUNCT__
44424a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
444305869f15SSatish Balay /*@
444436db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
444536db0b34SBarry Smith               provided by the user.
444636db0b34SBarry Smith 
4447c75a6043SHong Zhang       Collective on MPI_Comm
444836db0b34SBarry Smith 
444936db0b34SBarry Smith    Input Parameters:
445036db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
445136db0b34SBarry Smith .   m - number of rows
445236db0b34SBarry Smith .   n - number of columns
445336db0b34SBarry Smith .   i - row indices
445436db0b34SBarry Smith .   j - column indices
445536db0b34SBarry Smith -   a - matrix values
445636db0b34SBarry Smith 
445736db0b34SBarry Smith    Output Parameter:
445836db0b34SBarry Smith .   mat - the matrix
445936db0b34SBarry Smith 
446036db0b34SBarry Smith    Level: intermediate
446136db0b34SBarry Smith 
446236db0b34SBarry Smith    Notes:
44630551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4464292fb18eSBarry Smith     once the matrix is destroyed and not before
446536db0b34SBarry Smith 
446636db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
446736db0b34SBarry Smith 
4468bfeeae90SHong Zhang        The i and j indices are 0 based
446936db0b34SBarry Smith 
4470a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4471a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4472a4552177SSatish Balay     as shown:
4473a4552177SSatish Balay 
4474a4552177SSatish Balay         1 0 0
4475a4552177SSatish Balay         2 0 3
4476a4552177SSatish Balay         4 5 6
4477a4552177SSatish Balay 
4478a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
44799985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4480a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4481a4552177SSatish Balay 
44829985e31cSBarry Smith 
448369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
448436db0b34SBarry Smith 
448536db0b34SBarry Smith @*/
44867087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
448736db0b34SBarry Smith {
4488dfbe8321SBarry Smith   PetscErrorCode ierr;
4489cbcfb4deSHong Zhang   PetscInt       ii;
449036db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4491cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4492cbcfb4deSHong Zhang   PetscInt jj;
4493cbcfb4deSHong Zhang #endif
449436db0b34SBarry Smith 
449536db0b34SBarry Smith   PetscFunctionBegin;
4496f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4497f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4498f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4499a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4500ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4501ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4502ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4503dcca6d9dSJed Brown   ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr);
4504ab93d7beSBarry Smith 
450536db0b34SBarry Smith   aij->i            = i;
450636db0b34SBarry Smith   aij->j            = j;
450736db0b34SBarry Smith   aij->a            = a;
450836db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
450936db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4510e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4511e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
451236db0b34SBarry Smith 
451336db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
451436db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
45152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4516e32f2f54SBarry 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]);
45179985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4518e32f2f54SBarry 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);
4519e32f2f54SBarry 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);
45209985e31cSBarry Smith     }
452136db0b34SBarry Smith #endif
452236db0b34SBarry Smith   }
45232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
452436db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4525e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4526e32f2f54SBarry 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]);
452736db0b34SBarry Smith   }
452836db0b34SBarry Smith #endif
452936db0b34SBarry Smith 
4530b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4531b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
453236db0b34SBarry Smith   PetscFunctionReturn(0);
453336db0b34SBarry Smith }
45348a0b0e6bSVictor Minden #undef __FUNCT__
45358a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
453680ef6e79SMatthew G Knepley /*@C
4537d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
45388a0b0e6bSVictor Minden               provided by the user.
45398a0b0e6bSVictor Minden 
45408a0b0e6bSVictor Minden       Collective on MPI_Comm
45418a0b0e6bSVictor Minden 
45428a0b0e6bSVictor Minden    Input Parameters:
45438a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
45448a0b0e6bSVictor Minden .   m   - number of rows
45458a0b0e6bSVictor Minden .   n   - number of columns
45468a0b0e6bSVictor Minden .   i   - row indices
45478a0b0e6bSVictor Minden .   j   - column indices
45481230e6d1SVictor Minden .   a   - matrix values
45491230e6d1SVictor Minden .   nz  - number of nonzeros
45501230e6d1SVictor Minden -   idx - 0 or 1 based
45518a0b0e6bSVictor Minden 
45528a0b0e6bSVictor Minden    Output Parameter:
45538a0b0e6bSVictor Minden .   mat - the matrix
45548a0b0e6bSVictor Minden 
45558a0b0e6bSVictor Minden    Level: intermediate
45568a0b0e6bSVictor Minden 
45578a0b0e6bSVictor Minden    Notes:
45588a0b0e6bSVictor Minden        The i and j indices are 0 based
45598a0b0e6bSVictor Minden 
45608a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
45618a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
45628a0b0e6bSVictor Minden     as shown:
45638a0b0e6bSVictor Minden 
45648a0b0e6bSVictor Minden         1 0 0
45658a0b0e6bSVictor Minden         2 0 3
45668a0b0e6bSVictor Minden         4 5 6
45678a0b0e6bSVictor Minden 
45688a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
45698a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
45708a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
45718a0b0e6bSVictor Minden 
45728a0b0e6bSVictor Minden 
457369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
45748a0b0e6bSVictor Minden 
45758a0b0e6bSVictor Minden @*/
45761230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
45778a0b0e6bSVictor Minden {
45788a0b0e6bSVictor Minden   PetscErrorCode ierr;
4579d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
45808a0b0e6bSVictor Minden 
45818a0b0e6bSVictor Minden 
45828a0b0e6bSVictor Minden   PetscFunctionBegin;
45831795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
45841230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
4585c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
45861230e6d1SVictor Minden   }
45878a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
45888a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
45898a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
45901230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
45911230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
45921230e6d1SVictor Minden     if (idx) {
45931230e6d1SVictor Minden       row = i[ii] - 1;
45941230e6d1SVictor Minden       col = j[ii] - 1;
45951230e6d1SVictor Minden     } else {
45961230e6d1SVictor Minden       row = i[ii];
45971230e6d1SVictor Minden       col = j[ii];
45988a0b0e6bSVictor Minden     }
45991230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
46008a0b0e6bSVictor Minden   }
46018a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
46028a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4603d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
46048a0b0e6bSVictor Minden   PetscFunctionReturn(0);
46058a0b0e6bSVictor Minden }
460636db0b34SBarry Smith 
4607cc8ba8e1SBarry Smith #undef __FUNCT__
4608ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4609dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4610cc8ba8e1SBarry Smith {
4611dfbe8321SBarry Smith   PetscErrorCode ierr;
4612cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
461336db0b34SBarry Smith 
4614cc8ba8e1SBarry Smith   PetscFunctionBegin;
46158ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4616cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4617cc8ba8e1SBarry Smith     a->coloring = coloring;
461812c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
461997f1f81fSBarry Smith     PetscInt        i,*larray;
462012c595b3SBarry Smith     ISColoring      ocoloring;
462108b6dcc0SBarry Smith     ISColoringValue *colors;
462212c595b3SBarry Smith 
462312c595b3SBarry Smith     /* set coloring for diagonal portion */
4624785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr);
46252205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
46260298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
4627785e854fSJed Brown     ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr);
46282205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
462912c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4630d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
463112c595b3SBarry Smith     a->coloring = ocoloring;
463212c595b3SBarry Smith   }
4633cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4634cc8ba8e1SBarry Smith }
4635cc8ba8e1SBarry Smith 
4636ee4f033dSBarry Smith #undef __FUNCT__
4637ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
463897f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4639ee4f033dSBarry Smith {
4640ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4641d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
464254f21887SBarry Smith   MatScalar       *v      = a->a;
464354f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
464408b6dcc0SBarry Smith   ISColoringValue *color;
4645ee4f033dSBarry Smith 
4646ee4f033dSBarry Smith   PetscFunctionBegin;
4647e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4648ee4f033dSBarry Smith   color = a->coloring->colors;
4649ee4f033dSBarry Smith   /* loop over rows */
4650ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4651ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4652ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
46532205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4654ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4655cc8ba8e1SBarry Smith   }
4656cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4657cc8ba8e1SBarry Smith }
465836db0b34SBarry Smith 
4659acf2f550SJed Brown #undef __FUNCT__
4660acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4661acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4662acf2f550SJed Brown {
4663acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4664acf2f550SJed Brown   PetscErrorCode ierr;
4665acf2f550SJed Brown 
4666acf2f550SJed Brown   PetscFunctionBegin;
4667acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4668acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
46692205254eSKarl Rupp 
4670acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4671acf2f550SJed Brown   PetscFunctionReturn(0);
4672acf2f550SJed Brown }
4673acf2f550SJed Brown 
467481824310SBarry Smith /*
467581824310SBarry Smith     Special version for direct calls from Fortran
467681824310SBarry Smith */
4677b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
467881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
467981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
468081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
468181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
468281824310SBarry Smith #endif
468381824310SBarry Smith 
468481824310SBarry Smith /* Change these macros so can be used in void function */
468581824310SBarry Smith #undef CHKERRQ
4686ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
468781824310SBarry Smith #undef SETERRQ2
4688e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
46894994cf47SJed Brown #undef SETERRQ3
46904994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
469181824310SBarry Smith 
469281824310SBarry Smith #undef __FUNCT__
469381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
46948cc058d9SJed 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)
469581824310SBarry Smith {
469681824310SBarry Smith   Mat            A  = *AA;
469781824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
469881824310SBarry Smith   InsertMode     is = *isis;
469981824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
470081824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
470181824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
470281824310SBarry Smith   PetscErrorCode ierr;
470381824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
470454f21887SBarry Smith   MatScalar      *ap,value,*aa;
4705ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4706ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
470781824310SBarry Smith 
470881824310SBarry Smith   PetscFunctionBegin;
47094994cf47SJed Brown   MatCheckPreallocated(A,1);
471081824310SBarry Smith   imax  = a->imax;
471181824310SBarry Smith   ai    = a->i;
471281824310SBarry Smith   ailen = a->ilen;
471381824310SBarry Smith   aj    = a->j;
471481824310SBarry Smith   aa    = a->a;
471581824310SBarry Smith 
471681824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
471781824310SBarry Smith     row = im[k];
471881824310SBarry Smith     if (row < 0) continue;
471981824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4720ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
472181824310SBarry Smith #endif
472281824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
472381824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
472481824310SBarry Smith     low  = 0;
472581824310SBarry Smith     high = nrow;
472681824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
472781824310SBarry Smith       if (in[l] < 0) continue;
472881824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4729ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
473081824310SBarry Smith #endif
473181824310SBarry Smith       col = in[l];
47322205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
47332205254eSKarl Rupp       else value = v[k + l*m];
47342205254eSKarl Rupp 
473581824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
473681824310SBarry Smith 
47372205254eSKarl Rupp       if (col <= lastcol) low = 0;
47382205254eSKarl Rupp       else high = nrow;
473981824310SBarry Smith       lastcol = col;
474081824310SBarry Smith       while (high-low > 5) {
474181824310SBarry Smith         t = (low+high)/2;
474281824310SBarry Smith         if (rp[t] > col) high = t;
474381824310SBarry Smith         else             low  = t;
474481824310SBarry Smith       }
474581824310SBarry Smith       for (i=low; i<high; i++) {
474681824310SBarry Smith         if (rp[i] > col) break;
474781824310SBarry Smith         if (rp[i] == col) {
474881824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
474981824310SBarry Smith           else                  ap[i] = value;
475081824310SBarry Smith           goto noinsert;
475181824310SBarry Smith         }
475281824310SBarry Smith       }
475381824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
475481824310SBarry Smith       if (nonew == 1) goto noinsert;
4755ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4756fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
475781824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
475881824310SBarry Smith       /* shift up all the later entries in this row */
475981824310SBarry Smith       for (ii=N; ii>=i; ii--) {
476081824310SBarry Smith         rp[ii+1] = rp[ii];
476181824310SBarry Smith         ap[ii+1] = ap[ii];
476281824310SBarry Smith       }
476381824310SBarry Smith       rp[i] = col;
476481824310SBarry Smith       ap[i] = value;
476581824310SBarry Smith noinsert:;
476681824310SBarry Smith       low = i + 1;
476781824310SBarry Smith     }
476881824310SBarry Smith     ailen[row] = nrow;
476981824310SBarry Smith   }
477081824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
477181824310SBarry Smith   PetscFunctionReturnVoid();
477281824310SBarry Smith }
47739f7953f8SBarry Smith 
477462298a1eSBarry Smith 
4775