xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
1d5d45c9bSBarry Smith /*
23369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
3d5d45c9bSBarry Smith   matrix storage format.
4d5d45c9bSBarry Smith */
53369ce9aSBarry Smith 
6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8c6db04a5SJed Brown #include <petscbt.h>
9af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h>
100716a85fSBarry Smith 
114099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A)
124099cc6bSBarry Smith {
134099cc6bSBarry Smith   PetscErrorCode       ierr;
144099cc6bSBarry Smith   PetscBool            flg;
154099cc6bSBarry Smith   char                 type[256];
164099cc6bSBarry Smith 
174099cc6bSBarry Smith   PetscFunctionBegin;
181e1ea65dSPierre Jolivet   ierr = PetscObjectOptionsBegin((PetscObject)A);CHKERRQ(ierr);
194099cc6bSBarry Smith   ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr);
204099cc6bSBarry Smith   if (flg) {
214099cc6bSBarry Smith     ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr);
224099cc6bSBarry Smith   }
234099cc6bSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
244099cc6bSBarry Smith   PetscFunctionReturn(0);
254099cc6bSBarry Smith }
264099cc6bSBarry Smith 
27857cbf51SRichard Tran Mills PetscErrorCode MatGetColumnReductions_SeqAIJ(Mat A,PetscInt type,PetscReal *reductions)
280716a85fSBarry Smith {
290716a85fSBarry Smith   PetscErrorCode ierr;
300716a85fSBarry Smith   PetscInt       i,m,n;
310716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
320716a85fSBarry Smith 
330716a85fSBarry Smith   PetscFunctionBegin;
340716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
35a873a8cdSSam Reynolds   ierr = PetscArrayzero(reductions,n);CHKERRQ(ierr);
360716a85fSBarry Smith   if (type == NORM_2) {
370716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
38a873a8cdSSam Reynolds       reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
390716a85fSBarry Smith     }
400716a85fSBarry Smith   } else if (type == NORM_1) {
410716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
42a873a8cdSSam Reynolds       reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]);
430716a85fSBarry Smith     }
440716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
450716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
46a873a8cdSSam Reynolds       reductions[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),reductions[aij->j[i]]);
470716a85fSBarry Smith     }
48857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
49a873a8cdSSam Reynolds     for (i=0; i<aij->i[m]; i++) {
50857cbf51SRichard Tran Mills       reductions[aij->j[i]] += PetscRealPart(aij->a[i]);
51a873a8cdSSam Reynolds     }
52857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
53857cbf51SRichard Tran Mills     for (i=0; i<aij->i[m]; i++) {
54857cbf51SRichard Tran Mills       reductions[aij->j[i]] += PetscImaginaryPart(aij->a[i]);
55857cbf51SRichard Tran Mills     }
56857cbf51SRichard Tran Mills   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown reduction type");
570716a85fSBarry Smith 
580716a85fSBarry Smith   if (type == NORM_2) {
59a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
60857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
61a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
620716a85fSBarry Smith   }
630716a85fSBarry Smith   PetscFunctionReturn(0);
640716a85fSBarry Smith }
650716a85fSBarry Smith 
663a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is)
673a062f41SBarry Smith {
683a062f41SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
693a062f41SBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs;
703a062f41SBarry Smith   const PetscInt  *jj = a->j,*ii = a->i;
713a062f41SBarry Smith   PetscInt        *rows;
723a062f41SBarry Smith   PetscErrorCode  ierr;
733a062f41SBarry Smith 
743a062f41SBarry Smith   PetscFunctionBegin;
753a062f41SBarry Smith   for (i=0; i<m; i++) {
763a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
773a062f41SBarry Smith       cnt++;
783a062f41SBarry Smith     }
793a062f41SBarry Smith   }
803a062f41SBarry Smith   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
813a062f41SBarry Smith   cnt  = 0;
823a062f41SBarry Smith   for (i=0; i<m; i++) {
833a062f41SBarry Smith     if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) {
843a062f41SBarry Smith       rows[cnt] = i;
853a062f41SBarry Smith       cnt++;
863a062f41SBarry Smith     }
873a062f41SBarry Smith   }
883a062f41SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
893a062f41SBarry Smith   PetscFunctionReturn(0);
903a062f41SBarry Smith }
913a062f41SBarry Smith 
92f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
936ce1633cSBarry Smith {
946ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
95fff043a9SJunchao Zhang   const MatScalar *aa;
966ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
97b2db7409Sstefano_zampini   const PetscInt  *ii = a->i,*jj = a->j,*diag;
986ce1633cSBarry Smith   PetscInt        *rows;
996ce1633cSBarry Smith   PetscErrorCode  ierr;
1006ce1633cSBarry Smith 
1016ce1633cSBarry Smith   PetscFunctionBegin;
102fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
1036ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1046ce1633cSBarry Smith   diag = a->diag;
1056ce1633cSBarry Smith   for (i=0; i<m; i++) {
106b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
1076ce1633cSBarry Smith       cnt++;
1086ce1633cSBarry Smith     }
1096ce1633cSBarry Smith   }
110785e854fSJed Brown   ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr);
1116ce1633cSBarry Smith   cnt  = 0;
1126ce1633cSBarry Smith   for (i=0; i<m; i++) {
113b2db7409Sstefano_zampini     if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
1146ce1633cSBarry Smith       rows[cnt++] = i;
1156ce1633cSBarry Smith     }
1166ce1633cSBarry Smith   }
117f1f41ecbSJed Brown   *nrows = cnt;
118f1f41ecbSJed Brown   *zrows = rows;
119fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
120f1f41ecbSJed Brown   PetscFunctionReturn(0);
121f1f41ecbSJed Brown }
122f1f41ecbSJed Brown 
123f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
124f1f41ecbSJed Brown {
125f1f41ecbSJed Brown   PetscInt       nrows,*rows;
126f1f41ecbSJed Brown   PetscErrorCode ierr;
127f1f41ecbSJed Brown 
128f1f41ecbSJed Brown   PetscFunctionBegin;
1290298fd71SBarry Smith   *zrows = NULL;
130f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
131ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
1326ce1633cSBarry Smith   PetscFunctionReturn(0);
1336ce1633cSBarry Smith }
1346ce1633cSBarry Smith 
135b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
136b3a44c85SBarry Smith {
137b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
138b3a44c85SBarry Smith   const MatScalar *aa;
139b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
140b3a44c85SBarry Smith   const PetscInt  *ii;
141b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
142b3a44c85SBarry Smith   PetscErrorCode  ierr;
143b3a44c85SBarry Smith 
144b3a44c85SBarry Smith   PetscFunctionBegin;
1452e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
146f4259b30SLisandro Dalcin   *keptrows = NULL;
147b3a44c85SBarry Smith   ii        = a->i;
148b3a44c85SBarry Smith   for (i=0; i<m; i++) {
149b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
150b3a44c85SBarry Smith     if (!n) {
151b3a44c85SBarry Smith       cnt++;
152b3a44c85SBarry Smith       goto ok1;
153b3a44c85SBarry Smith     }
1542e5835c6SStefano Zampini     for (j=ii[i]; j<ii[i+1]; j++) {
155b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
156b3a44c85SBarry Smith     }
157b3a44c85SBarry Smith     cnt++;
158b3a44c85SBarry Smith ok1:;
159b3a44c85SBarry Smith   }
1602e5835c6SStefano Zampini   if (!cnt) {
1612e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
1622e5835c6SStefano Zampini     PetscFunctionReturn(0);
1632e5835c6SStefano Zampini   }
164854ce69bSBarry Smith   ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr);
165b3a44c85SBarry Smith   cnt  = 0;
166b3a44c85SBarry Smith   for (i=0; i<m; i++) {
167b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
168b3a44c85SBarry Smith     if (!n) continue;
1692e5835c6SStefano Zampini     for (j=ii[i]; j<ii[i+1]; j++) {
170b3a44c85SBarry Smith       if (aa[j] != 0.0) {
171b3a44c85SBarry Smith         rows[cnt++] = i;
172b3a44c85SBarry Smith         break;
173b3a44c85SBarry Smith       }
174b3a44c85SBarry Smith     }
175b3a44c85SBarry Smith   }
1762e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
177b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
178b3a44c85SBarry Smith   PetscFunctionReturn(0);
179b3a44c85SBarry Smith }
180b3a44c85SBarry Smith 
1817087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
18279299369SBarry Smith {
18379299369SBarry Smith   PetscErrorCode    ierr;
18479299369SBarry Smith   Mat_SeqAIJ        *aij = (Mat_SeqAIJ*) Y->data;
18599e65526SBarry Smith   PetscInt          i,m = Y->rmap->n;
18699e65526SBarry Smith   const PetscInt    *diag;
1872e5835c6SStefano Zampini   MatScalar         *aa;
18899e65526SBarry Smith   const PetscScalar *v;
189ace3abfcSBarry Smith   PetscBool         missing;
19079299369SBarry Smith 
19179299369SBarry Smith   PetscFunctionBegin;
19209f38230SBarry Smith   if (Y->assembled) {
1930298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
19409f38230SBarry Smith     if (!missing) {
19579299369SBarry Smith       diag = aij->diag;
19699e65526SBarry Smith       ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr);
1972e5835c6SStefano Zampini       ierr = MatSeqAIJGetArray(Y,&aa);CHKERRQ(ierr);
19879299369SBarry Smith       if (is == INSERT_VALUES) {
19979299369SBarry Smith         for (i=0; i<m; i++) {
20079299369SBarry Smith           aa[diag[i]] = v[i];
20179299369SBarry Smith         }
20279299369SBarry Smith       } else {
20379299369SBarry Smith         for (i=0; i<m; i++) {
20479299369SBarry Smith           aa[diag[i]] += v[i];
20579299369SBarry Smith         }
20679299369SBarry Smith       }
2072e5835c6SStefano Zampini       ierr = MatSeqAIJRestoreArray(Y,&aa);CHKERRQ(ierr);
20899e65526SBarry Smith       ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr);
20979299369SBarry Smith       PetscFunctionReturn(0);
21079299369SBarry Smith     }
211acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
21209f38230SBarry Smith   }
21309f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
21409f38230SBarry Smith   PetscFunctionReturn(0);
21509f38230SBarry Smith }
21679299369SBarry Smith 
2171a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
21817ab2063SBarry Smith {
219416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
220dfbe8321SBarry Smith   PetscErrorCode ierr;
22197f1f81fSBarry Smith   PetscInt       i,ishift;
22217ab2063SBarry Smith 
2233a40ed3dSBarry Smith   PetscFunctionBegin;
224d0f46423SBarry Smith   *m = A->rmap->n;
2253a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
226bfeeae90SHong Zhang   ishift = 0;
22753e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
2282462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
229bfeeae90SHong Zhang   } else if (oshift == 1) {
2301a83f524SJed Brown     PetscInt *tia;
231d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
2323b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
233854ce69bSBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr);
2341a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
2351a83f524SJed Brown     *ia = tia;
236ecc77c7aSBarry Smith     if (ja) {
2371a83f524SJed Brown       PetscInt *tja;
238854ce69bSBarry Smith       ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr);
2391a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
2401a83f524SJed Brown       *ja = tja;
241ecc77c7aSBarry Smith     }
2426945ee14SBarry Smith   } else {
243ecc77c7aSBarry Smith     *ia = a->i;
244ecc77c7aSBarry Smith     if (ja) *ja = a->j;
245a2ce50c7SBarry Smith   }
2463a40ed3dSBarry Smith   PetscFunctionReturn(0);
247a2744918SBarry Smith }
248a2744918SBarry Smith 
2491a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2506945ee14SBarry Smith {
251dfbe8321SBarry Smith   PetscErrorCode ierr;
2526945ee14SBarry Smith 
2533a40ed3dSBarry Smith   PetscFunctionBegin;
2543a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
255bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
256606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
257ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
258bcd2baecSBarry Smith   }
2593a40ed3dSBarry Smith   PetscFunctionReturn(0);
26017ab2063SBarry Smith }
26117ab2063SBarry Smith 
2621a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2633b2fbd54SBarry Smith {
2643b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
265dfbe8321SBarry Smith   PetscErrorCode ierr;
266d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
26797f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2683b2fbd54SBarry Smith 
2693a40ed3dSBarry Smith   PetscFunctionBegin;
270899cda47SBarry Smith   *nn = n;
2713a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2723b2fbd54SBarry Smith   if (symmetric) {
2732462f5fdSStefano Zampini     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2743b2fbd54SBarry Smith   } else {
275b9e7e5c1SBarry Smith     ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr);
276854ce69bSBarry Smith     ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
277b9e7e5c1SBarry Smith     ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr);
2783b2fbd54SBarry Smith     jj   = a->j;
2793b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
280bfeeae90SHong Zhang       collengths[jj[i]]++;
2813b2fbd54SBarry Smith     }
2823b2fbd54SBarry Smith     cia[0] = oshift;
2833b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2843b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2853b2fbd54SBarry Smith     }
286580bdb30SBarry Smith     ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr);
2873b2fbd54SBarry Smith     jj   = a->j;
288a93ec695SBarry Smith     for (row=0; row<m; row++) {
289a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
290a93ec695SBarry Smith       for (i=0; i<mr; i++) {
291bfeeae90SHong Zhang         col = *jj++;
2922205254eSKarl Rupp 
2933b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2943b2fbd54SBarry Smith       }
2953b2fbd54SBarry Smith     }
296606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2973b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2983b2fbd54SBarry Smith   }
2993a40ed3dSBarry Smith   PetscFunctionReturn(0);
3003b2fbd54SBarry Smith }
3013b2fbd54SBarry Smith 
3021a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
3033b2fbd54SBarry Smith {
304dfbe8321SBarry Smith   PetscErrorCode ierr;
305606d414cSSatish Balay 
3063a40ed3dSBarry Smith   PetscFunctionBegin;
3073a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
3083b2fbd54SBarry Smith 
309606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
310606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
3113a40ed3dSBarry Smith   PetscFunctionReturn(0);
3123b2fbd54SBarry Smith }
3133b2fbd54SBarry Smith 
3147cee066cSHong Zhang /*
3157cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
3167cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
317040ebd07SHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ()
3187cee066cSHong Zhang */
3197cee066cSHong 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)
3207cee066cSHong Zhang {
3217cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3227cee066cSHong Zhang   PetscErrorCode ierr;
3237cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
324071fcb05SBarry Smith   PetscInt       nz = a->i[m],row,mr,col,tmp;
3257cee066cSHong Zhang   PetscInt       *cspidx;
326071fcb05SBarry Smith   const PetscInt *jj;
3277cee066cSHong Zhang 
3287cee066cSHong Zhang   PetscFunctionBegin;
3297cee066cSHong Zhang   *nn = n;
3307cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
331625f6d37SHong Zhang 
332b9e7e5c1SBarry Smith   ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr);
333854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr);
334b9e7e5c1SBarry Smith   ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr);
335b9e7e5c1SBarry Smith   ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr);
3367cee066cSHong Zhang   jj   = a->j;
3377cee066cSHong Zhang   for (i=0; i<nz; i++) {
3387cee066cSHong Zhang     collengths[jj[i]]++;
3397cee066cSHong Zhang   }
3407cee066cSHong Zhang   cia[0] = oshift;
3417cee066cSHong Zhang   for (i=0; i<n; i++) {
3427cee066cSHong Zhang     cia[i+1] = cia[i] + collengths[i];
3437cee066cSHong Zhang   }
344580bdb30SBarry Smith   ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr);
3457cee066cSHong Zhang   jj   = a->j;
3467cee066cSHong Zhang   for (row=0; row<m; row++) {
3477cee066cSHong Zhang     mr = a->i[row+1] - a->i[row];
3487cee066cSHong Zhang     for (i=0; i<mr; i++) {
3497cee066cSHong Zhang       col         = *jj++;
350071fcb05SBarry Smith       tmp         = cia[col] + collengths[col]++ - oshift;
351071fcb05SBarry Smith       cspidx[tmp] = a->i[row] + i; /* index of a->j */
352071fcb05SBarry Smith       cja[tmp]    = row + oshift;
3537cee066cSHong Zhang     }
3547cee066cSHong Zhang   }
3557cee066cSHong Zhang   ierr   = PetscFree(collengths);CHKERRQ(ierr);
356071fcb05SBarry Smith   *ia    = cia;
357071fcb05SBarry Smith   *ja    = cja;
3587cee066cSHong Zhang   *spidx = cspidx;
3597cee066cSHong Zhang   PetscFunctionReturn(0);
3607cee066cSHong Zhang }
3617cee066cSHong Zhang 
3627cee066cSHong 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)
3637cee066cSHong Zhang {
3647cee066cSHong Zhang   PetscErrorCode ierr;
3657cee066cSHong Zhang 
3667cee066cSHong Zhang   PetscFunctionBegin;
3675243ef75SHong Zhang   ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
3687cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
3697cee066cSHong Zhang   PetscFunctionReturn(0);
3707cee066cSHong Zhang }
3717cee066cSHong Zhang 
37287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
37387d4246cSBarry Smith {
37487d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
37587d4246cSBarry Smith   PetscInt       *ai = a->i;
376fff043a9SJunchao Zhang   PetscScalar    *aa;
37787d4246cSBarry Smith   PetscErrorCode ierr;
37887d4246cSBarry Smith 
37987d4246cSBarry Smith   PetscFunctionBegin;
380fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
381fff043a9SJunchao Zhang   ierr = PetscArraycpy(aa+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr);
382fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
38387d4246cSBarry Smith   PetscFunctionReturn(0);
38487d4246cSBarry Smith }
38587d4246cSBarry Smith 
386bd04181cSBarry Smith /*
387bd04181cSBarry Smith     MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions
388bd04181cSBarry Smith 
389bd04181cSBarry Smith       -   a single row of values is set with each call
390bd04181cSBarry Smith       -   no row or column indices are negative or (in error) larger than the number of rows or columns
391bd04181cSBarry Smith       -   the values are always added to the matrix, not set
392bd04181cSBarry Smith       -   no new locations are introduced in the nonzero structure of the matrix
393bd04181cSBarry Smith 
3941f763a69SBarry Smith      This does NOT assume the global column indices are sorted
395bd04181cSBarry Smith 
3961f763a69SBarry Smith */
397bd04181cSBarry Smith 
398af0996ceSBarry Smith #include <petsc/private/isimpl.h>
399189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
400189e4007SBarry Smith {
401fff043a9SJunchao Zhang   PetscErrorCode ierr;
402189e4007SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4031f763a69SBarry Smith   PetscInt       low,high,t,row,nrow,i,col,l;
4041f763a69SBarry Smith   const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j;
4051f763a69SBarry Smith   PetscInt       lastcol = -1;
406fff043a9SJunchao Zhang   MatScalar      *ap,value,*aa;
407189e4007SBarry Smith   const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices;
408189e4007SBarry Smith 
409fff043a9SJunchao Zhang   PetscFunctionBegin;
410fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
411f38dd0b8SBarry Smith   row  = ridx[im[0]];
4121f763a69SBarry Smith   rp   = aj + ai[row];
4131f763a69SBarry Smith   ap   = aa + ai[row];
4141f763a69SBarry Smith   nrow = ailen[row];
415189e4007SBarry Smith   low  = 0;
416189e4007SBarry Smith   high = nrow;
417189e4007SBarry Smith   for (l=0; l<n; l++) { /* loop over added columns */
418189e4007SBarry Smith     col = cidx[in[l]];
419f38dd0b8SBarry Smith     value = v[l];
420189e4007SBarry Smith 
421189e4007SBarry Smith     if (col <= lastcol) low = 0;
422189e4007SBarry Smith     else high = nrow;
423189e4007SBarry Smith     lastcol = col;
424189e4007SBarry Smith     while (high-low > 5) {
425189e4007SBarry Smith       t = (low+high)/2;
426189e4007SBarry Smith       if (rp[t] > col) high = t;
427189e4007SBarry Smith       else low = t;
428189e4007SBarry Smith     }
429189e4007SBarry Smith     for (i=low; i<high; i++) {
430189e4007SBarry Smith       if (rp[i] == col) {
4311f763a69SBarry Smith         ap[i] += value;
432189e4007SBarry Smith         low = i + 1;
4331f763a69SBarry Smith         break;
434189e4007SBarry Smith       }
435189e4007SBarry Smith     }
436189e4007SBarry Smith   }
437fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
438f38dd0b8SBarry Smith   return 0;
439189e4007SBarry Smith }
440189e4007SBarry Smith 
44197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
44217ab2063SBarry Smith {
443fff043a9SJunchao Zhang   PetscErrorCode ierr;
444416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
445e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
44697f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
447e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
448ce496241SStefano Zampini   MatScalar      *ap=NULL,value=0.0,*aa;
449ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
450ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
45117ab2063SBarry Smith 
4523a40ed3dSBarry Smith   PetscFunctionBegin;
453fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
45417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
455416022c9SBarry Smith     row = im[k];
4565ef9f2a5SBarry Smith     if (row < 0) continue;
457*2c71b3e2SJacob Faibussowitsch     PetscAssertFalse(row >= A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,row,A->rmap->n-1);
458720833daSHong Zhang     rp   = aj + ai[row];
459876c6284SHong Zhang     if (!A->structure_only) ap = aa + ai[row];
46017ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
461416022c9SBarry Smith     low  = 0;
462c71e6ed7SBarry Smith     high = nrow;
46317ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
4645ef9f2a5SBarry Smith       if (in[l] < 0) continue;
465*2c71b3e2SJacob Faibussowitsch       PetscAssertFalse(in[l] >= A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,in[l],A->cmap->n-1);
466bfeeae90SHong Zhang       col = in[l];
467071fcb05SBarry Smith       if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m];
468071fcb05SBarry Smith       if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue;
46936db0b34SBarry Smith 
4702205254eSKarl Rupp       if (col <= lastcol) low = 0;
4712205254eSKarl Rupp       else high = nrow;
472e2ee6c50SBarry Smith       lastcol = col;
473416022c9SBarry Smith       while (high-low > 5) {
474416022c9SBarry Smith         t = (low+high)/2;
475416022c9SBarry Smith         if (rp[t] > col) high = t;
476416022c9SBarry Smith         else low = t;
47717ab2063SBarry Smith       }
478416022c9SBarry Smith       for (i=low; i<high; i++) {
47917ab2063SBarry Smith         if (rp[i] > col) break;
48017ab2063SBarry Smith         if (rp[i] == col) {
481876c6284SHong Zhang           if (!A->structure_only) {
4820c0d7e18SFande Kong             if (is == ADD_VALUES) {
4830c0d7e18SFande Kong               ap[i] += value;
4840c0d7e18SFande Kong               (void)PetscLogFlops(1.0);
4850c0d7e18SFande Kong             }
48617ab2063SBarry Smith             else ap[i] = value;
487720833daSHong Zhang           }
488e44c0bd4SBarry Smith           low = i + 1;
48917ab2063SBarry Smith           goto noinsert;
49017ab2063SBarry Smith         }
49117ab2063SBarry Smith       }
492dcd36c23SBarry Smith       if (value == 0.0 && ignorezeroentries && row != col) goto noinsert;
493c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
494*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(nonew == -1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%" PetscInt_FMT ",%" PetscInt_FMT ") in the matrix",row,col);
495720833daSHong Zhang       if (A->structure_only) {
496876c6284SHong Zhang         MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar);
497720833daSHong Zhang       } else {
498fef13f97SBarry Smith         MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
499720833daSHong Zhang       }
500c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
501416022c9SBarry Smith       /* shift up all the later entries in this row */
502580bdb30SBarry Smith       ierr  = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr);
50317ab2063SBarry Smith       rp[i] = col;
504580bdb30SBarry Smith       if (!A->structure_only) {
505580bdb30SBarry Smith         ierr  = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr);
506580bdb30SBarry Smith         ap[i] = value;
507580bdb30SBarry Smith       }
508416022c9SBarry Smith       low = i + 1;
509e56f5c9eSBarry Smith       A->nonzerostate++;
510e44c0bd4SBarry Smith noinsert:;
51117ab2063SBarry Smith     }
51217ab2063SBarry Smith     ailen[row] = nrow;
51317ab2063SBarry Smith   }
514fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
5153a40ed3dSBarry Smith   PetscFunctionReturn(0);
51617ab2063SBarry Smith }
51717ab2063SBarry Smith 
51819b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
51919b08ed1SBarry Smith {
52019b08ed1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
52119b08ed1SBarry Smith   PetscInt       *rp,k,row;
52219b08ed1SBarry Smith   PetscInt       *ai = a->i;
52319b08ed1SBarry Smith   PetscErrorCode ierr;
52419b08ed1SBarry Smith   PetscInt       *aj = a->j;
525fff043a9SJunchao Zhang   MatScalar      *aa,*ap;
52619b08ed1SBarry Smith 
52719b08ed1SBarry Smith   PetscFunctionBegin;
528*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->was_assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix.");
529*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(m*n+a->nz > a->maxnz,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of entries in matrix will be larger than maximum nonzeros allocated for %" PetscInt_FMT " in MatSeqAIJSetTotalPreallocation()",a->maxnz);
530fff043a9SJunchao Zhang 
531fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
53219b08ed1SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
53319b08ed1SBarry Smith     row  = im[k];
53419b08ed1SBarry Smith     rp   = aj + ai[row];
53519b08ed1SBarry Smith     ap   = aa + ai[row];
53619b08ed1SBarry Smith 
53719b08ed1SBarry Smith     ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr);
53819b08ed1SBarry Smith     if (!A->structure_only) {
53919b08ed1SBarry Smith       if (v) {
54019b08ed1SBarry Smith         ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr);
54119b08ed1SBarry Smith         v   += n;
54219b08ed1SBarry Smith       } else {
54319b08ed1SBarry Smith         ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr);
54419b08ed1SBarry Smith       }
54519b08ed1SBarry Smith     }
54619b08ed1SBarry Smith     a->ilen[row] = n;
54719b08ed1SBarry Smith     a->imax[row] = n;
54819b08ed1SBarry Smith     a->i[row+1]  = a->i[row]+n;
54919b08ed1SBarry Smith     a->nz       += n;
55019b08ed1SBarry Smith   }
551fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
55219b08ed1SBarry Smith   PetscFunctionReturn(0);
55319b08ed1SBarry Smith }
55419b08ed1SBarry Smith 
55519b08ed1SBarry Smith /*@
55619b08ed1SBarry Smith     MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix.
55719b08ed1SBarry Smith 
55819b08ed1SBarry Smith   Input Parameters:
55919b08ed1SBarry Smith +  A - the SeqAIJ matrix
56019b08ed1SBarry Smith -  nztotal - bound on the number of nonzeros
56119b08ed1SBarry Smith 
56219b08ed1SBarry Smith   Level: advanced
56319b08ed1SBarry Smith 
56419b08ed1SBarry Smith   Notes:
56519b08ed1SBarry Smith     This can be called if you will be provided the matrix row by row (from row zero) with sorted column indices for each row.
56619b08ed1SBarry Smith     Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used
56719b08ed1SBarry Smith     as always with multiple matrix assemblies.
56819b08ed1SBarry Smith 
56919b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation()
57019b08ed1SBarry Smith @*/
57119b08ed1SBarry Smith 
57219b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal)
57319b08ed1SBarry Smith {
57419b08ed1SBarry Smith   PetscErrorCode ierr;
57519b08ed1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
57619b08ed1SBarry Smith 
57719b08ed1SBarry Smith   PetscFunctionBegin;
57819b08ed1SBarry Smith   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
57919b08ed1SBarry Smith   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
58019b08ed1SBarry Smith   a->maxnz  = nztotal;
58119b08ed1SBarry Smith   if (!a->imax) {
58219b08ed1SBarry Smith     ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr);
58319b08ed1SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
58419b08ed1SBarry Smith   }
58519b08ed1SBarry Smith   if (!a->ilen) {
58619b08ed1SBarry Smith     ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr);
58719b08ed1SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
58819b08ed1SBarry Smith   } else {
58919b08ed1SBarry Smith     ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
59019b08ed1SBarry Smith   }
59119b08ed1SBarry Smith 
59219b08ed1SBarry Smith   /* allocate the matrix space */
59319b08ed1SBarry Smith   if (A->structure_only) {
59419b08ed1SBarry Smith     ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr);
59519b08ed1SBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr);
59619b08ed1SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr);
59719b08ed1SBarry Smith   } else {
59819b08ed1SBarry Smith     ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr);
59919b08ed1SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
60019b08ed1SBarry Smith   }
60119b08ed1SBarry Smith   a->i[0] = 0;
60219b08ed1SBarry Smith   if (A->structure_only) {
60319b08ed1SBarry Smith     a->singlemalloc = PETSC_FALSE;
60419b08ed1SBarry Smith     a->free_a       = PETSC_FALSE;
60519b08ed1SBarry Smith   } else {
60619b08ed1SBarry Smith     a->singlemalloc = PETSC_TRUE;
60719b08ed1SBarry Smith     a->free_a       = PETSC_TRUE;
60819b08ed1SBarry Smith   }
60919b08ed1SBarry Smith   a->free_ij         = PETSC_TRUE;
61019b08ed1SBarry Smith   A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation;
61119b08ed1SBarry Smith   A->preallocated   = PETSC_TRUE;
61219b08ed1SBarry Smith   PetscFunctionReturn(0);
61319b08ed1SBarry Smith }
61419b08ed1SBarry Smith 
615071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
616071fcb05SBarry Smith {
617071fcb05SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
618071fcb05SBarry Smith   PetscInt       *rp,k,row;
619071fcb05SBarry Smith   PetscInt       *ai = a->i,*ailen = a->ilen;
620071fcb05SBarry Smith   PetscErrorCode ierr;
621071fcb05SBarry Smith   PetscInt       *aj = a->j;
622fff043a9SJunchao Zhang   MatScalar      *aa,*ap;
623071fcb05SBarry Smith 
624071fcb05SBarry Smith   PetscFunctionBegin;
625fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
626071fcb05SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
627071fcb05SBarry Smith     row  = im[k];
628*2c71b3e2SJacob Faibussowitsch     PetscAssertFalse(n > a->imax[row],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Preallocation for row %" PetscInt_FMT " does not match number of columns provided",n);
629071fcb05SBarry Smith     rp   = aj + ai[row];
630071fcb05SBarry Smith     ap   = aa + ai[row];
631071fcb05SBarry Smith     if (!A->was_assembled) {
632071fcb05SBarry Smith       ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr);
633071fcb05SBarry Smith     }
634071fcb05SBarry Smith     if (!A->structure_only) {
635071fcb05SBarry Smith       if (v) {
636071fcb05SBarry Smith         ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr);
637071fcb05SBarry Smith         v   += n;
638071fcb05SBarry Smith       } else {
639071fcb05SBarry Smith         ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr);
640071fcb05SBarry Smith       }
641071fcb05SBarry Smith     }
642071fcb05SBarry Smith     ailen[row] = n;
643071fcb05SBarry Smith     a->nz      += n;
644071fcb05SBarry Smith   }
645fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
646071fcb05SBarry Smith   PetscFunctionReturn(0);
647071fcb05SBarry Smith }
648071fcb05SBarry Smith 
649a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
6507eb43aa7SLois Curfman McInnes {
651fff043a9SJunchao Zhang   PetscErrorCode ierr;
6527eb43aa7SLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
65397f1f81fSBarry Smith   PetscInt       *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
65497f1f81fSBarry Smith   PetscInt       *ai = a->i,*ailen = a->ilen;
655fff043a9SJunchao Zhang   MatScalar      *ap,*aa;
6567eb43aa7SLois Curfman McInnes 
6573a40ed3dSBarry Smith   PetscFunctionBegin;
658fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
6597eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
6607eb43aa7SLois Curfman McInnes     row = im[k];
66198921bdaSJacob Faibussowitsch     if (row < 0) {v += n; continue;} /* SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %" PetscInt_FMT,row); */
662*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(row >= A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,row,A->rmap->n-1);
663bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
6647eb43aa7SLois Curfman McInnes     nrow = ailen[row];
6657eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
66698921bdaSJacob Faibussowitsch       if (in[l] < 0) {v++; continue;} /* SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %" PetscInt_FMT,in[l]); */
667*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(in[l] >= A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,in[l],A->cmap->n-1);
668bfeeae90SHong Zhang       col  = in[l];
6697eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
6707eb43aa7SLois Curfman McInnes       while (high-low > 5) {
6717eb43aa7SLois Curfman McInnes         t = (low+high)/2;
6727eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
6737eb43aa7SLois Curfman McInnes         else low = t;
6747eb43aa7SLois Curfman McInnes       }
6757eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
6767eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
6777eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
678b49de8d1SLois Curfman McInnes           *v++ = ap[i];
6797eb43aa7SLois Curfman McInnes           goto finished;
6807eb43aa7SLois Curfman McInnes         }
6817eb43aa7SLois Curfman McInnes       }
68297e567efSBarry Smith       *v++ = 0.0;
6837eb43aa7SLois Curfman McInnes finished:;
6847eb43aa7SLois Curfman McInnes     }
6857eb43aa7SLois Curfman McInnes   }
686fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
6873a40ed3dSBarry Smith   PetscFunctionReturn(0);
6887eb43aa7SLois Curfman McInnes }
6897eb43aa7SLois Curfman McInnes 
6903ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer)
69117ab2063SBarry Smith {
6923ea6fe3dSLisandro Dalcin   Mat_SeqAIJ        *A = (Mat_SeqAIJ*)mat->data;
693c898d852SStefano Zampini   const PetscScalar *av;
6943ea6fe3dSLisandro Dalcin   PetscInt          header[4],M,N,m,nz,i;
6953ea6fe3dSLisandro Dalcin   PetscInt          *rowlens;
6966849ba73SBarry Smith   PetscErrorCode    ierr;
69717ab2063SBarry Smith 
6983a40ed3dSBarry Smith   PetscFunctionBegin;
6993ea6fe3dSLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
7002205254eSKarl Rupp 
7013ea6fe3dSLisandro Dalcin   M  = mat->rmap->N;
7023ea6fe3dSLisandro Dalcin   N  = mat->cmap->N;
7033ea6fe3dSLisandro Dalcin   m  = mat->rmap->n;
7043ea6fe3dSLisandro Dalcin   nz = A->nz;
705416022c9SBarry Smith 
7063ea6fe3dSLisandro Dalcin   /* write matrix header */
7073ea6fe3dSLisandro Dalcin   header[0] = MAT_FILE_CLASSID;
7083ea6fe3dSLisandro Dalcin   header[1] = M; header[2] = N; header[3] = nz;
7093ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);
710416022c9SBarry Smith 
7113ea6fe3dSLisandro Dalcin   /* fill in and store row lengths */
7123ea6fe3dSLisandro Dalcin   ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr);
7133ea6fe3dSLisandro Dalcin   for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i];
7143ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr);
7153ea6fe3dSLisandro Dalcin   ierr = PetscFree(rowlens);CHKERRQ(ierr);
7163ea6fe3dSLisandro Dalcin   /* store column indices */
7173ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr);
718416022c9SBarry Smith   /* store nonzero values */
719c898d852SStefano Zampini   ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr);
720c898d852SStefano Zampini   ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr);
721c898d852SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr);
722b37d52dbSMark F. Adams 
7233ea6fe3dSLisandro Dalcin   /* write block size option to the viewer's .info file */
7243ea6fe3dSLisandro Dalcin   ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr);
7253a40ed3dSBarry Smith   PetscFunctionReturn(0);
72617ab2063SBarry Smith }
727416022c9SBarry Smith 
7287dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer)
7297dc0baabSHong Zhang {
7307dc0baabSHong Zhang   PetscErrorCode ierr;
7317dc0baabSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
7327dc0baabSHong Zhang   PetscInt       i,k,m=A->rmap->N;
7337dc0baabSHong Zhang 
7347dc0baabSHong Zhang   PetscFunctionBegin;
7357dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
7367dc0baabSHong Zhang   for (i=0; i<m; i++) {
737c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i);CHKERRQ(ierr);
7387dc0baabSHong Zhang     for (k=a->i[i]; k<a->i[i+1]; k++) {
739c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ") ",a->j[k]);CHKERRQ(ierr);
7407dc0baabSHong Zhang     }
7417dc0baabSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
7427dc0baabSHong Zhang   }
7437dc0baabSHong Zhang   ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
7447dc0baabSHong Zhang   PetscFunctionReturn(0);
7457dc0baabSHong Zhang }
7467dc0baabSHong Zhang 
74709573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
748cd155464SBarry Smith 
749dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
750416022c9SBarry Smith {
751416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
752c898d852SStefano Zampini   const PetscScalar *av;
753dfbe8321SBarry Smith   PetscErrorCode    ierr;
75460e0710aSBarry Smith   PetscInt          i,j,m = A->rmap->n;
755e060cb09SBarry Smith   const char        *name;
756f3ef73ceSBarry Smith   PetscViewerFormat format;
75717ab2063SBarry Smith 
7583a40ed3dSBarry Smith   PetscFunctionBegin;
7597dc0baabSHong Zhang   if (A->structure_only) {
7607dc0baabSHong Zhang     ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr);
7617dc0baabSHong Zhang     PetscFunctionReturn(0);
7627dc0baabSHong Zhang   }
76343e49210SHong Zhang 
764b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
7652e5835c6SStefano Zampini   if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0);
7662e5835c6SStefano Zampini 
767c898d852SStefano Zampini   /* trigger copy to CPU if needed */
768c898d852SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
769c898d852SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
77071c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
77197f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
77260e0710aSBarry Smith     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) {
773c337ccceSJed Brown       /* Need a dummy value to ensure the dimension of the matrix. */
774d00d2cf4SBarry Smith       nofinalvalue = 1;
775d00d2cf4SBarry Smith     }
776d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
777c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",m,A->cmap->n);CHKERRQ(ierr);
778c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %" PetscInt_FMT " \n",a->nz);CHKERRQ(ierr);
779fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX)
780c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%" PetscInt_FMT ",4);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
781fbfe6fa7SJed Brown #else
782c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%" PetscInt_FMT ",3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
783fbfe6fa7SJed Brown #endif
784b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
78517ab2063SBarry Smith 
78617ab2063SBarry Smith     for (i=0; i<m; i++) {
78760e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
788aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
789c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT "  %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
79017ab2063SBarry Smith #else
791c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT "  %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr);
79217ab2063SBarry Smith #endif
79317ab2063SBarry Smith       }
79417ab2063SBarry Smith     }
795d00d2cf4SBarry Smith     if (nofinalvalue) {
796c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX)
797c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT "  %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr);
798c337ccceSJed Brown #else
799c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT "  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
800c337ccceSJed Brown #endif
801d00d2cf4SBarry Smith     }
802317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
803fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
804d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
805fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
806d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
80744cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
808c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i);CHKERRQ(ierr);
80960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
810aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
81136db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
812c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
81336db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
814c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
81536db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
816c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
8176831982aSBarry Smith         }
81844cd7ae7SLois Curfman McInnes #else
819c0aa6a63SJacob Faibussowitsch         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);}
82044cd7ae7SLois Curfman McInnes #endif
82144cd7ae7SLois Curfman McInnes       }
822b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
82344cd7ae7SLois Curfman McInnes     }
824d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
825fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
82697f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
827d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
828854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr);
829496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
830496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
83160e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
832496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
833aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
83436db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
835496be53dSLois Curfman McInnes #else
836496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
837496be53dSLois Curfman McInnes #endif
838496be53dSLois Curfman McInnes         }
839496be53dSLois Curfman McInnes       }
840496be53dSLois Curfman McInnes     }
8412e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
842c0aa6a63SJacob Faibussowitsch     ierr    = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT "\n\n",m,nzd);CHKERRQ(ierr);
8432e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
8442205254eSKarl Rupp       if (i+4<m) {
845c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);
8462205254eSKarl Rupp       } else if (i+3<m) {
847c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);
8482205254eSKarl Rupp       } else if (i+2<m) {
849c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
8502205254eSKarl Rupp       } else if (i+1<m) {
851c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
8522205254eSKarl Rupp       } else if (i<m) {
853c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
8542205254eSKarl Rupp       } else {
855c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT "\n",sptr[i]);CHKERRQ(ierr);
8562205254eSKarl Rupp       }
857496be53dSLois Curfman McInnes     }
858b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
859606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
860496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
86160e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
862c0aa6a63SJacob Faibussowitsch         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " ",a->j[j]+fshift);CHKERRQ(ierr);}
863496be53dSLois Curfman McInnes       }
864b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
865496be53dSLois Curfman McInnes     }
866b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
867496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
86860e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
869496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
870aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
87136db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
87260e0710aSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
8736831982aSBarry Smith           }
874496be53dSLois Curfman McInnes #else
87560e0710aSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);}
876496be53dSLois Curfman McInnes #endif
877496be53dSLois Curfman McInnes         }
878496be53dSLois Curfman McInnes       }
879b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
880496be53dSLois Curfman McInnes     }
881d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
882fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
88397f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
88487828ca2SBarry Smith     PetscScalar value;
88568f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX)
88668f1ed48SBarry Smith     PetscBool   realonly = PETSC_TRUE;
88768f1ed48SBarry Smith 
88868f1ed48SBarry Smith     for (i=0; i<a->i[m]; i++) {
88968f1ed48SBarry Smith       if (PetscImaginaryPart(a->a[i]) != 0.0) {
89068f1ed48SBarry Smith         realonly = PETSC_FALSE;
89168f1ed48SBarry Smith         break;
89268f1ed48SBarry Smith       }
89368f1ed48SBarry Smith     }
89468f1ed48SBarry Smith #endif
89502594712SBarry Smith 
896d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
89702594712SBarry Smith     for (i=0; i<m; i++) {
89802594712SBarry Smith       jcnt = 0;
899d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
900e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
90102594712SBarry Smith           value = a->a[cnt++];
902e24b481bSBarry Smith           jcnt++;
90302594712SBarry Smith         } else {
90402594712SBarry Smith           value = 0.0;
90502594712SBarry Smith         }
906aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
90768f1ed48SBarry Smith         if (realonly) {
90860e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr);
90968f1ed48SBarry Smith         } else {
91060e0710aSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr);
91168f1ed48SBarry Smith         }
91202594712SBarry Smith #else
91360e0710aSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr);
91402594712SBarry Smith #endif
91502594712SBarry Smith       }
916b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
91702594712SBarry Smith     }
918d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
9193c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
920150b93efSMatthew G. Knepley     PetscInt fshift=1;
921d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
9223c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
92319303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr);
9243c215bfdSMatthew Knepley #else
92519303e72SJonathan Guyer     ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr);
9263c215bfdSMatthew Knepley #endif
927c0aa6a63SJacob Faibussowitsch     ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
9283c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
92960e0710aSBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
9303c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
931c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
9323c215bfdSMatthew Knepley #else
933c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr);
9343c215bfdSMatthew Knepley #endif
9353c215bfdSMatthew Knepley       }
9363c215bfdSMatthew Knepley     }
937d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
9383a40ed3dSBarry Smith   } else {
939d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
940d5f3da31SBarry Smith     if (A->factortype) {
94116cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
942c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i);CHKERRQ(ierr);
94316cd7e1dSShri Abhyankar         /* L part */
94460e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
94516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
94616cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
947c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
94816cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
949c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
95016cd7e1dSShri Abhyankar           } else {
951c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
95216cd7e1dSShri Abhyankar           }
95316cd7e1dSShri Abhyankar #else
954c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
95516cd7e1dSShri Abhyankar #endif
95616cd7e1dSShri Abhyankar         }
95716cd7e1dSShri Abhyankar         /* diagonal */
95816cd7e1dSShri Abhyankar         j = a->diag[i];
95916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
96016cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
961c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
96216cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
963c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr);
96416cd7e1dSShri Abhyankar         } else {
965c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
96616cd7e1dSShri Abhyankar         }
96716cd7e1dSShri Abhyankar #else
968c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr);
96916cd7e1dSShri Abhyankar #endif
97016cd7e1dSShri Abhyankar 
97116cd7e1dSShri Abhyankar         /* U part */
97260e0710aSBarry Smith         for (j=a->diag[i+1]+1; j<a->diag[i]; j++) {
97316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
97416cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
975c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
97616cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
977c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr);
97816cd7e1dSShri Abhyankar           } else {
979c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
98016cd7e1dSShri Abhyankar           }
98116cd7e1dSShri Abhyankar #else
982c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
98316cd7e1dSShri Abhyankar #endif
98416cd7e1dSShri Abhyankar         }
98516cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
98616cd7e1dSShri Abhyankar       }
98716cd7e1dSShri Abhyankar     } else {
98817ab2063SBarry Smith       for (i=0; i<m; i++) {
989c0aa6a63SJacob Faibussowitsch         ierr = PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i);CHKERRQ(ierr);
99060e0710aSBarry Smith         for (j=a->i[i]; j<a->i[i+1]; j++) {
991aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
99236db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
993c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
99436db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
995c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
9963a40ed3dSBarry Smith           } else {
997c0aa6a63SJacob Faibussowitsch             ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr);
99817ab2063SBarry Smith           }
99917ab2063SBarry Smith #else
1000c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);
100117ab2063SBarry Smith #endif
100217ab2063SBarry Smith         }
1003b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
100417ab2063SBarry Smith       }
100516cd7e1dSShri Abhyankar     }
1006d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
100717ab2063SBarry Smith   }
1008b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
10093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1010416022c9SBarry Smith }
1011416022c9SBarry Smith 
10129804daf3SBarry Smith #include <petscdraw.h>
1013dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
1014416022c9SBarry Smith {
1015480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
1016416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1017dfbe8321SBarry Smith   PetscErrorCode    ierr;
1018383922c3SLisandro Dalcin   PetscInt          i,j,m = A->rmap->n;
1019383922c3SLisandro Dalcin   int               color;
1020b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1021b0a32e0cSBarry Smith   PetscViewer       viewer;
1022f3ef73ceSBarry Smith   PetscViewerFormat format;
1023fff043a9SJunchao Zhang   const PetscScalar *aa;
1024cddf8d76SBarry Smith 
10253a40ed3dSBarry Smith   PetscFunctionBegin;
1026480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1027b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1028b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1029383922c3SLisandro Dalcin 
1030416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
1031fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
1032fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1033383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
10340513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
1035b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
1036416022c9SBarry Smith     for (i=0; i<m; i++) {
1037cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
1038bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
1039bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
1040fff043a9SJunchao Zhang         if (PetscRealPart(aa[j]) >=  0.) continue;
1041b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1042cddf8d76SBarry Smith       }
1043cddf8d76SBarry Smith     }
1044b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
1045cddf8d76SBarry Smith     for (i=0; i<m; i++) {
1046cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
1047bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
1048bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
1049fff043a9SJunchao Zhang         if (aa[j] !=  0.) continue;
1050b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1051cddf8d76SBarry Smith       }
1052cddf8d76SBarry Smith     }
1053b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
1054cddf8d76SBarry Smith     for (i=0; i<m; i++) {
1055cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
1056bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
1057bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
1058fff043a9SJunchao Zhang         if (PetscRealPart(aa[j]) <=  0.) continue;
1059b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1060416022c9SBarry Smith       }
1061416022c9SBarry Smith     }
1062383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
10630513a670SBarry Smith   } else {
10640513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
10650513a670SBarry Smith     /* first determine max of all nonzero values */
1066b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1067383922c3SLisandro Dalcin     PetscInt  nz = a->nz, count = 0;
1068b0a32e0cSBarry Smith     PetscDraw popup;
10690513a670SBarry Smith 
10700513a670SBarry Smith     for (i=0; i<nz; i++) {
1071fff043a9SJunchao Zhang       if (PetscAbsScalar(aa[i]) > maxv) maxv = PetscAbsScalar(aa[i]);
10720513a670SBarry Smith     }
1073383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1074b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
107545f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1076383922c3SLisandro Dalcin 
1077383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
10780513a670SBarry Smith     for (i=0; i<m; i++) {
1079383922c3SLisandro Dalcin       y_l = m - i - 1.0;
1080383922c3SLisandro Dalcin       y_r = y_l + 1.0;
1081bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
1082383922c3SLisandro Dalcin         x_l = a->j[j];
1083383922c3SLisandro Dalcin         x_r = x_l + 1.0;
1084fff043a9SJunchao Zhang         color = PetscDrawRealToColor(PetscAbsScalar(aa[count]),minv,maxv);
1085b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
10860513a670SBarry Smith         count++;
10870513a670SBarry Smith       }
10880513a670SBarry Smith     }
1089383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
10900513a670SBarry Smith   }
1091fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
1092480ef9eaSBarry Smith   PetscFunctionReturn(0);
1093480ef9eaSBarry Smith }
1094cddf8d76SBarry Smith 
10959804daf3SBarry Smith #include <petscdraw.h>
1096dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
1097480ef9eaSBarry Smith {
1098dfbe8321SBarry Smith   PetscErrorCode ierr;
1099b0a32e0cSBarry Smith   PetscDraw      draw;
110036db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1101ace3abfcSBarry Smith   PetscBool      isnull;
1102480ef9eaSBarry Smith 
1103480ef9eaSBarry Smith   PetscFunctionBegin;
1104b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1105b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1106480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
1107480ef9eaSBarry Smith 
1108d0f46423SBarry Smith   xr   = A->cmap->n; yr  = A->rmap->n; h = yr/10.0; w = xr/10.0;
1109480ef9eaSBarry Smith   xr  += w;          yr += h;         xl = -w;     yl = -h;
1110b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1111832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1112b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
11130298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1114832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
11153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1116416022c9SBarry Smith }
1117416022c9SBarry Smith 
1118dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
1119416022c9SBarry Smith {
1120dfbe8321SBarry Smith   PetscErrorCode ierr;
1121ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1122416022c9SBarry Smith 
11233a40ed3dSBarry Smith   PetscFunctionBegin;
1124251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1125251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1126251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1127c45a1595SBarry Smith   if (iascii) {
11283a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
11290f5bd95cSBarry Smith   } else if (isbinary) {
11303a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
11310f5bd95cSBarry Smith   } else if (isdraw) {
11323a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
113311aeaf0aSBarry Smith   }
11344108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
11353a40ed3dSBarry Smith   PetscFunctionReturn(0);
113617ab2063SBarry Smith }
113719bcc07fSBarry Smith 
1138dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
113917ab2063SBarry Smith {
1140416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11416849ba73SBarry Smith   PetscErrorCode ierr;
1142580bdb30SBarry Smith   PetscInt       fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax;
1143d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
114454f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
11453447b6efSHong Zhang   PetscReal      ratio  = 0.6;
114617ab2063SBarry Smith 
11473a40ed3dSBarry Smith   PetscFunctionBegin;
11483a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
1149071fcb05SBarry Smith   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
1150b215bc84SStefano Zampini   if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) {
1151b215bc84SStefano Zampini     /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */
1152b215bc84SStefano Zampini     ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
1153b215bc84SStefano Zampini     PetscFunctionReturn(0);
1154b215bc84SStefano Zampini   }
115517ab2063SBarry Smith 
115643ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
115717ab2063SBarry Smith   for (i=1; i<m; i++) {
1158416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
115917ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
116094a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
116117ab2063SBarry Smith     if (fshift) {
1162bfeeae90SHong Zhang       ip = aj + ai[i];
1163bfeeae90SHong Zhang       ap = aa + ai[i];
116417ab2063SBarry Smith       N  = ailen[i];
1165580bdb30SBarry Smith       ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr);
1166580bdb30SBarry Smith       if (!A->structure_only) {
1167580bdb30SBarry Smith         ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr);
116817ab2063SBarry Smith       }
116917ab2063SBarry Smith     }
117017ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
117117ab2063SBarry Smith   }
117217ab2063SBarry Smith   if (m) {
117317ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
117417ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
117517ab2063SBarry Smith   }
11767b083b7cSBarry Smith 
117717ab2063SBarry Smith   /* reset ilen and imax for each row */
11787b083b7cSBarry Smith   a->nonzerorowcnt = 0;
1179396832f4SHong Zhang   if (A->structure_only) {
1180071fcb05SBarry Smith     ierr = PetscFree(a->imax);CHKERRQ(ierr);
1181071fcb05SBarry Smith     ierr = PetscFree(a->ilen);CHKERRQ(ierr);
1182396832f4SHong Zhang   } else { /* !A->structure_only */
118317ab2063SBarry Smith     for (i=0; i<m; i++) {
118417ab2063SBarry Smith       ailen[i] = imax[i] = ai[i+1] - ai[i];
11857b083b7cSBarry Smith       a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0);
118617ab2063SBarry Smith     }
1187396832f4SHong Zhang   }
1188bfeeae90SHong Zhang   a->nz = ai[m];
1189*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(fshift && a->nounused == -1,PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %" PetscInt_FMT " X %" PetscInt_FMT ", %" PetscInt_FMT " unneeded", m, A->cmap->n, fshift);
119017ab2063SBarry Smith 
119109f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
11927d3de750SJacob Faibussowitsch   ierr = PetscInfo(A,"Matrix size: %" PetscInt_FMT " X %" PetscInt_FMT "; storage space: %" PetscInt_FMT " unneeded,%" PetscInt_FMT " used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr);
11937d3de750SJacob Faibussowitsch   ierr = PetscInfo(A,"Number of mallocs during MatSetValues() is %" PetscInt_FMT "\n",a->reallocs);CHKERRQ(ierr);
11947d3de750SJacob Faibussowitsch   ierr = PetscInfo(A,"Maximum nonzeros in any row is %" PetscInt_FMT "\n",rmax);CHKERRQ(ierr);
11952205254eSKarl Rupp 
11968e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
1197dd5f02e7SSatish Balay   a->reallocs         = 0;
11986712e2f1SBarry Smith   A->info.nz_unneeded = (PetscReal)fshift;
119936db0b34SBarry Smith   a->rmax             = rmax;
12004e220ebcSLois Curfman McInnes 
1201396832f4SHong Zhang   if (!A->structure_only) {
120211e456e1SBarry Smith     ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
1203396832f4SHong Zhang   }
12044108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
12053a40ed3dSBarry Smith   PetscFunctionReturn(0);
120617ab2063SBarry Smith }
120717ab2063SBarry Smith 
120899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
120999cafbc1SBarry Smith {
121099cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
121199cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
12122e5835c6SStefano Zampini   MatScalar      *aa;
1213acf2f550SJed Brown   PetscErrorCode ierr;
121499cafbc1SBarry Smith 
121599cafbc1SBarry Smith   PetscFunctionBegin;
12162e5835c6SStefano Zampini   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
121799cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
12182e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
1219acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
122099cafbc1SBarry Smith   PetscFunctionReturn(0);
122199cafbc1SBarry Smith }
122299cafbc1SBarry Smith 
122399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
122499cafbc1SBarry Smith {
122599cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
122699cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
12272e5835c6SStefano Zampini   MatScalar      *aa;
1228acf2f550SJed Brown   PetscErrorCode ierr;
122999cafbc1SBarry Smith 
123099cafbc1SBarry Smith   PetscFunctionBegin;
12312e5835c6SStefano Zampini   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
123299cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
12332e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
1234acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
123599cafbc1SBarry Smith   PetscFunctionReturn(0);
123699cafbc1SBarry Smith }
123799cafbc1SBarry Smith 
1238dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
123917ab2063SBarry Smith {
1240dfbe8321SBarry Smith   PetscErrorCode ierr;
1241fff043a9SJunchao Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1242fff043a9SJunchao Zhang   MatScalar      *aa;
12433a40ed3dSBarry Smith 
12443a40ed3dSBarry Smith   PetscFunctionBegin;
1245fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayWrite(A,&aa);CHKERRQ(ierr);
1246fff043a9SJunchao Zhang   ierr = PetscArrayzero(aa,a->i[A->rmap->n]);CHKERRQ(ierr);
1247fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayWrite(A,&aa);CHKERRQ(ierr);
1248acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
12493a40ed3dSBarry Smith   PetscFunctionReturn(0);
125017ab2063SBarry Smith }
1251416022c9SBarry Smith 
1252dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
125317ab2063SBarry Smith {
1254416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1255dfbe8321SBarry Smith   PetscErrorCode ierr;
1256d5d45c9bSBarry Smith 
12573a40ed3dSBarry Smith   PetscFunctionBegin;
1258aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1259c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)A,"Rows=%" PetscInt_FMT ", Cols=%" PetscInt_FMT ", NZ=%" PetscInt_FMT,A->rmap->n,A->cmap->n,a->nz);
126017ab2063SBarry Smith #endif
1261e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
12626bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
12636bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
126405b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1265d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
1266071fcb05SBarry Smith   ierr = PetscFree(a->imax);CHKERRQ(ierr);
1267071fcb05SBarry Smith   ierr = PetscFree(a->ilen);CHKERRQ(ierr);
1268846b4da1SFande Kong   ierr = PetscFree(a->ipre);CHKERRQ(ierr);
126971f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
127005b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
12716bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
127205b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
1273cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
1274a30b2313SHong Zhang 
12754108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1276bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1277901853e0SKris Buschelman 
12786718818eSStefano Zampini   /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this.
12796718818eSStefano Zampini      That function is so heavily used (sometimes in an hidden way through multnumeric function pointers)
12806718818eSStefano Zampini      that is hard to properly add this data to the MatProduct data. We free it here to avoid
12816718818eSStefano Zampini      users reusing the matrix object with different data to incur in obscure segmentation faults
12826718818eSStefano Zampini      due to different matrix sizes */
12836718818eSStefano Zampini   ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr);
12846718818eSStefano Zampini 
1285f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr);
1286bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1287bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1288bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1289bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1290bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1291bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
12924222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA)
12934222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr);
1294e6e9a74fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr);
1295fcdce8c4SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr);
12964222ddf1SHong Zhang #endif
12973d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS)
12983d0639e7SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr);
12993d0639e7SStefano Zampini #endif
13004222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr);
1301af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
1302af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr);
1303af8000cdSHong Zhang #endif
1304d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1305d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr);
1306d24d4204SJose E. Roman #endif
130763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
130863c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr);
13094222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
131063c07aadSStefano Zampini #endif
1311b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1312c9225affSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr);
1313c9225affSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr);
1314bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1315bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1316846b4da1SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr);
1317bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1318bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
13194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr);
13204222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
13214222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr);
1322ad7e164aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJKron_C",NULL);CHKERRQ(ierr);
13233a40ed3dSBarry Smith   PetscFunctionReturn(0);
132417ab2063SBarry Smith }
132517ab2063SBarry Smith 
1326ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
132717ab2063SBarry Smith {
1328416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
13294846f1f5SKris Buschelman   PetscErrorCode ierr;
13303a40ed3dSBarry Smith 
13313a40ed3dSBarry Smith   PetscFunctionBegin;
1332a65d3064SKris Buschelman   switch (op) {
1333a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
13344e0d8c25SBarry Smith     a->roworiented = flg;
1335a65d3064SKris Buschelman     break;
1336a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1337a9817697SBarry Smith     a->keepnonzeropattern = flg;
1338a65d3064SKris Buschelman     break;
1339512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1340512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1341a65d3064SKris Buschelman     break;
1342a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
13434e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1344a65d3064SKris Buschelman     break;
1345a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
13464e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1347a65d3064SKris Buschelman     break;
134828b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
134928b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
135028b2fa4aSMatthew Knepley     break;
1351a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
13524e0d8c25SBarry Smith     a->ignorezeroentries = flg;
13530df259c2SBarry Smith     break;
13543d472b54SHong Zhang   case MAT_SPD:
1355b1646e73SJed Brown   case MAT_SYMMETRIC:
1356b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1357b1646e73SJed Brown   case MAT_HERMITIAN:
1358b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
1359957cac9fSHong Zhang   case MAT_STRUCTURE_ONLY:
13605021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
13615021d80fSJed Brown     break;
13628c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
1363a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1364a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
13657d3de750SJacob Faibussowitsch     ierr = PetscInfo(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1366a65d3064SKris Buschelman     break;
1367b87ac2d8SJed Brown   case MAT_USE_INODES:
1368b215bc84SStefano Zampini     ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr);
1369b87ac2d8SJed Brown     break;
1370c10200c1SHong Zhang   case MAT_SUBMAT_SINGLEIS:
1371c10200c1SHong Zhang     A->submat_singleis = flg;
1372c10200c1SHong Zhang     break;
1373071fcb05SBarry Smith   case MAT_SORTED_FULL:
1374071fcb05SBarry Smith     if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull;
1375071fcb05SBarry Smith     else     A->ops->setvalues = MatSetValues_SeqAIJ;
1376071fcb05SBarry Smith     break;
13771a2c6b5cSJunchao Zhang   case MAT_FORM_EXPLICIT_TRANSPOSE:
13781a2c6b5cSJunchao Zhang     A->form_explicit_transpose = flg;
13791a2c6b5cSJunchao Zhang     break;
1380a65d3064SKris Buschelman   default:
138198921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1382a65d3064SKris Buschelman   }
13833a40ed3dSBarry Smith   PetscFunctionReturn(0);
138417ab2063SBarry Smith }
138517ab2063SBarry Smith 
1386dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
138717ab2063SBarry Smith {
1388416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
13896849ba73SBarry Smith   PetscErrorCode    ierr;
1390fdc842d1SBarry Smith   PetscInt          i,j,n,*ai=a->i,*aj=a->j;
1391c898d852SStefano Zampini   PetscScalar       *x;
1392c898d852SStefano Zampini   const PetscScalar *aa;
139317ab2063SBarry Smith 
13943a40ed3dSBarry Smith   PetscFunctionBegin;
1395d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1396*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1397c898d852SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
1398d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1399d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
1400fdc842d1SBarry Smith     ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
14012c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
1402fdc842d1SBarry Smith     ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
1403c898d852SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
140435e7444dSHong Zhang     PetscFunctionReturn(0);
140535e7444dSHong Zhang   }
140635e7444dSHong Zhang 
1407fdc842d1SBarry Smith   ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
140835e7444dSHong Zhang   for (i=0; i<n; i++) {
1409fdc842d1SBarry Smith     x[i] = 0.0;
141035e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
141135e7444dSHong Zhang       if (aj[j] == i) {
141235e7444dSHong Zhang         x[i] = aa[j];
141317ab2063SBarry Smith         break;
141417ab2063SBarry Smith       }
141517ab2063SBarry Smith     }
141617ab2063SBarry Smith   }
1417fdc842d1SBarry Smith   ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
1418c898d852SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
14193a40ed3dSBarry Smith   PetscFunctionReturn(0);
142017ab2063SBarry Smith }
142117ab2063SBarry Smith 
1422c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
1423dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
142417ab2063SBarry Smith {
1425416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
14265f22a7b3SSebastian Grimberg   const MatScalar   *aa;
1427d9ca1df4SBarry Smith   PetscScalar       *y;
1428d9ca1df4SBarry Smith   const PetscScalar *x;
1429dfbe8321SBarry Smith   PetscErrorCode    ierr;
1430d0f46423SBarry Smith   PetscInt          m = A->rmap->n;
14315c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
14325f22a7b3SSebastian Grimberg   const MatScalar   *v;
1433a77337e4SBarry Smith   PetscScalar       alpha;
1434d9ca1df4SBarry Smith   PetscInt          n,i,j;
1435d9ca1df4SBarry Smith   const PetscInt    *idx,*ii,*ridx=NULL;
14363447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1437ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
14385c897100SBarry Smith #endif
143917ab2063SBarry Smith 
14403a40ed3dSBarry Smith   PetscFunctionBegin;
14412e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
1442d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
14431ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1444fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
14455c897100SBarry Smith 
14465c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1447fff043a9SJunchao Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,aa,y);
14485c897100SBarry Smith #else
14493447b6efSHong Zhang   if (usecprow) {
14503447b6efSHong Zhang     m    = cprow.nrows;
14513447b6efSHong Zhang     ii   = cprow.i;
14527b2bb3b9SHong Zhang     ridx = cprow.rindex;
14533447b6efSHong Zhang   } else {
14543447b6efSHong Zhang     ii = a->i;
14553447b6efSHong Zhang   }
145617ab2063SBarry Smith   for (i=0; i<m; i++) {
14573447b6efSHong Zhang     idx = a->j + ii[i];
1458fff043a9SJunchao Zhang     v   = aa + ii[i];
14593447b6efSHong Zhang     n   = ii[i+1] - ii[i];
14603447b6efSHong Zhang     if (usecprow) {
14617b2bb3b9SHong Zhang       alpha = x[ridx[i]];
14623447b6efSHong Zhang     } else {
146317ab2063SBarry Smith       alpha = x[i];
14643447b6efSHong Zhang     }
146504fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
146617ab2063SBarry Smith   }
14675c897100SBarry Smith #endif
1468dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1469d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
14701ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1471fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
14723a40ed3dSBarry Smith   PetscFunctionReturn(0);
147317ab2063SBarry Smith }
147417ab2063SBarry Smith 
1475dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
14765c897100SBarry Smith {
1477dfbe8321SBarry Smith   PetscErrorCode ierr;
14785c897100SBarry Smith 
14795c897100SBarry Smith   PetscFunctionBegin;
1480170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
14815c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
14825c897100SBarry Smith   PetscFunctionReturn(0);
14835c897100SBarry Smith }
14845c897100SBarry Smith 
1485c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
148678b84d54SShri Abhyankar 
1487dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
148817ab2063SBarry Smith {
1489416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1490d9fead3dSBarry Smith   PetscScalar       *y;
149154f21887SBarry Smith   const PetscScalar *x;
1492fff043a9SJunchao Zhang   const MatScalar   *aa,*a_a;
1493dfbe8321SBarry Smith   PetscErrorCode    ierr;
1494003131ecSBarry Smith   PetscInt          m=A->rmap->n;
14950298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
14967b083b7cSBarry Smith   PetscInt          n,i;
1497362ced78SSatish Balay   PetscScalar       sum;
1498ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
149917ab2063SBarry Smith 
1500b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
150197952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1502fee21e36SBarry Smith #endif
1503fee21e36SBarry Smith 
15043a40ed3dSBarry Smith   PetscFunctionBegin;
1505b215bc84SStefano Zampini   if (a->inode.use && a->inode.checked) {
1506b215bc84SStefano Zampini     ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr);
1507b215bc84SStefano Zampini     PetscFunctionReturn(0);
1508b215bc84SStefano Zampini   }
1509fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr);
15103649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15111ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1512416022c9SBarry Smith   ii   = a->i;
15134eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
1514580bdb30SBarry Smith     ierr = PetscArrayzero(y,m);CHKERRQ(ierr);
151597952fefSHong Zhang     m    = a->compressedrow.nrows;
151697952fefSHong Zhang     ii   = a->compressedrow.i;
151797952fefSHong Zhang     ridx = a->compressedrow.rindex;
151897952fefSHong Zhang     for (i=0; i<m; i++) {
151997952fefSHong Zhang       n           = ii[i+1] - ii[i];
152097952fefSHong Zhang       aj          = a->j + ii[i];
1521fff043a9SJunchao Zhang       aa          = a_a + ii[i];
152297952fefSHong Zhang       sum         = 0.0;
1523003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1524003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
152597952fefSHong Zhang       y[*ridx++] = sum;
152697952fefSHong Zhang     }
152797952fefSHong Zhang   } else { /* do not use compressed row format */
1528b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
15293d3eaba7SBarry Smith     aj   = a->j;
1530fff043a9SJunchao Zhang     aa   = a_a;
1531b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1532b05257ddSBarry Smith #else
153317ab2063SBarry Smith     for (i=0; i<m; i++) {
1534003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1535003131ecSBarry Smith       aj          = a->j + ii[i];
1536fff043a9SJunchao Zhang       aa          = a_a + ii[i];
153717ab2063SBarry Smith       sum         = 0.0;
1538003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153917ab2063SBarry Smith       y[i] = sum;
154017ab2063SBarry Smith     }
15418d195f9aSBarry Smith #endif
1542b05257ddSBarry Smith   }
15437b083b7cSBarry Smith   ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr);
15443649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15451ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1546fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr);
15473a40ed3dSBarry Smith   PetscFunctionReturn(0);
154817ab2063SBarry Smith }
154917ab2063SBarry Smith 
1550b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1551b434eb95SMatthew G. Knepley {
1552b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1553b434eb95SMatthew G. Knepley   PetscScalar       *y;
1554b434eb95SMatthew G. Knepley   const PetscScalar *x;
1555fff043a9SJunchao Zhang   const MatScalar   *aa,*a_a;
1556b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1557b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1558b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1559b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1560b434eb95SMatthew G. Knepley   PetscScalar       sum;
1561b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1562b434eb95SMatthew G. Knepley 
1563b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1564b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1565b434eb95SMatthew G. Knepley #endif
1566b434eb95SMatthew G. Knepley 
1567b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1568fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr);
1569b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1570b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1571b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1572b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1573b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1574b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1575b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1576b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1577b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1578fff043a9SJunchao Zhang       aa          = a_a + ii[i];
1579b434eb95SMatthew G. Knepley       sum         = 0.0;
1580b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1581b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1582b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1583b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1584b434eb95SMatthew G. Knepley     }
1585b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
15863d3eaba7SBarry Smith     ii = a->i;
1587b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1588b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1589b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1590fff043a9SJunchao Zhang       aa          = a_a + ii[i];
1591b434eb95SMatthew G. Knepley       sum         = 0.0;
1592b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1593b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1594b434eb95SMatthew G. Knepley       y[i] = sum;
1595b434eb95SMatthew G. Knepley     }
1596b434eb95SMatthew G. Knepley   }
1597b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1598b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1599b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1600fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr);
1601b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1602b434eb95SMatthew G. Knepley }
1603b434eb95SMatthew G. Knepley 
1604b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1605b434eb95SMatthew G. Knepley {
1606b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1607b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1608b434eb95SMatthew G. Knepley   const PetscScalar *x;
1609fff043a9SJunchao Zhang   const MatScalar   *aa,*a_a;
1610b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1611b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1612b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1613b434eb95SMatthew G. Knepley   PetscScalar       sum;
1614b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1615b434eb95SMatthew G. Knepley 
1616b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1617fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr);
1618b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1619d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1620b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1621b434eb95SMatthew G. Knepley     if (zz != yy) {
1622580bdb30SBarry Smith       ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr);
1623b434eb95SMatthew G. Knepley     }
1624b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1625b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1626b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1627b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1628b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1629b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1630fff043a9SJunchao Zhang       aa  = a_a + ii[i];
1631b434eb95SMatthew G. Knepley       sum = y[*ridx];
1632b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1633b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1634b434eb95SMatthew G. Knepley     }
1635b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
16363d3eaba7SBarry Smith     ii = a->i;
1637b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1638b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1639b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1640fff043a9SJunchao Zhang       aa  = a_a + ii[i];
1641b434eb95SMatthew G. Knepley       sum = y[i];
1642b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1643b434eb95SMatthew G. Knepley       z[i] = sum;
1644b434eb95SMatthew G. Knepley     }
1645b434eb95SMatthew G. Knepley   }
1646b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1647b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1648d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1649fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr);
1650b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1651b434eb95SMatthew G. Knepley }
1652b434eb95SMatthew G. Knepley 
1653c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
1654dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
165517ab2063SBarry Smith {
1656416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1657f15663dcSBarry Smith   PetscScalar       *y,*z;
1658f15663dcSBarry Smith   const PetscScalar *x;
1659fff043a9SJunchao Zhang   const MatScalar   *aa,*a_a;
1660dfbe8321SBarry Smith   PetscErrorCode    ierr;
1661d9ca1df4SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
1662d9ca1df4SBarry Smith   PetscInt          m = A->rmap->n,n,i;
1663362ced78SSatish Balay   PetscScalar       sum;
1664ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
16659ea0dfa2SSatish Balay 
16663a40ed3dSBarry Smith   PetscFunctionBegin;
1667b215bc84SStefano Zampini   if (a->inode.use && a->inode.checked) {
1668b215bc84SStefano Zampini     ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr);
1669b215bc84SStefano Zampini     PetscFunctionReturn(0);
1670b215bc84SStefano Zampini   }
1671fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr);
1672f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1673d9ca1df4SBarry Smith   ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
16744eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
16754eb6d288SHong Zhang     if (zz != yy) {
1676580bdb30SBarry Smith       ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr);
16774eb6d288SHong Zhang     }
167897952fefSHong Zhang     m    = a->compressedrow.nrows;
167997952fefSHong Zhang     ii   = a->compressedrow.i;
168097952fefSHong Zhang     ridx = a->compressedrow.rindex;
168197952fefSHong Zhang     for (i=0; i<m; i++) {
168297952fefSHong Zhang       n   = ii[i+1] - ii[i];
168397952fefSHong Zhang       aj  = a->j + ii[i];
1684fff043a9SJunchao Zhang       aa  = a_a + ii[i];
168597952fefSHong Zhang       sum = y[*ridx];
1686f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
168797952fefSHong Zhang       z[*ridx++] = sum;
168897952fefSHong Zhang     }
168997952fefSHong Zhang   } else { /* do not use compressed row format */
16903d3eaba7SBarry Smith     ii = a->i;
1691f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
16923d3eaba7SBarry Smith     aj = a->j;
1693fff043a9SJunchao Zhang     aa = a_a;
1694f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1695f15663dcSBarry Smith #else
169617ab2063SBarry Smith     for (i=0; i<m; i++) {
1697f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1698f15663dcSBarry Smith       aj  = a->j + ii[i];
1699fff043a9SJunchao Zhang       aa  = a_a + ii[i];
170017ab2063SBarry Smith       sum = y[i];
1701f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
170217ab2063SBarry Smith       z[i] = sum;
170317ab2063SBarry Smith     }
170402ab625aSSatish Balay #endif
1705f15663dcSBarry Smith   }
1706dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1707f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1708d9ca1df4SBarry Smith   ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr);
1709fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr);
17103a40ed3dSBarry Smith   PetscFunctionReturn(0);
171117ab2063SBarry Smith }
171217ab2063SBarry Smith 
171317ab2063SBarry Smith /*
171417ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
171517ab2063SBarry Smith */
1716dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
171717ab2063SBarry Smith {
1718416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
17196849ba73SBarry Smith   PetscErrorCode ierr;
1720d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
172117ab2063SBarry Smith 
17223a40ed3dSBarry Smith   PetscFunctionBegin;
172309f38230SBarry Smith   if (!a->diag) {
1724785e854fSJed Brown     ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr);
17253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
172609f38230SBarry Smith   }
1727d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
172809f38230SBarry Smith     a->diag[i] = a->i[i+1];
1729bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1730bfeeae90SHong Zhang       if (a->j[j] == i) {
173109f38230SBarry Smith         a->diag[i] = j;
173217ab2063SBarry Smith         break;
173317ab2063SBarry Smith       }
173417ab2063SBarry Smith     }
173517ab2063SBarry Smith   }
17363a40ed3dSBarry Smith   PetscFunctionReturn(0);
173717ab2063SBarry Smith }
173817ab2063SBarry Smith 
173961ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v)
174061ecd0c6SBarry Smith {
174161ecd0c6SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
174261ecd0c6SBarry Smith   const PetscInt    *diag = (const PetscInt*)a->diag;
174361ecd0c6SBarry Smith   const PetscInt    *ii = (const PetscInt*) a->i;
174461ecd0c6SBarry Smith   PetscInt          i,*mdiag = NULL;
174561ecd0c6SBarry Smith   PetscErrorCode    ierr;
174661ecd0c6SBarry Smith   PetscInt          cnt = 0; /* how many diagonals are missing */
174761ecd0c6SBarry Smith 
174861ecd0c6SBarry Smith   PetscFunctionBegin;
174961ecd0c6SBarry Smith   if (!A->preallocated || !a->nz) {
175061ecd0c6SBarry Smith     ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr);
175161ecd0c6SBarry Smith     ierr = MatShift_Basic(A,v);CHKERRQ(ierr);
175261ecd0c6SBarry Smith     PetscFunctionReturn(0);
175361ecd0c6SBarry Smith   }
175461ecd0c6SBarry Smith 
175561ecd0c6SBarry Smith   if (a->diagonaldense) {
175661ecd0c6SBarry Smith     cnt = 0;
175761ecd0c6SBarry Smith   } else {
175861ecd0c6SBarry Smith     ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr);
175961ecd0c6SBarry Smith     for (i=0; i<A->rmap->n; i++) {
176061ecd0c6SBarry Smith       if (diag[i] >= ii[i+1]) {
176161ecd0c6SBarry Smith         cnt++;
176261ecd0c6SBarry Smith         mdiag[i] = 1;
176361ecd0c6SBarry Smith       }
176461ecd0c6SBarry Smith     }
176561ecd0c6SBarry Smith   }
176661ecd0c6SBarry Smith   if (!cnt) {
176761ecd0c6SBarry Smith     ierr = MatShift_Basic(A,v);CHKERRQ(ierr);
176861ecd0c6SBarry Smith   } else {
1769b6f2aa54SBarry Smith     PetscScalar *olda = a->a;  /* preserve pointers to current matrix nonzeros structure and values */
1770b6f2aa54SBarry Smith     PetscInt    *oldj = a->j, *oldi = a->i;
177161ecd0c6SBarry Smith     PetscBool   singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij;
177261ecd0c6SBarry Smith 
177361ecd0c6SBarry Smith     a->a = NULL;
177461ecd0c6SBarry Smith     a->j = NULL;
177561ecd0c6SBarry Smith     a->i = NULL;
177661ecd0c6SBarry Smith     /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */
177761ecd0c6SBarry Smith     for (i=0; i<A->rmap->n; i++) {
177861ecd0c6SBarry Smith       a->imax[i] += mdiag[i];
1779447d62f5SStefano Zampini       a->imax[i] = PetscMin(a->imax[i],A->cmap->n);
178061ecd0c6SBarry Smith     }
178161ecd0c6SBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr);
178261ecd0c6SBarry Smith 
178361ecd0c6SBarry Smith     /* copy old values into new matrix data structure */
178461ecd0c6SBarry Smith     for (i=0; i<A->rmap->n; i++) {
178561ecd0c6SBarry Smith       ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr);
1786447d62f5SStefano Zampini       if (i < A->cmap->n) {
178761ecd0c6SBarry Smith         ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr);
178861ecd0c6SBarry Smith       }
1789447d62f5SStefano Zampini     }
179061ecd0c6SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
179161ecd0c6SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
179261ecd0c6SBarry Smith     if (singlemalloc) {
179361ecd0c6SBarry Smith       ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr);
179461ecd0c6SBarry Smith     } else {
179561ecd0c6SBarry Smith       if (free_a)  {ierr = PetscFree(olda);CHKERRQ(ierr);}
179661ecd0c6SBarry Smith       if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);}
179761ecd0c6SBarry Smith       if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);}
179861ecd0c6SBarry Smith     }
179961ecd0c6SBarry Smith   }
180061ecd0c6SBarry Smith   ierr = PetscFree(mdiag);CHKERRQ(ierr);
180161ecd0c6SBarry Smith   a->diagonaldense = PETSC_TRUE;
180261ecd0c6SBarry Smith   PetscFunctionReturn(0);
180361ecd0c6SBarry Smith }
180461ecd0c6SBarry Smith 
1805be5855fcSBarry Smith /*
1806be5855fcSBarry Smith      Checks for missing diagonals
1807be5855fcSBarry Smith */
1808ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1809be5855fcSBarry Smith {
1810be5855fcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
18117734d3b5SMatthew G. Knepley   PetscInt       *diag,*ii = a->i,i;
1812994fe344SLisandro Dalcin   PetscErrorCode ierr;
1813be5855fcSBarry Smith 
1814be5855fcSBarry Smith   PetscFunctionBegin;
181509f38230SBarry Smith   *missing = PETSC_FALSE;
18167734d3b5SMatthew G. Knepley   if (A->rmap->n > 0 && !ii) {
181709f38230SBarry Smith     *missing = PETSC_TRUE;
181809f38230SBarry Smith     if (d) *d = 0;
1819994fe344SLisandro Dalcin     ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr);
182009f38230SBarry Smith   } else {
182101445905SHong Zhang     PetscInt n;
182201445905SHong Zhang     n = PetscMin(A->rmap->n, A->cmap->n);
1823f1e2ffcdSBarry Smith     diag = a->diag;
182401445905SHong Zhang     for (i=0; i<n; i++) {
18257734d3b5SMatthew G. Knepley       if (diag[i] >= ii[i+1]) {
182609f38230SBarry Smith         *missing = PETSC_TRUE;
182709f38230SBarry Smith         if (d) *d = i;
18287d3de750SJacob Faibussowitsch         ierr = PetscInfo(A,"Matrix is missing diagonal number %" PetscInt_FMT "\n",i);CHKERRQ(ierr);
1829358d2f5dSShri Abhyankar         break;
183009f38230SBarry Smith       }
1831be5855fcSBarry Smith     }
1832be5855fcSBarry Smith   }
1833be5855fcSBarry Smith   PetscFunctionReturn(0);
1834be5855fcSBarry Smith }
1835be5855fcSBarry Smith 
18360da83c2eSBarry Smith #include <petscblaslapack.h>
18370da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
18380da83c2eSBarry Smith 
18390da83c2eSBarry Smith /*
18400da83c2eSBarry Smith     Note that values is allocated externally by the PC and then passed into this routine
18410da83c2eSBarry Smith */
18420da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag)
18430da83c2eSBarry Smith {
18440da83c2eSBarry Smith   PetscErrorCode  ierr;
18450da83c2eSBarry Smith   PetscInt        n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots;
18460da83c2eSBarry Smith   PetscBool       allowzeropivot,zeropivotdetected=PETSC_FALSE;
18470da83c2eSBarry Smith   const PetscReal shift = 0.0;
18480da83c2eSBarry Smith   PetscInt        ipvt[5];
18490da83c2eSBarry Smith   PetscScalar     work[25],*v_work;
18500da83c2eSBarry Smith 
18510da83c2eSBarry Smith   PetscFunctionBegin;
18520da83c2eSBarry Smith   allowzeropivot = PetscNot(A->erroriffailure);
18530da83c2eSBarry Smith   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
1854*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ncnt != n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %" PetscInt_FMT " doesn't match number matrix rows %" PetscInt_FMT,ncnt,n);
18550da83c2eSBarry Smith   for (i=0; i<nblocks; i++) {
18560da83c2eSBarry Smith     bsizemax = PetscMax(bsizemax,bsizes[i]);
18570da83c2eSBarry Smith   }
18580da83c2eSBarry Smith   ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr);
18590da83c2eSBarry Smith   if (bsizemax > 7) {
18600da83c2eSBarry Smith     ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr);
18610da83c2eSBarry Smith   }
18620da83c2eSBarry Smith   ncnt = 0;
18630da83c2eSBarry Smith   for (i=0; i<nblocks; i++) {
18640da83c2eSBarry Smith     for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j;
18650da83c2eSBarry Smith     ierr    = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr);
18660da83c2eSBarry Smith     switch (bsizes[i]) {
18670da83c2eSBarry Smith     case 1:
18680da83c2eSBarry Smith       *diag = 1.0/(*diag);
18690da83c2eSBarry Smith       break;
18700da83c2eSBarry Smith     case 2:
18710da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18720da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18730da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
18740da83c2eSBarry Smith       break;
18750da83c2eSBarry Smith     case 3:
18760da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18770da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18780da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
18790da83c2eSBarry Smith       break;
18800da83c2eSBarry Smith     case 4:
18810da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18820da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18830da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
18840da83c2eSBarry Smith       break;
18850da83c2eSBarry Smith     case 5:
18860da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18870da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18880da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
18890da83c2eSBarry Smith       break;
18900da83c2eSBarry Smith     case 6:
18910da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18920da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18930da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
18940da83c2eSBarry Smith       break;
18950da83c2eSBarry Smith     case 7:
18960da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
18970da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
18980da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
18990da83c2eSBarry Smith       break;
19000da83c2eSBarry Smith     default:
19010da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
19020da83c2eSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
19030da83c2eSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr);
19040da83c2eSBarry Smith     }
19050da83c2eSBarry Smith     ncnt   += bsizes[i];
19060da83c2eSBarry Smith     diag += bsizes[i]*bsizes[i];
19070da83c2eSBarry Smith   }
19080da83c2eSBarry Smith   if (bsizemax > 7) {
19090da83c2eSBarry Smith     ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr);
19100da83c2eSBarry Smith   }
19110da83c2eSBarry Smith   ierr = PetscFree(indx);CHKERRQ(ierr);
19120da83c2eSBarry Smith   PetscFunctionReturn(0);
19130da83c2eSBarry Smith }
19140da83c2eSBarry Smith 
1915422a814eSBarry Smith /*
1916422a814eSBarry Smith    Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways
1917422a814eSBarry Smith */
19187087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
191971f1c65dSBarry Smith {
192071f1c65dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*) A->data;
192171f1c65dSBarry Smith   PetscErrorCode  ierr;
1922d0f46423SBarry Smith   PetscInt        i,*diag,m = A->rmap->n;
19232e5835c6SStefano Zampini   const MatScalar *v;
192454f21887SBarry Smith   PetscScalar     *idiag,*mdiag;
192571f1c65dSBarry Smith 
192671f1c65dSBarry Smith   PetscFunctionBegin;
192771f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
192871f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
192971f1c65dSBarry Smith   diag = a->diag;
193071f1c65dSBarry Smith   if (!a->idiag) {
1931dcca6d9dSJed Brown     ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr);
19323bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr);
193371f1c65dSBarry Smith   }
19342e5835c6SStefano Zampini 
193571f1c65dSBarry Smith   mdiag = a->mdiag;
193671f1c65dSBarry Smith   idiag = a->idiag;
19372e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr);
1938422a814eSBarry Smith   if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) {
193971f1c65dSBarry Smith     for (i=0; i<m; i++) {
194071f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1941899639b0SHong Zhang       if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */
1942899639b0SHong Zhang         if (PetscRealPart(fshift)) {
19437d3de750SJacob Faibussowitsch           ierr = PetscInfo(A,"Zero diagonal on row %" PetscInt_FMT "\n",i);CHKERRQ(ierr);
19447b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
19457b6c816cSBarry Smith           A->factorerror_zeropivot_value = 0.0;
19467b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
194798921bdaSJacob Faibussowitsch         } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %" PetscInt_FMT,i);
1948899639b0SHong Zhang       }
194971f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
195071f1c65dSBarry Smith     }
195171f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
195271f1c65dSBarry Smith   } else {
195371f1c65dSBarry Smith     for (i=0; i<m; i++) {
195471f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
195571f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
195671f1c65dSBarry Smith     }
1957dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
195871f1c65dSBarry Smith   }
195971f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
19602e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr);
196171f1c65dSBarry Smith   PetscFunctionReturn(0);
196271f1c65dSBarry Smith }
196371f1c65dSBarry Smith 
1964c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
196541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
196617ab2063SBarry Smith {
1967416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1968e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
19692e5835c6SStefano Zampini   const MatScalar   *v,*idiag=NULL,*mdiag,*aa;
197054f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1971dfbe8321SBarry Smith   PetscErrorCode    ierr;
19723d3eaba7SBarry Smith   PetscInt          n,m = A->rmap->n,i;
197397f1f81fSBarry Smith   const PetscInt    *idx,*diag;
197417ab2063SBarry Smith 
19753a40ed3dSBarry Smith   PetscFunctionBegin;
1976b215bc84SStefano Zampini   if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) {
1977b215bc84SStefano Zampini     ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr);
1978b215bc84SStefano Zampini     PetscFunctionReturn(0);
1979b215bc84SStefano Zampini   }
1980b965ef7fSBarry Smith   its = its*lits;
198191723122SBarry Smith 
198271f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
198371f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
198471f1c65dSBarry Smith   a->fshift = fshift;
198571f1c65dSBarry Smith   a->omega  = omega;
1986ed480e8bSBarry Smith 
198771f1c65dSBarry Smith   diag  = a->diag;
198871f1c65dSBarry Smith   t     = a->ssor_work;
1989ed480e8bSBarry Smith   idiag = a->idiag;
199071f1c65dSBarry Smith   mdiag = a->mdiag;
1991ed480e8bSBarry Smith 
19922e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
19931ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
19943649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1995ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
199617ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
199717ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1998ed480e8bSBarry Smith     bs = b;
199917ab2063SBarry Smith     for (i=0; i<m; i++) {
200071f1c65dSBarry Smith       d   = fshift + mdiag[i];
2001416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
2002ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
20032e5835c6SStefano Zampini       v   = aa + diag[i] + 1;
200417ab2063SBarry Smith       sum = b[i]*d/omega;
2005003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
200617ab2063SBarry Smith       x[i] = sum;
200717ab2063SBarry Smith     }
20081ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
20093649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
20102e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2011efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20123a40ed3dSBarry Smith     PetscFunctionReturn(0);
201317ab2063SBarry Smith   }
2014c783ea89SBarry Smith 
2015*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(flag == SOR_APPLY_LOWER,PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
20162205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
20174c500f23SPierre Jolivet     /* Let  A = L + U + D; where L is lower triangular,
2018887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
201917ab2063SBarry Smith 
202017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
202117ab2063SBarry Smith 
2022887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
202317ab2063SBarry Smith     */
202417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
202517ab2063SBarry Smith 
202617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
202717ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
2028416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
2029ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
20302e5835c6SStefano Zampini       v   = aa + diag[i] + 1;
203117ab2063SBarry Smith       sum = b[i];
2032e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
2033ed480e8bSBarry Smith       x[i] = sum*idiag[i];
203417ab2063SBarry Smith     }
203517ab2063SBarry Smith 
203617ab2063SBarry Smith     /*  t = b - (2*E - D)x */
20372e5835c6SStefano Zampini     v = aa;
20382205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
203917ab2063SBarry Smith 
204017ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
2041ed480e8bSBarry Smith     ts   = t;
2042416022c9SBarry Smith     diag = a->diag;
204317ab2063SBarry Smith     for (i=0; i<m; i++) {
2044416022c9SBarry Smith       n   = diag[i] - a->i[i];
2045ed480e8bSBarry Smith       idx = a->j + a->i[i];
20462e5835c6SStefano Zampini       v   = aa + a->i[i];
204717ab2063SBarry Smith       sum = t[i];
2048003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
2049ed480e8bSBarry Smith       t[i] = sum*idiag[i];
2050733d66baSBarry Smith       /*  x = x + t */
2051733d66baSBarry Smith       x[i] += t[i];
205217ab2063SBarry Smith     }
205317ab2063SBarry Smith 
2054dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
20551ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
20563649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
20573a40ed3dSBarry Smith     PetscFunctionReturn(0);
205817ab2063SBarry Smith   }
205917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
206017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
206117ab2063SBarry Smith       for (i=0; i<m; i++) {
2062416022c9SBarry Smith         n   = diag[i] - a->i[i];
2063ed480e8bSBarry Smith         idx = a->j + a->i[i];
20642e5835c6SStefano Zampini         v   = aa + a->i[i];
206517ab2063SBarry Smith         sum = b[i];
2066e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
20675c99c7daSBarry Smith         t[i] = sum;
2068ed480e8bSBarry Smith         x[i] = sum*idiag[i];
206917ab2063SBarry Smith       }
20705c99c7daSBarry Smith       xb   = t;
2071efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
20723a40ed3dSBarry Smith     } else xb = b;
207317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
207417ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
2075416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
2076ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
20772e5835c6SStefano Zampini         v   = aa + diag[i] + 1;
207817ab2063SBarry Smith         sum = xb[i];
2079e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
20805c99c7daSBarry Smith         if (xb == b) {
2081ed480e8bSBarry Smith           x[i] = sum*idiag[i];
20825c99c7daSBarry Smith         } else {
2083b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
208417ab2063SBarry Smith         }
20855c99c7daSBarry Smith       }
2086b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
208717ab2063SBarry Smith     }
208817ab2063SBarry Smith     its--;
208917ab2063SBarry Smith   }
209017ab2063SBarry Smith   while (its--) {
209117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
209217ab2063SBarry Smith       for (i=0; i<m; i++) {
2093b19a5dc2SMark Adams         /* lower */
2094b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
2095ed480e8bSBarry Smith         idx = a->j + a->i[i];
20962e5835c6SStefano Zampini         v   = aa + a->i[i];
209717ab2063SBarry Smith         sum = b[i];
2098e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
2099b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
2100b19a5dc2SMark Adams         /* upper */
2101b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
2102b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
21032e5835c6SStefano Zampini         v   = aa + diag[i] + 1;
2104b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
2105b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
210617ab2063SBarry Smith       }
2107b19a5dc2SMark Adams       xb   = t;
21089f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
2109b19a5dc2SMark Adams     } else xb = b;
211017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
211117ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
2112b19a5dc2SMark Adams         sum = xb[i];
2113b19a5dc2SMark Adams         if (xb == b) {
2114b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
2115416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
2116ed480e8bSBarry Smith           idx = a->j + a->i[i];
21172e5835c6SStefano Zampini           v   = aa + a->i[i];
2118e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
2119ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
2120b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
2121b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
2122b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
21232e5835c6SStefano Zampini           v   = aa + diag[i] + 1;
2124b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
2125b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
212617ab2063SBarry Smith         }
2127b19a5dc2SMark Adams       }
2128b19a5dc2SMark Adams       if (xb == b) {
21299f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
2130b19a5dc2SMark Adams       } else {
2131b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
2132b19a5dc2SMark Adams       }
213317ab2063SBarry Smith     }
213417ab2063SBarry Smith   }
21352e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
21361ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
21373649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
2138365a8a9eSBarry Smith   PetscFunctionReturn(0);
213917ab2063SBarry Smith }
214017ab2063SBarry Smith 
2141dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
214217ab2063SBarry Smith {
2143416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
21444e220ebcSLois Curfman McInnes 
21453a40ed3dSBarry Smith   PetscFunctionBegin;
21464e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
21473966268fSBarry Smith   info->nz_allocated = a->maxnz;
21483966268fSBarry Smith   info->nz_used      = a->nz;
21493966268fSBarry Smith   info->nz_unneeded  = (a->maxnz - a->nz);
21503966268fSBarry Smith   info->assemblies   = A->num_ass;
21513966268fSBarry Smith   info->mallocs      = A->info.mallocs;
21527adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
2153d5f3da31SBarry Smith   if (A->factortype) {
21544e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
21554e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
21564e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
21574e220ebcSLois Curfman McInnes   } else {
21584e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
21594e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
21604e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
21614e220ebcSLois Curfman McInnes   }
21623a40ed3dSBarry Smith   PetscFunctionReturn(0);
216317ab2063SBarry Smith }
216417ab2063SBarry Smith 
21652b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
216617ab2063SBarry Smith {
2167416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
2168c7da8527SEric Chamberland   PetscInt          i,m = A->rmap->n - 1;
21696849ba73SBarry Smith   PetscErrorCode    ierr;
217097b48c8fSBarry Smith   const PetscScalar *xx;
21712e5835c6SStefano Zampini   PetscScalar       *bb,*aa;
2172c7da8527SEric Chamberland   PetscInt          d = 0;
217317ab2063SBarry Smith 
21743a40ed3dSBarry Smith   PetscFunctionBegin;
217597b48c8fSBarry Smith   if (x && b) {
217697b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
217797b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
217897b48c8fSBarry Smith     for (i=0; i<N; i++) {
2179*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]);
2180447d62f5SStefano Zampini       if (rows[i] >= A->cmap->n) continue;
218197b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
218297b48c8fSBarry Smith     }
218397b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
218497b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
218597b48c8fSBarry Smith   }
218697b48c8fSBarry Smith 
21872e5835c6SStefano Zampini   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
2188a9817697SBarry Smith   if (a->keepnonzeropattern) {
2189f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
2190*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]);
21912e5835c6SStefano Zampini       ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr);
2192f1e2ffcdSBarry Smith     }
2193f4df32b1SMatthew Knepley     if (diag != 0.0) {
2194c7da8527SEric Chamberland       for (i=0; i<N; i++) {
2195c7da8527SEric Chamberland         d = rows[i];
2196447d62f5SStefano Zampini         if (rows[i] >= A->cmap->n) continue;
2197*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(a->diag[d] >= a->i[d+1],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %" PetscInt_FMT,d);
2198c7da8527SEric Chamberland       }
2199f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
2200447d62f5SStefano Zampini         if (rows[i] >= A->cmap->n) continue;
22012e5835c6SStefano Zampini         aa[a->diag[rows[i]]] = diag;
2202f1e2ffcdSBarry Smith       }
2203f1e2ffcdSBarry Smith     }
2204f1e2ffcdSBarry Smith   } else {
2205f4df32b1SMatthew Knepley     if (diag != 0.0) {
220617ab2063SBarry Smith       for (i=0; i<N; i++) {
2207*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]);
22087ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
2209447d62f5SStefano Zampini           if (rows[i] >= A->cmap->n) {
2210447d62f5SStefano Zampini             a->ilen[rows[i]] = 0;
2211447d62f5SStefano Zampini           } else {
2212416022c9SBarry Smith             a->ilen[rows[i]]    = 1;
22132e5835c6SStefano Zampini             aa[a->i[rows[i]]]   = diag;
2214bfeeae90SHong Zhang             a->j[a->i[rows[i]]] = rows[i];
2215447d62f5SStefano Zampini           }
2216447d62f5SStefano Zampini         } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */
2217f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
221817ab2063SBarry Smith         }
221917ab2063SBarry Smith       }
22203a40ed3dSBarry Smith     } else {
222117ab2063SBarry Smith       for (i=0; i<N; i++) {
2222*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]);
2223416022c9SBarry Smith         a->ilen[rows[i]] = 0;
222417ab2063SBarry Smith       }
222517ab2063SBarry Smith     }
2226e56f5c9eSBarry Smith     A->nonzerostate++;
2227f1e2ffcdSBarry Smith   }
22282e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
22294099cc6bSBarry Smith   ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22303a40ed3dSBarry Smith   PetscFunctionReturn(0);
223117ab2063SBarry Smith }
223217ab2063SBarry Smith 
22336e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
22346e169961SBarry Smith {
22356e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
22366e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
22376e169961SBarry Smith   PetscErrorCode    ierr;
22382b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
22396e169961SBarry Smith   const PetscScalar *xx;
22402e5835c6SStefano Zampini   PetscScalar       *bb,*aa;
22416e169961SBarry Smith 
22426e169961SBarry Smith   PetscFunctionBegin;
22432e5835c6SStefano Zampini   if (!N) PetscFunctionReturn(0);
22442e5835c6SStefano Zampini   ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr);
22456e169961SBarry Smith   if (x && b) {
22466e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
22476e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
22482b40b63fSBarry Smith     vecs = PETSC_TRUE;
22496e169961SBarry Smith   }
22501795a4d1SJed Brown   ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr);
22516e169961SBarry Smith   for (i=0; i<N; i++) {
2252*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]);
22532e5835c6SStefano Zampini     ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr);
22542205254eSKarl Rupp 
22556e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
22566e169961SBarry Smith   }
22576e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
22586e169961SBarry Smith     if (!zeroed[i]) {
22596e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
22604cf107fdSStefano Zampini         if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) {
22612e5835c6SStefano Zampini           if (vecs) bb[i] -= aa[j]*xx[a->j[j]];
22622e5835c6SStefano Zampini           aa[j] = 0.0;
22636e169961SBarry Smith         }
22646e169961SBarry Smith       }
22654cf107fdSStefano Zampini     } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i];
22666e169961SBarry Smith   }
22676e169961SBarry Smith   if (x && b) {
22686e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
22696e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
22706e169961SBarry Smith   }
22716e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
22726e169961SBarry Smith   if (diag != 0.0) {
22736e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
22741d5a398dSstefano_zampini     if (missing) {
22751d5a398dSstefano_zampini       for (i=0; i<N; i++) {
22764cf107fdSStefano Zampini         if (rows[i] >= A->cmap->N) continue;
2277*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(a->nonew && rows[i] >= d,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %" PetscInt_FMT " (%" PetscInt_FMT ")",d,rows[i]);
22781d5a398dSstefano_zampini         ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
22791d5a398dSstefano_zampini       }
22801d5a398dSstefano_zampini     } else {
22816e169961SBarry Smith       for (i=0; i<N; i++) {
22822e5835c6SStefano Zampini         aa[a->diag[rows[i]]] = diag;
22836e169961SBarry Smith       }
22846e169961SBarry Smith     }
22851d5a398dSstefano_zampini   }
22862e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr);
22874099cc6bSBarry Smith   ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22886e169961SBarry Smith   PetscFunctionReturn(0);
22896e169961SBarry Smith }
22906e169961SBarry Smith 
2291a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
229217ab2063SBarry Smith {
22932e5835c6SStefano Zampini   PetscErrorCode  ierr;
2294fff043a9SJunchao Zhang   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
2295fff043a9SJunchao Zhang   const PetscScalar *aa;
2296fff043a9SJunchao Zhang   PetscInt          *itmp;
229717ab2063SBarry Smith 
22983a40ed3dSBarry Smith   PetscFunctionBegin;
22992e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
2300416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
23012e5835c6SStefano Zampini   if (v) *v = (PetscScalar*)(aa + a->i[row]);
230217ab2063SBarry Smith   if (idx) {
2303bfeeae90SHong Zhang     itmp = a->j + a->i[row];
230426fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
2305f4259b30SLisandro Dalcin     else *idx = NULL;
230617ab2063SBarry Smith   }
23072e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23083a40ed3dSBarry Smith   PetscFunctionReturn(0);
230917ab2063SBarry Smith }
231017ab2063SBarry Smith 
2311a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
231217ab2063SBarry Smith {
23133a40ed3dSBarry Smith   PetscFunctionBegin;
2314cb4a9cd9SHong Zhang   if (nz)  *nz = 0;
23152e5835c6SStefano Zampini   if (idx) *idx = NULL;
23162e5835c6SStefano Zampini   if (v)   *v = NULL;
23173a40ed3dSBarry Smith   PetscFunctionReturn(0);
231817ab2063SBarry Smith }
231917ab2063SBarry Smith 
2320dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
232117ab2063SBarry Smith {
2322416022c9SBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
23232e5835c6SStefano Zampini   const MatScalar *v;
232436db0b34SBarry Smith   PetscReal       sum = 0.0;
23256849ba73SBarry Smith   PetscErrorCode  ierr;
232697f1f81fSBarry Smith   PetscInt        i,j;
232717ab2063SBarry Smith 
23283a40ed3dSBarry Smith   PetscFunctionBegin;
23292e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr);
233017ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2331570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
2332570b7f6dSBarry Smith     PetscBLASInt one = 1,nz = a->nz;
233373cf7048SBarry Smith     PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one));
2334570b7f6dSBarry Smith #else
2335416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
233636db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
233717ab2063SBarry Smith     }
23388f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
2339570b7f6dSBarry Smith #endif
2340ca0c957dSBarry Smith     ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
23413a40ed3dSBarry Smith   } else if (type == NORM_1) {
234236db0b34SBarry Smith     PetscReal *tmp;
234397f1f81fSBarry Smith     PetscInt  *jj = a->j;
23441795a4d1SJed Brown     ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr);
2345064f8208SBarry Smith     *nrm = 0.0;
2346416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2347bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
234817ab2063SBarry Smith     }
2349d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2350064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
235117ab2063SBarry Smith     }
2352606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
235351f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
23543a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2355064f8208SBarry Smith     *nrm = 0.0;
2356d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
23572e5835c6SStefano Zampini       const PetscScalar *v2 = v + a->i[j];
235817ab2063SBarry Smith       sum = 0.0;
2359416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
23602e5835c6SStefano Zampini         sum += PetscAbsScalar(*v2); v2++;
236117ab2063SBarry Smith       }
2362064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
236317ab2063SBarry Smith     }
236451f70360SJed Brown     ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr);
2365f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
23662e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr);
23673a40ed3dSBarry Smith   PetscFunctionReturn(0);
236817ab2063SBarry Smith }
236917ab2063SBarry Smith 
23704e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
23714e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
23724e938277SHong Zhang {
23734e938277SHong Zhang   PetscErrorCode ierr;
23744e938277SHong Zhang   PetscInt       i,j,anzj;
23754e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
23764e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
23774e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
23784e938277SHong Zhang 
23794e938277SHong Zhang   PetscFunctionBegin;
23804e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
2381854ce69bSBarry Smith   ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr);
2382785e854fSJed Brown   ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr);
2383785e854fSJed Brown   ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr);
23844e938277SHong Zhang 
23854e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
23864e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
238726fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
23884e938277SHong Zhang   /* Form ati for csr format of A^T. */
238926fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
23904e938277SHong Zhang 
23914e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
2392580bdb30SBarry Smith   ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr);
23934e938277SHong Zhang 
23944e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
23954e938277SHong Zhang   for (i=0;i<am;i++) {
23964e938277SHong Zhang     anzj = ai[i+1] - ai[i];
23974e938277SHong Zhang     for (j=0;j<anzj;j++) {
23984e938277SHong Zhang       atj[atfill[*aj]] = i;
23994e938277SHong Zhang       atfill[*aj++]   += 1;
24004e938277SHong Zhang     }
24014e938277SHong Zhang   }
24024e938277SHong Zhang 
24034e938277SHong Zhang   /* Clean up temporary space and complete requests. */
24044e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2405ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
240633d57670SJed Brown   ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr);
2407b5bb3eecSMark Adams   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2408a2f3521dSMark F. Adams 
24094e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
24104e938277SHong Zhang   b->free_a  = PETSC_FALSE;
24114e938277SHong Zhang   b->free_ij = PETSC_TRUE;
24124e938277SHong Zhang   b->nonew   = 0;
24134e938277SHong Zhang   PetscFunctionReturn(0);
24144e938277SHong Zhang }
24154e938277SHong Zhang 
24167087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2417cd0d46ebSvictorle {
24183d3eaba7SBarry Smith   Mat_SeqAIJ      *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
241954f21887SBarry Smith   PetscInt        *adx,*bdx,*aii,*bii,*aptr,*bptr;
24202e5835c6SStefano Zampini   const MatScalar *va,*vb;
24216849ba73SBarry Smith   PetscErrorCode  ierr;
242297f1f81fSBarry Smith   PetscInt        ma,na,mb,nb, i;
2423cd0d46ebSvictorle 
2424cd0d46ebSvictorle   PetscFunctionBegin;
2425cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2426cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
24275485867bSBarry Smith   if (ma!=nb || na!=mb) {
24285485867bSBarry Smith     *f = PETSC_FALSE;
24295485867bSBarry Smith     PetscFunctionReturn(0);
24305485867bSBarry Smith   }
24312e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr);
24322e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr);
2433cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2434cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2435785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2436785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
2437cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2438cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2439cd0d46ebSvictorle 
2440cd0d46ebSvictorle   *f = PETSC_TRUE;
2441cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2442cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
244397f1f81fSBarry Smith       PetscInt    idc,idr;
24445485867bSBarry Smith       PetscScalar vc,vr;
2445cd0d46ebSvictorle       /* column/row index/value */
24465485867bSBarry Smith       idc = adx[aptr[i]];
24475485867bSBarry Smith       idr = bdx[bptr[idc]];
24485485867bSBarry Smith       vc  = va[aptr[i]];
24495485867bSBarry Smith       vr  = vb[bptr[idc]];
24505485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
24515485867bSBarry Smith         *f = PETSC_FALSE;
24525485867bSBarry Smith         goto done;
2453cd0d46ebSvictorle       } else {
24545485867bSBarry Smith         aptr[i]++;
24555485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2456cd0d46ebSvictorle       }
2457cd0d46ebSvictorle     }
2458cd0d46ebSvictorle   }
2459cd0d46ebSvictorle done:
2460cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
24613aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
24622e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr);
24632e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr);
2464cd0d46ebSvictorle   PetscFunctionReturn(0);
2465cd0d46ebSvictorle }
2466cd0d46ebSvictorle 
24677087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
24681cbb95d3SBarry Smith {
24693d3eaba7SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data;
247054f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
247154f21887SBarry Smith   MatScalar      *va,*vb;
24721cbb95d3SBarry Smith   PetscErrorCode ierr;
24731cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
24741cbb95d3SBarry Smith 
24751cbb95d3SBarry Smith   PetscFunctionBegin;
24761cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
24771cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
24781cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
24791cbb95d3SBarry Smith     *f = PETSC_FALSE;
24801cbb95d3SBarry Smith     PetscFunctionReturn(0);
24811cbb95d3SBarry Smith   }
24821cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
24831cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
24841cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
2485785e854fSJed Brown   ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr);
2486785e854fSJed Brown   ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr);
24871cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
24881cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
24891cbb95d3SBarry Smith 
24901cbb95d3SBarry Smith   *f = PETSC_TRUE;
24911cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
24921cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
24931cbb95d3SBarry Smith       PetscInt    idc,idr;
24941cbb95d3SBarry Smith       PetscScalar vc,vr;
24951cbb95d3SBarry Smith       /* column/row index/value */
24961cbb95d3SBarry Smith       idc = adx[aptr[i]];
24971cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
24981cbb95d3SBarry Smith       vc  = va[aptr[i]];
24991cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
25001cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
25011cbb95d3SBarry Smith         *f = PETSC_FALSE;
25021cbb95d3SBarry Smith         goto done;
25031cbb95d3SBarry Smith       } else {
25041cbb95d3SBarry Smith         aptr[i]++;
25051cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
25061cbb95d3SBarry Smith       }
25071cbb95d3SBarry Smith     }
25081cbb95d3SBarry Smith   }
25091cbb95d3SBarry Smith done:
25101cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
25111cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
25121cbb95d3SBarry Smith   PetscFunctionReturn(0);
25131cbb95d3SBarry Smith }
25141cbb95d3SBarry Smith 
2515ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
25169e29f15eSvictorle {
2517dfbe8321SBarry Smith   PetscErrorCode ierr;
25186e111a19SKarl Rupp 
25199e29f15eSvictorle   PetscFunctionBegin;
25205485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
25219e29f15eSvictorle   PetscFunctionReturn(0);
25229e29f15eSvictorle }
25239e29f15eSvictorle 
2524ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
25251cbb95d3SBarry Smith {
25261cbb95d3SBarry Smith   PetscErrorCode ierr;
25276e111a19SKarl Rupp 
25281cbb95d3SBarry Smith   PetscFunctionBegin;
25291cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
25301cbb95d3SBarry Smith   PetscFunctionReturn(0);
25311cbb95d3SBarry Smith }
25321cbb95d3SBarry Smith 
2533dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
253417ab2063SBarry Smith {
2535416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
2536fff8e43fSBarry Smith   const PetscScalar *l,*r;
2537fff8e43fSBarry Smith   PetscScalar       x;
253854f21887SBarry Smith   MatScalar         *v;
2539dfbe8321SBarry Smith   PetscErrorCode    ierr;
2540fff8e43fSBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz;
2541fff8e43fSBarry Smith   const PetscInt    *jj;
254217ab2063SBarry Smith 
25433a40ed3dSBarry Smith   PetscFunctionBegin;
254417ab2063SBarry Smith   if (ll) {
25453ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
25463ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2547e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2548*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(m != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
2549fff8e43fSBarry Smith     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
25502e5835c6SStefano Zampini     ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr);
255117ab2063SBarry Smith     for (i=0; i<m; i++) {
255217ab2063SBarry Smith       x = l[i];
2553416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
25542205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
255517ab2063SBarry Smith     }
2556fff8e43fSBarry Smith     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
2557efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
25582e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr);
255917ab2063SBarry Smith   }
256017ab2063SBarry Smith   if (rr) {
2561e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2562*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
2563fff8e43fSBarry Smith     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
25642e5835c6SStefano Zampini     ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr);
25652e5835c6SStefano Zampini     jj = a->j;
25662205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
25672e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr);
2568fff8e43fSBarry Smith     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
2569efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
257017ab2063SBarry Smith   }
2571acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
25723a40ed3dSBarry Smith   PetscFunctionReturn(0);
257317ab2063SBarry Smith }
257417ab2063SBarry Smith 
25757dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
257617ab2063SBarry Smith {
2577db02288aSLois Curfman McInnes   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data,*c;
25786849ba73SBarry Smith   PetscErrorCode    ierr;
2579d0f46423SBarry Smith   PetscInt          *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
258097f1f81fSBarry Smith   PetscInt          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
25815d0c19d7SBarry Smith   const PetscInt    *irow,*icol;
25822e5835c6SStefano Zampini   const PetscScalar *aa;
25835d0c19d7SBarry Smith   PetscInt          nrows,ncols;
258497f1f81fSBarry Smith   PetscInt          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
258554f21887SBarry Smith   MatScalar         *a_new,*mat_a;
2586416022c9SBarry Smith   Mat               C;
2587cdc6f3adSToby Isaac   PetscBool         stride;
258817ab2063SBarry Smith 
25893a40ed3dSBarry Smith   PetscFunctionBegin;
259017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2591b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2592b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
259317ab2063SBarry Smith 
2594251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2595ff718158SBarry Smith   if (stride) {
2596ff718158SBarry Smith     ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2597ff718158SBarry Smith   } else {
2598ff718158SBarry Smith     first = 0;
2599ff718158SBarry Smith     step  = 0;
2600ff718158SBarry Smith   }
2601fee21e36SBarry Smith   if (stride && step == 1) {
260202834360SBarry Smith     /* special case of contiguous rows */
2603dcca6d9dSJed Brown     ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr);
260402834360SBarry Smith     /* loop over new rows determining lens and starting points */
260502834360SBarry Smith     for (i=0; i<nrows; i++) {
2606bfeeae90SHong Zhang       kstart = ai[irow[i]];
2607a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
2608a91a9bebSLisandro Dalcin       starts[i] = kstart;
260902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2610bfeeae90SHong Zhang         if (aj[k] >= first) {
261102834360SBarry Smith           starts[i] = k;
261202834360SBarry Smith           break;
261302834360SBarry Smith         }
261402834360SBarry Smith       }
2615a2744918SBarry Smith       sum = 0;
261602834360SBarry Smith       while (k < kend) {
2617bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2618a2744918SBarry Smith         sum++;
261902834360SBarry Smith       }
2620a2744918SBarry Smith       lens[i] = sum;
262102834360SBarry Smith     }
262202834360SBarry Smith     /* create submatrix */
2623cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
262497f1f81fSBarry Smith       PetscInt n_cols,n_rows;
262508480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2626*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(n_rows != nrows || n_cols != ncols,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2627d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
262808480c60SBarry Smith       C    = *B;
26293a40ed3dSBarry Smith     } else {
26303bef6203SJed Brown       PetscInt rbs,cbs;
2631ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2632f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
26333bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
26343bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
26353bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
26367adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2637ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
263808480c60SBarry Smith     }
2639db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2640db02288aSLois Curfman McInnes 
264102834360SBarry Smith     /* loop over rows inserting into submatrix */
2642db02288aSLois Curfman McInnes     a_new = c->a;
2643db02288aSLois Curfman McInnes     j_new = c->j;
2644db02288aSLois Curfman McInnes     i_new = c->i;
26452e5835c6SStefano Zampini     ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
264602834360SBarry Smith     for (i=0; i<nrows; i++) {
2647a2744918SBarry Smith       ii    = starts[i];
2648a2744918SBarry Smith       lensi = lens[i];
2649a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2650a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
265102834360SBarry Smith       }
26522e5835c6SStefano Zampini       ierr       = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr);
2653a2744918SBarry Smith       a_new     += lensi;
2654a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2655a2744918SBarry Smith       c->ilen[i] = lensi;
265602834360SBarry Smith     }
26572e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
26580e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
26593a40ed3dSBarry Smith   } else {
266002834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
26611795a4d1SJed Brown     ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr);
2662854ce69bSBarry Smith     ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr);
26634dcab191SBarry Smith     for (i=0; i<ncols; i++) {
2664*2c71b3e2SJacob Faibussowitsch       PetscAssertFalse(icol[i] >= oldcols,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%" PetscInt_FMT "] %" PetscInt_FMT " >= A->cmap->n %" PetscInt_FMT,i,icol[i],oldcols);
26654dcab191SBarry Smith       smap[icol[i]] = i+1;
26664dcab191SBarry Smith     }
26674dcab191SBarry Smith 
266802834360SBarry Smith     /* determine lens of each row */
266902834360SBarry Smith     for (i=0; i<nrows; i++) {
2670bfeeae90SHong Zhang       kstart  = ai[irow[i]];
267102834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
267202834360SBarry Smith       lens[i] = 0;
267302834360SBarry Smith       for (k=kstart; k<kend; k++) {
2674bfeeae90SHong Zhang         if (smap[aj[k]]) {
267502834360SBarry Smith           lens[i]++;
267602834360SBarry Smith         }
267702834360SBarry Smith       }
267802834360SBarry Smith     }
267917ab2063SBarry Smith     /* Create and fill new matrix */
2680a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2681ace3abfcSBarry Smith       PetscBool equal;
26820f5bd95cSBarry Smith 
268399141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2684*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2685580bdb30SBarry Smith       ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr);
2686*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!equal,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2687580bdb30SBarry Smith       ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr);
268808480c60SBarry Smith       C    = *B;
26893a40ed3dSBarry Smith     } else {
26903bef6203SJed Brown       PetscInt rbs,cbs;
2691ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2692f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
26933bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
26943bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
26953bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
26967adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2697ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
269808480c60SBarry Smith     }
26992e5835c6SStefano Zampini     ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
270099141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
270117ab2063SBarry Smith     for (i=0; i<nrows; i++) {
270299141d43SSatish Balay       row      = irow[i];
2703bfeeae90SHong Zhang       kstart   = ai[row];
270499141d43SSatish Balay       kend     = kstart + a->ilen[row];
2705bfeeae90SHong Zhang       mat_i    = c->i[i];
270699141d43SSatish Balay       mat_j    = c->j + mat_i;
270799141d43SSatish Balay       mat_a    = c->a + mat_i;
270899141d43SSatish Balay       mat_ilen = c->ilen + i;
270917ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2710bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2711ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
27122e5835c6SStefano Zampini           *mat_a++ = aa[k];
271399141d43SSatish Balay           (*mat_ilen)++;
271499141d43SSatish Balay 
271517ab2063SBarry Smith         }
271617ab2063SBarry Smith       }
271717ab2063SBarry Smith     }
27182e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
271902834360SBarry Smith     /* Free work space */
272002834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2721606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2722606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
2723cdc6f3adSToby Isaac     /* sort */
2724cdc6f3adSToby Isaac     for (i = 0; i < nrows; i++) {
2725cdc6f3adSToby Isaac       PetscInt ilen;
2726cdc6f3adSToby Isaac 
2727cdc6f3adSToby Isaac       mat_i = c->i[i];
2728cdc6f3adSToby Isaac       mat_j = c->j + mat_i;
2729cdc6f3adSToby Isaac       mat_a = c->a + mat_i;
2730cdc6f3adSToby Isaac       ilen  = c->ilen[i];
2731390e1bf2SBarry Smith       ierr  = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr);
2732cdc6f3adSToby Isaac     }
273302834360SBarry Smith   }
27348c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE)
2735b470e4b4SRichard Tran Mills   ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr);
2736305c6ccfSStefano Zampini #endif
27376d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
27386d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
273917ab2063SBarry Smith 
274017ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2741416022c9SBarry Smith   *B   = C;
27423a40ed3dSBarry Smith   PetscFunctionReturn(0);
274317ab2063SBarry Smith }
274417ab2063SBarry Smith 
2745fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
274682d44351SHong Zhang {
274782d44351SHong Zhang   PetscErrorCode ierr;
274882d44351SHong Zhang   Mat            B;
274982d44351SHong Zhang 
275082d44351SHong Zhang   PetscFunctionBegin;
2751c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
275282d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
275382d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
275433d57670SJed Brown     ierr    = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr);
275582d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
275682d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
275782d44351SHong Zhang     *subMat = B;
2758c2d650bdSHong Zhang   } else {
2759c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2760c2d650bdSHong Zhang   }
276182d44351SHong Zhang   PetscFunctionReturn(0);
276282d44351SHong Zhang }
276382d44351SHong Zhang 
27649a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2765a871dcd8SBarry Smith {
276663b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2767dfbe8321SBarry Smith   PetscErrorCode ierr;
276863b91edcSBarry Smith   Mat            outA;
2769ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
277063b91edcSBarry Smith 
27713a40ed3dSBarry Smith   PetscFunctionBegin;
2772*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info->levels != 0,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
27731df811f5SHong Zhang 
2774b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2775b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2776a871dcd8SBarry Smith 
277763b91edcSBarry Smith   outA             = inA;
2778d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
2779f6224b95SHong Zhang   ierr = PetscFree(inA->solvertype);CHKERRQ(ierr);
2780f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr);
27812205254eSKarl Rupp 
2782c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
27836bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
27842205254eSKarl Rupp 
2785c3122656SLisandro Dalcin   a->row = row;
27862205254eSKarl Rupp 
2787c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
27886bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
27892205254eSKarl Rupp 
2790c3122656SLisandro Dalcin   a->col = col;
279163b91edcSBarry Smith 
279236db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
27936bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
27944c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
27953bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2796f0ec6fceSSatish Balay 
279794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2798854ce69bSBarry Smith     ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr);
27993bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
280094a9d846SBarry Smith   }
280163b91edcSBarry Smith 
2802f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2803137fb511SHong Zhang   if (row_identity && col_identity) {
2804ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2805137fb511SHong Zhang   } else {
2806719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2807137fb511SHong Zhang   }
28083a40ed3dSBarry Smith   PetscFunctionReturn(0);
2809a871dcd8SBarry Smith }
2810a871dcd8SBarry Smith 
2811f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2812f0b747eeSBarry Smith {
2813f0b747eeSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2814dfa0f9e5SStefano Zampini   PetscScalar    *v;
2815efee365bSSatish Balay   PetscErrorCode ierr;
2816c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
28173a40ed3dSBarry Smith 
28183a40ed3dSBarry Smith   PetscFunctionBegin;
2819dfa0f9e5SStefano Zampini   ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr);
2820c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
2821dfa0f9e5SStefano Zampini   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one));
2822efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2823dfa0f9e5SStefano Zampini   ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr);
2824acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
28253a40ed3dSBarry Smith   PetscFunctionReturn(0);
2826f0b747eeSBarry Smith }
2827f0b747eeSBarry Smith 
2828f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj)
282916b64355SHong Zhang {
283016b64355SHong Zhang   PetscErrorCode ierr;
283116b64355SHong Zhang   PetscInt       i;
283216b64355SHong Zhang 
283316b64355SHong Zhang   PetscFunctionBegin;
283416b64355SHong Zhang   if (!submatj->id) { /* delete data that are linked only to submats[id=0] */
283516b64355SHong Zhang     ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr);
283616b64355SHong Zhang 
283716b64355SHong Zhang     for (i=0; i<submatj->nrqr; ++i) {
283816b64355SHong Zhang       ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr);
283916b64355SHong Zhang     }
284016b64355SHong Zhang     ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr);
284116b64355SHong Zhang 
284216b64355SHong Zhang     if (submatj->rbuf1) {
284316b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr);
284416b64355SHong Zhang       ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr);
284516b64355SHong Zhang     }
284616b64355SHong Zhang 
284716b64355SHong Zhang     for (i=0; i<submatj->nrqs; ++i) {
284816b64355SHong Zhang       ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr);
284916b64355SHong Zhang     }
285016b64355SHong Zhang     ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr);
285116b64355SHong Zhang     ierr = PetscFree(submatj->pa);CHKERRQ(ierr);
285216b64355SHong Zhang   }
285316b64355SHong Zhang 
285416b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
285516b64355SHong Zhang   ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr);
285616b64355SHong Zhang   if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);}
285716b64355SHong Zhang   ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr);
285816b64355SHong Zhang #else
285916b64355SHong Zhang   ierr = PetscFree(submatj->rmap);CHKERRQ(ierr);
286016b64355SHong Zhang #endif
286116b64355SHong Zhang 
286216b64355SHong Zhang   if (!submatj->allcolumns) {
286316b64355SHong Zhang #if defined(PETSC_USE_CTABLE)
286416b64355SHong Zhang     ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr);
286516b64355SHong Zhang #else
286616b64355SHong Zhang     ierr = PetscFree(submatj->cmap);CHKERRQ(ierr);
286716b64355SHong Zhang #endif
286816b64355SHong Zhang   }
286916b64355SHong Zhang   ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr);
287016b64355SHong Zhang 
287116b64355SHong Zhang   ierr = PetscFree(submatj);CHKERRQ(ierr);
287216b64355SHong Zhang   PetscFunctionReturn(0);
287316b64355SHong Zhang }
287416b64355SHong Zhang 
28750fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C)
287616b64355SHong Zhang {
287716b64355SHong Zhang   PetscErrorCode ierr;
287816b64355SHong Zhang   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data;
28795c39f6d9SHong Zhang   Mat_SubSppt    *submatj = c->submatis1;
288016b64355SHong Zhang 
288116b64355SHong Zhang   PetscFunctionBegin;
288234136279SStefano Zampini   ierr = (*submatj->destroy)(C);CHKERRQ(ierr);
2883f68bb481SHong Zhang   ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr);
288416b64355SHong Zhang   PetscFunctionReturn(0);
288516b64355SHong Zhang }
288616b64355SHong Zhang 
28872d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[])
28882d033e1fSHong Zhang {
28892d033e1fSHong Zhang   PetscErrorCode ierr;
28902d033e1fSHong Zhang   PetscInt       i;
28910fb991dcSHong Zhang   Mat            C;
28920fb991dcSHong Zhang   Mat_SeqAIJ     *c;
28930fb991dcSHong Zhang   Mat_SubSppt    *submatj;
28942d033e1fSHong Zhang 
28952d033e1fSHong Zhang   PetscFunctionBegin;
28962d033e1fSHong Zhang   for (i=0; i<n; i++) {
28970fb991dcSHong Zhang     C       = (*mat)[i];
28980fb991dcSHong Zhang     c       = (Mat_SeqAIJ*)C->data;
28990fb991dcSHong Zhang     submatj = c->submatis1;
29002d033e1fSHong Zhang     if (submatj) {
2901682e4c99SStefano Zampini       if (--((PetscObject)C)->refct <= 0) {
290234136279SStefano Zampini         ierr = (*submatj->destroy)(C);CHKERRQ(ierr);
2903f68bb481SHong Zhang         ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr);
290434136279SStefano Zampini         ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr);
29052d033e1fSHong Zhang         ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr);
29062d033e1fSHong Zhang         ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr);
29072d033e1fSHong Zhang         ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr);
2908682e4c99SStefano Zampini       }
29092d033e1fSHong Zhang     } else {
29102d033e1fSHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
29112d033e1fSHong Zhang     }
29122d033e1fSHong Zhang   }
291386e85357SHong Zhang 
291463a75b2aSHong Zhang   /* Destroy Dummy submatrices created for reuse */
291563a75b2aSHong Zhang   ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr);
291663a75b2aSHong Zhang 
29172d033e1fSHong Zhang   ierr = PetscFree(*mat);CHKERRQ(ierr);
29182d033e1fSHong Zhang   PetscFunctionReturn(0);
29192d033e1fSHong Zhang }
29202d033e1fSHong Zhang 
29217dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2922cddf8d76SBarry Smith {
2923dfbe8321SBarry Smith   PetscErrorCode ierr;
292497f1f81fSBarry Smith   PetscInt       i;
2925cddf8d76SBarry Smith 
29263a40ed3dSBarry Smith   PetscFunctionBegin;
2927cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2928df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2929cddf8d76SBarry Smith   }
2930cddf8d76SBarry Smith 
2931cddf8d76SBarry Smith   for (i=0; i<n; i++) {
29327dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2933cddf8d76SBarry Smith   }
29343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2935cddf8d76SBarry Smith }
2936cddf8d76SBarry Smith 
293797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
29384dcbc457SBarry Smith {
2939e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
29406849ba73SBarry Smith   PetscErrorCode ierr;
29415d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
29425d0c19d7SBarry Smith   const PetscInt *idx;
294397f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2944f1af5d2fSBarry Smith   PetscBT        table;
2945bbd702dbSSatish Balay 
29463a40ed3dSBarry Smith   PetscFunctionBegin;
2947d0f46423SBarry Smith   m  = A->rmap->n;
2948e4d965acSSatish Balay   ai = a->i;
2949bfeeae90SHong Zhang   aj = a->j;
29508a047759SSatish Balay 
2951*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ov < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
295206763907SSatish Balay 
2953854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr);
295453b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
295506763907SSatish Balay 
2956e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2957b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2958e4d965acSSatish Balay     isz  = 0;
29596831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2960e4d965acSSatish Balay 
2961e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
29624dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2963b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2964e4d965acSSatish Balay 
2965dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2966e4d965acSSatish Balay     for (j=0; j<n; ++j) {
29672205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
29684dcbc457SBarry Smith     }
296906763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
29706bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2971e4d965acSSatish Balay 
297204a348a9SBarry Smith     k = 0;
297304a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
297404a348a9SBarry Smith       n = isz;
297506763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2976e4d965acSSatish Balay         row   = nidx[k];
2977e4d965acSSatish Balay         start = ai[row];
2978e4d965acSSatish Balay         end   = ai[row+1];
297904a348a9SBarry Smith         for (l = start; l<end; l++) {
2980efb16452SHong Zhang           val = aj[l];
29812205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2982e4d965acSSatish Balay         }
2983e4d965acSSatish Balay       }
2984e4d965acSSatish Balay     }
298570b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2986e4d965acSSatish Balay   }
298794bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2988606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
29893a40ed3dSBarry Smith   PetscFunctionReturn(0);
29904dcbc457SBarry Smith }
299117ab2063SBarry Smith 
29920513a670SBarry Smith /* -------------------------------------------------------------- */
2993dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
29940513a670SBarry Smith {
29950513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
29966849ba73SBarry Smith   PetscErrorCode ierr;
29973b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
29985d0c19d7SBarry Smith   const PetscInt *row,*col;
29995d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
300056cd22aeSBarry Smith   IS             icolp,irowp;
30010298fd71SBarry Smith   PetscInt       *cwork = NULL;
30020298fd71SBarry Smith   PetscScalar    *vwork = NULL;
30030513a670SBarry Smith 
30043a40ed3dSBarry Smith   PetscFunctionBegin;
30054c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
300656cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
30074c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
300856cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
30090513a670SBarry Smith 
30100513a670SBarry Smith   /* determine lengths of permuted rows */
3011854ce69bSBarry Smith   ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr);
30122205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
3013ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
3014f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
301533d57670SJed Brown   ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
30167adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
3017ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
3018606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
30190513a670SBarry Smith 
3020785e854fSJed Brown   ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr);
30210513a670SBarry Smith   for (i=0; i<m; i++) {
302232ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
30232205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
3024cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
302532ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
30260513a670SBarry Smith   }
3027606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
30282205254eSKarl Rupp 
30293c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
30302205254eSKarl Rupp 
30318c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE)
3032b470e4b4SRichard Tran Mills   ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr);
30339fe5e383SStefano Zampini #endif
30340513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
30350513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
303656cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
303756cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
30386bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
30396bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
30406768869dSprj-   if (rowp == colp) {
3041dc29a518SPierre Jolivet     ierr = MatPropagateSymmetryOptions(A,*B);CHKERRQ(ierr);
30426768869dSprj-   }
30433a40ed3dSBarry Smith   PetscFunctionReturn(0);
30440513a670SBarry Smith }
30450513a670SBarry Smith 
3046dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
3047cb5b572fSBarry Smith {
3048dfbe8321SBarry Smith   PetscErrorCode ierr;
3049cb5b572fSBarry Smith 
3050cb5b572fSBarry Smith   PetscFunctionBegin;
305133f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
305233f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
3053be6bf707SBarry Smith     Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
3054be6bf707SBarry Smith     Mat_SeqAIJ        *b = (Mat_SeqAIJ*)B->data;
30552e5835c6SStefano Zampini     const PetscScalar *aa;
3056be6bf707SBarry Smith 
30572e5835c6SStefano Zampini     ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
3058*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(a->i[A->rmap->n] != b->i[B->rmap->n],PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different %" PetscInt_FMT " != %" PetscInt_FMT,a->i[A->rmap->n],b->i[B->rmap->n]);
30592e5835c6SStefano Zampini     ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr);
3060cdc753b6SBarry Smith     ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
30612e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
3062cb5b572fSBarry Smith   } else {
3063cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
3064cb5b572fSBarry Smith   }
3065cb5b572fSBarry Smith   PetscFunctionReturn(0);
3066cb5b572fSBarry Smith }
3067cb5b572fSBarry Smith 
30684994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
3069273d9f13SBarry Smith {
3070dfbe8321SBarry Smith   PetscErrorCode ierr;
3071273d9f13SBarry Smith 
3072273d9f13SBarry Smith   PetscFunctionBegin;
3073f4259b30SLisandro Dalcin   ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr);
3074273d9f13SBarry Smith   PetscFunctionReturn(0);
3075273d9f13SBarry Smith }
3076273d9f13SBarry Smith 
3077f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
30786c0721eeSBarry Smith {
30796c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
30806e111a19SKarl Rupp 
30816c0721eeSBarry Smith   PetscFunctionBegin;
30826c0721eeSBarry Smith   *array = a->a;
30836c0721eeSBarry Smith   PetscFunctionReturn(0);
30846c0721eeSBarry Smith }
30856c0721eeSBarry Smith 
3086f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
30876c0721eeSBarry Smith {
30886c0721eeSBarry Smith   PetscFunctionBegin;
3089f38c1e66SStefano Zampini   *array = NULL;
30906c0721eeSBarry Smith   PetscFunctionReturn(0);
30916c0721eeSBarry Smith }
3092273d9f13SBarry Smith 
30938229c054SShri Abhyankar /*
30948229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
30958229c054SShri Abhyankar    have different nonzero structure.
30968229c054SShri Abhyankar */
3097b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz)
3098ec7775f6SShri Abhyankar {
3099b264fe52SHong Zhang   PetscInt       i,j,k,nzx,nzy;
3100ec7775f6SShri Abhyankar 
3101ec7775f6SShri Abhyankar   PetscFunctionBegin;
3102ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
3103ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
3104b264fe52SHong Zhang     const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i];
3105b264fe52SHong Zhang     nzx = xi[i+1] - xi[i];
3106b264fe52SHong Zhang     nzy = yi[i+1] - yi[i];
31078af7cee1SJed Brown     nnz[i] = 0;
31088af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
3109b264fe52SHong Zhang       for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */
3110b264fe52SHong Zhang       if (k<nzy && yjj[k]==xjj[j]) k++;             /* Skip duplicate */
31118af7cee1SJed Brown       nnz[i]++;
31128af7cee1SJed Brown     }
31138af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
3114ec7775f6SShri Abhyankar   }
3115ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
3116ec7775f6SShri Abhyankar }
3117ec7775f6SShri Abhyankar 
3118b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
3119b264fe52SHong Zhang {
3120b264fe52SHong Zhang   PetscInt       m = Y->rmap->N;
3121b264fe52SHong Zhang   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data;
3122b264fe52SHong Zhang   Mat_SeqAIJ     *y = (Mat_SeqAIJ*)Y->data;
3123b264fe52SHong Zhang   PetscErrorCode ierr;
3124b264fe52SHong Zhang 
3125b264fe52SHong Zhang   PetscFunctionBegin;
3126b264fe52SHong Zhang   /* Set the number of nonzeros in the new matrix */
3127b264fe52SHong Zhang   ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr);
3128b264fe52SHong Zhang   PetscFunctionReturn(0);
3129b264fe52SHong Zhang }
3130b264fe52SHong Zhang 
3131f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
3132ac90fabeSBarry Smith {
3133dfbe8321SBarry Smith   PetscErrorCode ierr;
3134ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
3135ac90fabeSBarry Smith 
3136ac90fabeSBarry Smith   PetscFunctionBegin;
313741f5e1b1SStefano Zampini   if (str == UNKNOWN_NONZERO_PATTERN && x->nz == y->nz) {
313881fa06acSBarry Smith     PetscBool e;
313981fa06acSBarry Smith     ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr);
314081fa06acSBarry Smith     if (e) {
314181fa06acSBarry Smith       ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr);
314281fa06acSBarry Smith       if (e) {
314381fa06acSBarry Smith         str = SAME_NONZERO_PATTERN;
314481fa06acSBarry Smith       }
314581fa06acSBarry Smith     }
314681fa06acSBarry Smith   }
3147ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
31482e5835c6SStefano Zampini     const PetscScalar *xa;
31492e5835c6SStefano Zampini     PetscScalar       *ya,alpha = a;
315081fa06acSBarry Smith     PetscBLASInt      one = 1,bnz;
315181fa06acSBarry Smith 
315281fa06acSBarry Smith     ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
31532e5835c6SStefano Zampini     ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr);
31542e5835c6SStefano Zampini     ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr);
31552e5835c6SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one));
31562e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr);
31572e5835c6SStefano Zampini     ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr);
315841f5e1b1SStefano Zampini     ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr);
3159acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
3160a3fa217bSJose E. Roman     ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
3161ab784542SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
3162ab784542SHong Zhang     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
3163ac90fabeSBarry Smith   } else {
31648229c054SShri Abhyankar     Mat      B;
31658229c054SShri Abhyankar     PetscInt *nnz;
3166785e854fSJed Brown     ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr);
3167ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
3168bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
316981fa06acSBarry Smith     ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr);
31702e5835c6SStefano Zampini     ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr);
31718229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
3172ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
3173ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
317479c2fd05SStefano Zampini     ierr = MatHeaderMerge(Y,&B);CHKERRQ(ierr);
31758229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
3176ac90fabeSBarry Smith   }
3177ac90fabeSBarry Smith   PetscFunctionReturn(0);
3178ac90fabeSBarry Smith }
3179ac90fabeSBarry Smith 
31802726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat)
3181354c94deSBarry Smith {
3182354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
3183354c94deSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
3184354c94deSBarry Smith   PetscInt       i,nz;
3185354c94deSBarry Smith   PetscScalar    *a;
3186ce496241SStefano Zampini   PetscErrorCode ierr;
3187354c94deSBarry Smith 
3188354c94deSBarry Smith   PetscFunctionBegin;
3189354c94deSBarry Smith   nz = aij->nz;
3190ce496241SStefano Zampini   ierr = MatSeqAIJGetArray(mat,&a);CHKERRQ(ierr);
31912205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
3192ce496241SStefano Zampini   ierr = MatSeqAIJRestoreArray(mat,&a);CHKERRQ(ierr);
3193354c94deSBarry Smith #else
3194354c94deSBarry Smith   PetscFunctionBegin;
3195354c94deSBarry Smith #endif
3196354c94deSBarry Smith   PetscFunctionReturn(0);
3197354c94deSBarry Smith }
3198354c94deSBarry Smith 
3199985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3200e34fafa9SBarry Smith {
3201e34fafa9SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3202e34fafa9SBarry Smith   PetscErrorCode  ierr;
3203d0f46423SBarry Smith   PetscInt        i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3204e34fafa9SBarry Smith   PetscReal       atmp;
3205985db425SBarry Smith   PetscScalar     *x;
3206ce496241SStefano Zampini   const MatScalar *aa,*av;
3207e34fafa9SBarry Smith 
3208e34fafa9SBarry Smith   PetscFunctionBegin;
3209*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3210ce496241SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
3211ce496241SStefano Zampini   aa = av;
3212e34fafa9SBarry Smith   ai = a->i;
3213e34fafa9SBarry Smith   aj = a->j;
3214e34fafa9SBarry Smith 
3215985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3216475b8b61SHong Zhang   ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
3217e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3218*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3219e34fafa9SBarry Smith   for (i=0; i<m; i++) {
3220e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3221e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
3222985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
3223985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3224985db425SBarry Smith       aa++; aj++;
3225985db425SBarry Smith     }
3226985db425SBarry Smith   }
3227475b8b61SHong Zhang   ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
3228ce496241SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
3229985db425SBarry Smith   PetscFunctionReturn(0);
3230985db425SBarry Smith }
3231985db425SBarry Smith 
3232985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3233985db425SBarry Smith {
3234985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3235985db425SBarry Smith   PetscErrorCode  ierr;
3236d0f46423SBarry Smith   PetscInt        i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3237985db425SBarry Smith   PetscScalar     *x;
3238ce496241SStefano Zampini   const MatScalar *aa,*av;
3239985db425SBarry Smith 
3240985db425SBarry Smith   PetscFunctionBegin;
3241*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3242ce496241SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
3243ce496241SStefano Zampini   aa = av;
3244985db425SBarry Smith   ai = a->i;
3245985db425SBarry Smith   aj = a->j;
3246985db425SBarry Smith 
3247985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3248fa213d2fSHong Zhang   ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
3249985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3250*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3251985db425SBarry Smith   for (i=0; i<m; i++) {
3252985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3253d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3254985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3255985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
3256985db425SBarry Smith       x[i] = 0.0;
3257985db425SBarry Smith       if (idx) {
3258985db425SBarry Smith         for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */
3259985db425SBarry Smith           if (aj[j] > j) {
3260985db425SBarry Smith             idx[i] = j;
3261985db425SBarry Smith             break;
3262985db425SBarry Smith           }
3263985db425SBarry Smith         }
32641a254869SHong Zhang         /* in case first implicit 0.0 in the row occurs at ncols-th column */
32651a254869SHong Zhang         if (j==ncols && j < A->cmap->n) idx[i] = j;
3266985db425SBarry Smith       }
3267985db425SBarry Smith     }
3268985db425SBarry Smith     for (j=0; j<ncols; j++) {
3269985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3270985db425SBarry Smith       aa++; aj++;
3271985db425SBarry Smith     }
3272985db425SBarry Smith   }
3273fa213d2fSHong Zhang   ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
3274ce496241SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
3275985db425SBarry Smith   PetscFunctionReturn(0);
3276985db425SBarry Smith }
3277985db425SBarry Smith 
3278c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3279c87e5d42SMatthew Knepley {
3280c87e5d42SMatthew Knepley   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3281c87e5d42SMatthew Knepley   PetscErrorCode  ierr;
3282c87e5d42SMatthew Knepley   PetscInt        i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3283ce496241SStefano Zampini   PetscScalar     *x;
3284ce496241SStefano Zampini   const MatScalar *aa,*av;
3285c87e5d42SMatthew Knepley 
3286c87e5d42SMatthew Knepley   PetscFunctionBegin;
3287ce496241SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
3288ce496241SStefano Zampini   aa = av;
3289c87e5d42SMatthew Knepley   ai = a->i;
3290c87e5d42SMatthew Knepley   aj = a->j;
3291c87e5d42SMatthew Knepley 
3292c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3293f07e67edSHong Zhang   ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
3294c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3295*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != m,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %" PetscInt_FMT " vs. %" PetscInt_FMT " rows", m, n);
3296c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
3297c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
3298f07e67edSHong Zhang     if (ncols == A->cmap->n) { /* row is dense */
3299f07e67edSHong Zhang       x[i] = *aa; if (idx) idx[i] = 0;
3300f07e67edSHong Zhang     } else {  /* row is sparse so already KNOW minimum is 0.0 or higher */
3301f07e67edSHong Zhang       x[i] = 0.0;
3302f07e67edSHong Zhang       if (idx) {   /* find first implicit 0.0 in the row */
3303289a08f5SMatthew Knepley         for (j=0; j<ncols; j++) {
3304f07e67edSHong Zhang           if (aj[j] > j) {
3305f07e67edSHong Zhang             idx[i] = j;
33062205254eSKarl Rupp             break;
33072205254eSKarl Rupp           }
3308289a08f5SMatthew Knepley         }
3309f07e67edSHong Zhang         /* in case first implicit 0.0 in the row occurs at ncols-th column */
3310f07e67edSHong Zhang         if (j==ncols && j < A->cmap->n) idx[i] = j;
3311f07e67edSHong Zhang       }
3312289a08f5SMatthew Knepley     }
3313c87e5d42SMatthew Knepley     for (j=0; j<ncols; j++) {
3314f07e67edSHong Zhang       if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3315c87e5d42SMatthew Knepley       aa++; aj++;
3316c87e5d42SMatthew Knepley     }
3317c87e5d42SMatthew Knepley   }
3318f07e67edSHong Zhang   ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
3319ce496241SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
3320c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
3321c87e5d42SMatthew Knepley }
3322c87e5d42SMatthew Knepley 
3323985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3324985db425SBarry Smith {
3325985db425SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
3326985db425SBarry Smith   PetscErrorCode  ierr;
3327d9ca1df4SBarry Smith   PetscInt        i,j,m = A->rmap->n,ncols,n;
3328d9ca1df4SBarry Smith   const PetscInt  *ai,*aj;
3329985db425SBarry Smith   PetscScalar     *x;
3330ce496241SStefano Zampini   const MatScalar *aa,*av;
3331985db425SBarry Smith 
3332985db425SBarry Smith   PetscFunctionBegin;
3333*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3334ce496241SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
3335ce496241SStefano Zampini   aa = av;
3336985db425SBarry Smith   ai = a->i;
3337985db425SBarry Smith   aj = a->j;
3338985db425SBarry Smith 
3339985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3340fa213d2fSHong Zhang   ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr);
3341985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3342*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != m,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3343985db425SBarry Smith   for (i=0; i<m; i++) {
3344985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3345d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3346985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3347985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
3348985db425SBarry Smith       x[i] = 0.0;
3349985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
3350985db425SBarry Smith         for (j=0; j<ncols; j++) {
3351985db425SBarry Smith           if (aj[j] > j) {
3352985db425SBarry Smith             idx[i] = j;
3353985db425SBarry Smith             break;
3354985db425SBarry Smith           }
3355985db425SBarry Smith         }
3356fa213d2fSHong Zhang         /* in case first implicit 0.0 in the row occurs at ncols-th column */
3357fa213d2fSHong Zhang         if (j==ncols && j < A->cmap->n) idx[i] = j;
3358985db425SBarry Smith       }
3359985db425SBarry Smith     }
3360985db425SBarry Smith     for (j=0; j<ncols; j++) {
3361985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3362985db425SBarry Smith       aa++; aj++;
3363e34fafa9SBarry Smith     }
3364e34fafa9SBarry Smith   }
3365fa213d2fSHong Zhang   ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr);
3366ce496241SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
3367e34fafa9SBarry Smith   PetscFunctionReturn(0);
3368e34fafa9SBarry Smith }
3369bbead8a2SBarry Smith 
3370713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3371bbead8a2SBarry Smith {
3372bbead8a2SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*) A->data;
3373bbead8a2SBarry Smith   PetscErrorCode  ierr;
337433d57670SJed Brown   PetscInt        i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
3375bbead8a2SBarry Smith   MatScalar       *diag,work[25],*v_work;
33760da83c2eSBarry Smith   const PetscReal shift = 0.0;
33771a9391e3SHong Zhang   PetscBool       allowzeropivot,zeropivotdetected=PETSC_FALSE;
3378bbead8a2SBarry Smith 
3379bbead8a2SBarry Smith   PetscFunctionBegin;
3380a455e926SHong Zhang   allowzeropivot = PetscNot(A->erroriffailure);
33814a0d0026SBarry Smith   if (a->ibdiagvalid) {
33824a0d0026SBarry Smith     if (values) *values = a->ibdiag;
33834a0d0026SBarry Smith     PetscFunctionReturn(0);
33844a0d0026SBarry Smith   }
3385bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3386bbead8a2SBarry Smith   if (!a->ibdiag) {
3387785e854fSJed Brown     ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr);
33883bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3389bbead8a2SBarry Smith   }
3390bbead8a2SBarry Smith   diag = a->ibdiag;
3391bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3392bbead8a2SBarry Smith   /* factor and invert each block */
3393bbead8a2SBarry Smith   switch (bs) {
3394bbead8a2SBarry Smith   case 1:
3395bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3396bbead8a2SBarry Smith       ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3397ec1892c8SHong Zhang       if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) {
3398ec1892c8SHong Zhang         if (allowzeropivot) {
33997b6c816cSBarry Smith           A->factorerrortype             = MAT_FACTOR_NUMERIC_ZEROPIVOT;
34007b6c816cSBarry Smith           A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]);
34017b6c816cSBarry Smith           A->factorerror_zeropivot_row   = i;
34027d3de750SJacob Faibussowitsch           ierr = PetscInfo(A,"Zero pivot, row %" PetscInt_FMT " pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr);
340398921bdaSJacob Faibussowitsch         } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %" PetscInt_FMT " pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);
3404ec1892c8SHong Zhang       }
3405bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3406bbead8a2SBarry Smith     }
3407bbead8a2SBarry Smith     break;
3408bbead8a2SBarry Smith   case 2:
3409bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3410bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3411bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
3412a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34137b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
341496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3415bbead8a2SBarry Smith       diag += 4;
3416bbead8a2SBarry Smith     }
3417bbead8a2SBarry Smith     break;
3418bbead8a2SBarry Smith   case 3:
3419bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3420bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3421bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
3422a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34237b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
342496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3425bbead8a2SBarry Smith       diag += 9;
3426bbead8a2SBarry Smith     }
3427bbead8a2SBarry Smith     break;
3428bbead8a2SBarry Smith   case 4:
3429bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3430bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3431bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
3432a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34337b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
343496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3435bbead8a2SBarry Smith       diag += 16;
3436bbead8a2SBarry Smith     }
3437bbead8a2SBarry Smith     break;
3438bbead8a2SBarry Smith   case 5:
3439bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3440bbead8a2SBarry 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;
3441bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
3442a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34437b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
344496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3445bbead8a2SBarry Smith       diag += 25;
3446bbead8a2SBarry Smith     }
3447bbead8a2SBarry Smith     break;
3448bbead8a2SBarry Smith   case 6:
3449bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3450bbead8a2SBarry 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;
3451bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
3452a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34537b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
345496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3455bbead8a2SBarry Smith       diag += 36;
3456bbead8a2SBarry Smith     }
3457bbead8a2SBarry Smith     break;
3458bbead8a2SBarry Smith   case 7:
3459bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3460bbead8a2SBarry 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;
3461bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
3462a455e926SHong Zhang       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34637b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
346496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3465bbead8a2SBarry Smith       diag += 49;
3466bbead8a2SBarry Smith     }
3467bbead8a2SBarry Smith     break;
3468bbead8a2SBarry Smith   default:
3469dcca6d9dSJed Brown     ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr);
3470bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3471bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3472bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3473bbead8a2SBarry Smith       }
3474bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
34755f8bbccaSHong Zhang       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
34767b6c816cSBarry Smith       if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
347796b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3478bbead8a2SBarry Smith       diag += bs2;
3479bbead8a2SBarry Smith     }
3480bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3481bbead8a2SBarry Smith   }
3482bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3483bbead8a2SBarry Smith   PetscFunctionReturn(0);
3484bbead8a2SBarry Smith }
3485bbead8a2SBarry Smith 
348673a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
348773a71a0fSBarry Smith {
348873a71a0fSBarry Smith   PetscErrorCode ierr;
348973a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
3490fff043a9SJunchao Zhang   PetscScalar    a,*aa;
349173a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
349273a71a0fSBarry Smith 
349373a71a0fSBarry Smith   PetscFunctionBegin;
349473a71a0fSBarry Smith   if (!x->assembled) {
349573a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
349673a71a0fSBarry Smith     for (i=0; i<m; i++) {
349773a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
349873a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
349973a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
350073a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
350173a71a0fSBarry Smith       }
350273a71a0fSBarry Smith     }
3503e2ce353bSJunchao Zhang   } else {
3504fff043a9SJunchao Zhang     ierr = MatSeqAIJGetArrayWrite(x,&aa);CHKERRQ(ierr);
3505fff043a9SJunchao Zhang     for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aa+i);CHKERRQ(ierr);}
3506fff043a9SJunchao Zhang     ierr = MatSeqAIJRestoreArrayWrite(x,&aa);CHKERRQ(ierr);
3507e2ce353bSJunchao Zhang   }
350873a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
350973a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
351073a71a0fSBarry Smith   PetscFunctionReturn(0);
351173a71a0fSBarry Smith }
351273a71a0fSBarry Smith 
3513679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */
3514679944adSJunchao Zhang PetscErrorCode  MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx)
3515679944adSJunchao Zhang {
3516679944adSJunchao Zhang   PetscErrorCode ierr;
3517679944adSJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
3518679944adSJunchao Zhang   PetscScalar    a;
3519679944adSJunchao Zhang   PetscInt       m,n,i,j,col,nskip;
3520679944adSJunchao Zhang 
3521679944adSJunchao Zhang   PetscFunctionBegin;
3522679944adSJunchao Zhang   nskip = high - low;
3523679944adSJunchao Zhang   ierr  = MatGetSize(x,&m,&n);CHKERRQ(ierr);
3524679944adSJunchao Zhang   n    -= nskip; /* shrink number of columns where nonzeros can be set */
3525679944adSJunchao Zhang   for (i=0; i<m; i++) {
3526679944adSJunchao Zhang     for (j=0; j<aij->imax[i]; j++) {
3527679944adSJunchao Zhang       ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
3528679944adSJunchao Zhang       col  = (PetscInt)(n*PetscRealPart(a));
3529679944adSJunchao Zhang       if (col >= low) col += nskip; /* shift col rightward to skip the hole */
3530679944adSJunchao Zhang       ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
3531679944adSJunchao Zhang     }
3532e2ce353bSJunchao Zhang   }
3533679944adSJunchao Zhang   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3534679944adSJunchao Zhang   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3535679944adSJunchao Zhang   PetscFunctionReturn(0);
3536679944adSJunchao Zhang }
3537679944adSJunchao Zhang 
3538682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
35390a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3540cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3541cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3542cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
354397304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
35447c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
35457c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3546f4259b30SLisandro Dalcin                                         NULL,
3547f4259b30SLisandro Dalcin                                         NULL,
3548f4259b30SLisandro Dalcin                                         NULL,
3549f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
3550cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3551f4259b30SLisandro Dalcin                                         NULL,
355241f059aeSBarry Smith                                         MatSOR_SeqAIJ,
355391e9d3e2SHong Zhang                                         MatTranspose_SeqAIJ,
355497304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3555cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3556cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3557cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3558cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
3559f4259b30SLisandro Dalcin                                 /* 20*/ NULL,
3560cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3561cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3562cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3563d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3564f4259b30SLisandro Dalcin                                         NULL,
3565f4259b30SLisandro Dalcin                                         NULL,
3566f4259b30SLisandro Dalcin                                         NULL,
3567f4259b30SLisandro Dalcin                                         NULL,
35684994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3569f4259b30SLisandro Dalcin                                         NULL,
3570f4259b30SLisandro Dalcin                                         NULL,
3571f4259b30SLisandro Dalcin                                         NULL,
3572f4259b30SLisandro Dalcin                                         NULL,
3573d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3574f4259b30SLisandro Dalcin                                         NULL,
3575f4259b30SLisandro Dalcin                                         NULL,
3576cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3577f4259b30SLisandro Dalcin                                         NULL,
3578d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
35797dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqAIJ,
3580cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3581cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3582cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3583d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3584cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
35857d68702bSBarry Smith                                         MatShift_SeqAIJ,
358679299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
35876e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
358873a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
35893b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
35903b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
35913b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3592a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
359393dfae19SHong Zhang                                 /* 54*/ MatFDColoringCreate_SeqXAIJ,
3594f4259b30SLisandro Dalcin                                         NULL,
3595f4259b30SLisandro Dalcin                                         NULL,
3596cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3597f4259b30SLisandro Dalcin                                         NULL,
3598f4259b30SLisandro Dalcin                                 /* 59*/ NULL,
3599b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3600b9b97703SBarry Smith                                         MatView_SeqAIJ,
3601f4259b30SLisandro Dalcin                                         NULL,
3602f4259b30SLisandro Dalcin                                         NULL,
3603f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
3604321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3605f4259b30SLisandro Dalcin                                         NULL,
3606f4259b30SLisandro Dalcin                                         NULL,
3607f4259b30SLisandro Dalcin                                         NULL,
3608d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3609c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3610f4259b30SLisandro Dalcin                                         NULL,
3611f4259b30SLisandro Dalcin                                         NULL,
3612f4259b30SLisandro Dalcin                                         NULL,
3613f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
36143acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
3615f4259b30SLisandro Dalcin                                         NULL,
3616f4259b30SLisandro Dalcin                                         NULL,
3617f4259b30SLisandro Dalcin                                         NULL,
36186ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
3619f4259b30SLisandro Dalcin                                         NULL,
3620f4259b30SLisandro Dalcin                                         NULL,
3621f4259b30SLisandro Dalcin                                         NULL,
3622bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3623d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
36241cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
3625f4259b30SLisandro Dalcin                                         NULL,
3626f4259b30SLisandro Dalcin                                         NULL,
3627f4259b30SLisandro Dalcin                                         NULL,
3628f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
3629f4259b30SLisandro Dalcin                                         NULL,
363026be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
3631f4259b30SLisandro Dalcin                                         NULL,
3632f4259b30SLisandro Dalcin                                         NULL,
36338fa4b5a6SHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy,
3634f4259b30SLisandro Dalcin                                         NULL,
3635f4259b30SLisandro Dalcin                                         NULL,
36366fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
3637f4259b30SLisandro Dalcin                                         NULL,
36384222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqAIJ,
3639f4259b30SLisandro Dalcin                                         NULL,
3640f4259b30SLisandro Dalcin                                         NULL,
364187d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
3642f4259b30SLisandro Dalcin                                         NULL,
3643d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
364499cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3645f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3646f4259b30SLisandro Dalcin                                         NULL,
3647f4259b30SLisandro Dalcin                                         NULL,
3648cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3649f4259b30SLisandro Dalcin                                         NULL,
36502af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
3651f4259b30SLisandro Dalcin                                         NULL,
3652599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3653f4259b30SLisandro Dalcin                                 /*114*/ NULL,
3654f4259b30SLisandro Dalcin                                         NULL,
3655f4259b30SLisandro Dalcin                                         NULL,
3656f4259b30SLisandro Dalcin                                         NULL,
3657f4259b30SLisandro Dalcin                                         NULL,
3658f4259b30SLisandro Dalcin                                 /*119*/ NULL,
3659f4259b30SLisandro Dalcin                                         NULL,
3660f4259b30SLisandro Dalcin                                         NULL,
3661f4259b30SLisandro Dalcin                                         NULL,
3662b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
36630716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3664a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqAIJ,
366537868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
36660da83c2eSBarry Smith                                         MatInvertVariableBlockDiagonal_SeqAIJ,
3667f4259b30SLisandro Dalcin                                         NULL,
3668f4259b30SLisandro Dalcin                                 /*129*/ NULL,
3669f4259b30SLisandro Dalcin                                         NULL,
3670f4259b30SLisandro Dalcin                                         NULL,
367175648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3672b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3673b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
36742b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
3675f4259b30SLisandro Dalcin                                         NULL,
3676f4259b30SLisandro Dalcin                                         NULL,
36773964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
3678f4259b30SLisandro Dalcin                                  /*139*/NULL,
3679f4259b30SLisandro Dalcin                                         NULL,
3680f4259b30SLisandro Dalcin                                         NULL,
36813a062f41SBarry Smith                                         MatFDColoringSetUp_SeqXAIJ,
36829c8f2541SHong Zhang                                         MatFindOffBlockDiagonalEntries_SeqAIJ,
36834222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqAIJ,
36844222ddf1SHong Zhang                                  /*145*/MatDestroySubMatrices_SeqAIJ,
3685f4259b30SLisandro Dalcin                                         NULL,
3686f4259b30SLisandro Dalcin                                         NULL
36879e29f15eSvictorle };
368817ab2063SBarry Smith 
36897087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3690bef8e0ddSBarry Smith {
3691bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
369297f1f81fSBarry Smith   PetscInt   i,nz,n;
3693bef8e0ddSBarry Smith 
3694bef8e0ddSBarry Smith   PetscFunctionBegin;
3695bef8e0ddSBarry Smith   nz = aij->maxnz;
3696d0f46423SBarry Smith   n  = mat->rmap->n;
3697bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3698bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3699bef8e0ddSBarry Smith   }
3700bef8e0ddSBarry Smith   aij->nz = nz;
3701bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3702bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3703bef8e0ddSBarry Smith   }
3704bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3705bef8e0ddSBarry Smith }
3706bef8e0ddSBarry Smith 
3707a3bb6f32SFande Kong /*
3708ddea5d60SJunchao Zhang  * Given a sparse matrix with global column indices, compact it by using a local column space.
3709ddea5d60SJunchao Zhang  * The result matrix helps saving memory in other algorithms, such as MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable()
3710ddea5d60SJunchao Zhang  */
3711a3bb6f32SFande Kong PetscErrorCode  MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping)
3712a3bb6f32SFande Kong {
3713a3bb6f32SFande Kong   Mat_SeqAIJ         *aij = (Mat_SeqAIJ*)mat->data;
3714a3bb6f32SFande Kong   PetscTable         gid1_lid1;
3715a3bb6f32SFande Kong   PetscTablePosition tpos;
371625b670f0SStefano Zampini   PetscInt           gid,lid,i,ec,nz = aij->nz;
371725b670f0SStefano Zampini   PetscInt           *garray,*jj = aij->j;
3718a3bb6f32SFande Kong   PetscErrorCode     ierr;
3719a3bb6f32SFande Kong 
3720a3bb6f32SFande Kong   PetscFunctionBegin;
3721a3bb6f32SFande Kong   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3722a3bb6f32SFande Kong   PetscValidPointer(mapping,2);
3723a3bb6f32SFande Kong   /* use a table */
3724a3bb6f32SFande Kong   ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr);
3725a3bb6f32SFande Kong   ec = 0;
372625b670f0SStefano Zampini   for (i=0; i<nz; i++) {
372725b670f0SStefano Zampini     PetscInt data,gid1 = jj[i] + 1;
3728a3bb6f32SFande Kong     ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr);
3729a3bb6f32SFande Kong     if (!data) {
3730a3bb6f32SFande Kong       /* one based table */
3731a3bb6f32SFande Kong       ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr);
3732a3bb6f32SFande Kong     }
3733a3bb6f32SFande Kong   }
3734a3bb6f32SFande Kong   /* form array of columns we need */
3735b3c64f9dSJunchao Zhang   ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
3736a3bb6f32SFande Kong   ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
3737a3bb6f32SFande Kong   while (tpos) {
3738a3bb6f32SFande Kong     ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
3739a3bb6f32SFande Kong     gid--;
3740a3bb6f32SFande Kong     lid--;
3741a3bb6f32SFande Kong     garray[lid] = gid;
3742a3bb6f32SFande Kong   }
3743a3bb6f32SFande Kong   ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */
3744a3bb6f32SFande Kong   ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr);
3745a3bb6f32SFande Kong   for (i=0; i<ec; i++) {
3746a3bb6f32SFande Kong     ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr);
3747a3bb6f32SFande Kong   }
3748a3bb6f32SFande Kong   /* compact out the extra columns in B */
374925b670f0SStefano Zampini   for (i=0; i<nz; i++) {
375025b670f0SStefano Zampini     PetscInt gid1 = jj[i] + 1;
3751a3bb6f32SFande Kong     ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr);
3752a3bb6f32SFande Kong     lid--;
375325b670f0SStefano Zampini     jj[i] = lid;
3754a3bb6f32SFande Kong   }
3755ca5434daSLawrence Mitchell   ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
3756a3bb6f32SFande Kong   ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr);
375725b670f0SStefano Zampini   ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr);
3758a3bb6f32SFande Kong   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr);
3759a3bb6f32SFande Kong   ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr);
3760a3bb6f32SFande Kong   PetscFunctionReturn(0);
3761a3bb6f32SFande Kong }
3762a3bb6f32SFande Kong 
3763bef8e0ddSBarry Smith /*@
3764bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3765bef8e0ddSBarry Smith        in the matrix.
3766bef8e0ddSBarry Smith 
3767bef8e0ddSBarry Smith   Input Parameters:
3768bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3769bef8e0ddSBarry Smith -  indices - the column indices
3770bef8e0ddSBarry Smith 
377115091d37SBarry Smith   Level: advanced
377215091d37SBarry Smith 
3773bef8e0ddSBarry Smith   Notes:
3774bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3775bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3776bef8e0ddSBarry Smith   of the MatSetValues() operation.
3777bef8e0ddSBarry Smith 
3778bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3779d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3780bef8e0ddSBarry Smith 
3781bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3782bef8e0ddSBarry Smith 
3783b9617806SBarry Smith     The indices should start with zero, not one.
3784b9617806SBarry Smith 
3785bef8e0ddSBarry Smith @*/
37867087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3787bef8e0ddSBarry Smith {
37884ac538c5SBarry Smith   PetscErrorCode ierr;
3789bef8e0ddSBarry Smith 
3790bef8e0ddSBarry Smith   PetscFunctionBegin;
37910700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
37924482741eSBarry Smith   PetscValidPointer(indices,2);
37934ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3794bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3795bef8e0ddSBarry Smith }
3796bef8e0ddSBarry Smith 
3797be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3798be6bf707SBarry Smith 
37997087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3800be6bf707SBarry Smith {
3801be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
38026849ba73SBarry Smith   PetscErrorCode ierr;
3803d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3804be6bf707SBarry Smith 
3805be6bf707SBarry Smith   PetscFunctionBegin;
3806*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!aij->nonew,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3807be6bf707SBarry Smith 
3808be6bf707SBarry Smith   /* allocate space for values if not already there */
3809be6bf707SBarry Smith   if (!aij->saved_values) {
3810854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr);
38113bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3812be6bf707SBarry Smith   }
3813be6bf707SBarry Smith 
3814be6bf707SBarry Smith   /* copy values over */
3815580bdb30SBarry Smith   ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr);
3816be6bf707SBarry Smith   PetscFunctionReturn(0);
3817be6bf707SBarry Smith }
3818be6bf707SBarry Smith 
3819be6bf707SBarry Smith /*@
3820be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3821be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3822be6bf707SBarry Smith        nonlinear portion.
3823be6bf707SBarry Smith 
3824be6bf707SBarry Smith    Collect on Mat
3825be6bf707SBarry Smith 
3826be6bf707SBarry Smith   Input Parameters:
38270e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3828be6bf707SBarry Smith 
382915091d37SBarry Smith   Level: advanced
383015091d37SBarry Smith 
3831be6bf707SBarry Smith   Common Usage, with SNESSolve():
3832be6bf707SBarry Smith $    Create Jacobian matrix
3833be6bf707SBarry Smith $    Set linear terms into matrix
3834be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3835be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3836be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3837512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3838be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3839be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3840be6bf707SBarry Smith $    In your Jacobian routine
3841be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3842be6bf707SBarry Smith $      Set nonlinear terms in matrix
3843be6bf707SBarry Smith 
3844be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3845be6bf707SBarry Smith $    // build linear portion of Jacobian
3846512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3847be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3848be6bf707SBarry Smith $    loop over nonlinear iterations
3849be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3850be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3851be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3852be6bf707SBarry Smith $       Solve linear system with Jacobian
3853be6bf707SBarry Smith $    endloop
3854be6bf707SBarry Smith 
3855be6bf707SBarry Smith   Notes:
3856be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3857512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3858be6bf707SBarry Smith     calling this routine.
3859be6bf707SBarry Smith 
38600c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
38610c468ba9SBarry Smith     and does not allocated additional space.
38620c468ba9SBarry Smith 
3863be6bf707SBarry Smith .seealso: MatRetrieveValues()
3864be6bf707SBarry Smith 
3865be6bf707SBarry Smith @*/
38667087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3867be6bf707SBarry Smith {
38684ac538c5SBarry Smith   PetscErrorCode ierr;
3869be6bf707SBarry Smith 
3870be6bf707SBarry Smith   PetscFunctionBegin;
38710700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3872*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3873*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
38744ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3875be6bf707SBarry Smith   PetscFunctionReturn(0);
3876be6bf707SBarry Smith }
3877be6bf707SBarry Smith 
38787087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3879be6bf707SBarry Smith {
3880be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
38816849ba73SBarry Smith   PetscErrorCode ierr;
3882d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3883be6bf707SBarry Smith 
3884be6bf707SBarry Smith   PetscFunctionBegin;
3885*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!aij->nonew,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3886*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!aij->saved_values,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3887be6bf707SBarry Smith   /* copy values over */
3888580bdb30SBarry Smith   ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr);
3889be6bf707SBarry Smith   PetscFunctionReturn(0);
3890be6bf707SBarry Smith }
3891be6bf707SBarry Smith 
3892be6bf707SBarry Smith /*@
3893be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3894be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3895be6bf707SBarry Smith        nonlinear portion.
3896be6bf707SBarry Smith 
3897be6bf707SBarry Smith    Collect on Mat
3898be6bf707SBarry Smith 
3899be6bf707SBarry Smith   Input Parameters:
3900386f7cf9SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3901be6bf707SBarry Smith 
390215091d37SBarry Smith   Level: advanced
390315091d37SBarry Smith 
3904be6bf707SBarry Smith .seealso: MatStoreValues()
3905be6bf707SBarry Smith 
3906be6bf707SBarry Smith @*/
39077087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3908be6bf707SBarry Smith {
39094ac538c5SBarry Smith   PetscErrorCode ierr;
3910be6bf707SBarry Smith 
3911be6bf707SBarry Smith   PetscFunctionBegin;
39120700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3913*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3914*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
39154ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3916be6bf707SBarry Smith   PetscFunctionReturn(0);
3917be6bf707SBarry Smith }
3918be6bf707SBarry Smith 
3919be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
392017ab2063SBarry Smith /*@C
3921682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
39220d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
39236e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
392451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
39252bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
392617ab2063SBarry Smith 
3927d083f849SBarry Smith    Collective
3928db81eaa0SLois Curfman McInnes 
392917ab2063SBarry Smith    Input Parameters:
3930db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
393117ab2063SBarry Smith .  m - number of rows
393217ab2063SBarry Smith .  n - number of columns
393317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
393451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
39350298fd71SBarry Smith          (possibly different for each row) or NULL
393617ab2063SBarry Smith 
393717ab2063SBarry Smith    Output Parameter:
3938416022c9SBarry Smith .  A - the matrix
393917ab2063SBarry Smith 
3940175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3941f6f02116SRichard Tran Mills    MatXXXXSetPreallocation() paradigm instead of this routine directly.
3942175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3943175b88e8SBarry Smith 
3944b259b22eSLois Curfman McInnes    Notes:
394549a6f317SBarry Smith    If nnz is given then nz is ignored
394649a6f317SBarry Smith 
394717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
394817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
39490002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
395044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
395117ab2063SBarry Smith 
395217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
39530298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
39543d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
39556da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
395617ab2063SBarry Smith 
3957682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
39584fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3959682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
39606c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
39616c7ebb05SLois Curfman McInnes 
39626c7ebb05SLois Curfman McInnes    Options Database Keys:
3963698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
39649db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
396517ab2063SBarry Smith 
3966027ccd11SLois Curfman McInnes    Level: intermediate
3967027ccd11SLois Curfman McInnes 
396869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
396936db0b34SBarry Smith 
397017ab2063SBarry Smith @*/
39717087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
397217ab2063SBarry Smith {
3973dfbe8321SBarry Smith   PetscErrorCode ierr;
39746945ee14SBarry Smith 
39753a40ed3dSBarry Smith   PetscFunctionBegin;
3976f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3977117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3978c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3979d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3980273d9f13SBarry Smith   PetscFunctionReturn(0);
3981273d9f13SBarry Smith }
3982273d9f13SBarry Smith 
3983273d9f13SBarry Smith /*@C
3984273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3985273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3986273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3987273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3988273d9f13SBarry Smith 
3989d083f849SBarry Smith    Collective
3990273d9f13SBarry Smith 
3991273d9f13SBarry Smith    Input Parameters:
39921c4f3114SJed Brown +  B - The matrix
3993273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3994273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
39950298fd71SBarry Smith          (possibly different for each row) or NULL
3996273d9f13SBarry Smith 
3997273d9f13SBarry Smith    Notes:
399849a6f317SBarry Smith      If nnz is given then nz is ignored
399949a6f317SBarry Smith 
4000273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
4001273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
4002273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
4003273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
4004273d9f13SBarry Smith 
4005273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
40060298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
4007273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
4008273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
4009273d9f13SBarry Smith 
4010aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
4011aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
4012aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
4013aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
4014aa95bbe8SBarry Smith 
4015a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
4016a96a251dSBarry Smith    entries or columns indices
4017a96a251dSBarry Smith 
4018273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
4019273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
4020273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
4021273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
4022273d9f13SBarry Smith 
4023273d9f13SBarry Smith    Options Database Keys:
4024698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
402547b2e64bSBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
4026273d9f13SBarry Smith 
4027273d9f13SBarry Smith    Level: intermediate
4028273d9f13SBarry Smith 
402919b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(),
403019b08ed1SBarry Smith           MatSeqAIJSetTotalPreallocation()
4031273d9f13SBarry Smith 
4032273d9f13SBarry Smith @*/
40337087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
4034273d9f13SBarry Smith {
40354ac538c5SBarry Smith   PetscErrorCode ierr;
4036a23d5eceSKris Buschelman 
4037a23d5eceSKris Buschelman   PetscFunctionBegin;
40386ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
40396ba663aaSJed Brown   PetscValidType(B,1);
40404ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
4041a23d5eceSKris Buschelman   PetscFunctionReturn(0);
4042a23d5eceSKris Buschelman }
4043a23d5eceSKris Buschelman 
40447087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
4045a23d5eceSKris Buschelman {
4046273d9f13SBarry Smith   Mat_SeqAIJ     *b;
40472576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
40486849ba73SBarry Smith   PetscErrorCode ierr;
404997f1f81fSBarry Smith   PetscInt       i;
4050273d9f13SBarry Smith 
4051273d9f13SBarry Smith   PetscFunctionBegin;
40522576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
4053a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
4054c461c341SBarry Smith     skipallocation = PETSC_TRUE;
4055c461c341SBarry Smith     nz             = 0;
4056c461c341SBarry Smith   }
405726283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
405826283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
4059899cda47SBarry Smith 
4060435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
4061*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %" PetscInt_FMT,nz);
4062cf9c20a2SJed Brown   if (PetscUnlikelyDebug(nnz)) {
4063d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
4064*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(nnz[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %" PetscInt_FMT " value %" PetscInt_FMT,i,nnz[i]);
4065*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(nnz[i] > B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %" PetscInt_FMT " value %" PetscInt_FMT " rowlength %" PetscInt_FMT,i,nnz[i],B->cmap->n);
4066b73539f3SBarry Smith     }
4067b73539f3SBarry Smith   }
4068b73539f3SBarry Smith 
4069273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
40702205254eSKarl Rupp 
4071273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
4072273d9f13SBarry Smith 
4073ab93d7beSBarry Smith   if (!skipallocation) {
40742ee49352SLisandro Dalcin     if (!b->imax) {
4075071fcb05SBarry Smith       ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr);
4076071fcb05SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
4077071fcb05SBarry Smith     }
4078071fcb05SBarry Smith     if (!b->ilen) {
4079071fcb05SBarry Smith       /* b->ilen will count nonzeros in each row so far. */
4080071fcb05SBarry Smith       ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr);
4081071fcb05SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
4082071fcb05SBarry Smith     } else {
4083071fcb05SBarry Smith       ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
40842ee49352SLisandro Dalcin     }
4085846b4da1SFande Kong     if (!b->ipre) {
4086846b4da1SFande Kong       ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr);
4087846b4da1SFande Kong       ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
4088846b4da1SFande Kong     }
4089273d9f13SBarry Smith     if (!nnz) {
4090435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
4091c62bd62aSJed Brown       else if (nz < 0) nz = 1;
40925d2a9ed1SStefano Zampini       nz = PetscMin(nz,B->cmap->n);
4093d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
4094d0f46423SBarry Smith       nz = nz*B->rmap->n;
4095273d9f13SBarry Smith     } else {
4096c73702f5SBarry Smith       PetscInt64 nz64 = 0;
4097c73702f5SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];}
4098c73702f5SBarry Smith       ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr);
4099273d9f13SBarry Smith     }
4100ab93d7beSBarry Smith 
4101273d9f13SBarry Smith     /* allocate the matrix space */
410253dd7562SDmitry Karpeev     /* FIXME: should B's old memory be unlogged? */
41032ee49352SLisandro Dalcin     ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
4104396832f4SHong Zhang     if (B->structure_only) {
41055848002fSHong Zhang       ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr);
41065848002fSHong Zhang       ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr);
4107396832f4SHong Zhang       ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr);
4108396832f4SHong Zhang     } else {
4109dcca6d9dSJed Brown       ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr);
41103bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
4111396832f4SHong Zhang     }
4112bfeeae90SHong Zhang     b->i[0] = 0;
4113d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
41145da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
41155da197adSKris Buschelman     }
4116396832f4SHong Zhang     if (B->structure_only) {
4117396832f4SHong Zhang       b->singlemalloc = PETSC_FALSE;
4118396832f4SHong Zhang       b->free_a       = PETSC_FALSE;
4119396832f4SHong Zhang     } else {
4120273d9f13SBarry Smith       b->singlemalloc = PETSC_TRUE;
4121e6b907acSBarry Smith       b->free_a       = PETSC_TRUE;
4122396832f4SHong Zhang     }
4123e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
4124c461c341SBarry Smith   } else {
4125e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
4126e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
4127c461c341SBarry Smith   }
4128273d9f13SBarry Smith 
4129846b4da1SFande Kong   if (b->ipre && nnz != b->ipre  && b->imax) {
4130846b4da1SFande Kong     /* reserve user-requested sparsity */
4131580bdb30SBarry Smith     ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr);
4132846b4da1SFande Kong   }
4133846b4da1SFande Kong 
4134273d9f13SBarry Smith   b->nz               = 0;
4135273d9f13SBarry Smith   b->maxnz            = nz;
4136273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
41372205254eSKarl Rupp   if (realalloc) {
41382205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
41392205254eSKarl Rupp   }
4140cb7b82ddSBarry Smith   B->was_assembled = PETSC_FALSE;
4141cb7b82ddSBarry Smith   B->assembled     = PETSC_FALSE;
4142273d9f13SBarry Smith   PetscFunctionReturn(0);
4143273d9f13SBarry Smith }
4144273d9f13SBarry Smith 
4145846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A)
4146846b4da1SFande Kong {
4147846b4da1SFande Kong   Mat_SeqAIJ     *a;
4148a5bbaf83SFande Kong   PetscInt       i;
4149846b4da1SFande Kong   PetscErrorCode ierr;
4150846b4da1SFande Kong 
4151846b4da1SFande Kong   PetscFunctionBegin;
4152846b4da1SFande Kong   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
415314d0e64fSAlex Lindsay 
415414d0e64fSAlex Lindsay   /* Check local size. If zero, then return */
415514d0e64fSAlex Lindsay   if (!A->rmap->n) PetscFunctionReturn(0);
415614d0e64fSAlex Lindsay 
4157846b4da1SFande Kong   a = (Mat_SeqAIJ*)A->data;
41582c814fdeSFande Kong   /* if no saved info, we error out */
4159*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->ipre,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info ");
41602c814fdeSFande Kong 
4161*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->i || !a->j || !a->a || !a->imax || !a->ilen,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Memory info is incomplete, and can not reset preallocation ");
41622c814fdeSFande Kong 
4163580bdb30SBarry Smith   ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr);
4164580bdb30SBarry Smith   ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr);
4165846b4da1SFande Kong   a->i[0] = 0;
4166846b4da1SFande Kong   for (i=1; i<A->rmap->n+1; i++) {
4167846b4da1SFande Kong     a->i[i] = a->i[i-1] + a->imax[i-1];
4168846b4da1SFande Kong   }
4169846b4da1SFande Kong   A->preallocated     = PETSC_TRUE;
4170846b4da1SFande Kong   a->nz               = 0;
4171846b4da1SFande Kong   a->maxnz            = a->i[A->rmap->n];
4172846b4da1SFande Kong   A->info.nz_unneeded = (double)a->maxnz;
4173846b4da1SFande Kong   A->was_assembled    = PETSC_FALSE;
4174846b4da1SFande Kong   A->assembled        = PETSC_FALSE;
4175846b4da1SFande Kong   PetscFunctionReturn(0);
4176846b4da1SFande Kong }
4177846b4da1SFande Kong 
417858d36128SBarry Smith /*@
4179a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
4180a1661176SMatthew Knepley 
4181a1661176SMatthew Knepley    Input Parameters:
4182a1661176SMatthew Knepley +  B - the matrix
4183a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
4184a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
4185a1661176SMatthew Knepley -  v - optional values in the matrix
4186a1661176SMatthew Knepley 
4187a1661176SMatthew Knepley    Level: developer
4188a1661176SMatthew Knepley 
41896a9b8d82SBarry Smith    Notes:
419058d36128SBarry Smith       The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
419158d36128SBarry Smith 
41926a9b8d82SBarry Smith       This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero
41936a9b8d82SBarry Smith       structure will be the union of all the previous nonzero structures.
41946a9b8d82SBarry Smith 
41956a9b8d82SBarry Smith     Developer Notes:
41966a9b8d82SBarry Smith       An optimization could be added to the implementation where it checks if the i, and j are identical to the current i and j and
41976a9b8d82SBarry Smith       then just copies the v values directly with PetscMemcpy().
41986a9b8d82SBarry Smith 
41996a9b8d82SBarry Smith       This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them.
42006a9b8d82SBarry Smith 
42016a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation()
4202a1661176SMatthew Knepley @*/
4203a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
4204a1661176SMatthew Knepley {
4205a1661176SMatthew Knepley   PetscErrorCode ierr;
4206a1661176SMatthew Knepley 
4207a1661176SMatthew Knepley   PetscFunctionBegin;
42080700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
42096ba663aaSJed Brown   PetscValidType(B,1);
42104ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
4211a1661176SMatthew Knepley   PetscFunctionReturn(0);
4212a1661176SMatthew Knepley }
4213a1661176SMatthew Knepley 
42147087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
4215a1661176SMatthew Knepley {
4216a1661176SMatthew Knepley   PetscInt       i;
4217a1661176SMatthew Knepley   PetscInt       m,n;
4218a1661176SMatthew Knepley   PetscInt       nz;
42196a9b8d82SBarry Smith   PetscInt       *nnz;
4220a1661176SMatthew Knepley   PetscErrorCode ierr;
4221a1661176SMatthew Knepley 
4222a1661176SMatthew Knepley   PetscFunctionBegin;
4223*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Ii[0],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %" PetscInt_FMT, Ii[0]);
4224779a8d59SSatish Balay 
4225779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
4226779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
4227779a8d59SSatish Balay 
4228779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
4229854ce69bSBarry Smith   ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr);
4230a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
4231b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
4232*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %" PetscInt_FMT " has a negative number of columns %" PetscInt_FMT, i, nz);
4233a1661176SMatthew Knepley     nnz[i] = nz;
4234a1661176SMatthew Knepley   }
4235a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
4236a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
4237a1661176SMatthew Knepley 
4238a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
4239071fcb05SBarry Smith     ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr);
4240a1661176SMatthew Knepley   }
4241a1661176SMatthew Knepley 
4242a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4243a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4244a1661176SMatthew Knepley 
42457827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
4246a1661176SMatthew Knepley   PetscFunctionReturn(0);
4247a1661176SMatthew Knepley }
4248a1661176SMatthew Knepley 
4249ad7e164aSPierre Jolivet /*@
4250ad7e164aSPierre Jolivet    MatSeqAIJKron - Computes C, the Kronecker product of A and B.
4251ad7e164aSPierre Jolivet 
4252ad7e164aSPierre Jolivet    Input Parameters:
4253ad7e164aSPierre Jolivet +  A - left-hand side matrix
4254ad7e164aSPierre Jolivet .  B - right-hand side matrix
4255ad7e164aSPierre Jolivet -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4256ad7e164aSPierre Jolivet 
4257ad7e164aSPierre Jolivet    Output Parameter:
4258ad7e164aSPierre Jolivet .  C - Kronecker product of A and B
4259ad7e164aSPierre Jolivet 
4260ad7e164aSPierre Jolivet    Level: intermediate
4261ad7e164aSPierre Jolivet 
4262ad7e164aSPierre Jolivet    Notes:
4263ad7e164aSPierre Jolivet       MAT_REUSE_MATRIX can only be used when the nonzero structure of the product matrix has not changed from that last call to MatSeqAIJKron().
4264ad7e164aSPierre Jolivet 
4265ad7e164aSPierre Jolivet .seealso: MatCreateSeqAIJ(), MATSEQAIJ, MATKAIJ, MatReuse
4266ad7e164aSPierre Jolivet @*/
4267ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron(Mat A,Mat B,MatReuse reuse,Mat *C)
4268ad7e164aSPierre Jolivet {
4269ad7e164aSPierre Jolivet   PetscErrorCode ierr;
4270ad7e164aSPierre Jolivet 
4271ad7e164aSPierre Jolivet   PetscFunctionBegin;
4272ad7e164aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4273ad7e164aSPierre Jolivet   PetscValidType(A,1);
4274ad7e164aSPierre Jolivet   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4275ad7e164aSPierre Jolivet   PetscValidType(B,2);
4276ad7e164aSPierre Jolivet   PetscValidPointer(C,4);
4277ad7e164aSPierre Jolivet   if (reuse == MAT_REUSE_MATRIX) {
4278ad7e164aSPierre Jolivet     PetscValidHeaderSpecific(*C,MAT_CLASSID,4);
4279ad7e164aSPierre Jolivet     PetscValidType(*C,4);
4280ad7e164aSPierre Jolivet   }
4281ad7e164aSPierre Jolivet   ierr = PetscTryMethod(A,"MatSeqAIJKron_C",(Mat,Mat,MatReuse,Mat*),(A,B,reuse,C));CHKERRQ(ierr);
4282ad7e164aSPierre Jolivet   PetscFunctionReturn(0);
4283ad7e164aSPierre Jolivet }
4284ad7e164aSPierre Jolivet 
4285ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron_SeqAIJ(Mat A,Mat B,MatReuse reuse,Mat *C)
4286ad7e164aSPierre Jolivet {
4287fff043a9SJunchao Zhang   PetscErrorCode     ierr;
4288ad7e164aSPierre Jolivet   Mat                newmat;
4289ad7e164aSPierre Jolivet   Mat_SeqAIJ         *a = (Mat_SeqAIJ*)A->data;
4290ad7e164aSPierre Jolivet   Mat_SeqAIJ         *b = (Mat_SeqAIJ*)B->data;
4291ad7e164aSPierre Jolivet   PetscScalar        *v;
4292fff043a9SJunchao Zhang   const PetscScalar  *aa,*ba;
4293ad7e164aSPierre Jolivet   PetscInt           *i,*j,m,n,p,q,nnz = 0,am = A->rmap->n,bm = B->rmap->n,an = A->cmap->n, bn = B->cmap->n;
4294ad7e164aSPierre Jolivet   PetscBool          flg;
4295ad7e164aSPierre Jolivet 
4296ad7e164aSPierre Jolivet   PetscFunctionBegin;
4297*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4298*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4299*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(B->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4300*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!B->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4301ad7e164aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr);
4302*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatType %s",((PetscObject)B)->type_name);
4303*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(reuse != MAT_INITIAL_MATRIX && reuse != MAT_REUSE_MATRIX,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatReuse %d",(int)reuse);
4304ad7e164aSPierre Jolivet   if (reuse == MAT_INITIAL_MATRIX) {
4305ad7e164aSPierre Jolivet     ierr = PetscMalloc2(am*bm+1,&i,a->i[am]*b->i[bm],&j);CHKERRQ(ierr);
4306ad7e164aSPierre Jolivet     ierr = MatCreate(PETSC_COMM_SELF,&newmat);CHKERRQ(ierr);
4307ad7e164aSPierre Jolivet     ierr = MatSetSizes(newmat,am*bm,an*bn,am*bm,an*bn);CHKERRQ(ierr);
4308ad7e164aSPierre Jolivet     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
4309ad7e164aSPierre Jolivet     i[0] = 0;
4310ad7e164aSPierre Jolivet     for (m = 0; m < am; ++m) {
4311ad7e164aSPierre Jolivet       for (p = 0; p < bm; ++p) {
4312ad7e164aSPierre Jolivet         i[m*bm + p + 1] = i[m*bm + p] + (a->i[m+1] - a->i[m]) * (b->i[p+1] - b->i[p]);
4313ad7e164aSPierre Jolivet         for (n = a->i[m]; n < a->i[m+1]; ++n) {
4314ad7e164aSPierre Jolivet           for (q = b->i[p]; q < b->i[p+1]; ++q) {
4315ad7e164aSPierre Jolivet             j[nnz++] = a->j[n]*bn + b->j[q];
4316ad7e164aSPierre Jolivet           }
4317ad7e164aSPierre Jolivet         }
4318ad7e164aSPierre Jolivet       }
4319ad7e164aSPierre Jolivet     }
4320ad7e164aSPierre Jolivet     ierr = MatSeqAIJSetPreallocationCSR(newmat,i,j,NULL);CHKERRQ(ierr);
4321ad7e164aSPierre Jolivet     *C = newmat;
4322ad7e164aSPierre Jolivet     ierr = PetscFree2(i,j);CHKERRQ(ierr);
4323ad7e164aSPierre Jolivet     nnz = 0;
4324ad7e164aSPierre Jolivet   }
4325ad7e164aSPierre Jolivet   ierr = MatSeqAIJGetArray(*C,&v);CHKERRQ(ierr);
4326fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
4327fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(B,&ba);CHKERRQ(ierr);
4328ad7e164aSPierre Jolivet   for (m = 0; m < am; ++m) {
4329ad7e164aSPierre Jolivet     for (p = 0; p < bm; ++p) {
4330ad7e164aSPierre Jolivet       for (n = a->i[m]; n < a->i[m+1]; ++n) {
4331ad7e164aSPierre Jolivet         for (q = b->i[p]; q < b->i[p+1]; ++q) {
4332fff043a9SJunchao Zhang           v[nnz++] = aa[n] * ba[q];
4333ad7e164aSPierre Jolivet         }
4334ad7e164aSPierre Jolivet       }
4335ad7e164aSPierre Jolivet     }
4336ad7e164aSPierre Jolivet   }
4337ad7e164aSPierre Jolivet   ierr = MatSeqAIJRestoreArray(*C,&v);CHKERRQ(ierr);
4338fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
4339fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(B,&ba);CHKERRQ(ierr);
4340ad7e164aSPierre Jolivet   PetscFunctionReturn(0);
4341ad7e164aSPierre Jolivet }
4342ad7e164aSPierre Jolivet 
4343c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
4344af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h>
4345170fe5c8SBarry Smith 
4346170fe5c8SBarry Smith /*
4347170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
4348170fe5c8SBarry Smith 
4349170fe5c8SBarry Smith                n                       p                          p
43502da392ccSBarry Smith         [             ]       [             ]         [                 ]
43512da392ccSBarry Smith       m [      A      ]  *  n [       B     ]   =   m [         C       ]
43522da392ccSBarry Smith         [             ]       [             ]         [                 ]
4353170fe5c8SBarry Smith 
4354170fe5c8SBarry Smith */
4355170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
4356170fe5c8SBarry Smith {
4357170fe5c8SBarry Smith   PetscErrorCode    ierr;
4358170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
4359170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
4360170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
436186214ceeSStefano Zampini   PetscInt          i,j,n,m,q,p;
4362170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
4363170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
4364170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
436586214ceeSStefano Zampini   PetscInt          clda = sub_c->lda;
436686214ceeSStefano Zampini   PetscInt          alda = sub_a->lda;
4367170fe5c8SBarry Smith 
4368170fe5c8SBarry Smith   PetscFunctionBegin;
4369d0f46423SBarry Smith   m    = A->rmap->n;
4370d0f46423SBarry Smith   n    = A->cmap->n;
4371d0f46423SBarry Smith   p    = B->cmap->n;
4372170fe5c8SBarry Smith   a    = sub_a->v;
4373170fe5c8SBarry Smith   b    = sub_b->a;
4374170fe5c8SBarry Smith   c    = sub_c->v;
437586214ceeSStefano Zampini   if (clda == m) {
4376580bdb30SBarry Smith     ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr);
437786214ceeSStefano Zampini   } else {
437886214ceeSStefano Zampini     for (j=0;j<p;j++)
437986214ceeSStefano Zampini       for (i=0;i<m;i++)
438086214ceeSStefano Zampini         c[j*clda + i] = 0.0;
438186214ceeSStefano Zampini   }
4382170fe5c8SBarry Smith   ii  = sub_b->i;
4383170fe5c8SBarry Smith   idx = sub_b->j;
4384170fe5c8SBarry Smith   for (i=0; i<n; i++) {
4385170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
4386170fe5c8SBarry Smith     while (q-->0) {
438786214ceeSStefano Zampini       c_q = c + clda*(*idx);
438886214ceeSStefano Zampini       a_q = a + alda*i;
4389854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
4390170fe5c8SBarry Smith       idx++;
4391170fe5c8SBarry Smith       b++;
4392170fe5c8SBarry Smith     }
4393170fe5c8SBarry Smith   }
4394170fe5c8SBarry Smith   PetscFunctionReturn(0);
4395170fe5c8SBarry Smith }
4396170fe5c8SBarry Smith 
43974222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C)
4398170fe5c8SBarry Smith {
4399170fe5c8SBarry Smith   PetscErrorCode ierr;
4400d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
440186214ceeSStefano Zampini   PetscBool      cisdense;
4402170fe5c8SBarry Smith 
4403170fe5c8SBarry Smith   PetscFunctionBegin;
4404*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->cmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %" PetscInt_FMT " != B->rmap->n %" PetscInt_FMT,A->cmap->n,B->rmap->n);
44054222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
44064222ddf1SHong Zhang   ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr);
440786214ceeSStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
440886214ceeSStefano Zampini   if (!cisdense) {
440986214ceeSStefano Zampini     ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr);
441086214ceeSStefano Zampini   }
441186214ceeSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
4412d73949e8SHong Zhang 
44134222ddf1SHong Zhang   C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
4414170fe5c8SBarry Smith   PetscFunctionReturn(0);
4415170fe5c8SBarry Smith }
4416170fe5c8SBarry Smith 
4417170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
44180bad9183SKris Buschelman /*MC
4419fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
44200bad9183SKris Buschelman    based on compressed sparse row format.
44210bad9183SKris Buschelman 
44220bad9183SKris Buschelman    Options Database Keys:
44230bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
44240bad9183SKris Buschelman 
44250bad9183SKris Buschelman    Level: beginner
44260bad9183SKris Buschelman 
44270cd7f59aSBarry Smith    Notes:
44280cd7f59aSBarry Smith     MatSetValues() may be called for this matrix type with a NULL argument for the numerical values,
44290cd7f59aSBarry Smith     in this case the values associated with the rows and columns one passes in are set to zero
44300cd7f59aSBarry Smith     in the matrix
44310cd7f59aSBarry Smith 
44320cd7f59aSBarry Smith     MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no
44330cd7f59aSBarry Smith     space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored
44340cd7f59aSBarry Smith 
44350cd7f59aSBarry Smith   Developer Notes:
44360cd7f59aSBarry Smith     It would be nice if all matrix formats supported passing NULL in for the numerical values
44370cd7f59aSBarry Smith 
4438ed73aabaSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType, MATSELL, MATSEQSELL, MATMPISELL
44390bad9183SKris Buschelman M*/
44400bad9183SKris Buschelman 
4441ccd284c7SBarry Smith /*MC
4442ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
4443ccd284c7SBarry Smith 
4444ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
4445ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
4446ed73aabaSBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
4447ccd284c7SBarry Smith    for communicators controlling multiple processes.  It is recommended that you call both of
4448ccd284c7SBarry Smith    the above preallocation routines for simplicity.
4449ccd284c7SBarry Smith 
4450ccd284c7SBarry Smith    Options Database Keys:
4451ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
4452ccd284c7SBarry Smith 
445395452b02SPatrick Sanan   Developer Notes:
4454ca9cdca7SRichard Tran Mills     Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when
4455ccd284c7SBarry Smith    enough exist.
4456ccd284c7SBarry Smith 
4457ccd284c7SBarry Smith   Level: beginner
4458ccd284c7SBarry Smith 
4459ed73aabaSBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ, MATMPIAIJ, MATSELL, MATSEQSELL, MATMPISELL
4460ccd284c7SBarry Smith M*/
4461ccd284c7SBarry Smith 
4462ccd284c7SBarry Smith /*MC
4463ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
4464ccd284c7SBarry Smith 
4465ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
4466ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
4467ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
4468ccd284c7SBarry Smith    for communicators controlling multiple processes.  It is recommended that you call both of
4469ccd284c7SBarry Smith    the above preallocation routines for simplicity.
4470ccd284c7SBarry Smith 
4471ccd284c7SBarry Smith    Options Database Keys:
4472ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
4473ccd284c7SBarry Smith 
4474ccd284c7SBarry Smith   Level: beginner
4475ccd284c7SBarry Smith 
4476ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
4477ccd284c7SBarry Smith M*/
4478ccd284c7SBarry Smith 
44797906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
44807906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
44817906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*);
44827906f579SHong Zhang #endif
4483d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
4484d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*);
4485d24d4204SJose E. Roman #endif
44867906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE)
44877906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*);
44887906f579SHong Zhang #endif
44897906f579SHong Zhang 
4490d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*);
4491c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*);
44924222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat);
44937906f579SHong Zhang 
44948c778c55SBarry Smith /*@C
44958f1ea47aSStefano Zampini    MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored
44968c778c55SBarry Smith 
44978c778c55SBarry Smith    Not Collective
44988c778c55SBarry Smith 
44998c778c55SBarry Smith    Input Parameter:
4500579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
45018c778c55SBarry Smith 
45028c778c55SBarry Smith    Output Parameter:
45038c778c55SBarry Smith .   array - pointer to the data
45048c778c55SBarry Smith 
45058c778c55SBarry Smith    Level: intermediate
45068c778c55SBarry Smith 
4507774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
45088c778c55SBarry Smith @*/
45098c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
45108c778c55SBarry Smith {
45118c778c55SBarry Smith   PetscErrorCode ierr;
4512d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
45138c778c55SBarry Smith 
45148c778c55SBarry Smith   PetscFunctionBegin;
4515d67d9f35SJunchao Zhang   if (aij->ops->getarray) {
4516d67d9f35SJunchao Zhang     ierr = (*aij->ops->getarray)(A,array);CHKERRQ(ierr);
4517d67d9f35SJunchao Zhang   } else {
4518d67d9f35SJunchao Zhang     *array = aij->a;
4519d67d9f35SJunchao Zhang   }
4520d67d9f35SJunchao Zhang   PetscFunctionReturn(0);
4521d67d9f35SJunchao Zhang }
4522d67d9f35SJunchao Zhang 
4523d67d9f35SJunchao Zhang /*@C
4524d67d9f35SJunchao Zhang    MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray()
4525d67d9f35SJunchao Zhang 
4526d67d9f35SJunchao Zhang    Not Collective
4527d67d9f35SJunchao Zhang 
4528d67d9f35SJunchao Zhang    Input Parameters:
4529d67d9f35SJunchao Zhang +  mat - a MATSEQAIJ matrix
4530d67d9f35SJunchao Zhang -  array - pointer to the data
4531d67d9f35SJunchao Zhang 
4532d67d9f35SJunchao Zhang    Level: intermediate
4533d67d9f35SJunchao Zhang 
4534d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
4535d67d9f35SJunchao Zhang @*/
4536d67d9f35SJunchao Zhang PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
4537d67d9f35SJunchao Zhang {
4538d67d9f35SJunchao Zhang   PetscErrorCode ierr;
4539d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
4540d67d9f35SJunchao Zhang 
4541d67d9f35SJunchao Zhang   PetscFunctionBegin;
4542d67d9f35SJunchao Zhang   if (aij->ops->restorearray) {
4543d67d9f35SJunchao Zhang     ierr = (*aij->ops->restorearray)(A,array);CHKERRQ(ierr);
4544d67d9f35SJunchao Zhang   } else {
4545d67d9f35SJunchao Zhang     *array = NULL;
4546d67d9f35SJunchao Zhang   }
45478c778c55SBarry Smith   PetscFunctionReturn(0);
45488c778c55SBarry Smith }
45498c778c55SBarry Smith 
455021e72a00SBarry Smith /*@C
45518f1ea47aSStefano Zampini    MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored
45528f1ea47aSStefano Zampini 
45538f1ea47aSStefano Zampini    Not Collective
45548f1ea47aSStefano Zampini 
45558f1ea47aSStefano Zampini    Input Parameter:
45568f1ea47aSStefano Zampini .  mat - a MATSEQAIJ matrix
45578f1ea47aSStefano Zampini 
45588f1ea47aSStefano Zampini    Output Parameter:
45598f1ea47aSStefano Zampini .   array - pointer to the data
45608f1ea47aSStefano Zampini 
45618f1ea47aSStefano Zampini    Level: intermediate
45628f1ea47aSStefano Zampini 
45638f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead()
45648f1ea47aSStefano Zampini @*/
45658f1ea47aSStefano Zampini PetscErrorCode  MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array)
45668f1ea47aSStefano Zampini {
45678f1ea47aSStefano Zampini   PetscErrorCode ierr;
4568d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
45698f1ea47aSStefano Zampini 
45708f1ea47aSStefano Zampini   PetscFunctionBegin;
4571d67d9f35SJunchao Zhang   if (aij->ops->getarrayread) {
4572d67d9f35SJunchao Zhang     ierr = (*aij->ops->getarrayread)(A,array);CHKERRQ(ierr);
4573d67d9f35SJunchao Zhang   } else {
4574d67d9f35SJunchao Zhang     *array = aij->a;
4575d67d9f35SJunchao Zhang   }
45768f1ea47aSStefano Zampini   PetscFunctionReturn(0);
45778f1ea47aSStefano Zampini }
45788f1ea47aSStefano Zampini 
45798f1ea47aSStefano Zampini /*@C
45808f1ea47aSStefano Zampini    MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead
45818f1ea47aSStefano Zampini 
45828f1ea47aSStefano Zampini    Not Collective
45838f1ea47aSStefano Zampini 
45848f1ea47aSStefano Zampini    Input Parameter:
45858f1ea47aSStefano Zampini .  mat - a MATSEQAIJ matrix
45868f1ea47aSStefano Zampini 
45878f1ea47aSStefano Zampini    Output Parameter:
45888f1ea47aSStefano Zampini .   array - pointer to the data
45898f1ea47aSStefano Zampini 
45908f1ea47aSStefano Zampini    Level: intermediate
45918f1ea47aSStefano Zampini 
45928f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead()
45938f1ea47aSStefano Zampini @*/
45948f1ea47aSStefano Zampini PetscErrorCode  MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array)
45958f1ea47aSStefano Zampini {
45968f1ea47aSStefano Zampini   PetscErrorCode ierr;
4597d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
45988f1ea47aSStefano Zampini 
45998f1ea47aSStefano Zampini   PetscFunctionBegin;
4600d67d9f35SJunchao Zhang   if (aij->ops->restorearrayread) {
4601d67d9f35SJunchao Zhang     ierr = (*aij->ops->restorearrayread)(A,array);CHKERRQ(ierr);
4602d67d9f35SJunchao Zhang   } else {
4603d67d9f35SJunchao Zhang     *array = NULL;
4604d67d9f35SJunchao Zhang   }
4605d67d9f35SJunchao Zhang   PetscFunctionReturn(0);
4606d67d9f35SJunchao Zhang }
4607d67d9f35SJunchao Zhang 
4608d67d9f35SJunchao Zhang /*@C
4609d67d9f35SJunchao Zhang    MatSeqAIJGetArrayWrite - gives write-only access to the array where the data for a MATSEQAIJ matrix is stored
4610d67d9f35SJunchao Zhang 
4611d67d9f35SJunchao Zhang    Not Collective
4612d67d9f35SJunchao Zhang 
4613d67d9f35SJunchao Zhang    Input Parameter:
4614d67d9f35SJunchao Zhang .  mat - a MATSEQAIJ matrix
4615d67d9f35SJunchao Zhang 
4616d67d9f35SJunchao Zhang    Output Parameter:
4617d67d9f35SJunchao Zhang .   array - pointer to the data
4618d67d9f35SJunchao Zhang 
4619d67d9f35SJunchao Zhang    Level: intermediate
4620d67d9f35SJunchao Zhang 
4621d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead()
4622d67d9f35SJunchao Zhang @*/
4623d67d9f35SJunchao Zhang PetscErrorCode  MatSeqAIJGetArrayWrite(Mat A,PetscScalar **array)
4624d67d9f35SJunchao Zhang {
4625d67d9f35SJunchao Zhang   PetscErrorCode ierr;
4626d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
4627d67d9f35SJunchao Zhang 
4628d67d9f35SJunchao Zhang   PetscFunctionBegin;
4629d67d9f35SJunchao Zhang   if (aij->ops->getarraywrite) {
4630d67d9f35SJunchao Zhang     ierr = (*aij->ops->getarraywrite)(A,array);CHKERRQ(ierr);
4631d67d9f35SJunchao Zhang   } else {
4632d67d9f35SJunchao Zhang     *array = aij->a;
4633d67d9f35SJunchao Zhang   }
4634d67d9f35SJunchao Zhang   PetscFunctionReturn(0);
4635d67d9f35SJunchao Zhang }
4636d67d9f35SJunchao Zhang 
4637d67d9f35SJunchao Zhang /*@C
4638d67d9f35SJunchao Zhang    MatSeqAIJRestoreArrayWrite - restore the read-only access array obtained from MatSeqAIJGetArrayRead
4639d67d9f35SJunchao Zhang 
4640d67d9f35SJunchao Zhang    Not Collective
4641d67d9f35SJunchao Zhang 
4642d67d9f35SJunchao Zhang    Input Parameter:
4643d67d9f35SJunchao Zhang .  mat - a MATSEQAIJ matrix
4644d67d9f35SJunchao Zhang 
4645d67d9f35SJunchao Zhang    Output Parameter:
4646d67d9f35SJunchao Zhang .   array - pointer to the data
4647d67d9f35SJunchao Zhang 
4648d67d9f35SJunchao Zhang    Level: intermediate
4649d67d9f35SJunchao Zhang 
4650d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead()
4651d67d9f35SJunchao Zhang @*/
4652d67d9f35SJunchao Zhang PetscErrorCode  MatSeqAIJRestoreArrayWrite(Mat A,PetscScalar **array)
4653d67d9f35SJunchao Zhang {
4654d67d9f35SJunchao Zhang   PetscErrorCode ierr;
4655d67d9f35SJunchao Zhang   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
4656d67d9f35SJunchao Zhang 
4657d67d9f35SJunchao Zhang   PetscFunctionBegin;
4658d67d9f35SJunchao Zhang   if (aij->ops->restorearraywrite) {
4659d67d9f35SJunchao Zhang     ierr = (*aij->ops->restorearraywrite)(A,array);CHKERRQ(ierr);
4660d67d9f35SJunchao Zhang   } else {
4661d67d9f35SJunchao Zhang     *array = NULL;
4662d67d9f35SJunchao Zhang   }
46638f1ea47aSStefano Zampini   PetscFunctionReturn(0);
46648f1ea47aSStefano Zampini }
46658f1ea47aSStefano Zampini 
46668f1ea47aSStefano Zampini /*@C
466721e72a00SBarry Smith    MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row
466821e72a00SBarry Smith 
466921e72a00SBarry Smith    Not Collective
467021e72a00SBarry Smith 
467121e72a00SBarry Smith    Input Parameter:
4672579dbff0SBarry Smith .  mat - a MATSEQAIJ matrix
467321e72a00SBarry Smith 
467421e72a00SBarry Smith    Output Parameter:
467521e72a00SBarry Smith .   nz - the maximum number of nonzeros in any row
467621e72a00SBarry Smith 
467721e72a00SBarry Smith    Level: intermediate
467821e72a00SBarry Smith 
467921e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
468021e72a00SBarry Smith @*/
468121e72a00SBarry Smith PetscErrorCode  MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz)
468221e72a00SBarry Smith {
468321e72a00SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
468421e72a00SBarry Smith 
468521e72a00SBarry Smith   PetscFunctionBegin;
468621e72a00SBarry Smith   *nz = aij->rmax;
468721e72a00SBarry Smith   PetscFunctionReturn(0);
468821e72a00SBarry Smith }
468921e72a00SBarry Smith 
469034b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA)
46915063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat,MatType,MatReuse,Mat*);
469202fe1965SBarry Smith #endif
46933d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS)
46945063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat,MatType,MatReuse,Mat*);
46953d0639e7SStefano Zampini #endif
469602fe1965SBarry Smith 
46978cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
4698273d9f13SBarry Smith {
4699273d9f13SBarry Smith   Mat_SeqAIJ     *b;
4700dfbe8321SBarry Smith   PetscErrorCode ierr;
470138baddfdSBarry Smith   PetscMPIInt    size;
4702273d9f13SBarry Smith 
4703273d9f13SBarry Smith   PetscFunctionBegin;
4704ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
4705*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size > 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
4706273d9f13SBarry Smith 
4707b00a9115SJed Brown   ierr = PetscNewLog(B,&b);CHKERRQ(ierr);
47082205254eSKarl Rupp 
4709b0a32e0cSBarry Smith   B->data = (void*)b;
47102205254eSKarl Rupp 
4711549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
4712071fcb05SBarry Smith   if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull;
47132205254eSKarl Rupp 
4714f4259b30SLisandro Dalcin   b->row                = NULL;
4715f4259b30SLisandro Dalcin   b->col                = NULL;
4716f4259b30SLisandro Dalcin   b->icol               = NULL;
4717b810aeb4SBarry Smith   b->reallocs           = 0;
471836db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4719f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4720416022c9SBarry Smith   b->nonew              = 0;
4721f4259b30SLisandro Dalcin   b->diag               = NULL;
4722f4259b30SLisandro Dalcin   b->solve_work         = NULL;
4723f4259b30SLisandro Dalcin   B->spptr              = NULL;
4724f4259b30SLisandro Dalcin   b->saved_values       = NULL;
4725f4259b30SLisandro Dalcin   b->idiag              = NULL;
4726f4259b30SLisandro Dalcin   b->mdiag              = NULL;
4727f4259b30SLisandro Dalcin   b->ssor_work          = NULL;
472871f1c65dSBarry Smith   b->omega              = 1.0;
472971f1c65dSBarry Smith   b->fshift             = 0.0;
473071f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4731bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4732a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
473317ab2063SBarry Smith 
473435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
47358c778c55SBarry Smith 
4736b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4737bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4738bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4739b3866ffcSBarry Smith #endif
474017f1a0eaSHong Zhang 
4741bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4742bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4743bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4744bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4745bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4746bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
47474dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr);
47489779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE)
47494a2a386eSRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr);
4750191b95cbSRichard Tran Mills #endif
475134b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA)
475202fe1965SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr);
47534222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr);
4754fcdce8c4SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr);
475502fe1965SBarry Smith #endif
47563d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS)
47573d0639e7SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr);
47583d0639e7SStefano Zampini #endif
4759bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4760af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
4761af8000cdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr);
4762af8000cdSHong Zhang #endif
4763d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
4764d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr);
4765d24d4204SJose E. Roman #endif
476663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE)
476763c07aadSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr);
47684222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr);
476963c07aadSStefano Zampini #endif
4770b49cda9fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr);
4771d4002b98SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr);
4772c9225affSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr);
4773bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4774bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4775bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4776846b4da1SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr);
4777bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4778bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
47794222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr);
47804222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr);
47814222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr);
4782ad7e164aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJKron_C",MatSeqAIJKron_SeqAIJ);CHKERRQ(ierr);
47834108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
478417667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
47854099cc6bSBarry Smith   ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr);  /* this allows changing the matrix subtype to say MATSEQAIJPERM */
47863a40ed3dSBarry Smith   PetscFunctionReturn(0);
478717ab2063SBarry Smith }
478817ab2063SBarry Smith 
4789b24902e0SBarry Smith /*
4790b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4791b24902e0SBarry Smith */
4792ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
479317ab2063SBarry Smith {
47942a350339SBarry Smith   Mat_SeqAIJ     *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data;
47956849ba73SBarry Smith   PetscErrorCode ierr;
4796071fcb05SBarry Smith   PetscInt       m = A->rmap->n,i;
479717ab2063SBarry Smith 
47983a40ed3dSBarry Smith   PetscFunctionBegin;
4799*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix");
4800273d9f13SBarry Smith 
4801d5f3da31SBarry Smith   C->factortype = A->factortype;
4802f4259b30SLisandro Dalcin   c->row        = NULL;
4803f4259b30SLisandro Dalcin   c->col        = NULL;
4804f4259b30SLisandro Dalcin   c->icol       = NULL;
48056ad4291fSHong Zhang   c->reallocs   = 0;
480617ab2063SBarry Smith 
48076ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
480817ab2063SBarry Smith 
4809aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4810aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4811eec197d1SBarry Smith 
4812071fcb05SBarry Smith   ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr);
4813071fcb05SBarry Smith   ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr);
4814071fcb05SBarry Smith   ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr);
4815071fcb05SBarry Smith   ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr);
48163bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
481717ab2063SBarry Smith 
481817ab2063SBarry Smith   /* allocate the matrix space */
4819f77e22a1SHong Zhang   if (mallocmatspace) {
4820dcca6d9dSJed Brown     ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr);
48213bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
48222205254eSKarl Rupp 
4823f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
48242205254eSKarl Rupp 
4825580bdb30SBarry Smith     ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr);
482617ab2063SBarry Smith     if (m > 0) {
4827580bdb30SBarry Smith       ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr);
4828be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
48292e5835c6SStefano Zampini         const PetscScalar *aa;
48302e5835c6SStefano Zampini 
48312e5835c6SStefano Zampini         ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
48322e5835c6SStefano Zampini         ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr);
48332e5835c6SStefano Zampini         ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
4834be6bf707SBarry Smith       } else {
4835580bdb30SBarry Smith         ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr);
483617ab2063SBarry Smith       }
483708480c60SBarry Smith     }
4838f77e22a1SHong Zhang   }
483917ab2063SBarry Smith 
48406ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4841416022c9SBarry Smith   c->roworiented       = a->roworiented;
4842416022c9SBarry Smith   c->nonew             = a->nonew;
4843416022c9SBarry Smith   if (a->diag) {
4844854ce69bSBarry Smith     ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr);
4845071fcb05SBarry Smith     ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr);
48463bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
4847071fcb05SBarry Smith   } else c->diag = NULL;
48482205254eSKarl Rupp 
4849f4259b30SLisandro Dalcin   c->solve_work         = NULL;
4850f4259b30SLisandro Dalcin   c->saved_values       = NULL;
4851f4259b30SLisandro Dalcin   c->idiag              = NULL;
4852f4259b30SLisandro Dalcin   c->ssor_work          = NULL;
4853a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4854e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4855e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
48566ad4291fSHong Zhang 
4857893ad86cSHong Zhang   c->rmax         = a->rmax;
4858416022c9SBarry Smith   c->nz           = a->nz;
48598ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4860273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4861754ec7b1SSatish Balay 
48626ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
48636ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4864cd6b891eSBarry Smith   if (a->compressedrow.use) {
48656ad4291fSHong Zhang     i    = a->compressedrow.nrows;
4866dcca6d9dSJed Brown     ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr);
4867580bdb30SBarry Smith     ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr);
4868580bdb30SBarry Smith     ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr);
486927ea64f8SHong Zhang   } else {
487027ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
48710298fd71SBarry Smith     c->compressedrow.i      = NULL;
48720298fd71SBarry Smith     c->compressedrow.rindex = NULL;
48736ad4291fSHong Zhang   }
4874ea632784SBarry Smith   c->nonzerorowcnt = a->nonzerorowcnt;
4875e56f5c9eSBarry Smith   C->nonzerostate  = A->nonzerostate;
48764846f1f5SKris Buschelman 
48772205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4878140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
48793a40ed3dSBarry Smith   PetscFunctionReturn(0);
488017ab2063SBarry Smith }
488117ab2063SBarry Smith 
4882b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4883b24902e0SBarry Smith {
4884b24902e0SBarry Smith   PetscErrorCode ierr;
4885b24902e0SBarry Smith 
4886b24902e0SBarry Smith   PetscFunctionBegin;
4887ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
48884b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4889cfd3f464SBarry Smith   if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) {
489033d57670SJed Brown     ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr);
4891cfd3f464SBarry Smith   }
4892a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4893f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4894b24902e0SBarry Smith   PetscFunctionReturn(0);
4895b24902e0SBarry Smith }
4896b24902e0SBarry Smith 
4897112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4898fbdbba38SShri Abhyankar {
489952f91c60SVaclav Hapla   PetscBool      isbinary, ishdf5;
490052f91c60SVaclav Hapla   PetscErrorCode ierr;
490152f91c60SVaclav Hapla 
490252f91c60SVaclav Hapla   PetscFunctionBegin;
490352f91c60SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
490452f91c60SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
4905c27b3999SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
4906c27b3999SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
490752f91c60SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
490852f91c60SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
490952f91c60SVaclav Hapla   if (isbinary) {
491052f91c60SVaclav Hapla     ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr);
491152f91c60SVaclav Hapla   } else if (ishdf5) {
491252f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
491352f91c60SVaclav Hapla     ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr);
491452f91c60SVaclav Hapla #else
491552f91c60SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
491652f91c60SVaclav Hapla #endif
491752f91c60SVaclav Hapla   } else {
491898921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
491952f91c60SVaclav Hapla   }
492052f91c60SVaclav Hapla   PetscFunctionReturn(0);
492152f91c60SVaclav Hapla }
492252f91c60SVaclav Hapla 
49233ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer)
492452f91c60SVaclav Hapla {
49253ea6fe3dSLisandro Dalcin   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)mat->data;
4926fbdbba38SShri Abhyankar   PetscErrorCode ierr;
49273ea6fe3dSLisandro Dalcin   PetscInt       header[4],*rowlens,M,N,nz,sum,rows,cols,i;
4928fbdbba38SShri Abhyankar 
4929fbdbba38SShri Abhyankar   PetscFunctionBegin;
49303ea6fe3dSLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
4931bbead8a2SBarry Smith 
49323ea6fe3dSLisandro Dalcin   /* read in matrix header */
49333ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
4934*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(header[0] != MAT_FILE_CLASSID,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
4935fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4936*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(M < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
4937*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(N < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
4938*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ");
4939fbdbba38SShri Abhyankar 
49403ea6fe3dSLisandro Dalcin   /* set block sizes from the viewer's .info file */
49413ea6fe3dSLisandro Dalcin   ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr);
49423ea6fe3dSLisandro Dalcin   /* set local and global sizes if not set already */
49433ea6fe3dSLisandro Dalcin   if (mat->rmap->n < 0) mat->rmap->n = M;
49443ea6fe3dSLisandro Dalcin   if (mat->cmap->n < 0) mat->cmap->n = N;
49453ea6fe3dSLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
49463ea6fe3dSLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
49473ea6fe3dSLisandro Dalcin   ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr);
49483ea6fe3dSLisandro Dalcin   ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr);
49493ea6fe3dSLisandro Dalcin 
49503ea6fe3dSLisandro Dalcin   /* check if the matrix sizes are correct */
49513ea6fe3dSLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
4952*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(M != rows || N != cols,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols);
49533ea6fe3dSLisandro Dalcin 
4954fbdbba38SShri Abhyankar   /* read in row lengths */
49553ea6fe3dSLisandro Dalcin   ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr);
49563ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr);
49573ea6fe3dSLisandro Dalcin   /* check if sum(rowlens) is same as nz */
49583ea6fe3dSLisandro Dalcin   sum = 0; for (i=0; i<M; i++) sum += rowlens[i];
4959*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(sum != nz,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Inconsistent matrix data in file: nonzeros = %" PetscInt_FMT ", sum-row-lengths = %" PetscInt_FMT,nz,sum);
49603ea6fe3dSLisandro Dalcin   /* preallocate and check sizes */
49613ea6fe3dSLisandro Dalcin   ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr);
49623ea6fe3dSLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
4963*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(M != rows || N != cols,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols);
49643ea6fe3dSLisandro Dalcin   /* store row lengths */
49653ea6fe3dSLisandro Dalcin   ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr);
49663ea6fe3dSLisandro Dalcin   ierr = PetscFree(rowlens);CHKERRQ(ierr);
4967fbdbba38SShri Abhyankar 
49683ea6fe3dSLisandro Dalcin   /* fill in "i" row pointers */
49693ea6fe3dSLisandro Dalcin   a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i];
49703ea6fe3dSLisandro Dalcin   /* read in "j" column indices */
49713ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr);
49723ea6fe3dSLisandro Dalcin   /* read in "a" nonzero values */
49733ea6fe3dSLisandro Dalcin   ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr);
4974fbdbba38SShri Abhyankar 
49753ea6fe3dSLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
49763ea6fe3dSLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4977fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4978fbdbba38SShri Abhyankar }
4979fbdbba38SShri Abhyankar 
4980ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
49817264ac53SSatish Balay {
49827264ac53SSatish Balay   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4983dfbe8321SBarry Smith   PetscErrorCode    ierr;
4984fff043a9SJunchao Zhang   const PetscScalar *aa,*ba;
4985eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4986eeffb40dSHong Zhang   PetscInt k;
4987eeffb40dSHong Zhang #endif
49887264ac53SSatish Balay 
49893a40ed3dSBarry Smith   PetscFunctionBegin;
4990bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4991d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4992ca44d042SBarry Smith     *flg = PETSC_FALSE;
4993ca44d042SBarry Smith     PetscFunctionReturn(0);
4994bcd2baecSBarry Smith   }
49957264ac53SSatish Balay 
49967264ac53SSatish Balay   /* if the a->i are the same */
4997580bdb30SBarry Smith   ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr);
4998abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
49997264ac53SSatish Balay 
50007264ac53SSatish Balay   /* if a->j are the same */
5001580bdb30SBarry Smith   ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr);
5002abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
5003bcd2baecSBarry Smith 
5004fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr);
5005fff043a9SJunchao Zhang   ierr = MatSeqAIJGetArrayRead(B,&ba);CHKERRQ(ierr);
5006bcd2baecSBarry Smith   /* if a->a are the same */
5007eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
5008eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
5009fff043a9SJunchao Zhang     if (PetscRealPart(aa[k]) != PetscRealPart(ba[k]) || PetscImaginaryPart(aa[k]) != PetscImaginaryPart(ba[k])) {
5010eeffb40dSHong Zhang       *flg = PETSC_FALSE;
50113a40ed3dSBarry Smith       PetscFunctionReturn(0);
5012eeffb40dSHong Zhang     }
5013eeffb40dSHong Zhang   }
5014eeffb40dSHong Zhang #else
5015fff043a9SJunchao Zhang   ierr = PetscArraycmp(aa,ba,a->nz,flg);CHKERRQ(ierr);
5016eeffb40dSHong Zhang #endif
5017fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr);
5018fff043a9SJunchao Zhang   ierr = MatSeqAIJRestoreArrayRead(B,&ba);CHKERRQ(ierr);
5019eeffb40dSHong Zhang   PetscFunctionReturn(0);
50207264ac53SSatish Balay }
502136db0b34SBarry Smith 
502205869f15SSatish Balay /*@
502336db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
502436db0b34SBarry Smith               provided by the user.
502536db0b34SBarry Smith 
5026d083f849SBarry Smith       Collective
502736db0b34SBarry Smith 
502836db0b34SBarry Smith    Input Parameters:
502936db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
503036db0b34SBarry Smith .   m - number of rows
503136db0b34SBarry Smith .   n - number of columns
5032483a2f95SBarry Smith .   i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix
503336db0b34SBarry Smith .   j - column indices
503436db0b34SBarry Smith -   a - matrix values
503536db0b34SBarry Smith 
503636db0b34SBarry Smith    Output Parameter:
503736db0b34SBarry Smith .   mat - the matrix
503836db0b34SBarry Smith 
503936db0b34SBarry Smith    Level: intermediate
504036db0b34SBarry Smith 
504136db0b34SBarry Smith    Notes:
50420551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
5043292fb18eSBarry Smith     once the matrix is destroyed and not before
504436db0b34SBarry Smith 
504536db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
504636db0b34SBarry Smith 
5047bfeeae90SHong Zhang        The i and j indices are 0 based
504836db0b34SBarry Smith 
5049a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
5050a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
50518eef79e4SBarry Smith     as shown
5052a4552177SSatish Balay 
50538eef79e4SBarry Smith $        1 0 0
50548eef79e4SBarry Smith $        2 0 3
50558eef79e4SBarry Smith $        4 5 6
50568eef79e4SBarry Smith $
50578eef79e4SBarry Smith $        i =  {0,1,3,6}  [size = nrow+1  = 3+1]
50588eef79e4SBarry Smith $        j =  {0,0,2,0,1,2}  [size = 6]; values must be sorted for each row
50598eef79e4SBarry Smith $        v =  {1,2,3,4,5,6}  [size = 6]
5060a4552177SSatish Balay 
506169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
506236db0b34SBarry Smith 
506336db0b34SBarry Smith @*/
5064c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat)
506536db0b34SBarry Smith {
5066dfbe8321SBarry Smith   PetscErrorCode ierr;
5067cbcfb4deSHong Zhang   PetscInt       ii;
506836db0b34SBarry Smith   Mat_SeqAIJ     *aij;
5069cbcfb4deSHong Zhang   PetscInt jj;
507036db0b34SBarry Smith 
507136db0b34SBarry Smith   PetscFunctionBegin;
5072*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(m > 0 && i[0],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
5073f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
5074f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
5075a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
5076ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
5077f4259b30SLisandro Dalcin   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr);
5078ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
5079071fcb05SBarry Smith   ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr);
5080071fcb05SBarry Smith   ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr);
5081ab93d7beSBarry Smith 
508236db0b34SBarry Smith   aij->i            = i;
508336db0b34SBarry Smith   aij->j            = j;
508436db0b34SBarry Smith   aij->a            = a;
508536db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
508636db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
5087e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
5088e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
508936db0b34SBarry Smith 
509036db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
509136db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
509276bd3646SJed Brown     if (PetscDefined(USE_DEBUG)) {
5093*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(i[ii+1] - i[ii] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %" PetscInt_FMT " length = %" PetscInt_FMT,ii,i[ii+1] - i[ii]);
50949985e31cSBarry Smith       for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
5095*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(j[jj] < j[jj-1],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %" PetscInt_FMT " (actual column %" PetscInt_FMT ") in row %" PetscInt_FMT " is not sorted",jj-i[ii],j[jj],ii);
5096*2c71b3e2SJacob Faibussowitsch         PetscCheckFalse(j[jj] == j[jj-1],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %" PetscInt_FMT " (actual column %" PetscInt_FMT ") in row %" PetscInt_FMT " is identical to previous entry",jj-i[ii],j[jj],ii);
50979985e31cSBarry Smith       }
509836db0b34SBarry Smith     }
509976bd3646SJed Brown   }
510076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
510136db0b34SBarry Smith     for (ii=0; ii<aij->i[m]; ii++) {
5102*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(j[ii] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %" PetscInt_FMT " index = %" PetscInt_FMT,ii,j[ii]);
5103*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(j[ii] > n - 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %" PetscInt_FMT " index = %" PetscInt_FMT,ii,j[ii]);
510436db0b34SBarry Smith     }
510576bd3646SJed Brown   }
510636db0b34SBarry Smith 
5107b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
5108b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
510936db0b34SBarry Smith   PetscFunctionReturn(0);
511036db0b34SBarry Smith }
511180ef6e79SMatthew G Knepley /*@C
5112d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
51138a0b0e6bSVictor Minden               provided by the user.
51148a0b0e6bSVictor Minden 
5115d083f849SBarry Smith       Collective
51168a0b0e6bSVictor Minden 
51178a0b0e6bSVictor Minden    Input Parameters:
51188a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
51198a0b0e6bSVictor Minden .   m   - number of rows
51208a0b0e6bSVictor Minden .   n   - number of columns
51218a0b0e6bSVictor Minden .   i   - row indices
51228a0b0e6bSVictor Minden .   j   - column indices
51231230e6d1SVictor Minden .   a   - matrix values
51241230e6d1SVictor Minden .   nz  - number of nonzeros
51251230e6d1SVictor Minden -   idx - 0 or 1 based
51268a0b0e6bSVictor Minden 
51278a0b0e6bSVictor Minden    Output Parameter:
51288a0b0e6bSVictor Minden .   mat - the matrix
51298a0b0e6bSVictor Minden 
51308a0b0e6bSVictor Minden    Level: intermediate
51318a0b0e6bSVictor Minden 
51328a0b0e6bSVictor Minden    Notes:
51339e99939fSJunchao Zhang        The i and j indices are 0 based. The format which is used for the sparse matrix input, is equivalent to a row-major ordering. i.e for the following matrix,
51349e99939fSJunchao Zhang        the input data expected is as shown
51359e99939fSJunchao Zhang .vb
51368a0b0e6bSVictor Minden         1 0 0
51378a0b0e6bSVictor Minden         2 0 3
51388a0b0e6bSVictor Minden         4 5 6
51398a0b0e6bSVictor Minden 
51408a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
51418a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
51428a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
51439e99939fSJunchao Zhang .ve
51448a0b0e6bSVictor Minden 
514569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
51468a0b0e6bSVictor Minden 
51478a0b0e6bSVictor Minden @*/
5148c3c607ccSBarry Smith PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx)
51498a0b0e6bSVictor Minden {
51508a0b0e6bSVictor Minden   PetscErrorCode ierr;
5151d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
51528a0b0e6bSVictor Minden 
51538a0b0e6bSVictor Minden   PetscFunctionBegin;
51541795a4d1SJed Brown   ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr);
51551230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
5156c8d679ebSHong Zhang     nnz[i[ii] - !!idx] += 1;
51571230e6d1SVictor Minden   }
51588a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
51598a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
51608a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
51611230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
51621230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
51631230e6d1SVictor Minden     if (idx) {
51641230e6d1SVictor Minden       row = i[ii] - 1;
51651230e6d1SVictor Minden       col = j[ii] - 1;
51661230e6d1SVictor Minden     } else {
51671230e6d1SVictor Minden       row = i[ii];
51681230e6d1SVictor Minden       col = j[ii];
51698a0b0e6bSVictor Minden     }
51701230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
51718a0b0e6bSVictor Minden   }
51728a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
51738a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
5174d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
51758a0b0e6bSVictor Minden   PetscFunctionReturn(0);
51768a0b0e6bSVictor Minden }
517736db0b34SBarry Smith 
5178acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
5179acf2f550SJed Brown {
5180acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
5181acf2f550SJed Brown   PetscErrorCode ierr;
5182acf2f550SJed Brown 
5183acf2f550SJed Brown   PetscFunctionBegin;
5184acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
5185acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
51862205254eSKarl Rupp 
5187acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
5188acf2f550SJed Brown   PetscFunctionReturn(0);
5189acf2f550SJed Brown }
5190acf2f550SJed Brown 
51919c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
51929c8f2541SHong Zhang {
51939c8f2541SHong Zhang   PetscErrorCode ierr;
51948761c3d6SHong Zhang   PetscMPIInt    size;
51959c8f2541SHong Zhang 
51969c8f2541SHong Zhang   PetscFunctionBegin;
5197ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
51987bbdc51dSHong Zhang   if (size == 1) {
51997bbdc51dSHong Zhang     if (scall == MAT_INITIAL_MATRIX) {
52007bbdc51dSHong Zhang       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
52017bbdc51dSHong Zhang     } else {
52028761c3d6SHong Zhang       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
52037bbdc51dSHong Zhang     }
52048761c3d6SHong Zhang   } else {
52059c8f2541SHong Zhang     ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
52068761c3d6SHong Zhang   }
52079c8f2541SHong Zhang   PetscFunctionReturn(0);
52089c8f2541SHong Zhang }
52099c8f2541SHong Zhang 
521081824310SBarry Smith /*
521153dd7562SDmitry Karpeev  Permute A into C's *local* index space using rowemb,colemb.
521253dd7562SDmitry Karpeev  The embedding are supposed to be injections and the above implies that the range of rowemb is a subset
521353dd7562SDmitry Karpeev  of [0,m), colemb is in [0,n).
521453dd7562SDmitry Karpeev  If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A.
521553dd7562SDmitry Karpeev  */
521653dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B)
521753dd7562SDmitry Karpeev {
521853dd7562SDmitry Karpeev   /* If making this function public, change the error returned in this function away from _PLIB. */
521953dd7562SDmitry Karpeev   PetscErrorCode ierr;
522053dd7562SDmitry Karpeev   Mat_SeqAIJ     *Baij;
522153dd7562SDmitry Karpeev   PetscBool      seqaij;
522253dd7562SDmitry Karpeev   PetscInt       m,n,*nz,i,j,count;
522353dd7562SDmitry Karpeev   PetscScalar    v;
522453dd7562SDmitry Karpeev   const PetscInt *rowindices,*colindices;
522553dd7562SDmitry Karpeev 
522653dd7562SDmitry Karpeev   PetscFunctionBegin;
522753dd7562SDmitry Karpeev   if (!B) PetscFunctionReturn(0);
522853dd7562SDmitry Karpeev   /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */
52294099cc6bSBarry Smith   ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
5230*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!seqaij,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type");
523153dd7562SDmitry Karpeev   if (rowemb) {
523253dd7562SDmitry Karpeev     ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr);
5233*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(m != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %" PetscInt_FMT " is incompatible with matrix row size %" PetscInt_FMT,m,B->rmap->n);
523453dd7562SDmitry Karpeev   } else {
5235*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(C->rmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix");
523653dd7562SDmitry Karpeev   }
523753dd7562SDmitry Karpeev   if (colemb) {
523853dd7562SDmitry Karpeev     ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr);
5239*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %" PetscInt_FMT " is incompatible with input matrix col size %" PetscInt_FMT,n,B->cmap->n);
524053dd7562SDmitry Karpeev   } else {
5241*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(C->cmap->n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix");
524253dd7562SDmitry Karpeev   }
524353dd7562SDmitry Karpeev 
524453dd7562SDmitry Karpeev   Baij = (Mat_SeqAIJ*)(B->data);
524553dd7562SDmitry Karpeev   if (pattern == DIFFERENT_NONZERO_PATTERN) {
524653dd7562SDmitry Karpeev     ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr);
524753dd7562SDmitry Karpeev     for (i=0; i<B->rmap->n; i++) {
524853dd7562SDmitry Karpeev       nz[i] = Baij->i[i+1] - Baij->i[i];
524953dd7562SDmitry Karpeev     }
525053dd7562SDmitry Karpeev     ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr);
525153dd7562SDmitry Karpeev     ierr = PetscFree(nz);CHKERRQ(ierr);
525253dd7562SDmitry Karpeev   }
525353dd7562SDmitry Karpeev   if (pattern == SUBSET_NONZERO_PATTERN) {
525453dd7562SDmitry Karpeev     ierr = MatZeroEntries(C);CHKERRQ(ierr);
525553dd7562SDmitry Karpeev   }
525653dd7562SDmitry Karpeev   count = 0;
525753dd7562SDmitry Karpeev   rowindices = NULL;
525853dd7562SDmitry Karpeev   colindices = NULL;
525953dd7562SDmitry Karpeev   if (rowemb) {
526053dd7562SDmitry Karpeev     ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr);
526153dd7562SDmitry Karpeev   }
526253dd7562SDmitry Karpeev   if (colemb) {
526353dd7562SDmitry Karpeev     ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr);
526453dd7562SDmitry Karpeev   }
526553dd7562SDmitry Karpeev   for (i=0; i<B->rmap->n; i++) {
526653dd7562SDmitry Karpeev     PetscInt row;
526753dd7562SDmitry Karpeev     row = i;
526853dd7562SDmitry Karpeev     if (rowindices) row = rowindices[i];
526953dd7562SDmitry Karpeev     for (j=Baij->i[i]; j<Baij->i[i+1]; j++) {
527053dd7562SDmitry Karpeev       PetscInt col;
527153dd7562SDmitry Karpeev       col  = Baij->j[count];
527253dd7562SDmitry Karpeev       if (colindices) col = colindices[col];
527353dd7562SDmitry Karpeev       v    = Baij->a[count];
527453dd7562SDmitry Karpeev       ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr);
527553dd7562SDmitry Karpeev       ++count;
527653dd7562SDmitry Karpeev     }
527753dd7562SDmitry Karpeev   }
527853dd7562SDmitry Karpeev   /* FIXME: set C's nonzerostate correctly. */
527953dd7562SDmitry Karpeev   /* Assembly for C is necessary. */
528053dd7562SDmitry Karpeev   C->preallocated = PETSC_TRUE;
528153dd7562SDmitry Karpeev   C->assembled     = PETSC_TRUE;
528253dd7562SDmitry Karpeev   C->was_assembled = PETSC_FALSE;
528353dd7562SDmitry Karpeev   PetscFunctionReturn(0);
528453dd7562SDmitry Karpeev }
528553dd7562SDmitry Karpeev 
52864099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL;
52874099cc6bSBarry Smith 
52884099cc6bSBarry Smith /*@C
52894099cc6bSBarry Smith    MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype
52904099cc6bSBarry Smith 
52914099cc6bSBarry Smith    Collective on Mat
52924099cc6bSBarry Smith 
52934099cc6bSBarry Smith    Input Parameters:
52944099cc6bSBarry Smith +  mat      - the matrix object
52954099cc6bSBarry Smith -  matype   - matrix type
52964099cc6bSBarry Smith 
52974099cc6bSBarry Smith    Options Database Key:
52984099cc6bSBarry Smith .  -mat_seqai_type  <method> - for example seqaijcrl
52994099cc6bSBarry Smith 
53004099cc6bSBarry Smith   Level: intermediate
53014099cc6bSBarry Smith 
53024099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
53034099cc6bSBarry Smith @*/
53044099cc6bSBarry Smith PetscErrorCode  MatSeqAIJSetType(Mat mat, MatType matype)
53054099cc6bSBarry Smith {
5306fd9d3c67SJed Brown   PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*);
53074099cc6bSBarry Smith   PetscBool      sametype;
53084099cc6bSBarry Smith 
53094099cc6bSBarry Smith   PetscFunctionBegin;
53104099cc6bSBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
53114099cc6bSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr);
53124099cc6bSBarry Smith   if (sametype) PetscFunctionReturn(0);
53134099cc6bSBarry Smith 
53144099cc6bSBarry Smith   ierr =  PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr);
5315*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
53164099cc6bSBarry Smith   ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr);
53174099cc6bSBarry Smith   PetscFunctionReturn(0);
53184099cc6bSBarry Smith }
53194099cc6bSBarry Smith 
53204099cc6bSBarry Smith /*@C
53214099cc6bSBarry Smith   MatSeqAIJRegister -  - Adds a new sub-matrix type for sequential AIJ matrices
53224099cc6bSBarry Smith 
53234099cc6bSBarry Smith    Not Collective
53244099cc6bSBarry Smith 
53254099cc6bSBarry Smith    Input Parameters:
53264099cc6bSBarry Smith +  name - name of a new user-defined matrix type, for example MATSEQAIJCRL
53274099cc6bSBarry Smith -  function - routine to convert to subtype
53284099cc6bSBarry Smith 
53294099cc6bSBarry Smith    Notes:
53304099cc6bSBarry Smith    MatSeqAIJRegister() may be called multiple times to add several user-defined solvers.
53314099cc6bSBarry Smith 
53324099cc6bSBarry Smith    Then, your matrix can be chosen with the procedural interface at runtime via the option
53334099cc6bSBarry Smith $     -mat_seqaij_type my_mat
53344099cc6bSBarry Smith 
53354099cc6bSBarry Smith    Level: advanced
53364099cc6bSBarry Smith 
53374099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll()
53384099cc6bSBarry Smith 
53394099cc6bSBarry Smith   Level: advanced
53404099cc6bSBarry Smith @*/
5341388d47a6SSatish Balay PetscErrorCode  MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *))
53424099cc6bSBarry Smith {
53434099cc6bSBarry Smith   PetscErrorCode ierr;
53444099cc6bSBarry Smith 
53454099cc6bSBarry Smith   PetscFunctionBegin;
53469cc31a68SJed Brown   ierr = MatInitializePackage();CHKERRQ(ierr);
53474099cc6bSBarry Smith   ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr);
53484099cc6bSBarry Smith   PetscFunctionReturn(0);
53494099cc6bSBarry Smith }
53504099cc6bSBarry Smith 
53514099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE;
53524099cc6bSBarry Smith 
53534099cc6bSBarry Smith /*@C
53544099cc6bSBarry Smith   MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ
53554099cc6bSBarry Smith 
53564099cc6bSBarry Smith   Not Collective
53574099cc6bSBarry Smith 
53584099cc6bSBarry Smith   Level: advanced
53594099cc6bSBarry Smith 
53604099cc6bSBarry Smith .seealso:  MatRegisterAll(), MatSeqAIJRegister()
53614099cc6bSBarry Smith @*/
53624099cc6bSBarry Smith PetscErrorCode  MatSeqAIJRegisterAll(void)
53634099cc6bSBarry Smith {
53644099cc6bSBarry Smith   PetscErrorCode ierr;
53654099cc6bSBarry Smith 
53664099cc6bSBarry Smith   PetscFunctionBegin;
53674099cc6bSBarry Smith   if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0);
53684099cc6bSBarry Smith   MatSeqAIJRegisterAllCalled = PETSC_TRUE;
53694099cc6bSBarry Smith 
53704099cc6bSBarry Smith   ierr = MatSeqAIJRegister(MATSEQAIJCRL,      MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
53714099cc6bSBarry Smith   ierr = MatSeqAIJRegister(MATSEQAIJPERM,     MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
53724dfdc2d9SRichard Tran Mills   ierr = MatSeqAIJRegister(MATSEQAIJSELL,     MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr);
53739779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE)
53746b62b571SRichard Tran Mills   ierr = MatSeqAIJRegister(MATSEQAIJMKL,      MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr);
5375485f9817SRichard Tran Mills #endif
53765063d097SStefano Zampini #if defined(PETSC_HAVE_CUDA)
53775063d097SStefano Zampini   ierr = MatSeqAIJRegister(MATSEQAIJCUSPARSE, MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr);
53785063d097SStefano Zampini #endif
53795063d097SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS)
53805063d097SStefano Zampini   ierr = MatSeqAIJRegister(MATSEQAIJKOKKOS,   MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr);
53815063d097SStefano Zampini #endif
53824099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA)
53834099cc6bSBarry Smith   ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr);
53844099cc6bSBarry Smith #endif
53854099cc6bSBarry Smith   PetscFunctionReturn(0);
53864099cc6bSBarry Smith }
538753dd7562SDmitry Karpeev 
538853dd7562SDmitry Karpeev /*
538981824310SBarry Smith     Special version for direct calls from Fortran
539081824310SBarry Smith */
5391af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
539281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
539381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
539481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
539581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
539681824310SBarry Smith #endif
539781824310SBarry Smith 
539881824310SBarry Smith /* Change these macros so can be used in void function */
539998921bdaSJacob Faibussowitsch 
540098921bdaSJacob Faibussowitsch /* Change these macros so can be used in void function */
540198921bdaSJacob Faibussowitsch /* Identical to CHKERRV, except it assigns to *_ierr */
540281824310SBarry Smith #undef CHKERRQ
540398921bdaSJacob Faibussowitsch #define CHKERRQ(ierr) do {                                                                     \
540498921bdaSJacob Faibussowitsch     PetscErrorCode ierr_msv_mpiaij = (ierr);                                                   \
540598921bdaSJacob Faibussowitsch     if (PetscUnlikely(ierr_msv_mpiaij)) {                                                      \
540698921bdaSJacob Faibussowitsch       *_ierr = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_msv_mpiaij,PETSC_ERROR_REPEAT," "); \
540798921bdaSJacob Faibussowitsch       return;                                                                                  \
540898921bdaSJacob Faibussowitsch     }                                                                                          \
540998921bdaSJacob Faibussowitsch   } while (0)
541098921bdaSJacob Faibussowitsch 
541198921bdaSJacob Faibussowitsch #undef SETERRQ
541298921bdaSJacob Faibussowitsch #define SETERRQ(comm,ierr,...) do {                                                            \
541398921bdaSJacob Faibussowitsch     *_ierr = PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__); \
541498921bdaSJacob Faibussowitsch     return;                                                                                    \
541598921bdaSJacob Faibussowitsch   } while (0)
541681824310SBarry Smith 
541719caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
541881824310SBarry Smith {
541981824310SBarry Smith   Mat            A  = *AA;
542081824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
542181824310SBarry Smith   InsertMode     is = *isis;
542281824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
542381824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
542481824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
542581824310SBarry Smith   PetscErrorCode ierr;
542681824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
542754f21887SBarry Smith   MatScalar      *ap,value,*aa;
5428ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
5429ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
543081824310SBarry Smith 
543181824310SBarry Smith   PetscFunctionBegin;
54324994cf47SJed Brown   MatCheckPreallocated(A,1);
543381824310SBarry Smith   imax  = a->imax;
543481824310SBarry Smith   ai    = a->i;
543581824310SBarry Smith   ailen = a->ilen;
543681824310SBarry Smith   aj    = a->j;
543781824310SBarry Smith   aa    = a->a;
543881824310SBarry Smith 
543981824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
544081824310SBarry Smith     row = im[k];
544181824310SBarry Smith     if (row < 0) continue;
5442cf9c20a2SJed Brown     if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
544381824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
544481824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
544581824310SBarry Smith     low  = 0;
544681824310SBarry Smith     high = nrow;
544781824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
544881824310SBarry Smith       if (in[l] < 0) continue;
5449cf9c20a2SJed Brown       if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
545081824310SBarry Smith       col = in[l];
54512205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
54522205254eSKarl Rupp       else value = v[k + l*m];
54532205254eSKarl Rupp 
545481824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
545581824310SBarry Smith 
54562205254eSKarl Rupp       if (col <= lastcol) low = 0;
54572205254eSKarl Rupp       else high = nrow;
545881824310SBarry Smith       lastcol = col;
545981824310SBarry Smith       while (high-low > 5) {
546081824310SBarry Smith         t = (low+high)/2;
546181824310SBarry Smith         if (rp[t] > col) high = t;
546281824310SBarry Smith         else             low  = t;
546381824310SBarry Smith       }
546481824310SBarry Smith       for (i=low; i<high; i++) {
546581824310SBarry Smith         if (rp[i] > col) break;
546681824310SBarry Smith         if (rp[i] == col) {
546781824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
546881824310SBarry Smith           else                  ap[i] = value;
546981824310SBarry Smith           goto noinsert;
547081824310SBarry Smith         }
547181824310SBarry Smith       }
547281824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
547381824310SBarry Smith       if (nonew == 1) goto noinsert;
5474ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
5475fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
547681824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
547781824310SBarry Smith       /* shift up all the later entries in this row */
547881824310SBarry Smith       for (ii=N; ii>=i; ii--) {
547981824310SBarry Smith         rp[ii+1] = rp[ii];
548081824310SBarry Smith         ap[ii+1] = ap[ii];
548181824310SBarry Smith       }
548281824310SBarry Smith       rp[i] = col;
548381824310SBarry Smith       ap[i] = value;
5484e56f5c9eSBarry Smith       A->nonzerostate++;
548581824310SBarry Smith noinsert:;
548681824310SBarry Smith       low = i + 1;
548781824310SBarry Smith     }
548881824310SBarry Smith     ailen[row] = nrow;
548981824310SBarry Smith   }
549081824310SBarry Smith   PetscFunctionReturnVoid();
549181824310SBarry Smith }
549298921bdaSJacob Faibussowitsch /* Undefining these here since they were redefined from their original definition above! No
549398921bdaSJacob Faibussowitsch  * other PETSc functions should be defined past this point, as it is impossible to recover the
549498921bdaSJacob Faibussowitsch  * original definitions */
549598921bdaSJacob Faibussowitsch #undef CHKERRQ
549698921bdaSJacob Faibussowitsch #undef SETERRQ
5497