xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 7cee066c24367720d931b33c41dfc5aaad322f9c)
1b377110cSBarry Smith 
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
77c4f633dSBarry Smith 
8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>          /*I "petscmat.h" I*/
9c6db04a5SJed Brown #include <petscblaslapack.h>
10c6db04a5SJed Brown #include <petscbt.h>
1106873bf2SBarry Smith #include <petsc-private/kernels/blocktranspose.h>
1278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1378b84d54SShri Abhyankar #include <petscthreadcomm.h>
1478b84d54SShri Abhyankar #endif
150716a85fSBarry Smith 
160716a85fSBarry Smith #undef __FUNCT__
170716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ"
180716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms)
190716a85fSBarry Smith {
200716a85fSBarry Smith   PetscErrorCode ierr;
210716a85fSBarry Smith   PetscInt       i,m,n;
220716a85fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)A->data;
230716a85fSBarry Smith 
240716a85fSBarry Smith   PetscFunctionBegin;
250716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
260716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
270716a85fSBarry Smith   if (type == NORM_2) {
280716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
290716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]);
300716a85fSBarry Smith     }
310716a85fSBarry Smith   } else if (type == NORM_1) {
320716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
330716a85fSBarry Smith       norms[aij->j[i]] += PetscAbsScalar(aij->a[i]);
340716a85fSBarry Smith     }
350716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
360716a85fSBarry Smith     for (i=0; i<aij->i[m]; i++) {
370716a85fSBarry Smith       norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]);
380716a85fSBarry Smith     }
390716a85fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType");
400716a85fSBarry Smith 
410716a85fSBarry Smith   if (type == NORM_2) {
428f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
430716a85fSBarry Smith   }
440716a85fSBarry Smith   PetscFunctionReturn(0);
450716a85fSBarry Smith }
460716a85fSBarry Smith 
474a2ae208SSatish Balay #undef __FUNCT__
48f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private"
49f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows)
506ce1633cSBarry Smith {
516ce1633cSBarry Smith   Mat_SeqAIJ      *a  = (Mat_SeqAIJ*)A->data;
526ce1633cSBarry Smith   const MatScalar *aa = a->a;
536ce1633cSBarry Smith   PetscInt        i,m=A->rmap->n,cnt = 0;
546ce1633cSBarry Smith   const PetscInt  *jj = a->j,*diag;
556ce1633cSBarry Smith   PetscInt        *rows;
566ce1633cSBarry Smith   PetscErrorCode  ierr;
576ce1633cSBarry Smith 
586ce1633cSBarry Smith   PetscFunctionBegin;
596ce1633cSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
606ce1633cSBarry Smith   diag = a->diag;
616ce1633cSBarry Smith   for (i=0; i<m; i++) {
626ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
636ce1633cSBarry Smith       cnt++;
646ce1633cSBarry Smith     }
656ce1633cSBarry Smith   }
666ce1633cSBarry Smith   ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr);
676ce1633cSBarry Smith   cnt  = 0;
686ce1633cSBarry Smith   for (i=0; i<m; i++) {
696ce1633cSBarry Smith     if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) {
706ce1633cSBarry Smith       rows[cnt++] = i;
716ce1633cSBarry Smith     }
726ce1633cSBarry Smith   }
73f1f41ecbSJed Brown   *nrows = cnt;
74f1f41ecbSJed Brown   *zrows = rows;
75f1f41ecbSJed Brown   PetscFunctionReturn(0);
76f1f41ecbSJed Brown }
77f1f41ecbSJed Brown 
78f1f41ecbSJed Brown #undef __FUNCT__
79f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ"
80f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows)
81f1f41ecbSJed Brown {
82f1f41ecbSJed Brown   PetscInt       nrows,*rows;
83f1f41ecbSJed Brown   PetscErrorCode ierr;
84f1f41ecbSJed Brown 
85f1f41ecbSJed Brown   PetscFunctionBegin;
860298fd71SBarry Smith   *zrows = NULL;
87f1f41ecbSJed Brown   ierr   = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr);
88ce94432eSBarry Smith   ierr   = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr);
896ce1633cSBarry Smith   PetscFunctionReturn(0);
906ce1633cSBarry Smith }
916ce1633cSBarry Smith 
926ce1633cSBarry Smith #undef __FUNCT__
93b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ"
94b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows)
95b3a44c85SBarry Smith {
96b3a44c85SBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
97b3a44c85SBarry Smith   const MatScalar *aa;
98b3a44c85SBarry Smith   PetscInt        m=A->rmap->n,cnt = 0;
99b3a44c85SBarry Smith   const PetscInt  *ii;
100b3a44c85SBarry Smith   PetscInt        n,i,j,*rows;
101b3a44c85SBarry Smith   PetscErrorCode  ierr;
102b3a44c85SBarry Smith 
103b3a44c85SBarry Smith   PetscFunctionBegin;
104b3a44c85SBarry Smith   *keptrows = 0;
105b3a44c85SBarry Smith   ii        = a->i;
106b3a44c85SBarry Smith   for (i=0; i<m; i++) {
107b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
108b3a44c85SBarry Smith     if (!n) {
109b3a44c85SBarry Smith       cnt++;
110b3a44c85SBarry Smith       goto ok1;
111b3a44c85SBarry Smith     }
112b3a44c85SBarry Smith     aa = a->a + ii[i];
113b3a44c85SBarry Smith     for (j=0; j<n; j++) {
114b3a44c85SBarry Smith       if (aa[j] != 0.0) goto ok1;
115b3a44c85SBarry Smith     }
116b3a44c85SBarry Smith     cnt++;
117b3a44c85SBarry Smith ok1:;
118b3a44c85SBarry Smith   }
119b3a44c85SBarry Smith   if (!cnt) PetscFunctionReturn(0);
120b3a44c85SBarry Smith   ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
121b3a44c85SBarry Smith   cnt  = 0;
122b3a44c85SBarry Smith   for (i=0; i<m; i++) {
123b3a44c85SBarry Smith     n = ii[i+1] - ii[i];
124b3a44c85SBarry Smith     if (!n) continue;
125b3a44c85SBarry Smith     aa = a->a + ii[i];
126b3a44c85SBarry Smith     for (j=0; j<n; j++) {
127b3a44c85SBarry Smith       if (aa[j] != 0.0) {
128b3a44c85SBarry Smith         rows[cnt++] = i;
129b3a44c85SBarry Smith         break;
130b3a44c85SBarry Smith       }
131b3a44c85SBarry Smith     }
132b3a44c85SBarry Smith   }
133b3a44c85SBarry Smith   ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr);
134b3a44c85SBarry Smith   PetscFunctionReturn(0);
135b3a44c85SBarry Smith }
136b3a44c85SBarry Smith 
137b3a44c85SBarry Smith #undef __FUNCT__
13879299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ"
1397087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is)
14079299369SBarry Smith {
14179299369SBarry Smith   PetscErrorCode ierr;
14279299369SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) Y->data;
143d0f46423SBarry Smith   PetscInt       i,*diag, m = Y->rmap->n;
14454f21887SBarry Smith   MatScalar      *aa = aij->a;
14554f21887SBarry Smith   PetscScalar    *v;
146ace3abfcSBarry Smith   PetscBool      missing;
14779299369SBarry Smith 
14879299369SBarry Smith   PetscFunctionBegin;
14909f38230SBarry Smith   if (Y->assembled) {
1500298fd71SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr);
15109f38230SBarry Smith     if (!missing) {
15279299369SBarry Smith       diag = aij->diag;
15379299369SBarry Smith       ierr = VecGetArray(D,&v);CHKERRQ(ierr);
15479299369SBarry Smith       if (is == INSERT_VALUES) {
15579299369SBarry Smith         for (i=0; i<m; i++) {
15679299369SBarry Smith           aa[diag[i]] = v[i];
15779299369SBarry Smith         }
15879299369SBarry Smith       } else {
15979299369SBarry Smith         for (i=0; i<m; i++) {
16079299369SBarry Smith           aa[diag[i]] += v[i];
16179299369SBarry Smith         }
16279299369SBarry Smith       }
16379299369SBarry Smith       ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
16479299369SBarry Smith       PetscFunctionReturn(0);
16579299369SBarry Smith     }
166acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
16709f38230SBarry Smith   }
16809f38230SBarry Smith   ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
16909f38230SBarry Smith   PetscFunctionReturn(0);
17009f38230SBarry Smith }
17179299369SBarry Smith 
17279299369SBarry Smith #undef __FUNCT__
1734a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
1741a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
17517ab2063SBarry Smith {
176416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
177dfbe8321SBarry Smith   PetscErrorCode ierr;
17897f1f81fSBarry Smith   PetscInt       i,ishift;
17917ab2063SBarry Smith 
1803a40ed3dSBarry Smith   PetscFunctionBegin;
181d0f46423SBarry Smith   *m = A->rmap->n;
1823a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
183bfeeae90SHong Zhang   ishift = 0;
18453e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
1851a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
186bfeeae90SHong Zhang   } else if (oshift == 1) {
1871a83f524SJed Brown     PetscInt *tia;
188d0f46423SBarry Smith     PetscInt nz = a->i[A->rmap->n];
1893b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
1901a83f524SJed Brown     ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),&tia);CHKERRQ(ierr);
1911a83f524SJed Brown     for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1;
1921a83f524SJed Brown     *ia = tia;
193ecc77c7aSBarry Smith     if (ja) {
1941a83f524SJed Brown       PetscInt *tja;
1951a83f524SJed Brown       ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&tja);CHKERRQ(ierr);
1961a83f524SJed Brown       for (i=0; i<nz; i++) tja[i] = a->j[i] + 1;
1971a83f524SJed Brown       *ja = tja;
198ecc77c7aSBarry Smith     }
1996945ee14SBarry Smith   } else {
200ecc77c7aSBarry Smith     *ia = a->i;
201ecc77c7aSBarry Smith     if (ja) *ja = a->j;
202a2ce50c7SBarry Smith   }
2033a40ed3dSBarry Smith   PetscFunctionReturn(0);
204a2744918SBarry Smith }
205a2744918SBarry Smith 
2064a2ae208SSatish Balay #undef __FUNCT__
2074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
2081a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2096945ee14SBarry Smith {
210dfbe8321SBarry Smith   PetscErrorCode ierr;
2116945ee14SBarry Smith 
2123a40ed3dSBarry Smith   PetscFunctionBegin;
2133a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
214bfeeae90SHong Zhang   if ((symmetric && !A->structurally_symmetric) || oshift == 1) {
215606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
216ecc77c7aSBarry Smith     if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);}
217bcd2baecSBarry Smith   }
2183a40ed3dSBarry Smith   PetscFunctionReturn(0);
21917ab2063SBarry Smith }
22017ab2063SBarry Smith 
2214a2ae208SSatish Balay #undef __FUNCT__
2224a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
2231a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2243b2fbd54SBarry Smith {
2253b2fbd54SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226dfbe8321SBarry Smith   PetscErrorCode ierr;
227d0f46423SBarry Smith   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
22897f1f81fSBarry Smith   PetscInt       nz = a->i[m],row,*jj,mr,col;
2293b2fbd54SBarry Smith 
2303a40ed3dSBarry Smith   PetscFunctionBegin;
231899cda47SBarry Smith   *nn = n;
2323a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2333b2fbd54SBarry Smith   if (symmetric) {
2341a83f524SJed Brown     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
2353b2fbd54SBarry Smith   } else {
23697f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
23797f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
23897f1f81fSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
23997f1f81fSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
2403b2fbd54SBarry Smith     jj   = a->j;
2413b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
242bfeeae90SHong Zhang       collengths[jj[i]]++;
2433b2fbd54SBarry Smith     }
2443b2fbd54SBarry Smith     cia[0] = oshift;
2453b2fbd54SBarry Smith     for (i=0; i<n; i++) {
2463b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
2473b2fbd54SBarry Smith     }
24897f1f81fSBarry Smith     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
2493b2fbd54SBarry Smith     jj   = a->j;
250a93ec695SBarry Smith     for (row=0; row<m; row++) {
251a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
252a93ec695SBarry Smith       for (i=0; i<mr; i++) {
253bfeeae90SHong Zhang         col = *jj++;
2542205254eSKarl Rupp 
2553b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
2563b2fbd54SBarry Smith       }
2573b2fbd54SBarry Smith     }
258606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
2593b2fbd54SBarry Smith     *ia  = cia; *ja = cja;
2603b2fbd54SBarry Smith   }
2613a40ed3dSBarry Smith   PetscFunctionReturn(0);
2623b2fbd54SBarry Smith }
2633b2fbd54SBarry Smith 
2644a2ae208SSatish Balay #undef __FUNCT__
2654a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
2661a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
2673b2fbd54SBarry Smith {
268dfbe8321SBarry Smith   PetscErrorCode ierr;
269606d414cSSatish Balay 
2703a40ed3dSBarry Smith   PetscFunctionBegin;
2713a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2723b2fbd54SBarry Smith 
273606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
274606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
2753a40ed3dSBarry Smith   PetscFunctionReturn(0);
2763b2fbd54SBarry Smith }
2773b2fbd54SBarry Smith 
278*7cee066cSHong Zhang /*
279*7cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from
280*7cee066cSHong Zhang  MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output
281*7cee066cSHong Zhang  spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqAIJ()
282*7cee066cSHong Zhang */
283*7cee066cSHong Zhang #undef __FUNCT__
284*7cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color"
285*7cee066cSHong 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)
286*7cee066cSHong Zhang {
287*7cee066cSHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
288*7cee066cSHong Zhang   PetscErrorCode ierr;
289*7cee066cSHong Zhang   PetscInt       i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n;
290*7cee066cSHong Zhang   PetscInt       nz = a->i[m],row,*jj,mr,col;
291*7cee066cSHong Zhang   PetscInt       *cspidx;
292*7cee066cSHong Zhang 
293*7cee066cSHong Zhang   PetscFunctionBegin;
294*7cee066cSHong Zhang   *nn = n;
295*7cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
296*7cee066cSHong Zhang   if (symmetric) {
297*7cee066cSHong Zhang     SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatGetColumnIJ_SeqAIJ_Color() not supported for the case symmetric");
298*7cee066cSHong Zhang     ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr);
299*7cee066cSHong Zhang   } else {
300*7cee066cSHong Zhang     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr);
301*7cee066cSHong Zhang     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
302*7cee066cSHong Zhang     ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr);
303*7cee066cSHong Zhang     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr);
304*7cee066cSHong Zhang     ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr);
305*7cee066cSHong Zhang     jj   = a->j;
306*7cee066cSHong Zhang     for (i=0; i<nz; i++) {
307*7cee066cSHong Zhang       collengths[jj[i]]++;
308*7cee066cSHong Zhang     }
309*7cee066cSHong Zhang     cia[0] = oshift;
310*7cee066cSHong Zhang     for (i=0; i<n; i++) {
311*7cee066cSHong Zhang       cia[i+1] = cia[i] + collengths[i];
312*7cee066cSHong Zhang     }
313*7cee066cSHong Zhang     ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr);
314*7cee066cSHong Zhang     jj   = a->j;
315*7cee066cSHong Zhang     for (row=0; row<m; row++) {
316*7cee066cSHong Zhang       mr = a->i[row+1] - a->i[row];
317*7cee066cSHong Zhang       for (i=0; i<mr; i++) {
318*7cee066cSHong Zhang         col = *jj++;
319*7cee066cSHong Zhang 
320*7cee066cSHong Zhang         cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */
321*7cee066cSHong Zhang         cja[cia[col] + collengths[col]++ - oshift]  = row + oshift;
322*7cee066cSHong Zhang       }
323*7cee066cSHong Zhang     }
324*7cee066cSHong Zhang     ierr   = PetscFree(collengths);CHKERRQ(ierr);
325*7cee066cSHong Zhang     *ia    = cia; *ja = cja;
326*7cee066cSHong Zhang     *spidx = cspidx;
327*7cee066cSHong Zhang   }
328*7cee066cSHong Zhang   PetscFunctionReturn(0);
329*7cee066cSHong Zhang }
330*7cee066cSHong Zhang 
331*7cee066cSHong Zhang #undef __FUNCT__
332*7cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color"
333*7cee066cSHong 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)
334*7cee066cSHong Zhang {
335*7cee066cSHong Zhang   PetscErrorCode ierr;
336*7cee066cSHong Zhang 
337*7cee066cSHong Zhang   PetscFunctionBegin;
338*7cee066cSHong Zhang   if (!ia) PetscFunctionReturn(0);
339*7cee066cSHong Zhang 
340*7cee066cSHong Zhang   ierr = PetscFree(*ia);CHKERRQ(ierr);
341*7cee066cSHong Zhang   ierr = PetscFree(*ja);CHKERRQ(ierr);
342*7cee066cSHong Zhang   ierr = PetscFree(*spidx);CHKERRQ(ierr);
343*7cee066cSHong Zhang   PetscFunctionReturn(0);
344*7cee066cSHong Zhang }
345*7cee066cSHong Zhang 
34687d4246cSBarry Smith #undef __FUNCT__
34787d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ"
34887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[])
34987d4246cSBarry Smith {
35087d4246cSBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
35187d4246cSBarry Smith   PetscInt       *ai = a->i;
35287d4246cSBarry Smith   PetscErrorCode ierr;
35387d4246cSBarry Smith 
35487d4246cSBarry Smith   PetscFunctionBegin;
35587d4246cSBarry Smith   ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr);
35687d4246cSBarry Smith   PetscFunctionReturn(0);
35787d4246cSBarry Smith }
35887d4246cSBarry Smith 
3594a2ae208SSatish Balay #undef __FUNCT__
3604a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
36197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is)
36217ab2063SBarry Smith {
363416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
364e2ee6c50SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
36597f1f81fSBarry Smith   PetscInt       *imax = a->imax,*ai = a->i,*ailen = a->ilen;
3666849ba73SBarry Smith   PetscErrorCode ierr;
367e2ee6c50SBarry Smith   PetscInt       *aj = a->j,nonew = a->nonew,lastcol = -1;
36854f21887SBarry Smith   MatScalar      *ap,value,*aa = a->a;
369ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
370ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
37117ab2063SBarry Smith 
3723a40ed3dSBarry Smith   PetscFunctionBegin;
37371fd2e92SBarry Smith   if (v) PetscValidScalarPointer(v,6);
37417ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
375416022c9SBarry Smith     row = im[k];
3765ef9f2a5SBarry Smith     if (row < 0) continue;
3772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
378e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
3793b2fbd54SBarry Smith #endif
380bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
38117ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
382416022c9SBarry Smith     low  = 0;
383c71e6ed7SBarry Smith     high = nrow;
38417ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
3855ef9f2a5SBarry Smith       if (in[l] < 0) continue;
3862515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
387e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
3883b2fbd54SBarry Smith #endif
389bfeeae90SHong Zhang       col = in[l];
39016371a99SBarry Smith       if (v) {
3914b0e389bSBarry Smith         if (roworiented) {
3925ef9f2a5SBarry Smith           value = v[l + k*n];
393bef8e0ddSBarry Smith         } else {
3944b0e389bSBarry Smith           value = v[k + l*m];
3954b0e389bSBarry Smith         }
39616371a99SBarry Smith       } else {
39775567043SBarry Smith         value = 0.;
39816371a99SBarry Smith       }
399abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
40036db0b34SBarry Smith 
4012205254eSKarl Rupp       if (col <= lastcol) low = 0;
4022205254eSKarl Rupp       else high = nrow;
403e2ee6c50SBarry Smith       lastcol = col;
404416022c9SBarry Smith       while (high-low > 5) {
405416022c9SBarry Smith         t = (low+high)/2;
406416022c9SBarry Smith         if (rp[t] > col) high = t;
407416022c9SBarry Smith         else low = t;
40817ab2063SBarry Smith       }
409416022c9SBarry Smith       for (i=low; i<high; i++) {
41017ab2063SBarry Smith         if (rp[i] > col) break;
41117ab2063SBarry Smith         if (rp[i] == col) {
412416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
41317ab2063SBarry Smith           else ap[i] = value;
414e44c0bd4SBarry Smith           low = i + 1;
41517ab2063SBarry Smith           goto noinsert;
41617ab2063SBarry Smith         }
41717ab2063SBarry Smith       }
418abc0a331SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
419c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
420e32f2f54SBarry Smith       if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col);
421fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
422c03d1d03SSatish Balay       N = nrow++ - 1; a->nz++; high++;
423416022c9SBarry Smith       /* shift up all the later entries in this row */
424416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
42517ab2063SBarry Smith         rp[ii+1] = rp[ii];
42617ab2063SBarry Smith         ap[ii+1] = ap[ii];
42717ab2063SBarry Smith       }
42817ab2063SBarry Smith       rp[i] = col;
42917ab2063SBarry Smith       ap[i] = value;
430416022c9SBarry Smith       low   = i + 1;
431e44c0bd4SBarry Smith noinsert:;
43217ab2063SBarry Smith     }
43317ab2063SBarry Smith     ailen[row] = nrow;
43417ab2063SBarry Smith   }
43588e51ccdSHong Zhang   A->same_nonzero = PETSC_FALSE;
4363a40ed3dSBarry Smith   PetscFunctionReturn(0);
43717ab2063SBarry Smith }
43817ab2063SBarry Smith 
43981824310SBarry Smith 
4404a2ae208SSatish Balay #undef __FUNCT__
4414a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
442a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[])
4437eb43aa7SLois Curfman McInnes {
4447eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
44597f1f81fSBarry Smith   PetscInt   *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
44697f1f81fSBarry Smith   PetscInt   *ai = a->i,*ailen = a->ilen;
44754f21887SBarry Smith   MatScalar  *ap,*aa = a->a;
4487eb43aa7SLois Curfman McInnes 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
4507eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
4517eb43aa7SLois Curfman McInnes     row = im[k];
452e32f2f54SBarry Smith     if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */
453e32f2f54SBarry Smith     if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1);
454bfeeae90SHong Zhang     rp   = aj + ai[row]; ap = aa + ai[row];
4557eb43aa7SLois Curfman McInnes     nrow = ailen[row];
4567eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
457e32f2f54SBarry Smith       if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */
458e32f2f54SBarry Smith       if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1);
459bfeeae90SHong Zhang       col  = in[l];
4607eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
4617eb43aa7SLois Curfman McInnes       while (high-low > 5) {
4627eb43aa7SLois Curfman McInnes         t = (low+high)/2;
4637eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
4647eb43aa7SLois Curfman McInnes         else low = t;
4657eb43aa7SLois Curfman McInnes       }
4667eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
4677eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
4687eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
469b49de8d1SLois Curfman McInnes           *v++ = ap[i];
4707eb43aa7SLois Curfman McInnes           goto finished;
4717eb43aa7SLois Curfman McInnes         }
4727eb43aa7SLois Curfman McInnes       }
47397e567efSBarry Smith       *v++ = 0.0;
4747eb43aa7SLois Curfman McInnes finished:;
4757eb43aa7SLois Curfman McInnes     }
4767eb43aa7SLois Curfman McInnes   }
4773a40ed3dSBarry Smith   PetscFunctionReturn(0);
4787eb43aa7SLois Curfman McInnes }
4797eb43aa7SLois Curfman McInnes 
48017ab2063SBarry Smith 
4814a2ae208SSatish Balay #undef __FUNCT__
4824a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
483dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
48417ab2063SBarry Smith {
485416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
4866849ba73SBarry Smith   PetscErrorCode ierr;
4876f69ff64SBarry Smith   PetscInt       i,*col_lens;
4886f69ff64SBarry Smith   int            fd;
489b37d52dbSMark F. Adams   FILE           *file;
49017ab2063SBarry Smith 
4913a40ed3dSBarry Smith   PetscFunctionBegin;
492b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
493d0f46423SBarry Smith   ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr);
4942205254eSKarl Rupp 
4950700a824SBarry Smith   col_lens[0] = MAT_FILE_CLASSID;
496d0f46423SBarry Smith   col_lens[1] = A->rmap->n;
497d0f46423SBarry Smith   col_lens[2] = A->cmap->n;
498416022c9SBarry Smith   col_lens[3] = a->nz;
499416022c9SBarry Smith 
500416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
501d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
502416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
50317ab2063SBarry Smith   }
504d0f46423SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
505606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
506416022c9SBarry Smith 
507416022c9SBarry Smith   /* store column indices (zero start index) */
5086f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
509416022c9SBarry Smith 
510416022c9SBarry Smith   /* store nonzero values */
5116f69ff64SBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
512b37d52dbSMark F. Adams 
513b37d52dbSMark F. Adams   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
514b37d52dbSMark F. Adams   if (file) {
515b37d52dbSMark F. Adams     fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs);
516b37d52dbSMark F. Adams   }
5173a40ed3dSBarry Smith   PetscFunctionReturn(0);
51817ab2063SBarry Smith }
519416022c9SBarry Smith 
52009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer);
521cd155464SBarry Smith 
5224a2ae208SSatish Balay #undef __FUNCT__
5234a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
525416022c9SBarry Smith {
526416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
527dfbe8321SBarry Smith   PetscErrorCode    ierr;
528d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,shift=0;
529e060cb09SBarry Smith   const char        *name;
530f3ef73ceSBarry Smith   PetscViewerFormat format;
53117ab2063SBarry Smith 
5323a40ed3dSBarry Smith   PetscFunctionBegin;
533b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
53471c2f376SKris Buschelman   if (format == PETSC_VIEWER_ASCII_MATLAB) {
53597f1f81fSBarry Smith     PetscInt nofinalvalue = 0;
536014b3a6eSMark Adams     if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) {
537d00d2cf4SBarry Smith       nofinalvalue = 1;
538d00d2cf4SBarry Smith     }
539d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
540d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr);
54177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr);
54277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
543b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
54417ab2063SBarry Smith 
54517ab2063SBarry Smith     for (i=0; i<m; i++) {
546416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
547aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
54877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
54917ab2063SBarry Smith #else
55077431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
55117ab2063SBarry Smith #endif
55217ab2063SBarry Smith       }
55317ab2063SBarry Smith     }
554d00d2cf4SBarry Smith     if (nofinalvalue) {
555d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%D %D  %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr);
556d00d2cf4SBarry Smith     }
557317d6ea6SBarry Smith     ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
558fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
559d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
56068369a75SKris Buschelman   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) {
561cd155464SBarry Smith     PetscFunctionReturn(0);
562fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
563d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
564dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
56544cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
56677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
56744cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
568aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
56936db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
570ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57136db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
572ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
57336db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
574ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
5756831982aSBarry Smith         }
57644cd7ae7SLois Curfman McInnes #else
577ba0e910bSBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);}
57844cd7ae7SLois Curfman McInnes #endif
57944cd7ae7SLois Curfman McInnes       }
580b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
58144cd7ae7SLois Curfman McInnes     }
582d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
583fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
58497f1f81fSBarry Smith     PetscInt nzd=0,fshift=1,*sptr;
585d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
586dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
58797f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr);
588496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
589496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
590496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
591496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
592aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
59336db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
594496be53dSLois Curfman McInnes #else
595496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
596496be53dSLois Curfman McInnes #endif
597496be53dSLois Curfman McInnes         }
598496be53dSLois Curfman McInnes       }
599496be53dSLois Curfman McInnes     }
6002e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
60177431f27SBarry Smith     ierr    = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr);
6022e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
6032205254eSKarl Rupp       if (i+4<m) {
6042205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);
6052205254eSKarl Rupp       } else if (i+3<m) {
6062205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);
6072205254eSKarl Rupp       } else if (i+2<m) {
6082205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);
6092205254eSKarl Rupp       } else if (i+1<m) {
6102205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);
6112205254eSKarl Rupp       } else if (i<m) {
6122205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);
6132205254eSKarl Rupp       } else {
6142205254eSKarl Rupp         ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);
6152205254eSKarl Rupp       }
616496be53dSLois Curfman McInnes     }
617b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
618606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
619496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
620496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
62177431f27SBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);}
622496be53dSLois Curfman McInnes       }
623b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
624496be53dSLois Curfman McInnes     }
625b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
626496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
627496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
628496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
629aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
63036db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
631b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6326831982aSBarry Smith           }
633496be53dSLois Curfman McInnes #else
634b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
635496be53dSLois Curfman McInnes #endif
636496be53dSLois Curfman McInnes         }
637496be53dSLois Curfman McInnes       }
638b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
639496be53dSLois Curfman McInnes     }
640d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
641fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
64297f1f81fSBarry Smith     PetscInt    cnt = 0,jcnt;
64387828ca2SBarry Smith     PetscScalar value;
64402594712SBarry Smith 
645d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
646dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
64702594712SBarry Smith     for (i=0; i<m; i++) {
64802594712SBarry Smith       jcnt = 0;
649d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
650e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
65102594712SBarry Smith           value = a->a[cnt++];
652e24b481bSBarry Smith           jcnt++;
65302594712SBarry Smith         } else {
65402594712SBarry Smith           value = 0.0;
65502594712SBarry Smith         }
656aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
657b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
65802594712SBarry Smith #else
659b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
66002594712SBarry Smith #endif
66102594712SBarry Smith       }
662b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
66302594712SBarry Smith     }
664d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6653c215bfdSMatthew Knepley   } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) {
666d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
667dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
6683c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6693c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr);
6703c215bfdSMatthew Knepley #else
6713c215bfdSMatthew Knepley     ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr);
6723c215bfdSMatthew Knepley #endif
673d0f46423SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr);
6743c215bfdSMatthew Knepley     for (i=0; i<m; i++) {
6753c215bfdSMatthew Knepley       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
6763c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX)
6773c215bfdSMatthew Knepley         if (PetscImaginaryPart(a->a[j]) > 0.0) {
678ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6793c215bfdSMatthew Knepley         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
680ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
6813c215bfdSMatthew Knepley         } else {
682ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
6833c215bfdSMatthew Knepley         }
6843c215bfdSMatthew Knepley #else
685ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr);
6863c215bfdSMatthew Knepley #endif
6873c215bfdSMatthew Knepley       }
6883c215bfdSMatthew Knepley     }
689d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
6903a40ed3dSBarry Smith   } else {
691d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
692dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr);
693d5f3da31SBarry Smith     if (A->factortype) {
69416cd7e1dSShri Abhyankar       for (i=0; i<m; i++) {
69516cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
69616cd7e1dSShri Abhyankar         /* L part */
69716cd7e1dSShri Abhyankar         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
69816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
69916cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
700ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
70116cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
702ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
70316cd7e1dSShri Abhyankar           } else {
704ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
70516cd7e1dSShri Abhyankar           }
70616cd7e1dSShri Abhyankar #else
707ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
70816cd7e1dSShri Abhyankar #endif
70916cd7e1dSShri Abhyankar         }
71016cd7e1dSShri Abhyankar         /* diagonal */
71116cd7e1dSShri Abhyankar         j = a->diag[i];
71216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
71316cd7e1dSShri Abhyankar         if (PetscImaginaryPart(a->a[j]) > 0.0) {
714ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
71516cd7e1dSShri Abhyankar         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
716ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr);
71716cd7e1dSShri Abhyankar         } else {
718ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr);
71916cd7e1dSShri Abhyankar         }
72016cd7e1dSShri Abhyankar #else
721ba0e910bSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr);
72216cd7e1dSShri Abhyankar #endif
72316cd7e1dSShri Abhyankar 
72416cd7e1dSShri Abhyankar         /* U part */
72516cd7e1dSShri Abhyankar         for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) {
72616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
72716cd7e1dSShri Abhyankar           if (PetscImaginaryPart(a->a[j]) > 0.0) {
728ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
72916cd7e1dSShri Abhyankar           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
730ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
73116cd7e1dSShri Abhyankar           } else {
732ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
73316cd7e1dSShri Abhyankar           }
73416cd7e1dSShri Abhyankar #else
735ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
73616cd7e1dSShri Abhyankar #endif
73716cd7e1dSShri Abhyankar         }
73816cd7e1dSShri Abhyankar         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
73916cd7e1dSShri Abhyankar       }
74016cd7e1dSShri Abhyankar     } else {
74117ab2063SBarry Smith       for (i=0; i<m; i++) {
74277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
743416022c9SBarry Smith         for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
744aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
74536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) > 0.0) {
746ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
74736db0b34SBarry Smith           } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
748ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
7493a40ed3dSBarry Smith           } else {
750ba0e910bSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
75117ab2063SBarry Smith           }
75217ab2063SBarry Smith #else
753ba0e910bSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);
75417ab2063SBarry Smith #endif
75517ab2063SBarry Smith         }
756b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
75717ab2063SBarry Smith       }
75816cd7e1dSShri Abhyankar     }
759d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
76017ab2063SBarry Smith   }
761b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7623a40ed3dSBarry Smith   PetscFunctionReturn(0);
763416022c9SBarry Smith }
764416022c9SBarry Smith 
7659804daf3SBarry Smith #include <petscdraw.h>
7664a2ae208SSatish Balay #undef __FUNCT__
7674a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
768dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
769416022c9SBarry Smith {
770480ef9eaSBarry Smith   Mat               A  = (Mat) Aa;
771416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
772dfbe8321SBarry Smith   PetscErrorCode    ierr;
773d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,color;
77436db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
775b0a32e0cSBarry Smith   PetscViewer       viewer;
776f3ef73ceSBarry Smith   PetscViewerFormat format;
777cddf8d76SBarry Smith 
7783a40ed3dSBarry Smith   PetscFunctionBegin;
779480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
780b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
78119bcc07fSBarry Smith 
782b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
783416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
7840513a670SBarry Smith 
785fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
7860513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
787b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
788416022c9SBarry Smith     for (i=0; i<m; i++) {
789cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
790bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
791bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
79236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
793b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
794cddf8d76SBarry Smith       }
795cddf8d76SBarry Smith     }
796b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
797cddf8d76SBarry Smith     for (i=0; i<m; i++) {
798cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
799bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
800bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
801cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
802b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
803cddf8d76SBarry Smith       }
804cddf8d76SBarry Smith     }
805b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
806cddf8d76SBarry Smith     for (i=0; i<m; i++) {
807cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
808bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
809bfeeae90SHong Zhang         x_l = a->j[j]; x_r = x_l + 1.0;
81036db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
811b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
812416022c9SBarry Smith       }
813416022c9SBarry Smith     }
8140513a670SBarry Smith   } else {
8150513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
8160513a670SBarry Smith     /* first determine max of all nonzero values */
81797f1f81fSBarry Smith     PetscInt  nz = a->nz,count;
818b0a32e0cSBarry Smith     PetscDraw popup;
81936db0b34SBarry Smith     PetscReal scale;
8200513a670SBarry Smith 
8210513a670SBarry Smith     for (i=0; i<nz; i++) {
8220513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
8230513a670SBarry Smith     }
824b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
825b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
8262205254eSKarl Rupp     if (popup) {
8272205254eSKarl Rupp       ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
8282205254eSKarl Rupp     }
8290513a670SBarry Smith     count = 0;
8300513a670SBarry Smith     for (i=0; i<m; i++) {
8310513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
832bfeeae90SHong Zhang       for (j=a->i[i]; j<a->i[i+1]; j++) {
833bfeeae90SHong Zhang         x_l   = a->j[j]; x_r = x_l + 1.0;
83497f1f81fSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count]));
835b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
8360513a670SBarry Smith         count++;
8370513a670SBarry Smith       }
8380513a670SBarry Smith     }
8390513a670SBarry Smith   }
840480ef9eaSBarry Smith   PetscFunctionReturn(0);
841480ef9eaSBarry Smith }
842cddf8d76SBarry Smith 
8439804daf3SBarry Smith #include <petscdraw.h>
8444a2ae208SSatish Balay #undef __FUNCT__
8454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
846dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
847480ef9eaSBarry Smith {
848dfbe8321SBarry Smith   PetscErrorCode ierr;
849b0a32e0cSBarry Smith   PetscDraw      draw;
85036db0b34SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
851ace3abfcSBarry Smith   PetscBool      isnull;
852480ef9eaSBarry Smith 
853480ef9eaSBarry Smith   PetscFunctionBegin;
854b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
855b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
856480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
857480ef9eaSBarry Smith 
858480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
859d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
860480ef9eaSBarry Smith   xr  += w;    yr += h;  xl = -w;     yl = -h;
861b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
862b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
8630298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
8643a40ed3dSBarry Smith   PetscFunctionReturn(0);
865416022c9SBarry Smith }
866416022c9SBarry Smith 
8674a2ae208SSatish Balay #undef __FUNCT__
8684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
869dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer)
870416022c9SBarry Smith {
871dfbe8321SBarry Smith   PetscErrorCode ierr;
872ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
873416022c9SBarry Smith 
8743a40ed3dSBarry Smith   PetscFunctionBegin;
875251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
876251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
877251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
878c45a1595SBarry Smith   if (iascii) {
8793a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
8800f5bd95cSBarry Smith   } else if (isbinary) {
8813a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
8820f5bd95cSBarry Smith   } else if (isdraw) {
8833a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
88411aeaf0aSBarry Smith   }
8854108e4d5SBarry Smith   ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr);
8863a40ed3dSBarry Smith   PetscFunctionReturn(0);
88717ab2063SBarry Smith }
88819bcc07fSBarry Smith 
8894a2ae208SSatish Balay #undef __FUNCT__
8904a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
891dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
89217ab2063SBarry Smith {
893416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
8946849ba73SBarry Smith   PetscErrorCode ierr;
89597f1f81fSBarry Smith   PetscInt       fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
896d0f46423SBarry Smith   PetscInt       m      = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0;
89754f21887SBarry Smith   MatScalar      *aa    = a->a,*ap;
8983447b6efSHong Zhang   PetscReal      ratio  = 0.6;
89917ab2063SBarry Smith 
9003a40ed3dSBarry Smith   PetscFunctionBegin;
9013a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
90217ab2063SBarry Smith 
90343ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
90417ab2063SBarry Smith   for (i=1; i<m; i++) {
905416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
90617ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
90794a9d846SBarry Smith     rmax    = PetscMax(rmax,ailen[i]);
90817ab2063SBarry Smith     if (fshift) {
909bfeeae90SHong Zhang       ip = aj + ai[i];
910bfeeae90SHong Zhang       ap = aa + ai[i];
91117ab2063SBarry Smith       N  = ailen[i];
91217ab2063SBarry Smith       for (j=0; j<N; j++) {
91317ab2063SBarry Smith         ip[j-fshift] = ip[j];
91417ab2063SBarry Smith         ap[j-fshift] = ap[j];
91517ab2063SBarry Smith       }
91617ab2063SBarry Smith     }
91717ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
91817ab2063SBarry Smith   }
91917ab2063SBarry Smith   if (m) {
92017ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
92117ab2063SBarry Smith     ai[m]   = ai[m-1] + ailen[m-1];
92217ab2063SBarry Smith   }
92317ab2063SBarry Smith   /* reset ilen and imax for each row */
92417ab2063SBarry Smith   for (i=0; i<m; i++) {
92517ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
92617ab2063SBarry Smith   }
927bfeeae90SHong Zhang   a->nz = ai[m];
92865e19b50SBarry Smith   if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift);
92917ab2063SBarry Smith 
93009f38230SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
931d0f46423SBarry Smith   ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr);
932ae15b995SBarry Smith   ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr);
933ae15b995SBarry Smith   ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr);
9342205254eSKarl Rupp 
9358e58a170SBarry Smith   A->info.mallocs    += a->reallocs;
936dd5f02e7SSatish Balay   a->reallocs         = 0;
9374e220ebcSLois Curfman McInnes   A->info.nz_unneeded = (double)fshift;
93836db0b34SBarry Smith   a->rmax             = rmax;
9394e220ebcSLois Curfman McInnes 
940cd6b891eSBarry Smith   ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr);
9412205254eSKarl Rupp 
94288e51ccdSHong Zhang   A->same_nonzero = PETSC_TRUE;
94371c2f376SKris Buschelman 
9444108e4d5SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr);
94571f1c65dSBarry Smith 
946acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
9473a40ed3dSBarry Smith   PetscFunctionReturn(0);
94817ab2063SBarry Smith }
94917ab2063SBarry Smith 
9504a2ae208SSatish Balay #undef __FUNCT__
95199cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ"
95299cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A)
95399cafbc1SBarry Smith {
95499cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
95599cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
95654f21887SBarry Smith   MatScalar      *aa = a->a;
957acf2f550SJed Brown   PetscErrorCode ierr;
95899cafbc1SBarry Smith 
95999cafbc1SBarry Smith   PetscFunctionBegin;
96099cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
961acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
96299cafbc1SBarry Smith   PetscFunctionReturn(0);
96399cafbc1SBarry Smith }
96499cafbc1SBarry Smith 
96599cafbc1SBarry Smith #undef __FUNCT__
96699cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ"
96799cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A)
96899cafbc1SBarry Smith {
96999cafbc1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
97099cafbc1SBarry Smith   PetscInt       i,nz = a->nz;
97154f21887SBarry Smith   MatScalar      *aa = a->a;
972acf2f550SJed Brown   PetscErrorCode ierr;
97399cafbc1SBarry Smith 
97499cafbc1SBarry Smith   PetscFunctionBegin;
97599cafbc1SBarry Smith   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
976acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
97799cafbc1SBarry Smith   PetscFunctionReturn(0);
97899cafbc1SBarry Smith }
97999cafbc1SBarry Smith 
98078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
98178b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A)
98278b84d54SShri Abhyankar {
98378b84d54SShri Abhyankar   PetscErrorCode ierr;
98478b84d54SShri Abhyankar   PetscInt       *trstarts=A->rmap->trstarts;
98578b84d54SShri Abhyankar   PetscInt       n,start,end;
98678b84d54SShri Abhyankar   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
98778b84d54SShri Abhyankar 
98878b84d54SShri Abhyankar   start = trstarts[thread_id];
98978b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
99019baf141SJed Brown   n     = a->i[end] - a->i[start];
99119baf141SJed Brown   ierr  = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr);
99278b84d54SShri Abhyankar   return 0;
99378b84d54SShri Abhyankar }
99478b84d54SShri Abhyankar 
99578b84d54SShri Abhyankar #undef __FUNCT__
99678b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ"
99778b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
99878b84d54SShri Abhyankar {
99978b84d54SShri Abhyankar   PetscErrorCode ierr;
100078b84d54SShri Abhyankar 
100178b84d54SShri Abhyankar   PetscFunctionBegin;
1002ce94432eSBarry Smith   ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr);
1003acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
100478b84d54SShri Abhyankar   PetscFunctionReturn(0);
100578b84d54SShri Abhyankar }
100678b84d54SShri Abhyankar #else
100799cafbc1SBarry Smith #undef __FUNCT__
10084a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
1009dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A)
101017ab2063SBarry Smith {
1011416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1012dfbe8321SBarry Smith   PetscErrorCode ierr;
10133a40ed3dSBarry Smith 
10143a40ed3dSBarry Smith   PetscFunctionBegin;
1015d0f46423SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
1016acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
10173a40ed3dSBarry Smith   PetscFunctionReturn(0);
101817ab2063SBarry Smith }
101978b84d54SShri Abhyankar #endif
1020416022c9SBarry Smith 
10214a2ae208SSatish Balay #undef __FUNCT__
10224a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
1023dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A)
102417ab2063SBarry Smith {
1025416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
1026dfbe8321SBarry Smith   PetscErrorCode ierr;
1027d5d45c9bSBarry Smith 
10283a40ed3dSBarry Smith   PetscFunctionBegin;
1029aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1030d0f46423SBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz);
103117ab2063SBarry Smith #endif
1032e6b907acSBarry Smith   ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr);
10336bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
10346bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
103505b42c5fSBarry Smith   ierr = PetscFree(a->diag);CHKERRQ(ierr);
1036d48dcb14SBarry Smith   ierr = PetscFree(a->ibdiag);CHKERRQ(ierr);
103705b42c5fSBarry Smith   ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);
103871f1c65dSBarry Smith   ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr);
103905b42c5fSBarry Smith   ierr = PetscFree(a->solve_work);CHKERRQ(ierr);
10406bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
104105b42c5fSBarry Smith   ierr = PetscFree(a->saved_values);CHKERRQ(ierr);
10426bf464f9SBarry Smith   ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr);
104305b42c5fSBarry Smith   ierr = PetscFree(a->xtoy);CHKERRQ(ierr);
10446bf464f9SBarry Smith   ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr);
1045cd6b891eSBarry Smith   ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr);
10460b7e3e3dSHong Zhang   ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr);
1047a30b2313SHong Zhang 
10484108e4d5SBarry Smith   ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr);
1049bf0cc555SLisandro Dalcin   ierr = PetscFree(A->data);CHKERRQ(ierr);
1050901853e0SKris Buschelman 
1051dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr);
1052bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr);
1053bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr);
1054bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr);
1055bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr);
1056bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr);
1057bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr);
1058bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr);
1059bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr);
1060bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr);
1061bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr);
10623a40ed3dSBarry Smith   PetscFunctionReturn(0);
106317ab2063SBarry Smith }
106417ab2063SBarry Smith 
10654a2ae208SSatish Balay #undef __FUNCT__
10664a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
1067ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg)
106817ab2063SBarry Smith {
1069416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
10704846f1f5SKris Buschelman   PetscErrorCode ierr;
10713a40ed3dSBarry Smith 
10723a40ed3dSBarry Smith   PetscFunctionBegin;
1073a65d3064SKris Buschelman   switch (op) {
1074a65d3064SKris Buschelman   case MAT_ROW_ORIENTED:
10754e0d8c25SBarry Smith     a->roworiented = flg;
1076a65d3064SKris Buschelman     break;
1077a9817697SBarry Smith   case MAT_KEEP_NONZERO_PATTERN:
1078a9817697SBarry Smith     a->keepnonzeropattern = flg;
1079a65d3064SKris Buschelman     break;
1080512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1081512a5fc5SBarry Smith     a->nonew = (flg ? 0 : 1);
1082a65d3064SKris Buschelman     break;
1083a65d3064SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
10844e0d8c25SBarry Smith     a->nonew = (flg ? -1 : 0);
1085a65d3064SKris Buschelman     break;
1086a65d3064SKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
10874e0d8c25SBarry Smith     a->nonew = (flg ? -2 : 0);
1088a65d3064SKris Buschelman     break;
108928b2fa4aSMatthew Knepley   case MAT_UNUSED_NONZERO_LOCATION_ERR:
109028b2fa4aSMatthew Knepley     a->nounused = (flg ? -1 : 0);
109128b2fa4aSMatthew Knepley     break;
1092a65d3064SKris Buschelman   case MAT_IGNORE_ZERO_ENTRIES:
10934e0d8c25SBarry Smith     a->ignorezeroentries = flg;
10940df259c2SBarry Smith     break;
1095cd6b891eSBarry Smith   case MAT_CHECK_COMPRESSED_ROW:
1096cd6b891eSBarry Smith     a->compressedrow.check = flg;
1097d487561eSHong Zhang     break;
10983d472b54SHong Zhang   case MAT_SPD:
1099b1646e73SJed Brown   case MAT_SYMMETRIC:
1100b1646e73SJed Brown   case MAT_STRUCTURALLY_SYMMETRIC:
1101b1646e73SJed Brown   case MAT_HERMITIAN:
1102b1646e73SJed Brown   case MAT_SYMMETRY_ETERNAL:
11035021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
11045021d80fSJed Brown     break;
11054e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
1106a65d3064SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1107a65d3064SKris Buschelman   case MAT_USE_HASH_TABLE:
1108290bbb0aSBarry Smith     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
1109a65d3064SKris Buschelman     break;
1110b87ac2d8SJed Brown   case MAT_USE_INODES:
1111b87ac2d8SJed Brown     /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */
1112b87ac2d8SJed Brown     break;
1113a65d3064SKris Buschelman   default:
1114e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op);
1115a65d3064SKris Buschelman   }
11164108e4d5SBarry Smith   ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr);
11173a40ed3dSBarry Smith   PetscFunctionReturn(0);
111817ab2063SBarry Smith }
111917ab2063SBarry Smith 
11204a2ae208SSatish Balay #undef __FUNCT__
11214a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
1122dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v)
112317ab2063SBarry Smith {
1124416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11256849ba73SBarry Smith   PetscErrorCode ierr;
1126d3e70bfaSHong Zhang   PetscInt       i,j,n,*ai=a->i,*aj=a->j,nz;
112735e7444dSHong Zhang   PetscScalar    *aa=a->a,*x,zero=0.0;
112817ab2063SBarry Smith 
11293a40ed3dSBarry Smith   PetscFunctionBegin;
1130d3e70bfaSHong Zhang   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1131e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
113235e7444dSHong Zhang 
1133d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) {
1134d3e70bfaSHong Zhang     PetscInt *diag=a->diag;
113535e7444dSHong Zhang     ierr = VecGetArray(v,&x);CHKERRQ(ierr);
11362c990fa1SHong Zhang     for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]];
113735e7444dSHong Zhang     ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
113835e7444dSHong Zhang     PetscFunctionReturn(0);
113935e7444dSHong Zhang   }
114035e7444dSHong Zhang 
11412dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
11421ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
114335e7444dSHong Zhang   for (i=0; i<n; i++) {
114435e7444dSHong Zhang     nz = ai[i+1] - ai[i];
11452f5a7c2eSBarry Smith     if (!nz) x[i] = 0.0;
114635e7444dSHong Zhang     for (j=ai[i]; j<ai[i+1]; j++) {
114735e7444dSHong Zhang       if (aj[j] == i) {
114835e7444dSHong Zhang         x[i] = aa[j];
114917ab2063SBarry Smith         break;
115017ab2063SBarry Smith       }
115117ab2063SBarry Smith     }
115217ab2063SBarry Smith   }
11531ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
11543a40ed3dSBarry Smith   PetscFunctionReturn(0);
115517ab2063SBarry Smith }
115617ab2063SBarry Smith 
1157c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
11584a2ae208SSatish Balay #undef __FUNCT__
11594a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
1160dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
116117ab2063SBarry Smith {
1162416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
11635c897100SBarry Smith   PetscScalar    *x,*y;
1164dfbe8321SBarry Smith   PetscErrorCode ierr;
1165d0f46423SBarry Smith   PetscInt       m = A->rmap->n;
11665c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1167a77337e4SBarry Smith   MatScalar         *v;
1168a77337e4SBarry Smith   PetscScalar       alpha;
11690298fd71SBarry Smith   PetscInt          n,i,j,*idx,*ii,*ridx=NULL;
11703447b6efSHong Zhang   Mat_CompressedRow cprow    = a->compressedrow;
1171ace3abfcSBarry Smith   PetscBool         usecprow = cprow.use;
11725c897100SBarry Smith #endif
117317ab2063SBarry Smith 
11743a40ed3dSBarry Smith   PetscFunctionBegin;
11752e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
11761ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
11771ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11785c897100SBarry Smith 
11795c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
1180bfeeae90SHong Zhang   fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y);
11815c897100SBarry Smith #else
11823447b6efSHong Zhang   if (usecprow) {
11833447b6efSHong Zhang     m    = cprow.nrows;
11843447b6efSHong Zhang     ii   = cprow.i;
11857b2bb3b9SHong Zhang     ridx = cprow.rindex;
11863447b6efSHong Zhang   } else {
11873447b6efSHong Zhang     ii = a->i;
11883447b6efSHong Zhang   }
118917ab2063SBarry Smith   for (i=0; i<m; i++) {
11903447b6efSHong Zhang     idx = a->j + ii[i];
11913447b6efSHong Zhang     v   = a->a + ii[i];
11923447b6efSHong Zhang     n   = ii[i+1] - ii[i];
11933447b6efSHong Zhang     if (usecprow) {
11947b2bb3b9SHong Zhang       alpha = x[ridx[i]];
11953447b6efSHong Zhang     } else {
119617ab2063SBarry Smith       alpha = x[i];
11973447b6efSHong Zhang     }
119804fbf559SBarry Smith     for (j=0; j<n; j++) y[idx[j]] += alpha*v[j];
119917ab2063SBarry Smith   }
12005c897100SBarry Smith #endif
1201dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
12021ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
12031ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
12043a40ed3dSBarry Smith   PetscFunctionReturn(0);
120517ab2063SBarry Smith }
120617ab2063SBarry Smith 
12074a2ae208SSatish Balay #undef __FUNCT__
12085c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
1209dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
12105c897100SBarry Smith {
1211dfbe8321SBarry Smith   PetscErrorCode ierr;
12125c897100SBarry Smith 
12135c897100SBarry Smith   PetscFunctionBegin;
1214170fe5c8SBarry Smith   ierr = VecSet(yy,0.0);CHKERRQ(ierr);
12155c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
12165c897100SBarry Smith   PetscFunctionReturn(0);
12175c897100SBarry Smith }
12185c897100SBarry Smith 
1219c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h>
122078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
122178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy)
122278b84d54SShri Abhyankar {
122378b84d54SShri Abhyankar   PetscErrorCode    ierr;
122478b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
122578b84d54SShri Abhyankar   PetscScalar       *y;
122678b84d54SShri Abhyankar   const PetscScalar *x;
122778b84d54SShri Abhyankar   const MatScalar   *aa;
122878b84d54SShri Abhyankar   PetscInt          *trstarts=A->rmap->trstarts;
122978b84d54SShri Abhyankar   PetscInt          n,start,end,i;
123078b84d54SShri Abhyankar   const PetscInt    *aj,*ai;
123178b84d54SShri Abhyankar   PetscScalar       sum;
123278b84d54SShri Abhyankar 
123378b84d54SShri Abhyankar   ierr  = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
123478b84d54SShri Abhyankar   ierr  = VecGetArray(yy,&y);CHKERRQ(ierr);
123578b84d54SShri Abhyankar   start = trstarts[thread_id];
123678b84d54SShri Abhyankar   end   = trstarts[thread_id+1];
123778b84d54SShri Abhyankar   aj    = a->j;
123878b84d54SShri Abhyankar   aa    = a->a;
123978b84d54SShri Abhyankar   ai    = a->i;
124078b84d54SShri Abhyankar   for (i=start; i<end; i++) {
124178b84d54SShri Abhyankar     n   = ai[i+1] - ai[i];
124278b84d54SShri Abhyankar     aj  = a->j + ai[i];
124378b84d54SShri Abhyankar     aa  = a->a + ai[i];
124478b84d54SShri Abhyankar     sum = 0.0;
124578b84d54SShri Abhyankar     PetscSparseDensePlusDot(sum,x,aa,aj,n);
124678b84d54SShri Abhyankar     y[i] = sum;
124778b84d54SShri Abhyankar   }
124878b84d54SShri Abhyankar   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
124978b84d54SShri Abhyankar   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
125078b84d54SShri Abhyankar   return 0;
125178b84d54SShri Abhyankar }
125278b84d54SShri Abhyankar 
125378b84d54SShri Abhyankar #undef __FUNCT__
125478b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ"
125578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
125678b84d54SShri Abhyankar {
125778b84d54SShri Abhyankar   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
125878b84d54SShri Abhyankar   PetscScalar       *y;
125978b84d54SShri Abhyankar   const PetscScalar *x;
126078b84d54SShri Abhyankar   const MatScalar   *aa;
126178b84d54SShri Abhyankar   PetscErrorCode    ierr;
126278b84d54SShri Abhyankar   PetscInt          m=A->rmap->n;
12630298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
126478b84d54SShri Abhyankar   PetscInt          n,i,nonzerorow=0;
126578b84d54SShri Abhyankar   PetscScalar       sum;
126678b84d54SShri Abhyankar   PetscBool         usecprow=a->compressedrow.use;
126778b84d54SShri Abhyankar 
126878b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
126978b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa)
127078b84d54SShri Abhyankar #endif
127178b84d54SShri Abhyankar 
127278b84d54SShri Abhyankar   PetscFunctionBegin;
127378b84d54SShri Abhyankar   aj = a->j;
127478b84d54SShri Abhyankar   aa = a->a;
127578b84d54SShri Abhyankar   ii = a->i;
127678b84d54SShri Abhyankar   if (usecprow) { /* use compressed row format */
127778b84d54SShri Abhyankar     ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
127878b84d54SShri Abhyankar     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
127978b84d54SShri Abhyankar     m    = a->compressedrow.nrows;
128078b84d54SShri Abhyankar     ii   = a->compressedrow.i;
128178b84d54SShri Abhyankar     ridx = a->compressedrow.rindex;
128278b84d54SShri Abhyankar     for (i=0; i<m; i++) {
128378b84d54SShri Abhyankar       n           = ii[i+1] - ii[i];
128478b84d54SShri Abhyankar       aj          = a->j + ii[i];
128578b84d54SShri Abhyankar       aa          = a->a + ii[i];
128678b84d54SShri Abhyankar       sum         = 0.0;
128778b84d54SShri Abhyankar       nonzerorow += (n>0);
128878b84d54SShri Abhyankar       PetscSparseDensePlusDot(sum,x,aa,aj,n);
128978b84d54SShri Abhyankar       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
129078b84d54SShri Abhyankar       y[*ridx++] = sum;
129178b84d54SShri Abhyankar     }
129278b84d54SShri Abhyankar     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
129378b84d54SShri Abhyankar     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
129478b84d54SShri Abhyankar   } else { /* do not use compressed row format */
129578b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
129678b84d54SShri Abhyankar     fortranmultaij_(&m,x,ii,aj,aa,y);
129778b84d54SShri Abhyankar #else
1298ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
129978b84d54SShri Abhyankar #endif
130078b84d54SShri Abhyankar   }
130178b84d54SShri Abhyankar   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
130278b84d54SShri Abhyankar   PetscFunctionReturn(0);
130378b84d54SShri Abhyankar }
130478b84d54SShri Abhyankar #else
13055c897100SBarry Smith #undef __FUNCT__
13064a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
1307dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
130817ab2063SBarry Smith {
1309416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1310d9fead3dSBarry Smith   PetscScalar       *y;
131154f21887SBarry Smith   const PetscScalar *x;
131254f21887SBarry Smith   const MatScalar   *aa;
1313dfbe8321SBarry Smith   PetscErrorCode    ierr;
1314003131ecSBarry Smith   PetscInt          m=A->rmap->n;
13150298fd71SBarry Smith   const PetscInt    *aj,*ii,*ridx=NULL;
13168aee2decSHong Zhang   PetscInt          n,i,nonzerorow=0;
1317362ced78SSatish Balay   PetscScalar       sum;
1318ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
131917ab2063SBarry Smith 
1320b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
132197952fefSHong Zhang #pragma disjoint(*x,*y,*aa)
1322fee21e36SBarry Smith #endif
1323fee21e36SBarry Smith 
13243a40ed3dSBarry Smith   PetscFunctionBegin;
13253649974fSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
13261ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
132797952fefSHong Zhang   aj   = a->j;
132897952fefSHong Zhang   aa   = a->a;
1329416022c9SBarry Smith   ii   = a->i;
13304eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
133197952fefSHong Zhang     m    = a->compressedrow.nrows;
133297952fefSHong Zhang     ii   = a->compressedrow.i;
133397952fefSHong Zhang     ridx = a->compressedrow.rindex;
133497952fefSHong Zhang     for (i=0; i<m; i++) {
133597952fefSHong Zhang       n           = ii[i+1] - ii[i];
133697952fefSHong Zhang       aj          = a->j + ii[i];
133797952fefSHong Zhang       aa          = a->a + ii[i];
133897952fefSHong Zhang       sum         = 0.0;
1339a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1340003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
1341003131ecSBarry Smith       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
134297952fefSHong Zhang       y[*ridx++] = sum;
134397952fefSHong Zhang     }
134497952fefSHong Zhang   } else { /* do not use compressed row format */
1345b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
1346b05257ddSBarry Smith     fortranmultaij_(&m,x,ii,aj,aa,y);
1347b05257ddSBarry Smith #else
134878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
1349ce94432eSBarry Smith     ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr);
135078b84d54SShri Abhyankar #else
135117ab2063SBarry Smith     for (i=0; i<m; i++) {
1352003131ecSBarry Smith       n           = ii[i+1] - ii[i];
1353003131ecSBarry Smith       aj          = a->j + ii[i];
1354003131ecSBarry Smith       aa          = a->a + ii[i];
135517ab2063SBarry Smith       sum         = 0.0;
1356a46b3154SVictor Eijkhout       nonzerorow += (n>0);
1357003131ecSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
135817ab2063SBarry Smith       y[i] = sum;
135917ab2063SBarry Smith     }
13608d195f9aSBarry Smith #endif
136178b84d54SShri Abhyankar #endif
1362b05257ddSBarry Smith   }
1363dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
13643649974fSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
13651ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
13663a40ed3dSBarry Smith   PetscFunctionReturn(0);
136717ab2063SBarry Smith }
136878b84d54SShri Abhyankar #endif
136917ab2063SBarry Smith 
1370b434eb95SMatthew G. Knepley #undef __FUNCT__
1371b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ"
1372b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy)
1373b434eb95SMatthew G. Knepley {
1374b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1375b434eb95SMatthew G. Knepley   PetscScalar       *y;
1376b434eb95SMatthew G. Knepley   const PetscScalar *x;
1377b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1378b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1379b434eb95SMatthew G. Knepley   PetscInt          m=A->rmap->n;
1380b434eb95SMatthew G. Knepley   const PetscInt    *aj,*ii,*ridx=NULL;
1381b434eb95SMatthew G. Knepley   PetscInt          n,i,nonzerorow=0;
1382b434eb95SMatthew G. Knepley   PetscScalar       sum;
1383b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1384b434eb95SMatthew G. Knepley 
1385b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
1386b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa)
1387b434eb95SMatthew G. Knepley #endif
1388b434eb95SMatthew G. Knepley 
1389b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1390b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1391b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1392b434eb95SMatthew G. Knepley   aj   = a->j;
1393b434eb95SMatthew G. Knepley   aa   = a->a;
1394b434eb95SMatthew G. Knepley   ii   = a->i;
1395b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1396b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1397b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1398b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1399b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1400b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1401b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1402b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1403b434eb95SMatthew G. Knepley       sum         = 0.0;
1404b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1405b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1406b434eb95SMatthew G. Knepley       /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */
1407b434eb95SMatthew G. Knepley       y[*ridx++] = sum;
1408b434eb95SMatthew G. Knepley     }
1409b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1410b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1411b434eb95SMatthew G. Knepley       n           = ii[i+1] - ii[i];
1412b434eb95SMatthew G. Knepley       aj          = a->j + ii[i];
1413b434eb95SMatthew G. Knepley       aa          = a->a + ii[i];
1414b434eb95SMatthew G. Knepley       sum         = 0.0;
1415b434eb95SMatthew G. Knepley       nonzerorow += (n>0);
1416b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1417b434eb95SMatthew G. Knepley       y[i] = sum;
1418b434eb95SMatthew G. Knepley     }
1419b434eb95SMatthew G. Knepley   }
1420b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr);
1421b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1422b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1423b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1424b434eb95SMatthew G. Knepley }
1425b434eb95SMatthew G. Knepley 
1426b434eb95SMatthew G. Knepley #undef __FUNCT__
1427b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ"
1428b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
1429b434eb95SMatthew G. Knepley {
1430b434eb95SMatthew G. Knepley   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1431b434eb95SMatthew G. Knepley   PetscScalar       *y,*z;
1432b434eb95SMatthew G. Knepley   const PetscScalar *x;
1433b434eb95SMatthew G. Knepley   const MatScalar   *aa;
1434b434eb95SMatthew G. Knepley   PetscErrorCode    ierr;
1435b434eb95SMatthew G. Knepley   PetscInt          m = A->rmap->n,*aj,*ii;
1436b434eb95SMatthew G. Knepley   PetscInt          n,i,*ridx=NULL;
1437b434eb95SMatthew G. Knepley   PetscScalar       sum;
1438b434eb95SMatthew G. Knepley   PetscBool         usecprow=a->compressedrow.use;
1439b434eb95SMatthew G. Knepley 
1440b434eb95SMatthew G. Knepley   PetscFunctionBegin;
1441b434eb95SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
1442b434eb95SMatthew G. Knepley   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
1443b434eb95SMatthew G. Knepley   if (zz != yy) {
1444b434eb95SMatthew G. Knepley     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
1445b434eb95SMatthew G. Knepley   } else {
1446b434eb95SMatthew G. Knepley     z = y;
1447b434eb95SMatthew G. Knepley   }
1448b434eb95SMatthew G. Knepley 
1449b434eb95SMatthew G. Knepley   aj = a->j;
1450b434eb95SMatthew G. Knepley   aa = a->a;
1451b434eb95SMatthew G. Knepley   ii = a->i;
1452b434eb95SMatthew G. Knepley   if (usecprow) { /* use compressed row format */
1453b434eb95SMatthew G. Knepley     if (zz != yy) {
1454b434eb95SMatthew G. Knepley       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
1455b434eb95SMatthew G. Knepley     }
1456b434eb95SMatthew G. Knepley     m    = a->compressedrow.nrows;
1457b434eb95SMatthew G. Knepley     ii   = a->compressedrow.i;
1458b434eb95SMatthew G. Knepley     ridx = a->compressedrow.rindex;
1459b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1460b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1461b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1462b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1463b434eb95SMatthew G. Knepley       sum = y[*ridx];
1464b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1465b434eb95SMatthew G. Knepley       z[*ridx++] = sum;
1466b434eb95SMatthew G. Knepley     }
1467b434eb95SMatthew G. Knepley   } else { /* do not use compressed row format */
1468b434eb95SMatthew G. Knepley     for (i=0; i<m; i++) {
1469b434eb95SMatthew G. Knepley       n   = ii[i+1] - ii[i];
1470b434eb95SMatthew G. Knepley       aj  = a->j + ii[i];
1471b434eb95SMatthew G. Knepley       aa  = a->a + ii[i];
1472b434eb95SMatthew G. Knepley       sum = y[i];
1473b434eb95SMatthew G. Knepley       PetscSparseDenseMaxDot(sum,x,aa,aj,n);
1474b434eb95SMatthew G. Knepley       z[i] = sum;
1475b434eb95SMatthew G. Knepley     }
1476b434eb95SMatthew G. Knepley   }
1477b434eb95SMatthew G. Knepley   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1478b434eb95SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
1479b434eb95SMatthew G. Knepley   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1480b434eb95SMatthew G. Knepley   if (zz != yy) {
1481b434eb95SMatthew G. Knepley     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
1482b434eb95SMatthew G. Knepley   }
1483b434eb95SMatthew G. Knepley   PetscFunctionReturn(0);
1484b434eb95SMatthew G. Knepley }
1485b434eb95SMatthew G. Knepley 
1486c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h>
14874a2ae208SSatish Balay #undef __FUNCT__
14884a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
1489dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
149017ab2063SBarry Smith {
1491416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1492f15663dcSBarry Smith   PetscScalar       *y,*z;
1493f15663dcSBarry Smith   const PetscScalar *x;
149454f21887SBarry Smith   const MatScalar   *aa;
1495dfbe8321SBarry Smith   PetscErrorCode    ierr;
1496d0f46423SBarry Smith   PetscInt          m = A->rmap->n,*aj,*ii;
14970298fd71SBarry Smith   PetscInt          n,i,*ridx=NULL;
1498362ced78SSatish Balay   PetscScalar       sum;
1499ace3abfcSBarry Smith   PetscBool         usecprow=a->compressedrow.use;
15009ea0dfa2SSatish Balay 
15013a40ed3dSBarry Smith   PetscFunctionBegin;
1502f15663dcSBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
15031ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
15042e8a6d31SBarry Smith   if (zz != yy) {
15051ebc52fbSHong Zhang     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
15062e8a6d31SBarry Smith   } else {
15072e8a6d31SBarry Smith     z = y;
15082e8a6d31SBarry Smith   }
1509bfeeae90SHong Zhang 
151097952fefSHong Zhang   aj = a->j;
151197952fefSHong Zhang   aa = a->a;
1512cddf8d76SBarry Smith   ii = a->i;
15134eb6d288SHong Zhang   if (usecprow) { /* use compressed row format */
15144eb6d288SHong Zhang     if (zz != yy) {
15154eb6d288SHong Zhang       ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr);
15164eb6d288SHong Zhang     }
151797952fefSHong Zhang     m    = a->compressedrow.nrows;
151897952fefSHong Zhang     ii   = a->compressedrow.i;
151997952fefSHong Zhang     ridx = a->compressedrow.rindex;
152097952fefSHong Zhang     for (i=0; i<m; i++) {
152197952fefSHong Zhang       n   = ii[i+1] - ii[i];
152297952fefSHong Zhang       aj  = a->j + ii[i];
152397952fefSHong Zhang       aa  = a->a + ii[i];
152497952fefSHong Zhang       sum = y[*ridx];
1525f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
152697952fefSHong Zhang       z[*ridx++] = sum;
152797952fefSHong Zhang     }
152897952fefSHong Zhang   } else { /* do not use compressed row format */
1529f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
1530f15663dcSBarry Smith     fortranmultaddaij_(&m,x,ii,aj,aa,y,z);
1531f15663dcSBarry Smith #else
153217ab2063SBarry Smith     for (i=0; i<m; i++) {
1533f15663dcSBarry Smith       n   = ii[i+1] - ii[i];
1534f15663dcSBarry Smith       aj  = a->j + ii[i];
1535f15663dcSBarry Smith       aa  = a->a + ii[i];
153617ab2063SBarry Smith       sum = y[i];
1537f15663dcSBarry Smith       PetscSparseDensePlusDot(sum,x,aa,aj,n);
153817ab2063SBarry Smith       z[i] = sum;
153917ab2063SBarry Smith     }
154002ab625aSSatish Balay #endif
1541f15663dcSBarry Smith   }
1542dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1543f15663dcSBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
15441ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
15452e8a6d31SBarry Smith   if (zz != yy) {
15461ebc52fbSHong Zhang     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
15472e8a6d31SBarry Smith   }
15488154be41SBarry Smith #if defined(PETSC_HAVE_CUSP)
15496b375ea7SVictor Minden   /*
1550918e98c3SVictor Minden   ierr = VecView(xx,0);CHKERRQ(ierr);
1551918e98c3SVictor Minden   ierr = VecView(zz,0);CHKERRQ(ierr);
1552918e98c3SVictor Minden   ierr = MatView(A,0);CHKERRQ(ierr);
15536b375ea7SVictor Minden   */
1554918e98c3SVictor Minden #endif
15553a40ed3dSBarry Smith   PetscFunctionReturn(0);
155617ab2063SBarry Smith }
155717ab2063SBarry Smith 
155817ab2063SBarry Smith /*
155917ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
156017ab2063SBarry Smith */
15614a2ae208SSatish Balay #undef __FUNCT__
15624a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
1563dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A)
156417ab2063SBarry Smith {
1565416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
15666849ba73SBarry Smith   PetscErrorCode ierr;
1567d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n;
156817ab2063SBarry Smith 
15693a40ed3dSBarry Smith   PetscFunctionBegin;
157009f38230SBarry Smith   if (!a->diag) {
157109f38230SBarry Smith     ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr);
15723bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr);
157309f38230SBarry Smith   }
1574d0f46423SBarry Smith   for (i=0; i<A->rmap->n; i++) {
157509f38230SBarry Smith     a->diag[i] = a->i[i+1];
1576bfeeae90SHong Zhang     for (j=a->i[i]; j<a->i[i+1]; j++) {
1577bfeeae90SHong Zhang       if (a->j[j] == i) {
157809f38230SBarry Smith         a->diag[i] = j;
157917ab2063SBarry Smith         break;
158017ab2063SBarry Smith       }
158117ab2063SBarry Smith     }
158217ab2063SBarry Smith   }
15833a40ed3dSBarry Smith   PetscFunctionReturn(0);
158417ab2063SBarry Smith }
158517ab2063SBarry Smith 
1586be5855fcSBarry Smith /*
1587be5855fcSBarry Smith      Checks for missing diagonals
1588be5855fcSBarry Smith */
15894a2ae208SSatish Balay #undef __FUNCT__
15904a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1591ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool  *missing,PetscInt *d)
1592be5855fcSBarry Smith {
1593be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
159497f1f81fSBarry Smith   PetscInt   *diag,*jj = a->j,i;
1595be5855fcSBarry Smith 
1596be5855fcSBarry Smith   PetscFunctionBegin;
159709f38230SBarry Smith   *missing = PETSC_FALSE;
1598d0f46423SBarry Smith   if (A->rmap->n > 0 && !jj) {
159909f38230SBarry Smith     *missing = PETSC_TRUE;
160009f38230SBarry Smith     if (d) *d = 0;
1601358d2f5dSShri Abhyankar     PetscInfo(A,"Matrix has no entries therefore is missing diagonal");
160209f38230SBarry Smith   } else {
1603f1e2ffcdSBarry Smith     diag = a->diag;
1604d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1605bfeeae90SHong Zhang       if (jj[diag[i]] != i) {
160609f38230SBarry Smith         *missing = PETSC_TRUE;
160709f38230SBarry Smith         if (d) *d = i;
160809f38230SBarry Smith         PetscInfo1(A,"Matrix is missing diagonal number %D",i);
1609358d2f5dSShri Abhyankar         break;
161009f38230SBarry Smith       }
1611be5855fcSBarry Smith     }
1612be5855fcSBarry Smith   }
1613be5855fcSBarry Smith   PetscFunctionReturn(0);
1614be5855fcSBarry Smith }
1615be5855fcSBarry Smith 
161671f1c65dSBarry Smith #undef __FUNCT__
161771f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ"
16187087cfbeSBarry Smith PetscErrorCode  MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift)
161971f1c65dSBarry Smith {
162071f1c65dSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
162171f1c65dSBarry Smith   PetscErrorCode ierr;
1622d0f46423SBarry Smith   PetscInt       i,*diag,m = A->rmap->n;
162354f21887SBarry Smith   MatScalar      *v = a->a;
162454f21887SBarry Smith   PetscScalar    *idiag,*mdiag;
162571f1c65dSBarry Smith 
162671f1c65dSBarry Smith   PetscFunctionBegin;
162771f1c65dSBarry Smith   if (a->idiagvalid) PetscFunctionReturn(0);
162871f1c65dSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
162971f1c65dSBarry Smith   diag = a->diag;
163071f1c65dSBarry Smith   if (!a->idiag) {
163171f1c65dSBarry Smith     ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr);
16323bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr);
163371f1c65dSBarry Smith     v    = a->a;
163471f1c65dSBarry Smith   }
163571f1c65dSBarry Smith   mdiag = a->mdiag;
163671f1c65dSBarry Smith   idiag = a->idiag;
163771f1c65dSBarry Smith 
1638028cd4eaSSatish Balay   if (omega == 1.0 && !PetscAbsScalar(fshift)) {
163971f1c65dSBarry Smith     for (i=0; i<m; i++) {
164071f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
1641e32f2f54SBarry Smith       if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i);
164271f1c65dSBarry Smith       idiag[i] = 1.0/v[diag[i]];
164371f1c65dSBarry Smith     }
164471f1c65dSBarry Smith     ierr = PetscLogFlops(m);CHKERRQ(ierr);
164571f1c65dSBarry Smith   } else {
164671f1c65dSBarry Smith     for (i=0; i<m; i++) {
164771f1c65dSBarry Smith       mdiag[i] = v[diag[i]];
164871f1c65dSBarry Smith       idiag[i] = omega/(fshift + v[diag[i]]);
164971f1c65dSBarry Smith     }
1650dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
165171f1c65dSBarry Smith   }
165271f1c65dSBarry Smith   a->idiagvalid = PETSC_TRUE;
165371f1c65dSBarry Smith   PetscFunctionReturn(0);
165471f1c65dSBarry Smith }
165571f1c65dSBarry Smith 
1656c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h>
16574a2ae208SSatish Balay #undef __FUNCT__
165841f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ"
165941f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
166017ab2063SBarry Smith {
1661416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
1662e6d1f457SBarry Smith   PetscScalar       *x,d,sum,*t,scale;
1663e6d1f457SBarry Smith   const MatScalar   *v = a->a,*idiag=0,*mdiag;
166454f21887SBarry Smith   const PetscScalar *b, *bs,*xb, *ts;
1665dfbe8321SBarry Smith   PetscErrorCode    ierr;
1666d0f46423SBarry Smith   PetscInt          n = A->cmap->n,m = A->rmap->n,i;
166797f1f81fSBarry Smith   const PetscInt    *idx,*diag;
166817ab2063SBarry Smith 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
1670b965ef7fSBarry Smith   its = its*lits;
167191723122SBarry Smith 
167271f1c65dSBarry Smith   if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */
167371f1c65dSBarry Smith   if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);}
167471f1c65dSBarry Smith   a->fshift = fshift;
167571f1c65dSBarry Smith   a->omega  = omega;
1676ed480e8bSBarry Smith 
167771f1c65dSBarry Smith   diag  = a->diag;
167871f1c65dSBarry Smith   t     = a->ssor_work;
1679ed480e8bSBarry Smith   idiag = a->idiag;
168071f1c65dSBarry Smith   mdiag = a->mdiag;
1681ed480e8bSBarry Smith 
16821ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
16833649974fSBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1684ed480e8bSBarry Smith   /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */
168517ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
168617ab2063SBarry Smith     /* apply (U + D/omega) to the vector */
1687ed480e8bSBarry Smith     bs = b;
168817ab2063SBarry Smith     for (i=0; i<m; i++) {
168971f1c65dSBarry Smith       d   = fshift + mdiag[i];
1690416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1691ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1692ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
169317ab2063SBarry Smith       sum = b[i]*d/omega;
1694003131ecSBarry Smith       PetscSparseDensePlusDot(sum,bs,v,idx,n);
169517ab2063SBarry Smith       x[i] = sum;
169617ab2063SBarry Smith     }
16971ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
16983649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1699efee365bSSatish Balay     ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17003a40ed3dSBarry Smith     PetscFunctionReturn(0);
170117ab2063SBarry Smith   }
1702c783ea89SBarry Smith 
17032205254eSKarl Rupp   if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
17042205254eSKarl Rupp   else if (flag & SOR_EISENSTAT) {
170517ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1706887ee2caSBarry Smith     U is upper triangular, E = D/omega; This routine applies
170717ab2063SBarry Smith 
170817ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
170917ab2063SBarry Smith 
1710887ee2caSBarry Smith     to a vector efficiently using Eisenstat's trick.
171117ab2063SBarry Smith     */
171217ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
171317ab2063SBarry Smith 
171417ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
171517ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1716416022c9SBarry Smith       n   = a->i[i+1] - diag[i] - 1;
1717ed480e8bSBarry Smith       idx = a->j + diag[i] + 1;
1718ed480e8bSBarry Smith       v   = a->a + diag[i] + 1;
171917ab2063SBarry Smith       sum = b[i];
1720e6d1f457SBarry Smith       PetscSparseDenseMinusDot(sum,x,v,idx,n);
1721ed480e8bSBarry Smith       x[i] = sum*idiag[i];
172217ab2063SBarry Smith     }
172317ab2063SBarry Smith 
172417ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1725416022c9SBarry Smith     v = a->a;
17262205254eSKarl Rupp     for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i];
172717ab2063SBarry Smith 
172817ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1729ed480e8bSBarry Smith     ts   = t;
1730416022c9SBarry Smith     diag = a->diag;
173117ab2063SBarry Smith     for (i=0; i<m; i++) {
1732416022c9SBarry Smith       n   = diag[i] - a->i[i];
1733ed480e8bSBarry Smith       idx = a->j + a->i[i];
1734ed480e8bSBarry Smith       v   = a->a + a->i[i];
173517ab2063SBarry Smith       sum = t[i];
1736003131ecSBarry Smith       PetscSparseDenseMinusDot(sum,ts,v,idx,n);
1737ed480e8bSBarry Smith       t[i] = sum*idiag[i];
1738733d66baSBarry Smith       /*  x = x + t */
1739733d66baSBarry Smith       x[i] += t[i];
174017ab2063SBarry Smith     }
174117ab2063SBarry Smith 
1742dc0b31edSSatish Balay     ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr);
17431ebc52fbSHong Zhang     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
17443649974fSBarry Smith     ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
17453a40ed3dSBarry Smith     PetscFunctionReturn(0);
174617ab2063SBarry Smith   }
174717ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
174817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
174917ab2063SBarry Smith       for (i=0; i<m; i++) {
1750416022c9SBarry Smith         n   = diag[i] - a->i[i];
1751ed480e8bSBarry Smith         idx = a->j + a->i[i];
1752ed480e8bSBarry Smith         v   = a->a + a->i[i];
175317ab2063SBarry Smith         sum = b[i];
1754e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17555c99c7daSBarry Smith         t[i] = sum;
1756ed480e8bSBarry Smith         x[i] = sum*idiag[i];
175717ab2063SBarry Smith       }
17585c99c7daSBarry Smith       xb   = t;
1759efee365bSSatish Balay       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
17603a40ed3dSBarry Smith     } else xb = b;
176117ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
176217ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1763416022c9SBarry Smith         n   = a->i[i+1] - diag[i] - 1;
1764ed480e8bSBarry Smith         idx = a->j + diag[i] + 1;
1765ed480e8bSBarry Smith         v   = a->a + diag[i] + 1;
176617ab2063SBarry Smith         sum = xb[i];
1767e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
17685c99c7daSBarry Smith         if (xb == b) {
1769ed480e8bSBarry Smith           x[i] = sum*idiag[i];
17705c99c7daSBarry Smith         } else {
1771b19a5dc2SMark Adams           x[i] = (1-omega)*x[i] + sum*idiag[i];  /* omega in idiag */
177217ab2063SBarry Smith         }
17735c99c7daSBarry Smith       }
1774b19a5dc2SMark Adams       ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
177517ab2063SBarry Smith     }
177617ab2063SBarry Smith     its--;
177717ab2063SBarry Smith   }
177817ab2063SBarry Smith   while (its--) {
177917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
178017ab2063SBarry Smith       for (i=0; i<m; i++) {
1781b19a5dc2SMark Adams         /* lower */
1782b19a5dc2SMark Adams         n   = diag[i] - a->i[i];
1783ed480e8bSBarry Smith         idx = a->j + a->i[i];
1784ed480e8bSBarry Smith         v   = a->a + a->i[i];
178517ab2063SBarry Smith         sum = b[i];
1786e6d1f457SBarry Smith         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1787b19a5dc2SMark Adams         t[i] = sum;             /* save application of the lower-triangular part */
1788b19a5dc2SMark Adams         /* upper */
1789b19a5dc2SMark Adams         n   = a->i[i+1] - diag[i] - 1;
1790b19a5dc2SMark Adams         idx = a->j + diag[i] + 1;
1791b19a5dc2SMark Adams         v   = a->a + diag[i] + 1;
1792b19a5dc2SMark Adams         PetscSparseDenseMinusDot(sum,x,v,idx,n);
1793b19a5dc2SMark Adams         x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */
179417ab2063SBarry Smith       }
1795b19a5dc2SMark Adams       xb   = t;
17969f863219SBarry Smith       ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1797b19a5dc2SMark Adams     } else xb = b;
179817ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
179917ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1800b19a5dc2SMark Adams         sum = xb[i];
1801b19a5dc2SMark Adams         if (xb == b) {
1802b19a5dc2SMark Adams           /* whole matrix (no checkpointing available) */
1803416022c9SBarry Smith           n   = a->i[i+1] - a->i[i];
1804ed480e8bSBarry Smith           idx = a->j + a->i[i];
1805ed480e8bSBarry Smith           v   = a->a + a->i[i];
1806e6d1f457SBarry Smith           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1807ed480e8bSBarry Smith           x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i];
1808b19a5dc2SMark Adams         } else { /* lower-triangular part has been saved, so only apply upper-triangular */
1809b19a5dc2SMark Adams           n   = a->i[i+1] - diag[i] - 1;
1810b19a5dc2SMark Adams           idx = a->j + diag[i] + 1;
1811b19a5dc2SMark Adams           v   = a->a + diag[i] + 1;
1812b19a5dc2SMark Adams           PetscSparseDenseMinusDot(sum,x,v,idx,n);
1813b19a5dc2SMark Adams           x[i] = (1. - omega)*x[i] + sum*idiag[i];  /* omega in idiag */
181417ab2063SBarry Smith         }
1815b19a5dc2SMark Adams       }
1816b19a5dc2SMark Adams       if (xb == b) {
18179f863219SBarry Smith         ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
1818b19a5dc2SMark Adams       } else {
1819b19a5dc2SMark Adams         ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */
1820b19a5dc2SMark Adams       }
182117ab2063SBarry Smith     }
182217ab2063SBarry Smith   }
18231ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
18243649974fSBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
1825365a8a9eSBarry Smith   PetscFunctionReturn(0);
182617ab2063SBarry Smith }
182717ab2063SBarry Smith 
18282af78befSBarry Smith 
18294a2ae208SSatish Balay #undef __FUNCT__
18304a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
1831dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
183217ab2063SBarry Smith {
1833416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
18344e220ebcSLois Curfman McInnes 
18353a40ed3dSBarry Smith   PetscFunctionBegin;
18364e220ebcSLois Curfman McInnes   info->block_size   = 1.0;
18374e220ebcSLois Curfman McInnes   info->nz_allocated = (double)a->maxnz;
18384e220ebcSLois Curfman McInnes   info->nz_used      = (double)a->nz;
18394e220ebcSLois Curfman McInnes   info->nz_unneeded  = (double)(a->maxnz - a->nz);
18404e220ebcSLois Curfman McInnes   info->assemblies   = (double)A->num_ass;
18418e58a170SBarry Smith   info->mallocs      = (double)A->info.mallocs;
18427adad957SLisandro Dalcin   info->memory       = ((PetscObject)A)->mem;
1843d5f3da31SBarry Smith   if (A->factortype) {
18444e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
18454e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
18464e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
18474e220ebcSLois Curfman McInnes   } else {
18484e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
18494e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
18504e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
18514e220ebcSLois Curfman McInnes   }
18523a40ed3dSBarry Smith   PetscFunctionReturn(0);
185317ab2063SBarry Smith }
185417ab2063SBarry Smith 
18554a2ae208SSatish Balay #undef __FUNCT__
18564a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
18572b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
185817ab2063SBarry Smith {
1859416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
18603b98c0a2SBarry Smith   PetscInt          i,m = A->rmap->n - 1,d = 0;
18616849ba73SBarry Smith   PetscErrorCode    ierr;
186297b48c8fSBarry Smith   const PetscScalar *xx;
186397b48c8fSBarry Smith   PetscScalar       *bb;
1864ace3abfcSBarry Smith   PetscBool         missing;
186517ab2063SBarry Smith 
18663a40ed3dSBarry Smith   PetscFunctionBegin;
186797b48c8fSBarry Smith   if (x && b) {
186897b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
186997b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
187097b48c8fSBarry Smith     for (i=0; i<N; i++) {
187197b48c8fSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
187297b48c8fSBarry Smith       bb[rows[i]] = diag*xx[rows[i]];
187397b48c8fSBarry Smith     }
187497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
187597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
187697b48c8fSBarry Smith   }
187797b48c8fSBarry Smith 
1878a9817697SBarry Smith   if (a->keepnonzeropattern) {
1879f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
1880e32f2f54SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1881bfeeae90SHong Zhang       ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1882f1e2ffcdSBarry Smith     }
1883f4df32b1SMatthew Knepley     if (diag != 0.0) {
188409f38230SBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
1885e32f2f54SBarry Smith       if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
1886f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1887f4df32b1SMatthew Knepley         a->a[a->diag[rows[i]]] = diag;
1888f1e2ffcdSBarry Smith       }
1889f1e2ffcdSBarry Smith     }
189088e51ccdSHong Zhang     A->same_nonzero = PETSC_TRUE;
1891f1e2ffcdSBarry Smith   } else {
1892f4df32b1SMatthew Knepley     if (diag != 0.0) {
189317ab2063SBarry Smith       for (i=0; i<N; i++) {
1894e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
18957ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1896416022c9SBarry Smith           a->ilen[rows[i]]    = 1;
1897f4df32b1SMatthew Knepley           a->a[a->i[rows[i]]] = diag;
1898bfeeae90SHong Zhang           a->j[a->i[rows[i]]] = rows[i];
18997ae801bdSBarry Smith         } else { /* in case row was completely empty */
1900f4df32b1SMatthew Knepley           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr);
190117ab2063SBarry Smith         }
190217ab2063SBarry Smith       }
19033a40ed3dSBarry Smith     } else {
190417ab2063SBarry Smith       for (i=0; i<N; i++) {
1905e32f2f54SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
1906416022c9SBarry Smith         a->ilen[rows[i]] = 0;
190717ab2063SBarry Smith       }
190817ab2063SBarry Smith     }
190988e51ccdSHong Zhang     A->same_nonzero = PETSC_FALSE;
1910f1e2ffcdSBarry Smith   }
191143a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19123a40ed3dSBarry Smith   PetscFunctionReturn(0);
191317ab2063SBarry Smith }
191417ab2063SBarry Smith 
19154a2ae208SSatish Balay #undef __FUNCT__
19166e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ"
19176e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
19186e169961SBarry Smith {
19196e169961SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
19206e169961SBarry Smith   PetscInt          i,j,m = A->rmap->n - 1,d = 0;
19216e169961SBarry Smith   PetscErrorCode    ierr;
19222b40b63fSBarry Smith   PetscBool         missing,*zeroed,vecs = PETSC_FALSE;
19236e169961SBarry Smith   const PetscScalar *xx;
19246e169961SBarry Smith   PetscScalar       *bb;
19256e169961SBarry Smith 
19266e169961SBarry Smith   PetscFunctionBegin;
19276e169961SBarry Smith   if (x && b) {
19286e169961SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
19296e169961SBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19302b40b63fSBarry Smith     vecs = PETSC_TRUE;
19316e169961SBarry Smith   }
19326e169961SBarry Smith   ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr);
19336e169961SBarry Smith   ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr);
19346e169961SBarry Smith   for (i=0; i<N; i++) {
19356e169961SBarry Smith     if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]);
19366e169961SBarry Smith     ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
19372205254eSKarl Rupp 
19386e169961SBarry Smith     zeroed[rows[i]] = PETSC_TRUE;
19396e169961SBarry Smith   }
19406e169961SBarry Smith   for (i=0; i<A->rmap->n; i++) {
19416e169961SBarry Smith     if (!zeroed[i]) {
19426e169961SBarry Smith       for (j=a->i[i]; j<a->i[i+1]; j++) {
19436e169961SBarry Smith         if (zeroed[a->j[j]]) {
19442b40b63fSBarry Smith           if (vecs) bb[i] -= a->a[j]*xx[a->j[j]];
19456e169961SBarry Smith           a->a[j] = 0.0;
19466e169961SBarry Smith         }
19476e169961SBarry Smith       }
19482b40b63fSBarry Smith     } else if (vecs) bb[i] = diag*xx[i];
19496e169961SBarry Smith   }
19506e169961SBarry Smith   if (x && b) {
19516e169961SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
19526e169961SBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
19536e169961SBarry Smith   }
19546e169961SBarry Smith   ierr = PetscFree(zeroed);CHKERRQ(ierr);
19556e169961SBarry Smith   if (diag != 0.0) {
19566e169961SBarry Smith     ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr);
19576e169961SBarry Smith     if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d);
19586e169961SBarry Smith     for (i=0; i<N; i++) {
19596e169961SBarry Smith       a->a[a->diag[rows[i]]] = diag;
19606e169961SBarry Smith     }
19616e169961SBarry Smith   }
19626e169961SBarry Smith   A->same_nonzero = PETSC_TRUE;
19636e169961SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19646e169961SBarry Smith   PetscFunctionReturn(0);
19656e169961SBarry Smith }
19666e169961SBarry Smith 
19676e169961SBarry Smith #undef __FUNCT__
19684a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
1969a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
197017ab2063SBarry Smith {
1971416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
197297f1f81fSBarry Smith   PetscInt   *itmp;
197317ab2063SBarry Smith 
19743a40ed3dSBarry Smith   PetscFunctionBegin;
1975e32f2f54SBarry Smith   if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row);
197617ab2063SBarry Smith 
1977416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1978bfeeae90SHong Zhang   if (v) *v = a->a + a->i[row];
197917ab2063SBarry Smith   if (idx) {
1980bfeeae90SHong Zhang     itmp = a->j + a->i[row];
198126fbe8dcSKarl Rupp     if (*nz) *idx = itmp;
198217ab2063SBarry Smith     else *idx = 0;
198317ab2063SBarry Smith   }
19843a40ed3dSBarry Smith   PetscFunctionReturn(0);
198517ab2063SBarry Smith }
198617ab2063SBarry Smith 
1987bfeeae90SHong Zhang /* remove this function? */
19884a2ae208SSatish Balay #undef __FUNCT__
19894a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
1990a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v)
199117ab2063SBarry Smith {
19923a40ed3dSBarry Smith   PetscFunctionBegin;
19933a40ed3dSBarry Smith   PetscFunctionReturn(0);
199417ab2063SBarry Smith }
199517ab2063SBarry Smith 
19964a2ae208SSatish Balay #undef __FUNCT__
19974a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1998dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
199917ab2063SBarry Smith {
2000416022c9SBarry Smith   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
200154f21887SBarry Smith   MatScalar      *v  = a->a;
200236db0b34SBarry Smith   PetscReal      sum = 0.0;
20036849ba73SBarry Smith   PetscErrorCode ierr;
200497f1f81fSBarry Smith   PetscInt       i,j;
200517ab2063SBarry Smith 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
200717ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
2008416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
200936db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
201017ab2063SBarry Smith     }
20118f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
20123a40ed3dSBarry Smith   } else if (type == NORM_1) {
201336db0b34SBarry Smith     PetscReal *tmp;
201497f1f81fSBarry Smith     PetscInt  *jj = a->j;
2015d0f46423SBarry Smith     ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
2016d0f46423SBarry Smith     ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr);
2017064f8208SBarry Smith     *nrm = 0.0;
2018416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
2019bfeeae90SHong Zhang       tmp[*jj++] += PetscAbsScalar(*v);  v++;
202017ab2063SBarry Smith     }
2021d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2022064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
202317ab2063SBarry Smith     }
2024606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
20253a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2026064f8208SBarry Smith     *nrm = 0.0;
2027d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2028bfeeae90SHong Zhang       v   = a->a + a->i[j];
202917ab2063SBarry Smith       sum = 0.0;
2030416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
2031cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
203217ab2063SBarry Smith       }
2033064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
203417ab2063SBarry Smith     }
2035f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm");
20363a40ed3dSBarry Smith   PetscFunctionReturn(0);
203717ab2063SBarry Smith }
203817ab2063SBarry Smith 
20394e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */
20404e938277SHong Zhang #undef __FUNCT__
20414e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ"
20424e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B)
20434e938277SHong Zhang {
20444e938277SHong Zhang   PetscErrorCode ierr;
20454e938277SHong Zhang   PetscInt       i,j,anzj;
20464e938277SHong Zhang   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data,*b;
20474e938277SHong Zhang   PetscInt       an=A->cmap->N,am=A->rmap->N;
20484e938277SHong Zhang   PetscInt       *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
20494e938277SHong Zhang 
20504e938277SHong Zhang   PetscFunctionBegin;
20514e938277SHong Zhang   /* Allocate space for symbolic transpose info and work array */
20524e938277SHong Zhang   ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr);
20534e938277SHong Zhang   ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr);
20544e938277SHong Zhang   ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr);
20554e938277SHong Zhang   ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr);
20564e938277SHong Zhang 
20574e938277SHong Zhang   /* Walk through aj and count ## of non-zeros in each row of A^T. */
20584e938277SHong Zhang   /* Note: offset by 1 for fast conversion into csr format. */
205926fbe8dcSKarl Rupp   for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1;
20604e938277SHong Zhang   /* Form ati for csr format of A^T. */
206126fbe8dcSKarl Rupp   for (i=0;i<an;i++) ati[i+1] += ati[i];
20624e938277SHong Zhang 
20634e938277SHong Zhang   /* Copy ati into atfill so we have locations of the next free space in atj */
20644e938277SHong Zhang   ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr);
20654e938277SHong Zhang 
20664e938277SHong Zhang   /* Walk through A row-wise and mark nonzero entries of A^T. */
20674e938277SHong Zhang   for (i=0;i<am;i++) {
20684e938277SHong Zhang     anzj = ai[i+1] - ai[i];
20694e938277SHong Zhang     for (j=0;j<anzj;j++) {
20704e938277SHong Zhang       atj[atfill[*aj]] = i;
20714e938277SHong Zhang       atfill[*aj++]   += 1;
20724e938277SHong Zhang     }
20734e938277SHong Zhang   }
20744e938277SHong Zhang 
20754e938277SHong Zhang   /* Clean up temporary space and complete requests. */
20764e938277SHong Zhang   ierr = PetscFree(atfill);CHKERRQ(ierr);
2077ce94432eSBarry Smith   ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr);
20782205254eSKarl Rupp 
2079a2f3521dSMark F. Adams   (*B)->rmap->bs = A->cmap->bs;
2080a2f3521dSMark F. Adams   (*B)->cmap->bs = A->rmap->bs;
2081a2f3521dSMark F. Adams 
20824e938277SHong Zhang   b          = (Mat_SeqAIJ*)((*B)->data);
20834e938277SHong Zhang   b->free_a  = PETSC_FALSE;
20844e938277SHong Zhang   b->free_ij = PETSC_TRUE;
20854e938277SHong Zhang   b->nonew   = 0;
20864e938277SHong Zhang   PetscFunctionReturn(0);
20874e938277SHong Zhang }
20884e938277SHong Zhang 
20894a2ae208SSatish Balay #undef __FUNCT__
20904a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
2091fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B)
209217ab2063SBarry Smith {
2093416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
2094416022c9SBarry Smith   Mat            C;
20956849ba73SBarry Smith   PetscErrorCode ierr;
2096d0f46423SBarry Smith   PetscInt       i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col;
209754f21887SBarry Smith   MatScalar      *array = a->a;
209817ab2063SBarry Smith 
20993a40ed3dSBarry Smith   PetscFunctionBegin;
2100e32f2f54SBarry Smith   if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
2101fc4dec0aSBarry Smith 
2102fc4dec0aSBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B == A) {
2103d0f46423SBarry Smith     ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr);
2104d0f46423SBarry Smith     ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr);
2105bfeeae90SHong Zhang 
2106bfeeae90SHong Zhang     for (i=0; i<ai[m]; i++) col[aj[i]] += 1;
2107ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2108d0f46423SBarry Smith     ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr);
2109a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr);
21107adad957SLisandro Dalcin     ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2111ab93d7beSBarry Smith     ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr);
2112606d414cSSatish Balay     ierr = PetscFree(col);CHKERRQ(ierr);
2113a541d17aSBarry Smith   } else {
2114a541d17aSBarry Smith     C = *B;
2115a541d17aSBarry Smith   }
2116a541d17aSBarry Smith 
211717ab2063SBarry Smith   for (i=0; i<m; i++) {
211817ab2063SBarry Smith     len    = ai[i+1]-ai[i];
211987d4246cSBarry Smith     ierr   = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
2120b9b97703SBarry Smith     array += len;
2121b9b97703SBarry Smith     aj    += len;
212217ab2063SBarry Smith   }
21236d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21246d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
212517ab2063SBarry Smith 
2126815cbec1SBarry Smith   if (reuse == MAT_INITIAL_MATRIX || *B != A) {
2127416022c9SBarry Smith     *B = C;
212817ab2063SBarry Smith   } else {
2129eb6b5d47SBarry Smith     ierr = MatHeaderMerge(A,C);CHKERRQ(ierr);
213017ab2063SBarry Smith   }
21313a40ed3dSBarry Smith   PetscFunctionReturn(0);
213217ab2063SBarry Smith }
213317ab2063SBarry Smith 
2134cd0d46ebSvictorle #undef __FUNCT__
21355fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ"
21367087cfbeSBarry Smith PetscErrorCode  MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
2137cd0d46ebSvictorle {
2138cd0d46ebSvictorle   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
213954f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
214054f21887SBarry Smith   MatScalar      *va,*vb;
21416849ba73SBarry Smith   PetscErrorCode ierr;
214297f1f81fSBarry Smith   PetscInt       ma,na,mb,nb, i;
2143cd0d46ebSvictorle 
2144cd0d46ebSvictorle   PetscFunctionBegin;
2145cd0d46ebSvictorle   bij = (Mat_SeqAIJ*) B->data;
2146cd0d46ebSvictorle 
2147cd0d46ebSvictorle   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
2148cd0d46ebSvictorle   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
21495485867bSBarry Smith   if (ma!=nb || na!=mb) {
21505485867bSBarry Smith     *f = PETSC_FALSE;
21515485867bSBarry Smith     PetscFunctionReturn(0);
21525485867bSBarry Smith   }
2153cd0d46ebSvictorle   aii  = aij->i; bii = bij->i;
2154cd0d46ebSvictorle   adx  = aij->j; bdx = bij->j;
2155cd0d46ebSvictorle   va   = aij->a; vb = bij->a;
215697f1f81fSBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
215797f1f81fSBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
2158cd0d46ebSvictorle   for (i=0; i<ma; i++) aptr[i] = aii[i];
2159cd0d46ebSvictorle   for (i=0; i<mb; i++) bptr[i] = bii[i];
2160cd0d46ebSvictorle 
2161cd0d46ebSvictorle   *f = PETSC_TRUE;
2162cd0d46ebSvictorle   for (i=0; i<ma; i++) {
2163cd0d46ebSvictorle     while (aptr[i]<aii[i+1]) {
216497f1f81fSBarry Smith       PetscInt    idc,idr;
21655485867bSBarry Smith       PetscScalar vc,vr;
2166cd0d46ebSvictorle       /* column/row index/value */
21675485867bSBarry Smith       idc = adx[aptr[i]];
21685485867bSBarry Smith       idr = bdx[bptr[idc]];
21695485867bSBarry Smith       vc  = va[aptr[i]];
21705485867bSBarry Smith       vr  = vb[bptr[idc]];
21715485867bSBarry Smith       if (i!=idr || PetscAbsScalar(vc-vr) > tol) {
21725485867bSBarry Smith         *f = PETSC_FALSE;
21735485867bSBarry Smith         goto done;
2174cd0d46ebSvictorle       } else {
21755485867bSBarry Smith         aptr[i]++;
21765485867bSBarry Smith         if (B || i!=idc) bptr[idc]++;
2177cd0d46ebSvictorle       }
2178cd0d46ebSvictorle     }
2179cd0d46ebSvictorle   }
2180cd0d46ebSvictorle done:
2181cd0d46ebSvictorle   ierr = PetscFree(aptr);CHKERRQ(ierr);
21823aeef889SHong Zhang   ierr = PetscFree(bptr);CHKERRQ(ierr);
2183cd0d46ebSvictorle   PetscFunctionReturn(0);
2184cd0d46ebSvictorle }
2185cd0d46ebSvictorle 
21861cbb95d3SBarry Smith #undef __FUNCT__
21871cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ"
21887087cfbeSBarry Smith PetscErrorCode  MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool  *f)
21891cbb95d3SBarry Smith {
21901cbb95d3SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data;
219154f21887SBarry Smith   PetscInt       *adx,*bdx,*aii,*bii,*aptr,*bptr;
219254f21887SBarry Smith   MatScalar      *va,*vb;
21931cbb95d3SBarry Smith   PetscErrorCode ierr;
21941cbb95d3SBarry Smith   PetscInt       ma,na,mb,nb, i;
21951cbb95d3SBarry Smith 
21961cbb95d3SBarry Smith   PetscFunctionBegin;
21971cbb95d3SBarry Smith   bij = (Mat_SeqAIJ*) B->data;
21981cbb95d3SBarry Smith 
21991cbb95d3SBarry Smith   ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr);
22001cbb95d3SBarry Smith   ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr);
22011cbb95d3SBarry Smith   if (ma!=nb || na!=mb) {
22021cbb95d3SBarry Smith     *f = PETSC_FALSE;
22031cbb95d3SBarry Smith     PetscFunctionReturn(0);
22041cbb95d3SBarry Smith   }
22051cbb95d3SBarry Smith   aii  = aij->i; bii = bij->i;
22061cbb95d3SBarry Smith   adx  = aij->j; bdx = bij->j;
22071cbb95d3SBarry Smith   va   = aij->a; vb = bij->a;
22081cbb95d3SBarry Smith   ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr);
22091cbb95d3SBarry Smith   ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr);
22101cbb95d3SBarry Smith   for (i=0; i<ma; i++) aptr[i] = aii[i];
22111cbb95d3SBarry Smith   for (i=0; i<mb; i++) bptr[i] = bii[i];
22121cbb95d3SBarry Smith 
22131cbb95d3SBarry Smith   *f = PETSC_TRUE;
22141cbb95d3SBarry Smith   for (i=0; i<ma; i++) {
22151cbb95d3SBarry Smith     while (aptr[i]<aii[i+1]) {
22161cbb95d3SBarry Smith       PetscInt    idc,idr;
22171cbb95d3SBarry Smith       PetscScalar vc,vr;
22181cbb95d3SBarry Smith       /* column/row index/value */
22191cbb95d3SBarry Smith       idc = adx[aptr[i]];
22201cbb95d3SBarry Smith       idr = bdx[bptr[idc]];
22211cbb95d3SBarry Smith       vc  = va[aptr[i]];
22221cbb95d3SBarry Smith       vr  = vb[bptr[idc]];
22231cbb95d3SBarry Smith       if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) {
22241cbb95d3SBarry Smith         *f = PETSC_FALSE;
22251cbb95d3SBarry Smith         goto done;
22261cbb95d3SBarry Smith       } else {
22271cbb95d3SBarry Smith         aptr[i]++;
22281cbb95d3SBarry Smith         if (B || i!=idc) bptr[idc]++;
22291cbb95d3SBarry Smith       }
22301cbb95d3SBarry Smith     }
22311cbb95d3SBarry Smith   }
22321cbb95d3SBarry Smith done:
22331cbb95d3SBarry Smith   ierr = PetscFree(aptr);CHKERRQ(ierr);
22341cbb95d3SBarry Smith   ierr = PetscFree(bptr);CHKERRQ(ierr);
22351cbb95d3SBarry Smith   PetscFunctionReturn(0);
22361cbb95d3SBarry Smith }
22371cbb95d3SBarry Smith 
22389e29f15eSvictorle #undef __FUNCT__
22399e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ"
2240ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22419e29f15eSvictorle {
2242dfbe8321SBarry Smith   PetscErrorCode ierr;
22436e111a19SKarl Rupp 
22449e29f15eSvictorle   PetscFunctionBegin;
22455485867bSBarry Smith   ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22469e29f15eSvictorle   PetscFunctionReturn(0);
22479e29f15eSvictorle }
22489e29f15eSvictorle 
22494a2ae208SSatish Balay #undef __FUNCT__
22501cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ"
2251ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool  *f)
22521cbb95d3SBarry Smith {
22531cbb95d3SBarry Smith   PetscErrorCode ierr;
22546e111a19SKarl Rupp 
22551cbb95d3SBarry Smith   PetscFunctionBegin;
22561cbb95d3SBarry Smith   ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr);
22571cbb95d3SBarry Smith   PetscFunctionReturn(0);
22581cbb95d3SBarry Smith }
22591cbb95d3SBarry Smith 
22601cbb95d3SBarry Smith #undef __FUNCT__
22614a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
2262dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
226317ab2063SBarry Smith {
2264416022c9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
226554f21887SBarry Smith   PetscScalar    *l,*r,x;
226654f21887SBarry Smith   MatScalar      *v;
2267dfbe8321SBarry Smith   PetscErrorCode ierr;
2268d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj;
226917ab2063SBarry Smith 
22703a40ed3dSBarry Smith   PetscFunctionBegin;
227117ab2063SBarry Smith   if (ll) {
22723ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
22733ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
2274e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
2275e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
22761ebc52fbSHong Zhang     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
2277416022c9SBarry Smith     v    = a->a;
227817ab2063SBarry Smith     for (i=0; i<m; i++) {
227917ab2063SBarry Smith       x = l[i];
2280416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
22812205254eSKarl Rupp       for (j=0; j<M; j++) (*v++) *= x;
228217ab2063SBarry Smith     }
22831ebc52fbSHong Zhang     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
2284efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
228517ab2063SBarry Smith   }
228617ab2063SBarry Smith   if (rr) {
2287e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
2288e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
22891ebc52fbSHong Zhang     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
2290416022c9SBarry Smith     v    = a->a; jj = a->j;
22912205254eSKarl Rupp     for (i=0; i<nz; i++) (*v++) *= r[*jj++];
22921ebc52fbSHong Zhang     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
2293efee365bSSatish Balay     ierr = PetscLogFlops(nz);CHKERRQ(ierr);
229417ab2063SBarry Smith   }
2295acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr);
22963a40ed3dSBarry Smith   PetscFunctionReturn(0);
229717ab2063SBarry Smith }
229817ab2063SBarry Smith 
22994a2ae208SSatish Balay #undef __FUNCT__
23004a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
230197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B)
230217ab2063SBarry Smith {
2303db02288aSLois Curfman McInnes   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*c;
23046849ba73SBarry Smith   PetscErrorCode ierr;
2305d0f46423SBarry Smith   PetscInt       *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens;
230697f1f81fSBarry Smith   PetscInt       row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
23075d0c19d7SBarry Smith   const PetscInt *irow,*icol;
23085d0c19d7SBarry Smith   PetscInt       nrows,ncols;
230997f1f81fSBarry Smith   PetscInt       *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
231054f21887SBarry Smith   MatScalar      *a_new,*mat_a;
2311416022c9SBarry Smith   Mat            C;
2312ace3abfcSBarry Smith   PetscBool      stride,sorted;
231317ab2063SBarry Smith 
23143a40ed3dSBarry Smith   PetscFunctionBegin;
231514ca34e6SBarry Smith   ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr);
2316e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
231714ca34e6SBarry Smith   ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr);
2318e32f2f54SBarry Smith   if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
231999141d43SSatish Balay 
232017ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
2321b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2322b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
232317ab2063SBarry Smith 
2324fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
2325251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr);
2326fee21e36SBarry Smith   if (stride && step == 1) {
232702834360SBarry Smith     /* special case of contiguous rows */
23280e83c824SBarry Smith     ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr);
232902834360SBarry Smith     /* loop over new rows determining lens and starting points */
233002834360SBarry Smith     for (i=0; i<nrows; i++) {
2331bfeeae90SHong Zhang       kstart = ai[irow[i]];
2332a2744918SBarry Smith       kend   = kstart + ailen[irow[i]];
233302834360SBarry Smith       for (k=kstart; k<kend; k++) {
2334bfeeae90SHong Zhang         if (aj[k] >= first) {
233502834360SBarry Smith           starts[i] = k;
233602834360SBarry Smith           break;
233702834360SBarry Smith         }
233802834360SBarry Smith       }
2339a2744918SBarry Smith       sum = 0;
234002834360SBarry Smith       while (k < kend) {
2341bfeeae90SHong Zhang         if (aj[k++] >= first+ncols) break;
2342a2744918SBarry Smith         sum++;
234302834360SBarry Smith       }
2344a2744918SBarry Smith       lens[i] = sum;
234502834360SBarry Smith     }
234602834360SBarry Smith     /* create submatrix */
2347cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
234897f1f81fSBarry Smith       PetscInt n_cols,n_rows;
234908480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
2350e32f2f54SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
2351d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
235208480c60SBarry Smith       C    = *B;
23533a40ed3dSBarry Smith     } else {
23543bef6203SJed Brown       PetscInt rbs,cbs;
2355ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2356f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
23573bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
23583bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
23593bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
23607adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2361ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
236208480c60SBarry Smith     }
2363db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
2364db02288aSLois Curfman McInnes 
236502834360SBarry Smith     /* loop over rows inserting into submatrix */
2366db02288aSLois Curfman McInnes     a_new = c->a;
2367db02288aSLois Curfman McInnes     j_new = c->j;
2368db02288aSLois Curfman McInnes     i_new = c->i;
2369bfeeae90SHong Zhang 
237002834360SBarry Smith     for (i=0; i<nrows; i++) {
2371a2744918SBarry Smith       ii    = starts[i];
2372a2744918SBarry Smith       lensi = lens[i];
2373a2744918SBarry Smith       for (k=0; k<lensi; k++) {
2374a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
237502834360SBarry Smith       }
237687828ca2SBarry Smith       ierr       = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
2377a2744918SBarry Smith       a_new     += lensi;
2378a2744918SBarry Smith       i_new[i+1] = i_new[i] + lensi;
2379a2744918SBarry Smith       c->ilen[i] = lensi;
238002834360SBarry Smith     }
23810e83c824SBarry Smith     ierr = PetscFree2(lens,starts);CHKERRQ(ierr);
23823a40ed3dSBarry Smith   } else {
238302834360SBarry Smith     ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
23840e83c824SBarry Smith     ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr);
238597f1f81fSBarry Smith     ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr);
23860e83c824SBarry Smith     ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
23874dcab191SBarry Smith     for (i=0; i<ncols; i++) {
23884dcab191SBarry Smith #if defined(PETSC_USE_DEBUG)
23894dcab191SBarry Smith       if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols);
23904dcab191SBarry Smith #endif
23914dcab191SBarry Smith       smap[icol[i]] = i+1;
23924dcab191SBarry Smith     }
23934dcab191SBarry Smith 
239402834360SBarry Smith     /* determine lens of each row */
239502834360SBarry Smith     for (i=0; i<nrows; i++) {
2396bfeeae90SHong Zhang       kstart  = ai[irow[i]];
239702834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
239802834360SBarry Smith       lens[i] = 0;
239902834360SBarry Smith       for (k=kstart; k<kend; k++) {
2400bfeeae90SHong Zhang         if (smap[aj[k]]) {
240102834360SBarry Smith           lens[i]++;
240202834360SBarry Smith         }
240302834360SBarry Smith       }
240402834360SBarry Smith     }
240517ab2063SBarry Smith     /* Create and fill new matrix */
2406a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
2407ace3abfcSBarry Smith       PetscBool equal;
24080f5bd95cSBarry Smith 
240999141d43SSatish Balay       c = (Mat_SeqAIJ*)((*B)->data);
2410e32f2f54SBarry Smith       if ((*B)->rmap->n  != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
2411d0f46423SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr);
2412f23aa3ddSBarry Smith       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
2413d0f46423SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
241408480c60SBarry Smith       C    = *B;
24153a40ed3dSBarry Smith     } else {
24163bef6203SJed Brown       PetscInt rbs,cbs;
2417ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2418f69a0ea3SMatthew Knepley       ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
24193bef6203SJed Brown       ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr);
24203bef6203SJed Brown       ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr);
24213bef6203SJed Brown       ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr);
24227adad957SLisandro Dalcin       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2423ab93d7beSBarry Smith       ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr);
242408480c60SBarry Smith     }
242599141d43SSatish Balay     c = (Mat_SeqAIJ*)(C->data);
242617ab2063SBarry Smith     for (i=0; i<nrows; i++) {
242799141d43SSatish Balay       row      = irow[i];
2428bfeeae90SHong Zhang       kstart   = ai[row];
242999141d43SSatish Balay       kend     = kstart + a->ilen[row];
2430bfeeae90SHong Zhang       mat_i    = c->i[i];
243199141d43SSatish Balay       mat_j    = c->j + mat_i;
243299141d43SSatish Balay       mat_a    = c->a + mat_i;
243399141d43SSatish Balay       mat_ilen = c->ilen + i;
243417ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
2435bfeeae90SHong Zhang         if ((tcol=smap[a->j[k]])) {
2436ed480e8bSBarry Smith           *mat_j++ = tcol - 1;
243799141d43SSatish Balay           *mat_a++ = a->a[k];
243899141d43SSatish Balay           (*mat_ilen)++;
243999141d43SSatish Balay 
244017ab2063SBarry Smith         }
244117ab2063SBarry Smith       }
244217ab2063SBarry Smith     }
244302834360SBarry Smith     /* Free work space */
244402834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2445606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
2446606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
244702834360SBarry Smith   }
24486d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24496d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
245017ab2063SBarry Smith 
245117ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
2452416022c9SBarry Smith   *B   = C;
24533a40ed3dSBarry Smith   PetscFunctionReturn(0);
245417ab2063SBarry Smith }
245517ab2063SBarry Smith 
24561df811f5SHong Zhang #undef __FUNCT__
245782d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ"
2458fc08c53fSHong Zhang PetscErrorCode  MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat)
245982d44351SHong Zhang {
246082d44351SHong Zhang   PetscErrorCode ierr;
246182d44351SHong Zhang   Mat            B;
246282d44351SHong Zhang 
246382d44351SHong Zhang   PetscFunctionBegin;
2464c2d650bdSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
246582d44351SHong Zhang     ierr    = MatCreate(subComm,&B);CHKERRQ(ierr);
246682d44351SHong Zhang     ierr    = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr);
2467a2f3521dSMark F. Adams     ierr    = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
246882d44351SHong Zhang     ierr    = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
246982d44351SHong Zhang     ierr    = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr);
247082d44351SHong Zhang     *subMat = B;
2471c2d650bdSHong Zhang   } else {
2472c2d650bdSHong Zhang     ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2473c2d650bdSHong Zhang   }
247482d44351SHong Zhang   PetscFunctionReturn(0);
247582d44351SHong Zhang }
247682d44351SHong Zhang 
247782d44351SHong Zhang #undef __FUNCT__
24784a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
24790481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info)
2480a871dcd8SBarry Smith {
248163b91edcSBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)inA->data;
2482dfbe8321SBarry Smith   PetscErrorCode ierr;
248363b91edcSBarry Smith   Mat            outA;
2484ace3abfcSBarry Smith   PetscBool      row_identity,col_identity;
248563b91edcSBarry Smith 
24863a40ed3dSBarry Smith   PetscFunctionBegin;
2487e32f2f54SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
24881df811f5SHong Zhang 
2489b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
2490b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
2491a871dcd8SBarry Smith 
249263b91edcSBarry Smith   outA             = inA;
2493d5f3da31SBarry Smith   outA->factortype = MAT_FACTOR_LU;
24942205254eSKarl Rupp 
2495c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
24966bf464f9SBarry Smith   ierr = ISDestroy(&a->row);CHKERRQ(ierr);
24972205254eSKarl Rupp 
2498c3122656SLisandro Dalcin   a->row = row;
24992205254eSKarl Rupp 
2500c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
25016bf464f9SBarry Smith   ierr = ISDestroy(&a->col);CHKERRQ(ierr);
25022205254eSKarl Rupp 
2503c3122656SLisandro Dalcin   a->col = col;
250463b91edcSBarry Smith 
250536db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
25066bf464f9SBarry Smith   ierr = ISDestroy(&a->icol);CHKERRQ(ierr);
25074c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
25083bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr);
2509f0ec6fceSSatish Balay 
251094a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
2511d0f46423SBarry Smith     ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
25123bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr);
251394a9d846SBarry Smith   }
251463b91edcSBarry Smith 
2515f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
2516137fb511SHong Zhang   if (row_identity && col_identity) {
2517ad04f41aSHong Zhang     ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr);
2518137fb511SHong Zhang   } else {
2519719d5645SBarry Smith     ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr);
2520137fb511SHong Zhang   }
25213a40ed3dSBarry Smith   PetscFunctionReturn(0);
2522a871dcd8SBarry Smith }
2523a871dcd8SBarry Smith 
25244a2ae208SSatish Balay #undef __FUNCT__
25254a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
2526f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha)
2527f0b747eeSBarry Smith {
2528f0b747eeSBarry Smith   Mat_SeqAIJ     *a     = (Mat_SeqAIJ*)inA->data;
2529f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
2530efee365bSSatish Balay   PetscErrorCode ierr;
2531c5df96a5SBarry Smith   PetscBLASInt   one = 1,bnz;
25323a40ed3dSBarry Smith 
25333a40ed3dSBarry Smith   PetscFunctionBegin;
2534c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr);
25358b83055fSJed Brown   PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one));
2536efee365bSSatish Balay   ierr = PetscLogFlops(a->nz);CHKERRQ(ierr);
2537acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr);
25383a40ed3dSBarry Smith   PetscFunctionReturn(0);
2539f0b747eeSBarry Smith }
2540f0b747eeSBarry Smith 
25414a2ae208SSatish Balay #undef __FUNCT__
25424a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
254397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2544cddf8d76SBarry Smith {
2545dfbe8321SBarry Smith   PetscErrorCode ierr;
254697f1f81fSBarry Smith   PetscInt       i;
2547cddf8d76SBarry Smith 
25483a40ed3dSBarry Smith   PetscFunctionBegin;
2549cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2550b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
2551cddf8d76SBarry Smith   }
2552cddf8d76SBarry Smith 
2553cddf8d76SBarry Smith   for (i=0; i<n; i++) {
25546a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2555cddf8d76SBarry Smith   }
25563a40ed3dSBarry Smith   PetscFunctionReturn(0);
2557cddf8d76SBarry Smith }
2558cddf8d76SBarry Smith 
25594a2ae208SSatish Balay #undef __FUNCT__
25604a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
256197f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov)
25624dcbc457SBarry Smith {
2563e4d965acSSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
25646849ba73SBarry Smith   PetscErrorCode ierr;
25655d0c19d7SBarry Smith   PetscInt       row,i,j,k,l,m,n,*nidx,isz,val;
25665d0c19d7SBarry Smith   const PetscInt *idx;
256797f1f81fSBarry Smith   PetscInt       start,end,*ai,*aj;
2568f1af5d2fSBarry Smith   PetscBT        table;
2569bbd702dbSSatish Balay 
25703a40ed3dSBarry Smith   PetscFunctionBegin;
2571d0f46423SBarry Smith   m  = A->rmap->n;
2572e4d965acSSatish Balay   ai = a->i;
2573bfeeae90SHong Zhang   aj = a->j;
25748a047759SSatish Balay 
2575e32f2f54SBarry Smith   if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used");
257606763907SSatish Balay 
257797f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr);
257853b8de81SBarry Smith   ierr = PetscBTCreate(m,&table);CHKERRQ(ierr);
257906763907SSatish Balay 
2580e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
2581b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
2582e4d965acSSatish Balay     isz  = 0;
25836831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
2584e4d965acSSatish Balay 
2585e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
25864dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
2587b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
2588e4d965acSSatish Balay 
2589dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
2590e4d965acSSatish Balay     for (j=0; j<n; ++j) {
25912205254eSKarl Rupp       if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j];
25924dcbc457SBarry Smith     }
259306763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
25946bf464f9SBarry Smith     ierr = ISDestroy(&is[i]);CHKERRQ(ierr);
2595e4d965acSSatish Balay 
259604a348a9SBarry Smith     k = 0;
259704a348a9SBarry Smith     for (j=0; j<ov; j++) { /* for each overlap */
259804a348a9SBarry Smith       n = isz;
259906763907SSatish Balay       for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */
2600e4d965acSSatish Balay         row   = nidx[k];
2601e4d965acSSatish Balay         start = ai[row];
2602e4d965acSSatish Balay         end   = ai[row+1];
260304a348a9SBarry Smith         for (l = start; l<end; l++) {
2604efb16452SHong Zhang           val = aj[l];
26052205254eSKarl Rupp           if (!PetscBTLookupSet(table,val)) nidx[isz++] = val;
2606e4d965acSSatish Balay         }
2607e4d965acSSatish Balay       }
2608e4d965acSSatish Balay     }
260970b3c8c7SBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr);
2610e4d965acSSatish Balay   }
261194bacf5dSBarry Smith   ierr = PetscBTDestroy(&table);CHKERRQ(ierr);
2612606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
26133a40ed3dSBarry Smith   PetscFunctionReturn(0);
26144dcbc457SBarry Smith }
261517ab2063SBarry Smith 
26160513a670SBarry Smith /* -------------------------------------------------------------- */
26174a2ae208SSatish Balay #undef __FUNCT__
26184a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
2619dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
26200513a670SBarry Smith {
26210513a670SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
26226849ba73SBarry Smith   PetscErrorCode ierr;
26233b98c0a2SBarry Smith   PetscInt       i,nz = 0,m = A->rmap->n,n = A->cmap->n;
26245d0c19d7SBarry Smith   const PetscInt *row,*col;
26255d0c19d7SBarry Smith   PetscInt       *cnew,j,*lens;
262656cd22aeSBarry Smith   IS             icolp,irowp;
26270298fd71SBarry Smith   PetscInt       *cwork = NULL;
26280298fd71SBarry Smith   PetscScalar    *vwork = NULL;
26290513a670SBarry Smith 
26303a40ed3dSBarry Smith   PetscFunctionBegin;
26314c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
263256cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
26334c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
263456cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
26350513a670SBarry Smith 
26360513a670SBarry Smith   /* determine lengths of permuted rows */
263797f1f81fSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr);
26382205254eSKarl Rupp   for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i];
2639ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
2640f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr);
2641a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
26427adad957SLisandro Dalcin   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2643ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr);
2644606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
26450513a670SBarry Smith 
264697f1f81fSBarry Smith   ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr);
26470513a670SBarry Smith   for (i=0; i<m; i++) {
264832ec9ce4SBarry Smith     ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26492205254eSKarl Rupp     for (j=0; j<nz; j++) cnew[j] = col[cwork[j]];
2650cdc0ba36SBarry Smith     ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
265132ec9ce4SBarry Smith     ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
26520513a670SBarry Smith   }
2653606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
26542205254eSKarl Rupp 
26553c7d62e4SBarry Smith   (*B)->assembled = PETSC_FALSE;
26562205254eSKarl Rupp 
26570513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
26580513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
265956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
266056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
26616bf464f9SBarry Smith   ierr = ISDestroy(&irowp);CHKERRQ(ierr);
26626bf464f9SBarry Smith   ierr = ISDestroy(&icolp);CHKERRQ(ierr);
26633a40ed3dSBarry Smith   PetscFunctionReturn(0);
26640513a670SBarry Smith }
26650513a670SBarry Smith 
26664a2ae208SSatish Balay #undef __FUNCT__
26674a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
2668dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
2669cb5b572fSBarry Smith {
2670dfbe8321SBarry Smith   PetscErrorCode ierr;
2671cb5b572fSBarry Smith 
2672cb5b572fSBarry Smith   PetscFunctionBegin;
267333f4a19fSKris Buschelman   /* If the two matrices have the same copy implementation, use fast copy. */
267433f4a19fSKris Buschelman   if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) {
2675be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
2676be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
2677be6bf707SBarry Smith 
2678700c5bfcSBarry Smith     if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different");
2679d0f46423SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr);
2680cb5b572fSBarry Smith   } else {
2681cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2682cb5b572fSBarry Smith   }
2683cb5b572fSBarry Smith   PetscFunctionReturn(0);
2684cb5b572fSBarry Smith }
2685cb5b572fSBarry Smith 
26864a2ae208SSatish Balay #undef __FUNCT__
26874994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ"
26884994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A)
2689273d9f13SBarry Smith {
2690dfbe8321SBarry Smith   PetscErrorCode ierr;
2691273d9f13SBarry Smith 
2692273d9f13SBarry Smith   PetscFunctionBegin;
2693ab93d7beSBarry Smith   ierr =  MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
2694273d9f13SBarry Smith   PetscFunctionReturn(0);
2695273d9f13SBarry Smith }
2696273d9f13SBarry Smith 
26974a2ae208SSatish Balay #undef __FUNCT__
26988c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ"
26998c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[])
27006c0721eeSBarry Smith {
27016c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
27026e111a19SKarl Rupp 
27036c0721eeSBarry Smith   PetscFunctionBegin;
27046c0721eeSBarry Smith   *array = a->a;
27056c0721eeSBarry Smith   PetscFunctionReturn(0);
27066c0721eeSBarry Smith }
27076c0721eeSBarry Smith 
27084a2ae208SSatish Balay #undef __FUNCT__
27098c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ"
27108c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[])
27116c0721eeSBarry Smith {
27126c0721eeSBarry Smith   PetscFunctionBegin;
27136c0721eeSBarry Smith   PetscFunctionReturn(0);
27146c0721eeSBarry Smith }
2715273d9f13SBarry Smith 
2716b7caf3d6SHong Zhang /*---------------------------------------------*/
2717b7caf3d6SHong Zhang /* #define JACOBIANCOLOROPT */
2718b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT)
2719b7caf3d6SHong Zhang #include <petsctime.h>
2720b7caf3d6SHong Zhang #endif
2721ee4f033dSBarry Smith #undef __FUNCT__
2722ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
2723dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2724ee4f033dSBarry Smith {
27256849ba73SBarry Smith   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void*))coloring->f;
27266849ba73SBarry Smith   PetscErrorCode ierr;
2727b7caf3d6SHong Zhang   PetscInt       k,start,end,l,row,col,**vscaleforrow;
2728b7caf3d6SHong Zhang   PetscScalar    dx,*y,*xx,*w3_array;
2729b7caf3d6SHong Zhang   PetscScalar    *vscale_array;
2730b7caf3d6SHong Zhang   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin,unorm;
2731b7caf3d6SHong Zhang   Vec            w1      = coloring->w1,w2=coloring->w2,w3;
2732b7caf3d6SHong Zhang   void           *fctx   = coloring->fctx;
2733b7caf3d6SHong Zhang   PetscBool      flg     = PETSC_FALSE;
2734b7caf3d6SHong Zhang   PetscInt       ctype   = coloring->ctype,N,col_start=0,col_end=0;
2735b7caf3d6SHong Zhang   Vec            x1_tmp;
2736b7caf3d6SHong Zhang   Mat_SeqAIJ     *csp = (Mat_SeqAIJ*)J->data;
2737b7caf3d6SHong Zhang   PetscInt       *den2sp=coloring->den2sp,*idx=den2sp;
2738b7caf3d6SHong Zhang   PetscScalar    *ca=csp->a;
2739b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT)
2740b7caf3d6SHong Zhang   PetscLogDouble t0,t1,time_setvalues=0.0;
2741b7caf3d6SHong Zhang #endif
2742b7caf3d6SHong Zhang 
2743b7caf3d6SHong Zhang   PetscFunctionBegin;
2744b7caf3d6SHong Zhang   PetscValidHeaderSpecific(J,MAT_CLASSID,1);
2745b7caf3d6SHong Zhang   PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2);
2746b7caf3d6SHong Zhang   PetscValidHeaderSpecific(x1,VEC_CLASSID,3);
2747b7caf3d6SHong Zhang   if (!f) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()");
2748b7caf3d6SHong Zhang 
2749b7caf3d6SHong Zhang   ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr);
2750b7caf3d6SHong Zhang   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
2751b7caf3d6SHong Zhang   ierr = PetscOptionsGetBool(NULL,"-mat_fd_coloring_dont_rezero",&flg,NULL);CHKERRQ(ierr);
2752b7caf3d6SHong Zhang   if (flg) {
2753b7caf3d6SHong Zhang     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2754b7caf3d6SHong Zhang   } else {
2755b7caf3d6SHong Zhang     PetscBool assembled;
2756b7caf3d6SHong Zhang     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
2757b7caf3d6SHong Zhang     if (assembled) {
2758b7caf3d6SHong Zhang       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2759b7caf3d6SHong Zhang     }
2760b7caf3d6SHong Zhang   }
2761b7caf3d6SHong Zhang 
2762b7caf3d6SHong Zhang   x1_tmp = x1;
2763b7caf3d6SHong Zhang   if (!coloring->vscale) {
2764b7caf3d6SHong Zhang     ierr = VecDuplicate(x1_tmp,&coloring->vscale);CHKERRQ(ierr);
2765b7caf3d6SHong Zhang   }
2766b7caf3d6SHong Zhang 
2767b7caf3d6SHong Zhang   if (coloring->htype[0] == 'w') { /* tacky test; need to make systematic if we add other approaches to computing h*/
2768b7caf3d6SHong Zhang     ierr = VecNorm(x1_tmp,NORM_2,&unorm);CHKERRQ(ierr);
2769b7caf3d6SHong Zhang   }
2770b7caf3d6SHong Zhang   ierr = VecGetOwnershipRange(w1,&start,&end);CHKERRQ(ierr); /* OwnershipRange is used by ghosted x! */
2771b7caf3d6SHong Zhang 
2772b7caf3d6SHong Zhang   /* Set w1 = F(x1) */
2773b7caf3d6SHong Zhang   if (!coloring->fset) {
2774b7caf3d6SHong Zhang     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2775b7caf3d6SHong Zhang     ierr = (*f)(sctx,x1_tmp,w1,fctx);CHKERRQ(ierr);
2776b7caf3d6SHong Zhang     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2777b7caf3d6SHong Zhang   } else {
2778b7caf3d6SHong Zhang     coloring->fset = PETSC_FALSE;
2779b7caf3d6SHong Zhang   }
2780b7caf3d6SHong Zhang 
2781b7caf3d6SHong Zhang   if (!coloring->w3) {
2782b7caf3d6SHong Zhang     ierr = VecDuplicate(x1_tmp,&coloring->w3);CHKERRQ(ierr);
2783b7caf3d6SHong Zhang     ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w3);CHKERRQ(ierr);
2784b7caf3d6SHong Zhang   }
2785b7caf3d6SHong Zhang   w3 = coloring->w3;
2786b7caf3d6SHong Zhang 
2787b7caf3d6SHong Zhang   /* Compute all the local scale factors, including ghost points */
2788b7caf3d6SHong Zhang   ierr = VecGetLocalSize(x1_tmp,&N);CHKERRQ(ierr);
2789b7caf3d6SHong Zhang   ierr = VecGetArray(x1_tmp,&xx);CHKERRQ(ierr);
2790b7caf3d6SHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2791b7caf3d6SHong Zhang   if (ctype == IS_COLORING_GHOSTED) {
2792b7caf3d6SHong Zhang     col_start = 0; col_end = N;
2793b7caf3d6SHong Zhang   } else if (ctype == IS_COLORING_GLOBAL) {
2794b7caf3d6SHong Zhang     xx           = xx - start;
2795b7caf3d6SHong Zhang     vscale_array = vscale_array - start;
2796b7caf3d6SHong Zhang     col_start    = start; col_end = N + start;
2797b7caf3d6SHong Zhang   }
2798b7caf3d6SHong Zhang   for (col=col_start; col<col_end; col++) {
2799b7caf3d6SHong Zhang     /* Loop over each local column, vscale[col] = 1./(epsilon*dx[col]) */
2800b7caf3d6SHong Zhang     if (coloring->htype[0] == 'w') {
2801b7caf3d6SHong Zhang       dx = 1.0 + unorm;
2802b7caf3d6SHong Zhang     } else {
2803b7caf3d6SHong Zhang       dx = xx[col];
2804b7caf3d6SHong Zhang     }
2805b7caf3d6SHong Zhang     if (dx == (PetscScalar)0.0) dx = 1.0;
2806b7caf3d6SHong Zhang     if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2807b7caf3d6SHong Zhang     else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2808b7caf3d6SHong Zhang     dx               *= epsilon;
2809b7caf3d6SHong Zhang     vscale_array[col] = (PetscScalar)1.0/dx;
2810b7caf3d6SHong Zhang   }
2811b7caf3d6SHong Zhang   if (ctype == IS_COLORING_GLOBAL) vscale_array = vscale_array + start;
2812b7caf3d6SHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2813b7caf3d6SHong Zhang   if (ctype == IS_COLORING_GLOBAL) {
2814b7caf3d6SHong Zhang     ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2815b7caf3d6SHong Zhang     ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2816b7caf3d6SHong Zhang   }
2817b7caf3d6SHong Zhang 
2818b7caf3d6SHong Zhang   if (coloring->vscaleforrow) {
2819b7caf3d6SHong Zhang     vscaleforrow = coloring->vscaleforrow;
2820b7caf3d6SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_NULL,"Null Object: coloring->vscaleforrow");
2821b7caf3d6SHong Zhang 
2822b7caf3d6SHong Zhang   /*
2823b7caf3d6SHong Zhang     Loop over each color
2824b7caf3d6SHong Zhang   */
2825b7caf3d6SHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2826b7caf3d6SHong Zhang   for (k=0; k<coloring->ncolors; k++) { /* loop over colors */
2827b7caf3d6SHong Zhang     coloring->currentcolor = k;
2828b7caf3d6SHong Zhang 
2829b7caf3d6SHong Zhang     ierr = VecCopy(x1_tmp,w3);CHKERRQ(ierr);
2830b7caf3d6SHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);
2831b7caf3d6SHong Zhang     if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array - start;
2832b7caf3d6SHong Zhang     /*
2833b7caf3d6SHong Zhang       Loop over each column associated with color
2834b7caf3d6SHong Zhang       adding the perturbation to the vector w3.
2835b7caf3d6SHong Zhang     */
2836b7caf3d6SHong Zhang     for (l=0; l<coloring->ncolumns[k]; l++) { /* loop over columns */
2837b7caf3d6SHong Zhang       col = coloring->columns[k][l];    /* local column of the matrix we are probing for */
2838b7caf3d6SHong Zhang       if (coloring->htype[0] == 'w') {
2839b7caf3d6SHong Zhang         dx = 1.0 + unorm;
2840b7caf3d6SHong Zhang       } else {
2841b7caf3d6SHong Zhang         dx = xx[col];
2842b7caf3d6SHong Zhang       }
2843b7caf3d6SHong Zhang       if (dx == (PetscScalar)0.0) dx = 1.0;
2844b7caf3d6SHong Zhang       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2845b7caf3d6SHong Zhang       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2846b7caf3d6SHong Zhang       dx            *= epsilon;
2847b7caf3d6SHong Zhang       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2848b7caf3d6SHong Zhang       w3_array[col] += dx;
2849b7caf3d6SHong Zhang     }
2850b7caf3d6SHong Zhang     if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array + start;
2851b7caf3d6SHong Zhang     ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2852b7caf3d6SHong Zhang 
2853b7caf3d6SHong Zhang     /*
2854b7caf3d6SHong Zhang       Evaluate function at w3 = x1 + dx (here dx is a vector of perturbations)
2855b7caf3d6SHong Zhang                            w2 = F(x1 + dx) - F(x1)
2856b7caf3d6SHong Zhang     */
2857b7caf3d6SHong Zhang     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2858b7caf3d6SHong Zhang     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
2859b7caf3d6SHong Zhang     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2860b7caf3d6SHong Zhang     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
2861b7caf3d6SHong Zhang 
2862b7caf3d6SHong Zhang     /*
2863b7caf3d6SHong Zhang       Loop over rows of vector, putting results into Jacobian matrix
2864b7caf3d6SHong Zhang     */
2865b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT)
2866b7caf3d6SHong Zhang     ierr = PetscTime(&t0);CHKERRQ(ierr);
2867b7caf3d6SHong Zhang #endif
2868b7caf3d6SHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2869b7caf3d6SHong Zhang     for (l=0; l<coloring->nrows[k]; l++) { /* loop over rows */
2870b7caf3d6SHong Zhang       row     = coloring->rows[k][l];            /* local row index */
2871b7caf3d6SHong Zhang       y[row] *= vscale_array[vscaleforrow[k][l]];
2872b7caf3d6SHong Zhang       ca[idx[l]] = y[row];
2873b7caf3d6SHong Zhang     }
2874b7caf3d6SHong Zhang     idx = idx + coloring->nrows[k];
2875b7caf3d6SHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2876b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT)
2877b7caf3d6SHong Zhang     ierr = PetscTime(&t1);CHKERRQ(ierr);
2878b7caf3d6SHong Zhang     time_setvalues += t1-t0;
2879b7caf3d6SHong Zhang #endif
2880b7caf3d6SHong Zhang   } /* endof for each color */
2881b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT)
2882b7caf3d6SHong Zhang   printf("     MatFDColoringApply_SeqAIJ: time_setvalues %g\n",time_setvalues);
2883b7caf3d6SHong Zhang #endif
2884b7caf3d6SHong Zhang   if (ctype == IS_COLORING_GLOBAL) xx = xx + start;
2885b7caf3d6SHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2886b7caf3d6SHong Zhang   ierr = VecRestoreArray(x1_tmp,&xx);CHKERRQ(ierr);
2887b7caf3d6SHong Zhang 
2888b7caf3d6SHong Zhang   coloring->currentcolor = -1;
2889b7caf3d6SHong Zhang   ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr);
2890b7caf3d6SHong Zhang   PetscFunctionReturn(0);
2891b7caf3d6SHong Zhang }
2892b7caf3d6SHong Zhang /* --------------------------------------------------------*/
2893b7caf3d6SHong Zhang 
2894b7caf3d6SHong Zhang #undef __FUNCT__
2895b7caf3d6SHong Zhang #define __FUNCT__ "MatFDColoringApply_SeqAIJ_old"
2896b7caf3d6SHong Zhang PetscErrorCode MatFDColoringApply_SeqAIJ_old(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
2897b7caf3d6SHong Zhang {
2898b7caf3d6SHong Zhang   PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void*))coloring->f;
2899b7caf3d6SHong Zhang   PetscErrorCode ierr;
29004e269d77SPeter Brune   PetscInt       k,N,start,end,l,row,col,srow,**vscaleforrow;
2901efb30889SBarry Smith   PetscScalar    dx,*y,*xx,*w3_array;
290287828ca2SBarry Smith   PetscScalar    *vscale_array;
2903ee4f033dSBarry Smith   PetscReal      epsilon = coloring->error_rel,umin = coloring->umin;
2904ee4f033dSBarry Smith   Vec            w1,w2,w3;
2905ee4f033dSBarry Smith   void           *fctx = coloring->fctx;
2906ace3abfcSBarry Smith   PetscBool      flg   = PETSC_FALSE;
2907ee4f033dSBarry Smith 
2908ee4f033dSBarry Smith   PetscFunctionBegin;
2909b7caf3d6SHong Zhang   printf("MatFDColoringApply_SeqAIJ ...\n");
2910ee4f033dSBarry Smith   if (!coloring->w1) {
2911ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
29123bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w1);CHKERRQ(ierr);
2913ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
29143bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w2);CHKERRQ(ierr);
2915ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
29163bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w3);CHKERRQ(ierr);
2917ee4f033dSBarry Smith   }
2918ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
2919ee4f033dSBarry Smith 
2920ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
29210298fd71SBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,NULL);CHKERRQ(ierr);
2922ee4f033dSBarry Smith   if (flg) {
2923ae15b995SBarry Smith     ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr);
2924ee4f033dSBarry Smith   } else {
2925ace3abfcSBarry Smith     PetscBool assembled;
29260b9b6f31SBarry Smith     ierr = MatAssembled(J,&assembled);CHKERRQ(ierr);
29270b9b6f31SBarry Smith     if (assembled) {
2928ee4f033dSBarry Smith       ierr = MatZeroEntries(J);CHKERRQ(ierr);
2929ee4f033dSBarry Smith     }
29300b9b6f31SBarry Smith   }
2931ee4f033dSBarry Smith 
2932ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
2933ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
2934ee4f033dSBarry Smith 
29354e269d77SPeter Brune   if (!coloring->fset) {
293666f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
2937ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
293866f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
29394e269d77SPeter Brune   } else {
29404e269d77SPeter Brune     coloring->fset = PETSC_FALSE;
2941ee4f033dSBarry Smith   }
2942ee4f033dSBarry Smith 
2943ee4f033dSBarry Smith   /*
2944ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
2945ee4f033dSBarry Smith   */
29461ebc52fbSHong Zhang   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
29471ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
2948ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
2949ee4f033dSBarry Smith     /*
2950ee4f033dSBarry Smith        Loop over each column associated with color adding the
2951ee4f033dSBarry Smith        perturbation to the vector w3.
2952ee4f033dSBarry Smith     */
2953ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2954ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2955ee4f033dSBarry Smith       dx  = xx[col];
2956ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2957ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2958ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2959ee4f033dSBarry Smith       dx               *= epsilon;
2960ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
2961ee4f033dSBarry Smith     }
2962ee4f033dSBarry Smith   }
29632205254eSKarl Rupp   vscale_array = vscale_array + start;
29642205254eSKarl Rupp 
29652205254eSKarl Rupp   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2966ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2967ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2968ee4f033dSBarry Smith 
2969ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2970ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2971ee4f033dSBarry Smith 
2972ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2973ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2974ee4f033dSBarry Smith 
29751ebc52fbSHong Zhang   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2976ee4f033dSBarry Smith   /*
2977ee4f033dSBarry Smith       Loop over each color
2978ee4f033dSBarry Smith   */
2979ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
298049b058dcSBarry Smith     coloring->currentcolor = k;
29812205254eSKarl Rupp 
2982ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
29831ebc52fbSHong Zhang     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2984ee4f033dSBarry Smith     /*
2985ee4f033dSBarry Smith        Loop over each column associated with color adding the
2986ee4f033dSBarry Smith        perturbation to the vector w3.
2987ee4f033dSBarry Smith     */
2988ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2989ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2990ee4f033dSBarry Smith       dx  = xx[col];
29915b8514ebSBarry Smith       if (dx == 0.0) dx = 1.0;
2992ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2993ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2994ee4f033dSBarry Smith       dx *= epsilon;
2995e32f2f54SBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter");
2996ee4f033dSBarry Smith       w3_array[col] += dx;
2997ee4f033dSBarry Smith     }
29981ebc52fbSHong Zhang     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2999ee4f033dSBarry Smith 
3000ee4f033dSBarry Smith     /*
3001ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
3002ee4f033dSBarry Smith     */
3003ee4f033dSBarry Smith 
300466f9b7ceSBarry Smith     ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
3005ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
300666f9b7ceSBarry Smith     ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr);
3007efb30889SBarry Smith     ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr);
3008ee4f033dSBarry Smith 
3009ee4f033dSBarry Smith     /*
3010ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
3011ee4f033dSBarry Smith     */
30121ebc52fbSHong Zhang     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
3013ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
3014ee4f033dSBarry Smith       row     = coloring->rows[k][l];
3015ee4f033dSBarry Smith       col     = coloring->columnsforrow[k][l];
3016ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
3017ee4f033dSBarry Smith       srow    = row + start;
3018ee4f033dSBarry Smith       ierr    = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
3019ee4f033dSBarry Smith     }
30201ebc52fbSHong Zhang     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
3021ee4f033dSBarry Smith   }
302249b058dcSBarry Smith   coloring->currentcolor = k;
30232205254eSKarl Rupp 
30241ebc52fbSHong Zhang   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
30252205254eSKarl Rupp   xx   = xx + start;
30262205254eSKarl Rupp   ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
3027ee4f033dSBarry Smith   ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3028ee4f033dSBarry Smith   ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3029ee4f033dSBarry Smith   PetscFunctionReturn(0);
3030ee4f033dSBarry Smith }
3031ee4f033dSBarry Smith 
30328229c054SShri Abhyankar /*
30338229c054SShri Abhyankar    Computes the number of nonzeros per row needed for preallocation when X and Y
30348229c054SShri Abhyankar    have different nonzero structure.
30358229c054SShri Abhyankar */
3036ac90fabeSBarry Smith #undef __FUNCT__
30378229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ"
30388229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz)
3039ec7775f6SShri Abhyankar {
30408229c054SShri Abhyankar   PetscInt       i,m=Y->rmap->N;
3041ec7775f6SShri Abhyankar   Mat_SeqAIJ     *x  = (Mat_SeqAIJ*)X->data;
3042ec7775f6SShri Abhyankar   Mat_SeqAIJ     *y  = (Mat_SeqAIJ*)Y->data;
3043ec7775f6SShri Abhyankar   const PetscInt *xi = x->i,*yi = y->i;
3044ec7775f6SShri Abhyankar 
3045ec7775f6SShri Abhyankar   PetscFunctionBegin;
3046ec7775f6SShri Abhyankar   /* Set the number of nonzeros in the new matrix */
3047ec7775f6SShri Abhyankar   for (i=0; i<m; i++) {
30488af7cee1SJed Brown     PetscInt       j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i];
30498af7cee1SJed Brown     const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i];
30508af7cee1SJed Brown     nnz[i] = 0;
30518af7cee1SJed Brown     for (j=0,k=0; j<nzx; j++) {                   /* Point in X */
30528af7cee1SJed Brown       for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */
30538af7cee1SJed Brown       if (k<nzy && yj[k]==xj[j]) k++;             /* Skip duplicate */
30548af7cee1SJed Brown       nnz[i]++;
30558af7cee1SJed Brown     }
30568af7cee1SJed Brown     for (; k<nzy; k++) nnz[i]++;
3057ec7775f6SShri Abhyankar   }
3058ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
3059ec7775f6SShri Abhyankar }
3060ec7775f6SShri Abhyankar 
3061ec7775f6SShri Abhyankar #undef __FUNCT__
3062ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
3063f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str)
3064ac90fabeSBarry Smith {
3065dfbe8321SBarry Smith   PetscErrorCode ierr;
306697f1f81fSBarry Smith   PetscInt       i;
3067ac90fabeSBarry Smith   Mat_SeqAIJ     *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data;
3068c5df96a5SBarry Smith   PetscBLASInt   one=1,bnz;
3069ac90fabeSBarry Smith 
3070ac90fabeSBarry Smith   PetscFunctionBegin;
3071c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr);
3072ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
3073f4df32b1SMatthew Knepley     PetscScalar alpha = a;
30748b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one));
3075acf2f550SJed Brown     ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr);
3076c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
3077a30b2313SHong Zhang     if (y->xtoy && y->XtoY != X) {
3078a30b2313SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
30796bf464f9SBarry Smith       ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr);
3080a30b2313SHong Zhang     }
3081a30b2313SHong Zhang     if (!y->xtoy) { /* get xtoy */
30820298fd71SBarry Smith       ierr    = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr);
3083a30b2313SHong Zhang       y->XtoY = X;
3084407f6b05SHong Zhang       ierr    = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
3085c537a176SHong Zhang     }
3086f4df32b1SMatthew Knepley     for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]);
3087ba0e910bSBarry Smith     ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(double)(PetscReal)(x->nz)/(y->nz+1));CHKERRQ(ierr);
3088ac90fabeSBarry Smith   } else {
30898229c054SShri Abhyankar     Mat      B;
30908229c054SShri Abhyankar     PetscInt *nnz;
309116b2e9dcSShri Abhyankar     ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
3092ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr);
3093bc5a2726SShri Abhyankar     ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr);
30944aa94f47SShri Abhyankar     ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr);
3095a2f3521dSMark F. Adams     ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr);
3096176df525SBarry Smith     ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr);
30978229c054SShri Abhyankar     ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr);
3098ecd8bba6SJed Brown     ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr);
3099ec7775f6SShri Abhyankar     ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr);
3100ec7775f6SShri Abhyankar     ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr);
31018229c054SShri Abhyankar     ierr = PetscFree(nnz);CHKERRQ(ierr);
3102ac90fabeSBarry Smith   }
3103ac90fabeSBarry Smith   PetscFunctionReturn(0);
3104ac90fabeSBarry Smith }
3105ac90fabeSBarry Smith 
3106521d7252SBarry Smith #undef __FUNCT__
3107354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ"
31087087cfbeSBarry Smith PetscErrorCode  MatConjugate_SeqAIJ(Mat mat)
3109354c94deSBarry Smith {
3110354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX)
3111354c94deSBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)mat->data;
3112354c94deSBarry Smith   PetscInt    i,nz;
3113354c94deSBarry Smith   PetscScalar *a;
3114354c94deSBarry Smith 
3115354c94deSBarry Smith   PetscFunctionBegin;
3116354c94deSBarry Smith   nz = aij->nz;
3117354c94deSBarry Smith   a  = aij->a;
31182205254eSKarl Rupp   for (i=0; i<nz; i++) a[i] = PetscConj(a[i]);
3119354c94deSBarry Smith #else
3120354c94deSBarry Smith   PetscFunctionBegin;
3121354c94deSBarry Smith #endif
3122354c94deSBarry Smith   PetscFunctionReturn(0);
3123354c94deSBarry Smith }
3124354c94deSBarry Smith 
3125e34fafa9SBarry Smith #undef __FUNCT__
3126985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ"
3127985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3128e34fafa9SBarry Smith {
3129e34fafa9SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3130e34fafa9SBarry Smith   PetscErrorCode ierr;
3131d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3132e34fafa9SBarry Smith   PetscReal      atmp;
3133985db425SBarry Smith   PetscScalar    *x;
3134e34fafa9SBarry Smith   MatScalar      *aa;
3135e34fafa9SBarry Smith 
3136e34fafa9SBarry Smith   PetscFunctionBegin;
3137e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3138e34fafa9SBarry Smith   aa = a->a;
3139e34fafa9SBarry Smith   ai = a->i;
3140e34fafa9SBarry Smith   aj = a->j;
3141e34fafa9SBarry Smith 
3142985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3143e34fafa9SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3144e34fafa9SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3145e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3146e34fafa9SBarry Smith   for (i=0; i<m; i++) {
3147e34fafa9SBarry Smith     ncols = ai[1] - ai[0]; ai++;
31489189402eSHong Zhang     x[i]  = 0.0;
3149e34fafa9SBarry Smith     for (j=0; j<ncols; j++) {
3150985db425SBarry Smith       atmp = PetscAbsScalar(*aa);
3151985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3152985db425SBarry Smith       aa++; aj++;
3153985db425SBarry Smith     }
3154985db425SBarry Smith   }
3155985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3156985db425SBarry Smith   PetscFunctionReturn(0);
3157985db425SBarry Smith }
3158985db425SBarry Smith 
3159985db425SBarry Smith #undef __FUNCT__
3160985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ"
3161985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3162985db425SBarry Smith {
3163985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3164985db425SBarry Smith   PetscErrorCode ierr;
3165d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3166985db425SBarry Smith   PetscScalar    *x;
3167985db425SBarry Smith   MatScalar      *aa;
3168985db425SBarry Smith 
3169985db425SBarry Smith   PetscFunctionBegin;
3170e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3171985db425SBarry Smith   aa = a->a;
3172985db425SBarry Smith   ai = a->i;
3173985db425SBarry Smith   aj = a->j;
3174985db425SBarry Smith 
3175985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3176985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3177985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3178e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3179985db425SBarry Smith   for (i=0; i<m; i++) {
3180985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3181d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3182985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3183985db425SBarry Smith     } else {  /* row is sparse so already KNOW maximum is 0.0 or higher */
3184985db425SBarry Smith       x[i] = 0.0;
3185985db425SBarry Smith       if (idx) {
3186985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3187985db425SBarry Smith         for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */
3188985db425SBarry Smith           if (aj[j] > j) {
3189985db425SBarry Smith             idx[i] = j;
3190985db425SBarry Smith             break;
3191985db425SBarry Smith           }
3192985db425SBarry Smith         }
3193985db425SBarry Smith       }
3194985db425SBarry Smith     }
3195985db425SBarry Smith     for (j=0; j<ncols; j++) {
3196985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3197985db425SBarry Smith       aa++; aj++;
3198985db425SBarry Smith     }
3199985db425SBarry Smith   }
3200985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3201985db425SBarry Smith   PetscFunctionReturn(0);
3202985db425SBarry Smith }
3203985db425SBarry Smith 
3204985db425SBarry Smith #undef __FUNCT__
3205c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ"
3206c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3207c87e5d42SMatthew Knepley {
3208c87e5d42SMatthew Knepley   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3209c87e5d42SMatthew Knepley   PetscErrorCode ierr;
3210c87e5d42SMatthew Knepley   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3211c87e5d42SMatthew Knepley   PetscReal      atmp;
3212c87e5d42SMatthew Knepley   PetscScalar    *x;
3213c87e5d42SMatthew Knepley   MatScalar      *aa;
3214c87e5d42SMatthew Knepley 
3215c87e5d42SMatthew Knepley   PetscFunctionBegin;
3216e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3217c87e5d42SMatthew Knepley   aa = a->a;
3218c87e5d42SMatthew Knepley   ai = a->i;
3219c87e5d42SMatthew Knepley   aj = a->j;
3220c87e5d42SMatthew Knepley 
3221c87e5d42SMatthew Knepley   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3222c87e5d42SMatthew Knepley   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3223c87e5d42SMatthew Knepley   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
32243bb78c5cSMatthew G Knepley   if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %d vs. %d rows", A->rmap->n, n);
3225c87e5d42SMatthew Knepley   for (i=0; i<m; i++) {
3226c87e5d42SMatthew Knepley     ncols = ai[1] - ai[0]; ai++;
3227289a08f5SMatthew Knepley     if (ncols) {
3228289a08f5SMatthew Knepley       /* Get first nonzero */
3229289a08f5SMatthew Knepley       for (j = 0; j < ncols; j++) {
3230289a08f5SMatthew Knepley         atmp = PetscAbsScalar(aa[j]);
32312205254eSKarl Rupp         if (atmp > 1.0e-12) {
32322205254eSKarl Rupp           x[i] = atmp;
32332205254eSKarl Rupp           if (idx) idx[i] = aj[j];
32342205254eSKarl Rupp           break;
32352205254eSKarl Rupp         }
3236289a08f5SMatthew Knepley       }
323712431cb0SMatthew G Knepley       if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;}
3238289a08f5SMatthew Knepley     } else {
3239289a08f5SMatthew Knepley       x[i] = 0.0; if (idx) idx[i] = 0;
3240289a08f5SMatthew Knepley     }
3241c87e5d42SMatthew Knepley     for (j = 0; j < ncols; j++) {
3242c87e5d42SMatthew Knepley       atmp = PetscAbsScalar(*aa);
3243289a08f5SMatthew Knepley       if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;}
3244c87e5d42SMatthew Knepley       aa++; aj++;
3245c87e5d42SMatthew Knepley     }
3246c87e5d42SMatthew Knepley   }
3247c87e5d42SMatthew Knepley   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3248c87e5d42SMatthew Knepley   PetscFunctionReturn(0);
3249c87e5d42SMatthew Knepley }
3250c87e5d42SMatthew Knepley 
3251c87e5d42SMatthew Knepley #undef __FUNCT__
3252985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ"
3253985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[])
3254985db425SBarry Smith {
3255985db425SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
3256985db425SBarry Smith   PetscErrorCode ierr;
3257d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,*ai,*aj,ncols,n;
3258985db425SBarry Smith   PetscScalar    *x;
3259985db425SBarry Smith   MatScalar      *aa;
3260985db425SBarry Smith 
3261985db425SBarry Smith   PetscFunctionBegin;
3262e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3263985db425SBarry Smith   aa = a->a;
3264985db425SBarry Smith   ai = a->i;
3265985db425SBarry Smith   aj = a->j;
3266985db425SBarry Smith 
3267985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
3268985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
3269985db425SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
3270e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
3271985db425SBarry Smith   for (i=0; i<m; i++) {
3272985db425SBarry Smith     ncols = ai[1] - ai[0]; ai++;
3273d0f46423SBarry Smith     if (ncols == A->cmap->n) { /* row is dense */
3274985db425SBarry Smith       x[i] = *aa; if (idx) idx[i] = 0;
3275985db425SBarry Smith     } else {  /* row is sparse so already KNOW minimum is 0.0 or lower */
3276985db425SBarry Smith       x[i] = 0.0;
3277985db425SBarry Smith       if (idx) {   /* find first implicit 0.0 in the row */
3278985db425SBarry Smith         idx[i] = 0; /* in case ncols is zero */
3279985db425SBarry Smith         for (j=0; j<ncols; j++) {
3280985db425SBarry Smith           if (aj[j] > j) {
3281985db425SBarry Smith             idx[i] = j;
3282985db425SBarry Smith             break;
3283985db425SBarry Smith           }
3284985db425SBarry Smith         }
3285985db425SBarry Smith       }
3286985db425SBarry Smith     }
3287985db425SBarry Smith     for (j=0; j<ncols; j++) {
3288985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;}
3289985db425SBarry Smith       aa++; aj++;
3290e34fafa9SBarry Smith     }
3291e34fafa9SBarry Smith   }
3292e34fafa9SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
3293e34fafa9SBarry Smith   PetscFunctionReturn(0);
3294e34fafa9SBarry Smith }
3295bbead8a2SBarry Smith 
3296bbead8a2SBarry Smith #include <petscblaslapack.h>
329706873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h>
3298bbead8a2SBarry Smith 
3299bbead8a2SBarry Smith #undef __FUNCT__
3300bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ"
3301713ccfa9SJed Brown PetscErrorCode  MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values)
3302bbead8a2SBarry Smith {
3303bbead8a2SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*) A->data;
3304bbead8a2SBarry Smith   PetscErrorCode ierr;
330534fc4b71SJed Brown   PetscInt       i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j;
3306bbead8a2SBarry Smith   MatScalar      *diag,work[25],*v_work;
3307bbead8a2SBarry Smith   PetscReal      shift = 0.0;
3308bbead8a2SBarry Smith 
3309bbead8a2SBarry Smith   PetscFunctionBegin;
33104a0d0026SBarry Smith   if (a->ibdiagvalid) {
33114a0d0026SBarry Smith     if (values) *values = a->ibdiag;
33124a0d0026SBarry Smith     PetscFunctionReturn(0);
33134a0d0026SBarry Smith   }
3314bbead8a2SBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
3315bbead8a2SBarry Smith   if (!a->ibdiag) {
3316bbead8a2SBarry Smith     ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr);
33173bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr);
3318bbead8a2SBarry Smith   }
3319bbead8a2SBarry Smith   diag = a->ibdiag;
3320bbead8a2SBarry Smith   if (values) *values = a->ibdiag;
3321bbead8a2SBarry Smith   /* factor and invert each block */
3322bbead8a2SBarry Smith   switch (bs) {
3323bbead8a2SBarry Smith   case 1:
3324bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3325bbead8a2SBarry Smith       ierr    = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr);
3326bbead8a2SBarry Smith       diag[i] = (PetscScalar)1.0 / (diag[i] + shift);
3327bbead8a2SBarry Smith     }
3328bbead8a2SBarry Smith     break;
3329bbead8a2SBarry Smith   case 2:
3330bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3331bbead8a2SBarry Smith       ij[0] = 2*i; ij[1] = 2*i + 1;
3332bbead8a2SBarry Smith       ierr  = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr);
333396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr);
333496b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr);
3335bbead8a2SBarry Smith       diag += 4;
3336bbead8a2SBarry Smith     }
3337bbead8a2SBarry Smith     break;
3338bbead8a2SBarry Smith   case 3:
3339bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3340bbead8a2SBarry Smith       ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2;
3341bbead8a2SBarry Smith       ierr  = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr);
334296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr);
334396b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr);
3344bbead8a2SBarry Smith       diag += 9;
3345bbead8a2SBarry Smith     }
3346bbead8a2SBarry Smith     break;
3347bbead8a2SBarry Smith   case 4:
3348bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3349bbead8a2SBarry Smith       ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3;
3350bbead8a2SBarry Smith       ierr  = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr);
335196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr);
335296b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr);
3353bbead8a2SBarry Smith       diag += 16;
3354bbead8a2SBarry Smith     }
3355bbead8a2SBarry Smith     break;
3356bbead8a2SBarry Smith   case 5:
3357bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3358bbead8a2SBarry 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;
3359bbead8a2SBarry Smith       ierr  = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr);
336096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr);
336196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr);
3362bbead8a2SBarry Smith       diag += 25;
3363bbead8a2SBarry Smith     }
3364bbead8a2SBarry Smith     break;
3365bbead8a2SBarry Smith   case 6:
3366bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3367bbead8a2SBarry 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;
3368bbead8a2SBarry Smith       ierr  = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr);
336996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr);
337096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr);
3371bbead8a2SBarry Smith       diag += 36;
3372bbead8a2SBarry Smith     }
3373bbead8a2SBarry Smith     break;
3374bbead8a2SBarry Smith   case 7:
3375bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3376bbead8a2SBarry 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;
3377bbead8a2SBarry Smith       ierr  = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr);
337896b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr);
337996b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr);
3380bbead8a2SBarry Smith       diag += 49;
3381bbead8a2SBarry Smith     }
3382bbead8a2SBarry Smith     break;
3383bbead8a2SBarry Smith   default:
3384bbead8a2SBarry Smith     ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr);
3385bbead8a2SBarry Smith     for (i=0; i<mbs; i++) {
3386bbead8a2SBarry Smith       for (j=0; j<bs; j++) {
3387bbead8a2SBarry Smith         IJ[j] = bs*i + j;
3388bbead8a2SBarry Smith       }
3389bbead8a2SBarry Smith       ierr  = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr);
339096b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr);
339196b95a6bSBarry Smith       ierr  = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr);
3392bbead8a2SBarry Smith       diag += bs2;
3393bbead8a2SBarry Smith     }
3394bbead8a2SBarry Smith     ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr);
3395bbead8a2SBarry Smith   }
3396bbead8a2SBarry Smith   a->ibdiagvalid = PETSC_TRUE;
3397bbead8a2SBarry Smith   PetscFunctionReturn(0);
3398bbead8a2SBarry Smith }
3399bbead8a2SBarry Smith 
340073a71a0fSBarry Smith #undef __FUNCT__
340173a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ"
340273a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx)
340373a71a0fSBarry Smith {
340473a71a0fSBarry Smith   PetscErrorCode ierr;
340573a71a0fSBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)x->data;
340673a71a0fSBarry Smith   PetscScalar    a;
340773a71a0fSBarry Smith   PetscInt       m,n,i,j,col;
340873a71a0fSBarry Smith 
340973a71a0fSBarry Smith   PetscFunctionBegin;
341073a71a0fSBarry Smith   if (!x->assembled) {
341173a71a0fSBarry Smith     ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
341273a71a0fSBarry Smith     for (i=0; i<m; i++) {
341373a71a0fSBarry Smith       for (j=0; j<aij->imax[i]; j++) {
341473a71a0fSBarry Smith         ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr);
341573a71a0fSBarry Smith         col  = (PetscInt)(n*PetscRealPart(a));
341673a71a0fSBarry Smith         ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr);
341773a71a0fSBarry Smith       }
341873a71a0fSBarry Smith     }
341973a71a0fSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded");
342073a71a0fSBarry Smith   ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
342173a71a0fSBarry Smith   ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
342273a71a0fSBarry Smith   PetscFunctionReturn(0);
342373a71a0fSBarry Smith }
342473a71a0fSBarry Smith 
34257087cfbeSBarry Smith extern PetscErrorCode  MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*);
3426682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
34270a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ,
3428cb5b572fSBarry Smith                                         MatGetRow_SeqAIJ,
3429cb5b572fSBarry Smith                                         MatRestoreRow_SeqAIJ,
3430cb5b572fSBarry Smith                                         MatMult_SeqAIJ,
343197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqAIJ,
34327c922b88SBarry Smith                                         MatMultTranspose_SeqAIJ,
34337c922b88SBarry Smith                                         MatMultTransposeAdd_SeqAIJ,
3434db4efbfdSBarry Smith                                         0,
3435db4efbfdSBarry Smith                                         0,
3436db4efbfdSBarry Smith                                         0,
3437db4efbfdSBarry Smith                                 /* 10*/ 0,
3438cb5b572fSBarry Smith                                         MatLUFactor_SeqAIJ,
3439cb5b572fSBarry Smith                                         0,
344041f059aeSBarry Smith                                         MatSOR_SeqAIJ,
344117ab2063SBarry Smith                                         MatTranspose_SeqAIJ,
344297304618SKris Buschelman                                 /*1 5*/ MatGetInfo_SeqAIJ,
3443cb5b572fSBarry Smith                                         MatEqual_SeqAIJ,
3444cb5b572fSBarry Smith                                         MatGetDiagonal_SeqAIJ,
3445cb5b572fSBarry Smith                                         MatDiagonalScale_SeqAIJ,
3446cb5b572fSBarry Smith                                         MatNorm_SeqAIJ,
344797304618SKris Buschelman                                 /* 20*/ 0,
3448cb5b572fSBarry Smith                                         MatAssemblyEnd_SeqAIJ,
3449cb5b572fSBarry Smith                                         MatSetOption_SeqAIJ,
3450cb5b572fSBarry Smith                                         MatZeroEntries_SeqAIJ,
3451d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqAIJ,
3452db4efbfdSBarry Smith                                         0,
3453db4efbfdSBarry Smith                                         0,
3454db4efbfdSBarry Smith                                         0,
3455db4efbfdSBarry Smith                                         0,
34564994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqAIJ,
3457db4efbfdSBarry Smith                                         0,
3458db4efbfdSBarry Smith                                         0,
34598c778c55SBarry Smith                                         0,
34608c778c55SBarry Smith                                         0,
3461d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqAIJ,
3462cb5b572fSBarry Smith                                         0,
3463cb5b572fSBarry Smith                                         0,
3464cb5b572fSBarry Smith                                         MatILUFactor_SeqAIJ,
3465cb5b572fSBarry Smith                                         0,
3466d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqAIJ,
3467cb5b572fSBarry Smith                                         MatGetSubMatrices_SeqAIJ,
3468cb5b572fSBarry Smith                                         MatIncreaseOverlap_SeqAIJ,
3469cb5b572fSBarry Smith                                         MatGetValues_SeqAIJ,
3470cb5b572fSBarry Smith                                         MatCopy_SeqAIJ,
3471d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqAIJ,
3472cb5b572fSBarry Smith                                         MatScale_SeqAIJ,
3473cb5b572fSBarry Smith                                         0,
347479299369SBarry Smith                                         MatDiagonalSet_SeqAIJ,
34756e169961SBarry Smith                                         MatZeroRowsColumns_SeqAIJ,
347673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqAIJ,
34773b2fbd54SBarry Smith                                         MatGetRowIJ_SeqAIJ,
34783b2fbd54SBarry Smith                                         MatRestoreRowIJ_SeqAIJ,
34793b2fbd54SBarry Smith                                         MatGetColumnIJ_SeqAIJ,
3480a93ec695SBarry Smith                                         MatRestoreColumnIJ_SeqAIJ,
3481d519adbfSMatthew Knepley                                 /* 54*/ MatFDColoringCreate_SeqAIJ,
3482b9617806SBarry Smith                                         0,
34830513a670SBarry Smith                                         0,
3484cda55fadSBarry Smith                                         MatPermute_SeqAIJ,
3485cda55fadSBarry Smith                                         0,
3486d519adbfSMatthew Knepley                                 /* 59*/ 0,
3487b9b97703SBarry Smith                                         MatDestroy_SeqAIJ,
3488b9b97703SBarry Smith                                         MatView_SeqAIJ,
3489357abbc8SBarry Smith                                         0,
3490321b30b9SSatish Balay                                         MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ,
3491321b30b9SSatish Balay                                 /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ,
3492321b30b9SSatish Balay                                         MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ,
3493ee4f033dSBarry Smith                                         0,
3494ee4f033dSBarry Smith                                         0,
3495ee4f033dSBarry Smith                                         0,
3496d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqAIJ,
3497c87e5d42SMatthew Knepley                                         MatGetRowMinAbs_SeqAIJ,
3498ee4f033dSBarry Smith                                         0,
3499ee4f033dSBarry Smith                                         MatSetColoring_SeqAIJ,
3500dcf5cc72SBarry Smith                                         0,
3501d519adbfSMatthew Knepley                                 /* 74*/ MatSetValuesAdifor_SeqAIJ,
35023acb8795SBarry Smith                                         MatFDColoringApply_AIJ,
350397304618SKris Buschelman                                         0,
350497304618SKris Buschelman                                         0,
350597304618SKris Buschelman                                         0,
35066ce1633cSBarry Smith                                 /* 79*/ MatFindZeroDiagonals_SeqAIJ,
350797304618SKris Buschelman                                         0,
350897304618SKris Buschelman                                         0,
350997304618SKris Buschelman                                         0,
3510bc011b1eSHong Zhang                                         MatLoad_SeqAIJ,
3511d519adbfSMatthew Knepley                                 /* 84*/ MatIsSymmetric_SeqAIJ,
35121cbb95d3SBarry Smith                                         MatIsHermitian_SeqAIJ,
35136284ec50SHong Zhang                                         0,
35146284ec50SHong Zhang                                         0,
3515bc011b1eSHong Zhang                                         0,
3516d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqAIJ_SeqAIJ,
351726be0446SHong Zhang                                         MatMatMultSymbolic_SeqAIJ_SeqAIJ,
351826be0446SHong Zhang                                         MatMatMultNumeric_SeqAIJ_SeqAIJ,
351965e8a0caSHong Zhang                                         MatPtAP_SeqAIJ_SeqAIJ,
35204a1b09b7SHong Zhang                                         MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy,
352165e8a0caSHong Zhang                                 /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ,
35226fc122caSHong Zhang                                         MatMatTransposeMult_SeqAIJ_SeqAIJ,
35236fc122caSHong Zhang                                         MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ,
35246fc122caSHong Zhang                                         MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ,
35252121bac1SHong Zhang                                         0,
35262121bac1SHong Zhang                                 /* 99*/ 0,
3527609c6c4dSKris Buschelman                                         0,
3528609c6c4dSKris Buschelman                                         0,
352987d4246cSBarry Smith                                         MatConjugate_SeqAIJ,
353087d4246cSBarry Smith                                         0,
3531d519adbfSMatthew Knepley                                 /*104*/ MatSetValuesRow_SeqAIJ,
353299cafbc1SBarry Smith                                         MatRealPart_SeqAIJ,
3533f5edf698SHong Zhang                                         MatImaginaryPart_SeqAIJ,
3534f5edf698SHong Zhang                                         0,
35352bebee5dSHong Zhang                                         0,
3536cbd44569SHong Zhang                                 /*109*/ MatMatSolve_SeqAIJ,
3537985db425SBarry Smith                                         0,
35382af78befSBarry Smith                                         MatGetRowMin_SeqAIJ,
35392af78befSBarry Smith                                         0,
3540599ef60dSHong Zhang                                         MatMissingDiagonal_SeqAIJ,
3541d519adbfSMatthew Knepley                                 /*114*/ 0,
3542599ef60dSHong Zhang                                         0,
35433c2a7987SHong Zhang                                         0,
3544fe97e370SBarry Smith                                         0,
3545fbdbba38SShri Abhyankar                                         0,
3546fbdbba38SShri Abhyankar                                 /*119*/ 0,
3547fbdbba38SShri Abhyankar                                         0,
3548fbdbba38SShri Abhyankar                                         0,
354982d44351SHong Zhang                                         0,
3550b3a44c85SBarry Smith                                         MatGetMultiProcBlock_SeqAIJ,
35510716a85fSBarry Smith                                 /*124*/ MatFindNonzeroRows_SeqAIJ,
3552bbead8a2SBarry Smith                                         MatGetColumnNorms_SeqAIJ,
355337868618SMatthew G Knepley                                         MatInvertBlockDiagonal_SeqAIJ,
355437868618SMatthew G Knepley                                         0,
355537868618SMatthew G Knepley                                         0,
35565df89d91SHong Zhang                                 /*129*/ 0,
355775648e8dSHong Zhang                                         MatTransposeMatMult_SeqAIJ_SeqAIJ,
355875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ,
355975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ,
3560b9af6bddSHong Zhang                                         MatTransposeColoringCreate_SeqAIJ,
3561b9af6bddSHong Zhang                                 /*134*/ MatTransColoringApplySpToDen_SeqAIJ,
35622b8ad9a3SHong Zhang                                         MatTransColoringApplyDenToSp_SeqAIJ,
35632b8ad9a3SHong Zhang                                         MatRARt_SeqAIJ_SeqAIJ,
35642b8ad9a3SHong Zhang                                         MatRARtSymbolic_SeqAIJ_SeqAIJ,
35653964eb88SJed Brown                                         MatRARtNumeric_SeqAIJ_SeqAIJ,
35663964eb88SJed Brown                                  /*139*/0,
35673964eb88SJed Brown                                         0
35689e29f15eSvictorle };
356917ab2063SBarry Smith 
35704a2ae208SSatish Balay #undef __FUNCT__
35714a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
35727087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices)
3573bef8e0ddSBarry Smith {
3574bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
357597f1f81fSBarry Smith   PetscInt   i,nz,n;
3576bef8e0ddSBarry Smith 
3577bef8e0ddSBarry Smith   PetscFunctionBegin;
3578bef8e0ddSBarry Smith   nz = aij->maxnz;
3579d0f46423SBarry Smith   n  = mat->rmap->n;
3580bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
3581bef8e0ddSBarry Smith     aij->j[i] = indices[i];
3582bef8e0ddSBarry Smith   }
3583bef8e0ddSBarry Smith   aij->nz = nz;
3584bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
3585bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
3586bef8e0ddSBarry Smith   }
3587bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3588bef8e0ddSBarry Smith }
3589bef8e0ddSBarry Smith 
35904a2ae208SSatish Balay #undef __FUNCT__
35914a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
3592bef8e0ddSBarry Smith /*@
3593bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
3594bef8e0ddSBarry Smith        in the matrix.
3595bef8e0ddSBarry Smith 
3596bef8e0ddSBarry Smith   Input Parameters:
3597bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
3598bef8e0ddSBarry Smith -  indices - the column indices
3599bef8e0ddSBarry Smith 
360015091d37SBarry Smith   Level: advanced
360115091d37SBarry Smith 
3602bef8e0ddSBarry Smith   Notes:
3603bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
3604bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
3605bef8e0ddSBarry Smith   of the MatSetValues() operation.
3606bef8e0ddSBarry Smith 
3607bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
3608d1be2dadSMatthew Knepley   MatCreateSeqAIJ(), and the columns indices MUST be sorted.
3609bef8e0ddSBarry Smith 
3610bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
3611bef8e0ddSBarry Smith 
3612b9617806SBarry Smith     The indices should start with zero, not one.
3613b9617806SBarry Smith 
3614bef8e0ddSBarry Smith @*/
36157087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices)
3616bef8e0ddSBarry Smith {
36174ac538c5SBarry Smith   PetscErrorCode ierr;
3618bef8e0ddSBarry Smith 
3619bef8e0ddSBarry Smith   PetscFunctionBegin;
36200700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
36214482741eSBarry Smith   PetscValidPointer(indices,2);
36224ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr);
3623bef8e0ddSBarry Smith   PetscFunctionReturn(0);
3624bef8e0ddSBarry Smith }
3625bef8e0ddSBarry Smith 
3626be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
3627be6bf707SBarry Smith 
36284a2ae208SSatish Balay #undef __FUNCT__
36294a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
36307087cfbeSBarry Smith PetscErrorCode  MatStoreValues_SeqAIJ(Mat mat)
3631be6bf707SBarry Smith {
3632be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
36336849ba73SBarry Smith   PetscErrorCode ierr;
3634d0f46423SBarry Smith   size_t         nz = aij->i[mat->rmap->n];
3635be6bf707SBarry Smith 
3636be6bf707SBarry Smith   PetscFunctionBegin;
3637f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3638be6bf707SBarry Smith 
3639be6bf707SBarry Smith   /* allocate space for values if not already there */
3640be6bf707SBarry Smith   if (!aij->saved_values) {
364187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
36423bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr);
3643be6bf707SBarry Smith   }
3644be6bf707SBarry Smith 
3645be6bf707SBarry Smith   /* copy values over */
364687828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3647be6bf707SBarry Smith   PetscFunctionReturn(0);
3648be6bf707SBarry Smith }
3649be6bf707SBarry Smith 
36504a2ae208SSatish Balay #undef __FUNCT__
3651b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
3652be6bf707SBarry Smith /*@
3653be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
3654be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3655be6bf707SBarry Smith        nonlinear portion.
3656be6bf707SBarry Smith 
3657be6bf707SBarry Smith    Collect on Mat
3658be6bf707SBarry Smith 
3659be6bf707SBarry Smith   Input Parameters:
36600e609b76SBarry Smith .  mat - the matrix (currently only AIJ matrices support this option)
3661be6bf707SBarry Smith 
366215091d37SBarry Smith   Level: advanced
366315091d37SBarry Smith 
3664be6bf707SBarry Smith   Common Usage, with SNESSolve():
3665be6bf707SBarry Smith $    Create Jacobian matrix
3666be6bf707SBarry Smith $    Set linear terms into matrix
3667be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
3668be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
3669be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
3670512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3671be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3672be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
3673be6bf707SBarry Smith $    In your Jacobian routine
3674be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
3675be6bf707SBarry Smith $      Set nonlinear terms in matrix
3676be6bf707SBarry Smith 
3677be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
3678be6bf707SBarry Smith $    // build linear portion of Jacobian
3679512a5fc5SBarry Smith $    ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);
3680be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
3681be6bf707SBarry Smith $    loop over nonlinear iterations
3682be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
3683be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
3684be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
3685be6bf707SBarry Smith $       Solve linear system with Jacobian
3686be6bf707SBarry Smith $    endloop
3687be6bf707SBarry Smith 
3688be6bf707SBarry Smith   Notes:
3689be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
3690512a5fc5SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before
3691be6bf707SBarry Smith     calling this routine.
3692be6bf707SBarry Smith 
36930c468ba9SBarry Smith     When this is called multiple times it overwrites the previous set of stored values
36940c468ba9SBarry Smith     and does not allocated additional space.
36950c468ba9SBarry Smith 
3696be6bf707SBarry Smith .seealso: MatRetrieveValues()
3697be6bf707SBarry Smith 
3698be6bf707SBarry Smith @*/
36997087cfbeSBarry Smith PetscErrorCode  MatStoreValues(Mat mat)
3700be6bf707SBarry Smith {
37014ac538c5SBarry Smith   PetscErrorCode ierr;
3702be6bf707SBarry Smith 
3703be6bf707SBarry Smith   PetscFunctionBegin;
37040700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3705e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3706e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
37074ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr);
3708be6bf707SBarry Smith   PetscFunctionReturn(0);
3709be6bf707SBarry Smith }
3710be6bf707SBarry Smith 
37114a2ae208SSatish Balay #undef __FUNCT__
37124a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
37137087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues_SeqAIJ(Mat mat)
3714be6bf707SBarry Smith {
3715be6bf707SBarry Smith   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
37166849ba73SBarry Smith   PetscErrorCode ierr;
3717d0f46423SBarry Smith   PetscInt       nz = aij->i[mat->rmap->n];
3718be6bf707SBarry Smith 
3719be6bf707SBarry Smith   PetscFunctionBegin;
3720f23aa3ddSBarry Smith   if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first");
3721f23aa3ddSBarry Smith   if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first");
3722be6bf707SBarry Smith   /* copy values over */
372387828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
3724be6bf707SBarry Smith   PetscFunctionReturn(0);
3725be6bf707SBarry Smith }
3726be6bf707SBarry Smith 
37274a2ae208SSatish Balay #undef __FUNCT__
37284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
3729be6bf707SBarry Smith /*@
3730be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
3731be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
3732be6bf707SBarry Smith        nonlinear portion.
3733be6bf707SBarry Smith 
3734be6bf707SBarry Smith    Collect on Mat
3735be6bf707SBarry Smith 
3736be6bf707SBarry Smith   Input Parameters:
3737be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
3738be6bf707SBarry Smith 
373915091d37SBarry Smith   Level: advanced
374015091d37SBarry Smith 
3741be6bf707SBarry Smith .seealso: MatStoreValues()
3742be6bf707SBarry Smith 
3743be6bf707SBarry Smith @*/
37447087cfbeSBarry Smith PetscErrorCode  MatRetrieveValues(Mat mat)
3745be6bf707SBarry Smith {
37464ac538c5SBarry Smith   PetscErrorCode ierr;
3747be6bf707SBarry Smith 
3748be6bf707SBarry Smith   PetscFunctionBegin;
37490700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3750e32f2f54SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3751e32f2f54SBarry Smith   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
37524ac538c5SBarry Smith   ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr);
3753be6bf707SBarry Smith   PetscFunctionReturn(0);
3754be6bf707SBarry Smith }
3755be6bf707SBarry Smith 
3756f83d6046SBarry Smith 
3757be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
37584a2ae208SSatish Balay #undef __FUNCT__
37594a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
376017ab2063SBarry Smith /*@C
3761682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
37620d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
37636e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
376451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
37652bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
376617ab2063SBarry Smith 
3767db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
3768db81eaa0SLois Curfman McInnes 
376917ab2063SBarry Smith    Input Parameters:
3770db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
377117ab2063SBarry Smith .  m - number of rows
377217ab2063SBarry Smith .  n - number of columns
377317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
377451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
37750298fd71SBarry Smith          (possibly different for each row) or NULL
377617ab2063SBarry Smith 
377717ab2063SBarry Smith    Output Parameter:
3778416022c9SBarry Smith .  A - the matrix
377917ab2063SBarry Smith 
3780175b88e8SBarry Smith    It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(),
3781ae1d86c5SBarry Smith    MatXXXXSetPreallocation() paradgm instead of this routine directly.
3782175b88e8SBarry Smith    [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation]
3783175b88e8SBarry Smith 
3784b259b22eSLois Curfman McInnes    Notes:
378549a6f317SBarry Smith    If nnz is given then nz is ignored
378649a6f317SBarry Smith 
378717ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
378817ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
37890002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
379044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
379117ab2063SBarry Smith 
379217ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
37930298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
37943d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
37956da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
379617ab2063SBarry Smith 
3797682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
37984fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
3799682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
38006c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
38016c7ebb05SLois Curfman McInnes 
38026c7ebb05SLois Curfman McInnes    Options Database Keys:
3803698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
38049db58ca8SBarry Smith -  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
380517ab2063SBarry Smith 
3806027ccd11SLois Curfman McInnes    Level: intermediate
3807027ccd11SLois Curfman McInnes 
380869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
380936db0b34SBarry Smith 
381017ab2063SBarry Smith @*/
38117087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
381217ab2063SBarry Smith {
3813dfbe8321SBarry Smith   PetscErrorCode ierr;
38146945ee14SBarry Smith 
38153a40ed3dSBarry Smith   PetscFunctionBegin;
3816f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3817117016b1SBarry Smith   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3818c4752a88SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
3819d28bb7d2SJed Brown   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3820273d9f13SBarry Smith   PetscFunctionReturn(0);
3821273d9f13SBarry Smith }
3822273d9f13SBarry Smith 
38234a2ae208SSatish Balay #undef __FUNCT__
38244a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
3825273d9f13SBarry Smith /*@C
3826273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
3827273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
3828273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
3829273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
3830273d9f13SBarry Smith 
3831273d9f13SBarry Smith    Collective on MPI_Comm
3832273d9f13SBarry Smith 
3833273d9f13SBarry Smith    Input Parameters:
3834117016b1SBarry Smith +  B - The matrix-free
3835273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
3836273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
38370298fd71SBarry Smith          (possibly different for each row) or NULL
3838273d9f13SBarry Smith 
3839273d9f13SBarry Smith    Notes:
384049a6f317SBarry Smith      If nnz is given then nz is ignored
384149a6f317SBarry Smith 
3842273d9f13SBarry Smith     The AIJ format (also called the Yale sparse matrix format or
3843273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
3844273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
3845273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
3846273d9f13SBarry Smith 
3847273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
38480298fd71SBarry Smith    Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory
3849273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
3850273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
3851273d9f13SBarry Smith 
3852aa95bbe8SBarry Smith    You can call MatGetInfo() to get information on how effective the preallocation was;
3853aa95bbe8SBarry Smith    for example the fields mallocs,nz_allocated,nz_used,nz_unneeded;
3854aa95bbe8SBarry Smith    You can also run with the option -info and look for messages with the string
3855aa95bbe8SBarry Smith    malloc in them to see if additional memory allocation was needed.
3856aa95bbe8SBarry Smith 
3857a96a251dSBarry Smith    Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix
3858a96a251dSBarry Smith    entries or columns indices
3859a96a251dSBarry Smith 
3860273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
3861273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
3862273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
3863273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
3864273d9f13SBarry Smith 
3865273d9f13SBarry Smith    Options Database Keys:
3866698d4c6aSKris Buschelman +  -mat_no_inode  - Do not use inodes
3867698d4c6aSKris Buschelman .  -mat_inode_limit <limit> - Sets inode limit (max limit=5)
3868273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
3869273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
3870273d9f13SBarry Smith         the user still MUST index entries starting at 0!
3871273d9f13SBarry Smith 
3872273d9f13SBarry Smith    Level: intermediate
3873273d9f13SBarry Smith 
387469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo()
3875273d9f13SBarry Smith 
3876273d9f13SBarry Smith @*/
38777087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[])
3878273d9f13SBarry Smith {
38794ac538c5SBarry Smith   PetscErrorCode ierr;
3880a23d5eceSKris Buschelman 
3881a23d5eceSKris Buschelman   PetscFunctionBegin;
38826ba663aaSJed Brown   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
38836ba663aaSJed Brown   PetscValidType(B,1);
38844ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr);
3885a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3886a23d5eceSKris Buschelman }
3887a23d5eceSKris Buschelman 
3888a23d5eceSKris Buschelman #undef __FUNCT__
3889a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ"
38907087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz)
3891a23d5eceSKris Buschelman {
3892273d9f13SBarry Smith   Mat_SeqAIJ     *b;
38932576faa2SJed Brown   PetscBool      skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE;
38946849ba73SBarry Smith   PetscErrorCode ierr;
389597f1f81fSBarry Smith   PetscInt       i;
3896273d9f13SBarry Smith 
3897273d9f13SBarry Smith   PetscFunctionBegin;
38982576faa2SJed Brown   if (nz >= 0 || nnz) realalloc = PETSC_TRUE;
3899a96a251dSBarry Smith   if (nz == MAT_SKIP_ALLOCATION) {
3900c461c341SBarry Smith     skipallocation = PETSC_TRUE;
3901c461c341SBarry Smith     nz             = 0;
3902c461c341SBarry Smith   }
3903c461c341SBarry Smith 
390426283091SBarry Smith   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
390526283091SBarry Smith   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
3906899cda47SBarry Smith 
3907435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
3908e32f2f54SBarry Smith   if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
3909b73539f3SBarry Smith   if (nnz) {
3910d0f46423SBarry Smith     for (i=0; i<B->rmap->n; i++) {
3911e32f2f54SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
3912e32f2f54SBarry Smith       if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap->n);
3913b73539f3SBarry Smith     }
3914b73539f3SBarry Smith   }
3915b73539f3SBarry Smith 
3916273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
39172205254eSKarl Rupp 
3918273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
3919273d9f13SBarry Smith 
3920ab93d7beSBarry Smith   if (!skipallocation) {
39212ee49352SLisandro Dalcin     if (!b->imax) {
3922d0f46423SBarry Smith       ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr);
39233bb1ff40SBarry Smith       ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);
39242ee49352SLisandro Dalcin     }
3925273d9f13SBarry Smith     if (!nnz) {
3926435da068SBarry Smith       if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
3927c62bd62aSJed Brown       else if (nz < 0) nz = 1;
3928d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) b->imax[i] = nz;
3929d0f46423SBarry Smith       nz = nz*B->rmap->n;
3930273d9f13SBarry Smith     } else {
3931273d9f13SBarry Smith       nz = 0;
3932d0f46423SBarry Smith       for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
3933273d9f13SBarry Smith     }
3934ab93d7beSBarry Smith     /* b->ilen will count nonzeros in each row so far. */
39352205254eSKarl Rupp     for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0;
3936ab93d7beSBarry Smith 
3937273d9f13SBarry Smith     /* allocate the matrix space */
39382ee49352SLisandro Dalcin     ierr    = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr);
3939d0f46423SBarry Smith     ierr    = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr);
39403bb1ff40SBarry Smith     ierr    = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr);
3941bfeeae90SHong Zhang     b->i[0] = 0;
3942d0f46423SBarry Smith     for (i=1; i<B->rmap->n+1; i++) {
39435da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
39445da197adSKris Buschelman     }
3945273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
3946e6b907acSBarry Smith     b->free_a       = PETSC_TRUE;
3947e6b907acSBarry Smith     b->free_ij      = PETSC_TRUE;
3948b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE)
3949b31eba2aSShri Abhyankar     ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr);
3950b31eba2aSShri Abhyankar #endif
3951c461c341SBarry Smith   } else {
3952e6b907acSBarry Smith     b->free_a  = PETSC_FALSE;
3953e6b907acSBarry Smith     b->free_ij = PETSC_FALSE;
3954c461c341SBarry Smith   }
3955273d9f13SBarry Smith 
3956273d9f13SBarry Smith   b->nz               = 0;
3957273d9f13SBarry Smith   b->maxnz            = nz;
3958273d9f13SBarry Smith   B->info.nz_unneeded = (double)b->maxnz;
39592205254eSKarl Rupp   if (realalloc) {
39602205254eSKarl Rupp     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
39612205254eSKarl Rupp   }
3962273d9f13SBarry Smith   PetscFunctionReturn(0);
3963273d9f13SBarry Smith }
3964273d9f13SBarry Smith 
3965a1661176SMatthew Knepley #undef  __FUNCT__
3966a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR"
396758d36128SBarry Smith /*@
3968a1661176SMatthew Knepley    MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format.
3969a1661176SMatthew Knepley 
3970a1661176SMatthew Knepley    Input Parameters:
3971a1661176SMatthew Knepley +  B - the matrix
3972a1661176SMatthew Knepley .  i - the indices into j for the start of each row (starts with zero)
3973a1661176SMatthew Knepley .  j - the column indices for each row (starts with zero) these must be sorted for each row
3974a1661176SMatthew Knepley -  v - optional values in the matrix
3975a1661176SMatthew Knepley 
3976a1661176SMatthew Knepley    Level: developer
3977a1661176SMatthew Knepley 
397858d36128SBarry Smith    The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays()
397958d36128SBarry Smith 
3980a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential
3981a1661176SMatthew Knepley 
3982a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ
3983a1661176SMatthew Knepley @*/
3984a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[])
3985a1661176SMatthew Knepley {
3986a1661176SMatthew Knepley   PetscErrorCode ierr;
3987a1661176SMatthew Knepley 
3988a1661176SMatthew Knepley   PetscFunctionBegin;
39890700a824SBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
39906ba663aaSJed Brown   PetscValidType(B,1);
39914ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr);
3992a1661176SMatthew Knepley   PetscFunctionReturn(0);
3993a1661176SMatthew Knepley }
3994a1661176SMatthew Knepley 
3995a1661176SMatthew Knepley #undef  __FUNCT__
3996a1661176SMatthew Knepley #define __FUNCT__  "MatSeqAIJSetPreallocationCSR_SeqAIJ"
39977087cfbeSBarry Smith PetscErrorCode  MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[])
3998a1661176SMatthew Knepley {
3999a1661176SMatthew Knepley   PetscInt       i;
4000a1661176SMatthew Knepley   PetscInt       m,n;
4001a1661176SMatthew Knepley   PetscInt       nz;
4002a1661176SMatthew Knepley   PetscInt       *nnz, nz_max = 0;
4003a1661176SMatthew Knepley   PetscScalar    *values;
4004a1661176SMatthew Knepley   PetscErrorCode ierr;
4005a1661176SMatthew Knepley 
4006a1661176SMatthew Knepley   PetscFunctionBegin;
400765e19b50SBarry Smith   if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]);
4008779a8d59SSatish Balay 
4009779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
4010779a8d59SSatish Balay   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
4011779a8d59SSatish Balay 
4012779a8d59SSatish Balay   ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr);
4013a1661176SMatthew Knepley   ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr);
4014a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
4015b7940d39SSatish Balay     nz     = Ii[i+1]- Ii[i];
4016a1661176SMatthew Knepley     nz_max = PetscMax(nz_max, nz);
401765e19b50SBarry Smith     if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz);
4018a1661176SMatthew Knepley     nnz[i] = nz;
4019a1661176SMatthew Knepley   }
4020a1661176SMatthew Knepley   ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr);
4021a1661176SMatthew Knepley   ierr = PetscFree(nnz);CHKERRQ(ierr);
4022a1661176SMatthew Knepley 
4023a1661176SMatthew Knepley   if (v) {
4024a1661176SMatthew Knepley     values = (PetscScalar*) v;
4025a1661176SMatthew Knepley   } else {
40260e83c824SBarry Smith     ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr);
4027a1661176SMatthew Knepley     ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr);
4028a1661176SMatthew Knepley   }
4029a1661176SMatthew Knepley 
4030a1661176SMatthew Knepley   for (i = 0; i < m; i++) {
4031b7940d39SSatish Balay     nz   = Ii[i+1] - Ii[i];
4032b7940d39SSatish Balay     ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr);
4033a1661176SMatthew Knepley   }
4034a1661176SMatthew Knepley 
4035a1661176SMatthew Knepley   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4036a1661176SMatthew Knepley   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4037a1661176SMatthew Knepley 
4038a1661176SMatthew Knepley   if (!v) {
4039a1661176SMatthew Knepley     ierr = PetscFree(values);CHKERRQ(ierr);
4040a1661176SMatthew Knepley   }
40417827cd58SJed Brown   ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
4042a1661176SMatthew Knepley   PetscFunctionReturn(0);
4043a1661176SMatthew Knepley }
4044a1661176SMatthew Knepley 
4045c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h>
404606873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h>
4047170fe5c8SBarry Smith 
4048170fe5c8SBarry Smith #undef __FUNCT__
4049170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ"
4050170fe5c8SBarry Smith /*
4051170fe5c8SBarry Smith     Computes (B'*A')' since computing B*A directly is untenable
4052170fe5c8SBarry Smith 
4053170fe5c8SBarry Smith                n                       p                          p
4054170fe5c8SBarry Smith         (              )       (              )         (                  )
4055170fe5c8SBarry Smith       m (      A       )  *  n (       B      )   =   m (         C        )
4056170fe5c8SBarry Smith         (              )       (              )         (                  )
4057170fe5c8SBarry Smith 
4058170fe5c8SBarry Smith */
4059170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C)
4060170fe5c8SBarry Smith {
4061170fe5c8SBarry Smith   PetscErrorCode    ierr;
4062170fe5c8SBarry Smith   Mat_SeqDense      *sub_a = (Mat_SeqDense*)A->data;
4063170fe5c8SBarry Smith   Mat_SeqAIJ        *sub_b = (Mat_SeqAIJ*)B->data;
4064170fe5c8SBarry Smith   Mat_SeqDense      *sub_c = (Mat_SeqDense*)C->data;
40651de00fd4SBarry Smith   PetscInt          i,n,m,q,p;
4066170fe5c8SBarry Smith   const PetscInt    *ii,*idx;
4067170fe5c8SBarry Smith   const PetscScalar *b,*a,*a_q;
4068170fe5c8SBarry Smith   PetscScalar       *c,*c_q;
4069170fe5c8SBarry Smith 
4070170fe5c8SBarry Smith   PetscFunctionBegin;
4071d0f46423SBarry Smith   m    = A->rmap->n;
4072d0f46423SBarry Smith   n    = A->cmap->n;
4073d0f46423SBarry Smith   p    = B->cmap->n;
4074170fe5c8SBarry Smith   a    = sub_a->v;
4075170fe5c8SBarry Smith   b    = sub_b->a;
4076170fe5c8SBarry Smith   c    = sub_c->v;
4077170fe5c8SBarry Smith   ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr);
4078170fe5c8SBarry Smith 
4079170fe5c8SBarry Smith   ii  = sub_b->i;
4080170fe5c8SBarry Smith   idx = sub_b->j;
4081170fe5c8SBarry Smith   for (i=0; i<n; i++) {
4082170fe5c8SBarry Smith     q = ii[i+1] - ii[i];
4083170fe5c8SBarry Smith     while (q-->0) {
4084170fe5c8SBarry Smith       c_q = c + m*(*idx);
4085170fe5c8SBarry Smith       a_q = a + m*i;
4086854c7f52SBarry Smith       PetscKernelAXPY(c_q,*b,a_q,m);
4087170fe5c8SBarry Smith       idx++;
4088170fe5c8SBarry Smith       b++;
4089170fe5c8SBarry Smith     }
4090170fe5c8SBarry Smith   }
4091170fe5c8SBarry Smith   PetscFunctionReturn(0);
4092170fe5c8SBarry Smith }
4093170fe5c8SBarry Smith 
4094170fe5c8SBarry Smith #undef __FUNCT__
4095170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ"
4096170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C)
4097170fe5c8SBarry Smith {
4098170fe5c8SBarry Smith   PetscErrorCode ierr;
4099d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
4100170fe5c8SBarry Smith   Mat            Cmat;
4101170fe5c8SBarry Smith 
4102170fe5c8SBarry Smith   PetscFunctionBegin;
4103e32f2f54SBarry Smith   if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n);
4104ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr);
4105170fe5c8SBarry Smith   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
4106a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr);
4107170fe5c8SBarry Smith   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
41080298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
4109d73949e8SHong Zhang 
4110d73949e8SHong Zhang   Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ;
41112205254eSKarl Rupp 
4112170fe5c8SBarry Smith   *C = Cmat;
4113170fe5c8SBarry Smith   PetscFunctionReturn(0);
4114170fe5c8SBarry Smith }
4115170fe5c8SBarry Smith 
4116170fe5c8SBarry Smith /* ----------------------------------------------------------------*/
4117170fe5c8SBarry Smith #undef __FUNCT__
4118170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ"
4119170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
4120170fe5c8SBarry Smith {
4121170fe5c8SBarry Smith   PetscErrorCode ierr;
4122170fe5c8SBarry Smith 
4123170fe5c8SBarry Smith   PetscFunctionBegin;
4124170fe5c8SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
41253ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
4126170fe5c8SBarry Smith     ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr);
41273ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
4128170fe5c8SBarry Smith   }
41293ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
4130170fe5c8SBarry Smith   ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr);
41313ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
4132170fe5c8SBarry Smith   PetscFunctionReturn(0);
4133170fe5c8SBarry Smith }
4134170fe5c8SBarry Smith 
4135170fe5c8SBarry Smith 
41360bad9183SKris Buschelman /*MC
4137fafad747SKris Buschelman    MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices,
41380bad9183SKris Buschelman    based on compressed sparse row format.
41390bad9183SKris Buschelman 
41400bad9183SKris Buschelman    Options Database Keys:
41410bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions()
41420bad9183SKris Buschelman 
41430bad9183SKris Buschelman   Level: beginner
41440bad9183SKris Buschelman 
4145f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType
41460bad9183SKris Buschelman M*/
41470bad9183SKris Buschelman 
4148ccd284c7SBarry Smith /*MC
4149ccd284c7SBarry Smith    MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
4150ccd284c7SBarry Smith 
4151ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
4152ccd284c7SBarry Smith    and MATMPIAIJ otherwise.  As a result, for single process communicators,
4153ccd284c7SBarry Smith   MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
4154ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
4155ccd284c7SBarry Smith   the above preallocation routines for simplicity.
4156ccd284c7SBarry Smith 
4157ccd284c7SBarry Smith    Options Database Keys:
4158ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
4159ccd284c7SBarry Smith 
4160ccd284c7SBarry Smith   Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when
4161ccd284c7SBarry Smith    enough exist.
4162ccd284c7SBarry Smith 
4163ccd284c7SBarry Smith   Level: beginner
4164ccd284c7SBarry Smith 
4165ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ
4166ccd284c7SBarry Smith M*/
4167ccd284c7SBarry Smith 
4168ccd284c7SBarry Smith /*MC
4169ccd284c7SBarry Smith    MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices.
4170ccd284c7SBarry Smith 
4171ccd284c7SBarry Smith    This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator,
4172ccd284c7SBarry Smith    and MATMPIAIJCRL otherwise.  As a result, for single process communicators,
4173ccd284c7SBarry Smith    MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported
4174ccd284c7SBarry Smith   for communicators controlling multiple processes.  It is recommended that you call both of
4175ccd284c7SBarry Smith   the above preallocation routines for simplicity.
4176ccd284c7SBarry Smith 
4177ccd284c7SBarry Smith    Options Database Keys:
4178ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions()
4179ccd284c7SBarry Smith 
4180ccd284c7SBarry Smith   Level: beginner
4181ccd284c7SBarry Smith 
4182ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL
4183ccd284c7SBarry Smith M*/
4184ccd284c7SBarry Smith 
4185b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
41868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*);
4187b5e56a35SBarry Smith #endif
4188ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
41898cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*);
4190af1023dbSSatish Balay #endif
41918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*);
41928cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*);
41938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*);
41947087cfbeSBarry Smith extern PetscErrorCode  MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*);
4195611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
41968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
4197611f576cSBarry Smith #endif
4198611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
41998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*);
4200611f576cSBarry Smith #endif
4201f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
42028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*);
4203f3c0ef26SHong Zhang #endif
4204eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
42058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*);
4206eb3b5408SSatish Balay #endif
4207586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
42088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*);
4209586621ddSJed Brown #endif
4210719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
42118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*);
4212719d5645SBarry Smith #endif
4213b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
42148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*);
42157087cfbeSBarry Smith extern PetscErrorCode  MatlabEnginePut_SeqAIJ(PetscObject,void*);
42167087cfbeSBarry Smith extern PetscErrorCode  MatlabEngineGet_SeqAIJ(PetscObject,void*);
4217b3866ffcSBarry Smith #endif
421817f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
42198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*);
422017f1a0eaSHong Zhang #endif
422117667f90SBarry Smith 
4222c0c8ee5eSDmitry Karpeev 
42238c778c55SBarry Smith #undef __FUNCT__
42248c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray"
42258c778c55SBarry Smith /*@C
42268c778c55SBarry Smith    MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored
42278c778c55SBarry Smith 
42288c778c55SBarry Smith    Not Collective
42298c778c55SBarry Smith 
42308c778c55SBarry Smith    Input Parameter:
42318c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
42328c778c55SBarry Smith 
42338c778c55SBarry Smith    Output Parameter:
42348c778c55SBarry Smith .   array - pointer to the data
42358c778c55SBarry Smith 
42368c778c55SBarry Smith    Level: intermediate
42378c778c55SBarry Smith 
4238774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90()
42398c778c55SBarry Smith @*/
42408c778c55SBarry Smith PetscErrorCode  MatSeqAIJGetArray(Mat A,PetscScalar **array)
42418c778c55SBarry Smith {
42428c778c55SBarry Smith   PetscErrorCode ierr;
42438c778c55SBarry Smith 
42448c778c55SBarry Smith   PetscFunctionBegin;
42458c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
42468c778c55SBarry Smith   PetscFunctionReturn(0);
42478c778c55SBarry Smith }
42488c778c55SBarry Smith 
42498c778c55SBarry Smith #undef __FUNCT__
42508c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray"
42518c778c55SBarry Smith /*@C
42528c778c55SBarry Smith    MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray()
42538c778c55SBarry Smith 
42548c778c55SBarry Smith    Not Collective
42558c778c55SBarry Smith 
42568c778c55SBarry Smith    Input Parameters:
42578c778c55SBarry Smith .  mat - a MATSEQDENSE matrix
42588c778c55SBarry Smith .  array - pointer to the data
42598c778c55SBarry Smith 
42608c778c55SBarry Smith    Level: intermediate
42618c778c55SBarry Smith 
4262774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90()
42638c778c55SBarry Smith @*/
42648c778c55SBarry Smith PetscErrorCode  MatSeqAIJRestoreArray(Mat A,PetscScalar **array)
42658c778c55SBarry Smith {
42668c778c55SBarry Smith   PetscErrorCode ierr;
42678c778c55SBarry Smith 
42688c778c55SBarry Smith   PetscFunctionBegin;
42698c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
42708c778c55SBarry Smith   PetscFunctionReturn(0);
42718c778c55SBarry Smith }
42728c778c55SBarry Smith 
42734a2ae208SSatish Balay #undef __FUNCT__
42744a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
42758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B)
4276273d9f13SBarry Smith {
4277273d9f13SBarry Smith   Mat_SeqAIJ     *b;
4278dfbe8321SBarry Smith   PetscErrorCode ierr;
427938baddfdSBarry Smith   PetscMPIInt    size;
4280273d9f13SBarry Smith 
4281273d9f13SBarry Smith   PetscFunctionBegin;
4282ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
4283e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
4284273d9f13SBarry Smith 
428538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr);
42862205254eSKarl Rupp 
4287b0a32e0cSBarry Smith   B->data = (void*)b;
42882205254eSKarl Rupp 
4289549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
42902205254eSKarl Rupp 
4291416022c9SBarry Smith   b->row                = 0;
4292416022c9SBarry Smith   b->col                = 0;
429382bf6240SBarry Smith   b->icol               = 0;
4294b810aeb4SBarry Smith   b->reallocs           = 0;
429536db0b34SBarry Smith   b->ignorezeroentries  = PETSC_FALSE;
4296f1e2ffcdSBarry Smith   b->roworiented        = PETSC_TRUE;
4297416022c9SBarry Smith   b->nonew              = 0;
4298416022c9SBarry Smith   b->diag               = 0;
4299416022c9SBarry Smith   b->solve_work         = 0;
43002a1b7f2aSHong Zhang   B->spptr              = 0;
4301be6bf707SBarry Smith   b->saved_values       = 0;
4302d7f994e1SBarry Smith   b->idiag              = 0;
430371f1c65dSBarry Smith   b->mdiag              = 0;
430471f1c65dSBarry Smith   b->ssor_work          = 0;
430571f1c65dSBarry Smith   b->omega              = 1.0;
430671f1c65dSBarry Smith   b->fshift             = 0.0;
430771f1c65dSBarry Smith   b->idiagvalid         = PETSC_FALSE;
4308bbead8a2SBarry Smith   b->ibdiagvalid        = PETSC_FALSE;
4309a9817697SBarry Smith   b->keepnonzeropattern = PETSC_FALSE;
4310a30b2313SHong Zhang   b->xtoy               = 0;
4311a30b2313SHong Zhang   b->XtoY               = 0;
431288e51ccdSHong Zhang   B->same_nonzero       = PETSC_FALSE;
431317ab2063SBarry Smith 
431435d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
4315bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr);
4316bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr);
43178c778c55SBarry Smith 
4318b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4319bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr);
4320bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
4321bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
4322b3866ffcSBarry Smith #endif
4323b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX)
4324bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr);
4325b5e56a35SBarry Smith #endif
4326ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
4327bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr);
4328719d5645SBarry Smith #endif
4329611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU)
4330bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr);
4331611f576cSBarry Smith #endif
4332f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST)
4333bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr);
4334f3c0ef26SHong Zhang #endif
4335611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS)
4336bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr);
4337611f576cSBarry Smith #endif
4338eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK)
4339bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr);
4340eb3b5408SSatish Balay #endif
4341586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD)
4342bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr);
4343586621ddSJed Brown #endif
4344719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL)
4345bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr);
4346719d5645SBarry Smith #endif
434717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE)
4348bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr);
434917f1a0eaSHong Zhang #endif
435017f1a0eaSHong Zhang 
4351bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr);
4352bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr);
4353bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr);
4354bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
4355bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr);
4356bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
4357bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr);
4358bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr);
4359bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr);
4360bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr);
4361bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4362bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr);
4363bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr);
4364bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr);
4365bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr);
4366bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
4367bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
4368bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
43694108e4d5SBarry Smith   ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr);
437017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
43713a40ed3dSBarry Smith   PetscFunctionReturn(0);
437217ab2063SBarry Smith }
437317ab2063SBarry Smith 
43744a2ae208SSatish Balay #undef __FUNCT__
4375b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ"
4376b24902e0SBarry Smith /*
4377b24902e0SBarry Smith     Given a matrix generated with MatGetFactor() duplicates all the information in A into B
4378b24902e0SBarry Smith */
4379ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace)
438017ab2063SBarry Smith {
4381416022c9SBarry Smith   Mat_SeqAIJ     *c,*a = (Mat_SeqAIJ*)A->data;
43826849ba73SBarry Smith   PetscErrorCode ierr;
4383d0f46423SBarry Smith   PetscInt       i,m = A->rmap->n;
438417ab2063SBarry Smith 
43853a40ed3dSBarry Smith   PetscFunctionBegin;
4386273d9f13SBarry Smith   c = (Mat_SeqAIJ*)C->data;
4387273d9f13SBarry Smith 
4388d5f3da31SBarry Smith   C->factortype = A->factortype;
4389416022c9SBarry Smith   c->row        = 0;
4390416022c9SBarry Smith   c->col        = 0;
439182bf6240SBarry Smith   c->icol       = 0;
43926ad4291fSHong Zhang   c->reallocs   = 0;
439317ab2063SBarry Smith 
43946ad4291fSHong Zhang   C->assembled = PETSC_TRUE;
439517ab2063SBarry Smith 
4396aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr);
4397aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr);
4398eec197d1SBarry Smith 
439933b91e9fSSatish Balay   ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr);
44003bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr);
440117ab2063SBarry Smith   for (i=0; i<m; i++) {
4402416022c9SBarry Smith     c->imax[i] = a->imax[i];
4403416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
440417ab2063SBarry Smith   }
440517ab2063SBarry Smith 
440617ab2063SBarry Smith   /* allocate the matrix space */
4407f77e22a1SHong Zhang   if (mallocmatspace) {
4408a96a251dSBarry Smith     ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr);
44093bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
44102205254eSKarl Rupp 
4411f1e2ffcdSBarry Smith     c->singlemalloc = PETSC_TRUE;
44122205254eSKarl Rupp 
441397f1f81fSBarry Smith     ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
441417ab2063SBarry Smith     if (m > 0) {
441597f1f81fSBarry Smith       ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr);
4416be6bf707SBarry Smith       if (cpvalues == MAT_COPY_VALUES) {
4417bfeeae90SHong Zhang         ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
4418be6bf707SBarry Smith       } else {
4419bfeeae90SHong Zhang         ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr);
442017ab2063SBarry Smith       }
442108480c60SBarry Smith     }
4422f77e22a1SHong Zhang   }
442317ab2063SBarry Smith 
44246ad4291fSHong Zhang   c->ignorezeroentries = a->ignorezeroentries;
4425416022c9SBarry Smith   c->roworiented       = a->roworiented;
4426416022c9SBarry Smith   c->nonew             = a->nonew;
4427416022c9SBarry Smith   if (a->diag) {
442897f1f81fSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr);
44293bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr);
443017ab2063SBarry Smith     for (i=0; i<m; i++) {
4431416022c9SBarry Smith       c->diag[i] = a->diag[i];
443217ab2063SBarry Smith     }
44333a40ed3dSBarry Smith   } else c->diag = 0;
44342205254eSKarl Rupp 
44356ad4291fSHong Zhang   c->solve_work         = 0;
44366ad4291fSHong Zhang   c->saved_values       = 0;
44376ad4291fSHong Zhang   c->idiag              = 0;
443871f1c65dSBarry Smith   c->ssor_work          = 0;
4439a9817697SBarry Smith   c->keepnonzeropattern = a->keepnonzeropattern;
4440e6b907acSBarry Smith   c->free_a             = PETSC_TRUE;
4441e6b907acSBarry Smith   c->free_ij            = PETSC_TRUE;
44426ad4291fSHong Zhang   c->xtoy               = 0;
44436ad4291fSHong Zhang   c->XtoY               = 0;
44446ad4291fSHong Zhang 
4445893ad86cSHong Zhang   c->rmax         = a->rmax;
4446416022c9SBarry Smith   c->nz           = a->nz;
44478ed568f8SMatthew G Knepley   c->maxnz        = a->nz;       /* Since we allocate exactly the right amount */
4448273d9f13SBarry Smith   C->preallocated = PETSC_TRUE;
4449754ec7b1SSatish Balay 
44506ad4291fSHong Zhang   c->compressedrow.use   = a->compressedrow.use;
44516ad4291fSHong Zhang   c->compressedrow.nrows = a->compressedrow.nrows;
4452cd6b891eSBarry Smith   c->compressedrow.check = a->compressedrow.check;
4453cd6b891eSBarry Smith   if (a->compressedrow.use) {
44546ad4291fSHong Zhang     i    = a->compressedrow.nrows;
44550e83c824SBarry Smith     ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr);
44566ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr);
44576ad4291fSHong Zhang     ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr);
445827ea64f8SHong Zhang   } else {
445927ea64f8SHong Zhang     c->compressedrow.use    = PETSC_FALSE;
44600298fd71SBarry Smith     c->compressedrow.i      = NULL;
44610298fd71SBarry Smith     c->compressedrow.rindex = NULL;
44626ad4291fSHong Zhang   }
446388e51ccdSHong Zhang   C->same_nonzero = A->same_nonzero;
44644846f1f5SKris Buschelman 
44652205254eSKarl Rupp   ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr);
4466140e18c1SBarry Smith   ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr);
44673a40ed3dSBarry Smith   PetscFunctionReturn(0);
446817ab2063SBarry Smith }
446917ab2063SBarry Smith 
44704a2ae208SSatish Balay #undef __FUNCT__
4471b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ"
4472b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
4473b24902e0SBarry Smith {
4474b24902e0SBarry Smith   PetscErrorCode ierr;
4475b24902e0SBarry Smith 
4476b24902e0SBarry Smith   PetscFunctionBegin;
4477ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr);
44784b6263acSBarry Smith   ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4479a2f3521dSMark F. Adams   ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr);
4480a54f2f98SBarry Smith   ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr);
4481f77e22a1SHong Zhang   ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr);
4482b24902e0SBarry Smith   PetscFunctionReturn(0);
4483b24902e0SBarry Smith }
4484b24902e0SBarry Smith 
4485b24902e0SBarry Smith #undef __FUNCT__
44864a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
4487112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer)
4488fbdbba38SShri Abhyankar {
4489fbdbba38SShri Abhyankar   Mat_SeqAIJ     *a;
4490fbdbba38SShri Abhyankar   PetscErrorCode ierr;
4491fbdbba38SShri Abhyankar   PetscInt       i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols;
4492fbdbba38SShri Abhyankar   int            fd;
4493fbdbba38SShri Abhyankar   PetscMPIInt    size;
4494fbdbba38SShri Abhyankar   MPI_Comm       comm;
4495bbead8a2SBarry Smith   PetscInt       bs = 1;
4496fbdbba38SShri Abhyankar 
4497fbdbba38SShri Abhyankar   PetscFunctionBegin;
4498fbdbba38SShri Abhyankar   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
4499fbdbba38SShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4500fbdbba38SShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor");
4501bbead8a2SBarry Smith 
45020298fd71SBarry Smith   ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr);
45030298fd71SBarry Smith   ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr);
4504bbead8a2SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
45051814747fSJed Brown   if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);}
4506bbead8a2SBarry Smith 
4507fbdbba38SShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4508fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
4509fbdbba38SShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
4510fbdbba38SShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
4511fbdbba38SShri Abhyankar 
4512bbead8a2SBarry Smith   if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
4513fbdbba38SShri Abhyankar 
4514fbdbba38SShri Abhyankar   /* read in row lengths */
4515fbdbba38SShri Abhyankar   ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
4516fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
4517fbdbba38SShri Abhyankar 
4518fbdbba38SShri Abhyankar   /* check if sum of rowlengths is same as nz */
4519fbdbba38SShri Abhyankar   for (i=0,sum=0; i< M; i++) sum +=rowlengths[i];
4520fbdbba38SShri Abhyankar   if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum);
4521fbdbba38SShri Abhyankar 
4522fbdbba38SShri Abhyankar   /* set global size if not set already*/
4523f501eaabSShri Abhyankar   if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) {
4524fbdbba38SShri Abhyankar     ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
4525aabbc4fbSShri Abhyankar   } else {
4526fbdbba38SShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
4527fbdbba38SShri Abhyankar     ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr);
45284c5b953cSHong Zhang     if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */
45294c5b953cSHong Zhang       ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr);
45304c5b953cSHong Zhang     }
4531f501eaabSShri Abhyankar     if (M != rows ||  N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
4532aabbc4fbSShri Abhyankar   }
4533fbdbba38SShri Abhyankar   ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr);
4534fbdbba38SShri Abhyankar   a    = (Mat_SeqAIJ*)newMat->data;
4535fbdbba38SShri Abhyankar 
4536fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
4537fbdbba38SShri Abhyankar 
4538fbdbba38SShri Abhyankar   /* read in nonzero values */
4539fbdbba38SShri Abhyankar   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
4540fbdbba38SShri Abhyankar 
4541fbdbba38SShri Abhyankar   /* set matrix "i" values */
4542fbdbba38SShri Abhyankar   a->i[0] = 0;
4543fbdbba38SShri Abhyankar   for (i=1; i<= M; i++) {
4544fbdbba38SShri Abhyankar     a->i[i]      = a->i[i-1] + rowlengths[i-1];
4545fbdbba38SShri Abhyankar     a->ilen[i-1] = rowlengths[i-1];
4546fbdbba38SShri Abhyankar   }
4547fbdbba38SShri Abhyankar   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
4548fbdbba38SShri Abhyankar 
4549fbdbba38SShri Abhyankar   ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4550fbdbba38SShri Abhyankar   ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4551fbdbba38SShri Abhyankar   PetscFunctionReturn(0);
4552fbdbba38SShri Abhyankar }
4553fbdbba38SShri Abhyankar 
4554fbdbba38SShri Abhyankar #undef __FUNCT__
4555b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
4556ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg)
45577264ac53SSatish Balay {
45587264ac53SSatish Balay   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data;
4559dfbe8321SBarry Smith   PetscErrorCode ierr;
4560eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4561eeffb40dSHong Zhang   PetscInt k;
4562eeffb40dSHong Zhang #endif
45637264ac53SSatish Balay 
45643a40ed3dSBarry Smith   PetscFunctionBegin;
4565bfeeae90SHong Zhang   /* If the  matrix dimensions are not equal,or no of nonzeros */
4566d0f46423SBarry Smith   if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) {
4567ca44d042SBarry Smith     *flg = PETSC_FALSE;
4568ca44d042SBarry Smith     PetscFunctionReturn(0);
4569bcd2baecSBarry Smith   }
45707264ac53SSatish Balay 
45717264ac53SSatish Balay   /* if the a->i are the same */
4572d0f46423SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4573abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
45747264ac53SSatish Balay 
45757264ac53SSatish Balay   /* if a->j are the same */
457697f1f81fSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr);
4577abc0a331SBarry Smith   if (!*flg) PetscFunctionReturn(0);
4578bcd2baecSBarry Smith 
4579bcd2baecSBarry Smith   /* if a->a are the same */
4580eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX)
4581eeffb40dSHong Zhang   for (k=0; k<a->nz; k++) {
4582eeffb40dSHong Zhang     if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) {
4583eeffb40dSHong Zhang       *flg = PETSC_FALSE;
45843a40ed3dSBarry Smith       PetscFunctionReturn(0);
4585eeffb40dSHong Zhang     }
4586eeffb40dSHong Zhang   }
4587eeffb40dSHong Zhang #else
4588eeffb40dSHong Zhang   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
4589eeffb40dSHong Zhang #endif
4590eeffb40dSHong Zhang   PetscFunctionReturn(0);
45917264ac53SSatish Balay }
459236db0b34SBarry Smith 
45934a2ae208SSatish Balay #undef __FUNCT__
45944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
459505869f15SSatish Balay /*@
459636db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
459736db0b34SBarry Smith               provided by the user.
459836db0b34SBarry Smith 
4599c75a6043SHong Zhang       Collective on MPI_Comm
460036db0b34SBarry Smith 
460136db0b34SBarry Smith    Input Parameters:
460236db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
460336db0b34SBarry Smith .   m - number of rows
460436db0b34SBarry Smith .   n - number of columns
460536db0b34SBarry Smith .   i - row indices
460636db0b34SBarry Smith .   j - column indices
460736db0b34SBarry Smith -   a - matrix values
460836db0b34SBarry Smith 
460936db0b34SBarry Smith    Output Parameter:
461036db0b34SBarry Smith .   mat - the matrix
461136db0b34SBarry Smith 
461236db0b34SBarry Smith    Level: intermediate
461336db0b34SBarry Smith 
461436db0b34SBarry Smith    Notes:
46150551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
4616292fb18eSBarry Smith     once the matrix is destroyed and not before
461736db0b34SBarry Smith 
461836db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
461936db0b34SBarry Smith 
4620bfeeae90SHong Zhang        The i and j indices are 0 based
462136db0b34SBarry Smith 
4622a4552177SSatish Balay        The format which is used for the sparse matrix input, is equivalent to a
4623a4552177SSatish Balay     row-major ordering.. i.e for the following matrix, the input data expected is
4624a4552177SSatish Balay     as shown:
4625a4552177SSatish Balay 
4626a4552177SSatish Balay         1 0 0
4627a4552177SSatish Balay         2 0 3
4628a4552177SSatish Balay         4 5 6
4629a4552177SSatish Balay 
4630a4552177SSatish Balay         i =  {0,1,3,6}  [size = nrow+1  = 3+1]
46319985e31cSBarry Smith         j =  {0,0,2,0,1,2}  [size = nz = 6]; values must be sorted for each row
4632a4552177SSatish Balay         v =  {1,2,3,4,5,6}  [size = nz = 6]
4633a4552177SSatish Balay 
46349985e31cSBarry Smith 
463569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
463636db0b34SBarry Smith 
463736db0b34SBarry Smith @*/
46387087cfbeSBarry Smith PetscErrorCode  MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat)
463936db0b34SBarry Smith {
4640dfbe8321SBarry Smith   PetscErrorCode ierr;
4641cbcfb4deSHong Zhang   PetscInt       ii;
464236db0b34SBarry Smith   Mat_SeqAIJ     *aij;
4643cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG)
4644cbcfb4deSHong Zhang   PetscInt jj;
4645cbcfb4deSHong Zhang #endif
464636db0b34SBarry Smith 
464736db0b34SBarry Smith   PetscFunctionBegin;
4648f23aa3ddSBarry Smith   if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0");
4649f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
4650f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4651a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
4652ab93d7beSBarry Smith   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
4653ab93d7beSBarry Smith   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr);
4654ab93d7beSBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
4655ab93d7beSBarry Smith   ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr);
4656ab93d7beSBarry Smith 
465736db0b34SBarry Smith   aij->i            = i;
465836db0b34SBarry Smith   aij->j            = j;
465936db0b34SBarry Smith   aij->a            = a;
466036db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
466136db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
4662e6b907acSBarry Smith   aij->free_a       = PETSC_FALSE;
4663e6b907acSBarry Smith   aij->free_ij      = PETSC_FALSE;
466436db0b34SBarry Smith 
466536db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
466636db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
46672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
4668e32f2f54SBarry Smith     if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]);
46699985e31cSBarry Smith     for (jj=i[ii]+1; jj<i[ii+1]; jj++) {
4670e32f2f54SBarry Smith       if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii);
4671e32f2f54SBarry Smith       if (j[jj] == j[jj]-1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii);
46729985e31cSBarry Smith     }
467336db0b34SBarry Smith #endif
467436db0b34SBarry Smith   }
46752515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
467636db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
4677e32f2f54SBarry Smith     if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]);
4678e32f2f54SBarry Smith     if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]);
467936db0b34SBarry Smith   }
468036db0b34SBarry Smith #endif
468136db0b34SBarry Smith 
4682b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4683b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
468436db0b34SBarry Smith   PetscFunctionReturn(0);
468536db0b34SBarry Smith }
46868a0b0e6bSVictor Minden #undef __FUNCT__
46878a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple"
468880ef6e79SMatthew G Knepley /*@C
4689d021a1c5SVictor Minden      MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format)
46908a0b0e6bSVictor Minden               provided by the user.
46918a0b0e6bSVictor Minden 
46928a0b0e6bSVictor Minden       Collective on MPI_Comm
46938a0b0e6bSVictor Minden 
46948a0b0e6bSVictor Minden    Input Parameters:
46958a0b0e6bSVictor Minden +   comm - must be an MPI communicator of size 1
46968a0b0e6bSVictor Minden .   m   - number of rows
46978a0b0e6bSVictor Minden .   n   - number of columns
46988a0b0e6bSVictor Minden .   i   - row indices
46998a0b0e6bSVictor Minden .   j   - column indices
47001230e6d1SVictor Minden .   a   - matrix values
47011230e6d1SVictor Minden .   nz  - number of nonzeros
47021230e6d1SVictor Minden -   idx - 0 or 1 based
47038a0b0e6bSVictor Minden 
47048a0b0e6bSVictor Minden    Output Parameter:
47058a0b0e6bSVictor Minden .   mat - the matrix
47068a0b0e6bSVictor Minden 
47078a0b0e6bSVictor Minden    Level: intermediate
47088a0b0e6bSVictor Minden 
47098a0b0e6bSVictor Minden    Notes:
47108a0b0e6bSVictor Minden        The i and j indices are 0 based
47118a0b0e6bSVictor Minden 
47128a0b0e6bSVictor Minden        The format which is used for the sparse matrix input, is equivalent to a
47138a0b0e6bSVictor Minden     row-major ordering.. i.e for the following matrix, the input data expected is
47148a0b0e6bSVictor Minden     as shown:
47158a0b0e6bSVictor Minden 
47168a0b0e6bSVictor Minden         1 0 0
47178a0b0e6bSVictor Minden         2 0 3
47188a0b0e6bSVictor Minden         4 5 6
47198a0b0e6bSVictor Minden 
47208a0b0e6bSVictor Minden         i =  {0,1,1,2,2,2}
47218a0b0e6bSVictor Minden         j =  {0,0,2,0,1,2}
47228a0b0e6bSVictor Minden         v =  {1,2,3,4,5,6}
47238a0b0e6bSVictor Minden 
47248a0b0e6bSVictor Minden 
472569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR()
47268a0b0e6bSVictor Minden 
47278a0b0e6bSVictor Minden @*/
47281230e6d1SVictor Minden PetscErrorCode  MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx)
47298a0b0e6bSVictor Minden {
47308a0b0e6bSVictor Minden   PetscErrorCode ierr;
4731d021a1c5SVictor Minden   PetscInt       ii, *nnz, one = 1,row,col;
47328a0b0e6bSVictor Minden 
47338a0b0e6bSVictor Minden 
47348a0b0e6bSVictor Minden   PetscFunctionBegin;
4735d021a1c5SVictor Minden   ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr);
47361230e6d1SVictor Minden   ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr);
47371230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
47381230e6d1SVictor Minden     nnz[i[ii]] += 1;
47391230e6d1SVictor Minden   }
47408a0b0e6bSVictor Minden   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
47418a0b0e6bSVictor Minden   ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr);
4742a2f3521dSMark F. Adams   /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */
47438a0b0e6bSVictor Minden   ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr);
47441230e6d1SVictor Minden   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr);
47451230e6d1SVictor Minden   for (ii = 0; ii < nz; ii++) {
47461230e6d1SVictor Minden     if (idx) {
47471230e6d1SVictor Minden       row = i[ii] - 1;
47481230e6d1SVictor Minden       col = j[ii] - 1;
47491230e6d1SVictor Minden     } else {
47501230e6d1SVictor Minden       row = i[ii];
47511230e6d1SVictor Minden       col = j[ii];
47528a0b0e6bSVictor Minden     }
47531230e6d1SVictor Minden     ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr);
47548a0b0e6bSVictor Minden   }
47558a0b0e6bSVictor Minden   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
47568a0b0e6bSVictor Minden   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4757d021a1c5SVictor Minden   ierr = PetscFree(nnz);CHKERRQ(ierr);
47588a0b0e6bSVictor Minden   PetscFunctionReturn(0);
47598a0b0e6bSVictor Minden }
476036db0b34SBarry Smith 
4761cc8ba8e1SBarry Smith #undef __FUNCT__
4762ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
4763dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
4764cc8ba8e1SBarry Smith {
4765dfbe8321SBarry Smith   PetscErrorCode ierr;
4766cc8ba8e1SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
476736db0b34SBarry Smith 
4768cc8ba8e1SBarry Smith   PetscFunctionBegin;
47698ee2e534SBarry Smith   if (coloring->ctype == IS_COLORING_GLOBAL) {
4770cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
4771cc8ba8e1SBarry Smith     a->coloring = coloring;
477212c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
477397f1f81fSBarry Smith     PetscInt        i,*larray;
477412c595b3SBarry Smith     ISColoring      ocoloring;
477508b6dcc0SBarry Smith     ISColoringValue *colors;
477612c595b3SBarry Smith 
477712c595b3SBarry Smith     /* set coloring for diagonal portion */
47780e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr);
47792205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) larray[i] = i;
47800298fd71SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr);
47810e83c824SBarry Smith     ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr);
47822205254eSKarl Rupp     for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]];
478312c595b3SBarry Smith     ierr        = PetscFree(larray);CHKERRQ(ierr);
4784d0f46423SBarry Smith     ierr        = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr);
478512c595b3SBarry Smith     a->coloring = ocoloring;
478612c595b3SBarry Smith   }
4787cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4788cc8ba8e1SBarry Smith }
4789cc8ba8e1SBarry Smith 
4790ee4f033dSBarry Smith #undef __FUNCT__
4791ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
479297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues)
4793ee4f033dSBarry Smith {
4794ee4f033dSBarry Smith   Mat_SeqAIJ      *a      = (Mat_SeqAIJ*)A->data;
4795d0f46423SBarry Smith   PetscInt        m       = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j;
479654f21887SBarry Smith   MatScalar       *v      = a->a;
479754f21887SBarry Smith   PetscScalar     *values = (PetscScalar*)advalues;
479808b6dcc0SBarry Smith   ISColoringValue *color;
4799ee4f033dSBarry Smith 
4800ee4f033dSBarry Smith   PetscFunctionBegin;
4801e32f2f54SBarry Smith   if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix");
4802ee4f033dSBarry Smith   color = a->coloring->colors;
4803ee4f033dSBarry Smith   /* loop over rows */
4804ee4f033dSBarry Smith   for (i=0; i<m; i++) {
4805ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
4806ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
48072205254eSKarl Rupp     for (j=0; j<nz; j++) *v++ = values[color[*jj++]];
4808ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
4809cc8ba8e1SBarry Smith   }
4810cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
4811cc8ba8e1SBarry Smith }
481236db0b34SBarry Smith 
4813acf2f550SJed Brown #undef __FUNCT__
4814acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal"
4815acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A)
4816acf2f550SJed Brown {
4817acf2f550SJed Brown   Mat_SeqAIJ     *a=(Mat_SeqAIJ*)A->data;
4818acf2f550SJed Brown   PetscErrorCode ierr;
4819acf2f550SJed Brown 
4820acf2f550SJed Brown   PetscFunctionBegin;
4821acf2f550SJed Brown   a->idiagvalid  = PETSC_FALSE;
4822acf2f550SJed Brown   a->ibdiagvalid = PETSC_FALSE;
48232205254eSKarl Rupp 
4824acf2f550SJed Brown   ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr);
4825acf2f550SJed Brown   PetscFunctionReturn(0);
4826acf2f550SJed Brown }
4827acf2f550SJed Brown 
482881824310SBarry Smith /*
482981824310SBarry Smith     Special version for direct calls from Fortran
483081824310SBarry Smith */
4831b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h>
483281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
483381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ
483481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
483581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij
483681824310SBarry Smith #endif
483781824310SBarry Smith 
483881824310SBarry Smith /* Change these macros so can be used in void function */
483981824310SBarry Smith #undef CHKERRQ
4840ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr)
484181824310SBarry Smith #undef SETERRQ2
4842e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr)
48434994cf47SJed Brown #undef SETERRQ3
48444994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr)
484581824310SBarry Smith 
484681824310SBarry Smith #undef __FUNCT__
484781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_"
48488cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr)
484981824310SBarry Smith {
485081824310SBarry Smith   Mat            A  = *AA;
485181824310SBarry Smith   PetscInt       m  = *mm, n = *nn;
485281824310SBarry Smith   InsertMode     is = *isis;
485381824310SBarry Smith   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
485481824310SBarry Smith   PetscInt       *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N;
485581824310SBarry Smith   PetscInt       *imax,*ai,*ailen;
485681824310SBarry Smith   PetscErrorCode ierr;
485781824310SBarry Smith   PetscInt       *aj,nonew = a->nonew,lastcol = -1;
485854f21887SBarry Smith   MatScalar      *ap,value,*aa;
4859ace3abfcSBarry Smith   PetscBool      ignorezeroentries = a->ignorezeroentries;
4860ace3abfcSBarry Smith   PetscBool      roworiented       = a->roworiented;
486181824310SBarry Smith 
486281824310SBarry Smith   PetscFunctionBegin;
48634994cf47SJed Brown   MatCheckPreallocated(A,1);
486481824310SBarry Smith   imax  = a->imax;
486581824310SBarry Smith   ai    = a->i;
486681824310SBarry Smith   ailen = a->ilen;
486781824310SBarry Smith   aj    = a->j;
486881824310SBarry Smith   aa    = a->a;
486981824310SBarry Smith 
487081824310SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
487181824310SBarry Smith     row = im[k];
487281824310SBarry Smith     if (row < 0) continue;
487381824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4874ce94432eSBarry Smith     if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
487581824310SBarry Smith #endif
487681824310SBarry Smith     rp   = aj + ai[row]; ap = aa + ai[row];
487781824310SBarry Smith     rmax = imax[row]; nrow = ailen[row];
487881824310SBarry Smith     low  = 0;
487981824310SBarry Smith     high = nrow;
488081824310SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
488181824310SBarry Smith       if (in[l] < 0) continue;
488281824310SBarry Smith #if defined(PETSC_USE_DEBUG)
4883ce94432eSBarry Smith       if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
488481824310SBarry Smith #endif
488581824310SBarry Smith       col = in[l];
48862205254eSKarl Rupp       if (roworiented) value = v[l + k*n];
48872205254eSKarl Rupp       else value = v[k + l*m];
48882205254eSKarl Rupp 
488981824310SBarry Smith       if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue;
489081824310SBarry Smith 
48912205254eSKarl Rupp       if (col <= lastcol) low = 0;
48922205254eSKarl Rupp       else high = nrow;
489381824310SBarry Smith       lastcol = col;
489481824310SBarry Smith       while (high-low > 5) {
489581824310SBarry Smith         t = (low+high)/2;
489681824310SBarry Smith         if (rp[t] > col) high = t;
489781824310SBarry Smith         else             low  = t;
489881824310SBarry Smith       }
489981824310SBarry Smith       for (i=low; i<high; i++) {
490081824310SBarry Smith         if (rp[i] > col) break;
490181824310SBarry Smith         if (rp[i] == col) {
490281824310SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
490381824310SBarry Smith           else                  ap[i] = value;
490481824310SBarry Smith           goto noinsert;
490581824310SBarry Smith         }
490681824310SBarry Smith       }
490781824310SBarry Smith       if (value == 0.0 && ignorezeroentries) goto noinsert;
490881824310SBarry Smith       if (nonew == 1) goto noinsert;
4909ce94432eSBarry Smith       if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
4910fef13f97SBarry Smith       MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar);
491181824310SBarry Smith       N = nrow++ - 1; a->nz++; high++;
491281824310SBarry Smith       /* shift up all the later entries in this row */
491381824310SBarry Smith       for (ii=N; ii>=i; ii--) {
491481824310SBarry Smith         rp[ii+1] = rp[ii];
491581824310SBarry Smith         ap[ii+1] = ap[ii];
491681824310SBarry Smith       }
491781824310SBarry Smith       rp[i] = col;
491881824310SBarry Smith       ap[i] = value;
491981824310SBarry Smith noinsert:;
492081824310SBarry Smith       low = i + 1;
492181824310SBarry Smith     }
492281824310SBarry Smith     ailen[row] = nrow;
492381824310SBarry Smith   }
492481824310SBarry Smith   A->same_nonzero = PETSC_FALSE;
492581824310SBarry Smith   PetscFunctionReturnVoid();
492681824310SBarry Smith }
49279f7953f8SBarry Smith 
492862298a1eSBarry Smith 
4929