xref: /petsc/src/mat/impls/aij/mpi/mumps/mumps.c (revision a5e57a0946837d842ba2599fd685e200498f01a9)
11c2a3de1SBarry Smith 
2397b6df1SKris Buschelman /*
3c2b5dc30SHong Zhang     Provides an interface to the MUMPS sparse solver
4397b6df1SKris Buschelman */
551d5961aSHong Zhang 
6c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h> /*I  "petscmat.h"  I*/
7c6db04a5SJed Brown #include <../src/mat/impls/sbaij/mpi/mpisbaij.h>
8397b6df1SKris Buschelman 
9397b6df1SKris Buschelman EXTERN_C_BEGIN
10397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
112907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
122907cef9SHong Zhang #include <cmumps_c.h>
132907cef9SHong Zhang #else
14c6db04a5SJed Brown #include <zmumps_c.h>
152907cef9SHong Zhang #endif
162907cef9SHong Zhang #else
172907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
182907cef9SHong Zhang #include <smumps_c.h>
19397b6df1SKris Buschelman #else
20c6db04a5SJed Brown #include <dmumps_c.h>
21397b6df1SKris Buschelman #endif
222907cef9SHong Zhang #endif
23397b6df1SKris Buschelman EXTERN_C_END
24397b6df1SKris Buschelman #define JOB_INIT -1
253d472b54SHong Zhang #define JOB_FACTSYMBOLIC 1
263d472b54SHong Zhang #define JOB_FACTNUMERIC 2
273d472b54SHong Zhang #define JOB_SOLVE 3
28397b6df1SKris Buschelman #define JOB_END -2
293d472b54SHong Zhang 
302907cef9SHong Zhang /* calls to MUMPS */
312907cef9SHong Zhang #if defined(PETSC_USE_COMPLEX)
322907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
332907cef9SHong Zhang #define PetscMUMPS_c cmumps_c
342907cef9SHong Zhang #else
352907cef9SHong Zhang #define PetscMUMPS_c zmumps_c
362907cef9SHong Zhang #endif
372907cef9SHong Zhang #else
382907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
392907cef9SHong Zhang #define PetscMUMPS_c smumps_c
402907cef9SHong Zhang #else
412907cef9SHong Zhang #define PetscMUMPS_c dmumps_c
422907cef9SHong Zhang #endif
432907cef9SHong Zhang #endif
442907cef9SHong Zhang 
453d472b54SHong Zhang 
46397b6df1SKris Buschelman /* macros s.t. indices match MUMPS documentation */
47397b6df1SKris Buschelman #define ICNTL(I) icntl[(I)-1]
48397b6df1SKris Buschelman #define CNTL(I) cntl[(I)-1]
49397b6df1SKris Buschelman #define INFOG(I) infog[(I)-1]
50a7aca84bSHong Zhang #define INFO(I) info[(I)-1]
51397b6df1SKris Buschelman #define RINFOG(I) rinfog[(I)-1]
52adc1d99fSHong Zhang #define RINFO(I) rinfo[(I)-1]
53397b6df1SKris Buschelman 
54397b6df1SKris Buschelman typedef struct {
55397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
562907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
572907cef9SHong Zhang   CMUMPS_STRUC_C id;
582907cef9SHong Zhang #else
59397b6df1SKris Buschelman   ZMUMPS_STRUC_C id;
602907cef9SHong Zhang #endif
612907cef9SHong Zhang #else
622907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
632907cef9SHong Zhang   SMUMPS_STRUC_C id;
64397b6df1SKris Buschelman #else
65397b6df1SKris Buschelman   DMUMPS_STRUC_C id;
66397b6df1SKris Buschelman #endif
672907cef9SHong Zhang #endif
682907cef9SHong Zhang 
69397b6df1SKris Buschelman   MatStructure   matstruc;
70c1490034SHong Zhang   PetscMPIInt    myid,size;
71*a5e57a09SHong Zhang   PetscInt       *irn,*jcn,nz,sym;
72397b6df1SKris Buschelman   PetscScalar    *val;
73397b6df1SKris Buschelman   MPI_Comm       comm_mumps;
74329ec9b3SHong Zhang   VecScatter     scat_rhs, scat_sol;
7564e6c443SBarry Smith   PetscBool      isAIJ,CleanUpMUMPS;
76329ec9b3SHong Zhang   Vec            b_seq,x_seq;
77*a5e57a09SHong Zhang   PetscInt       ICNTL9_pre; /* check if ICNTL(9) is changed from previous MatSolve */
78bf0cc555SLisandro Dalcin   PetscErrorCode (*Destroy)(Mat);
79bccb9932SShri Abhyankar   PetscErrorCode (*ConvertToTriples)(Mat, int, MatReuse, int*, int**, int**, PetscScalar**);
80f0c56d0fSKris Buschelman } Mat_MUMPS;
81f0c56d0fSKris Buschelman 
8209573ac7SBarry Smith extern PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*);
83b24902e0SBarry Smith 
8467877ebaSShri Abhyankar 
8567877ebaSShri Abhyankar /* MatConvertToTriples_A_B */
8667877ebaSShri Abhyankar /*convert Petsc matrix to triples: row[nz], col[nz], val[nz] */
87397b6df1SKris Buschelman /*
88397b6df1SKris Buschelman   input:
8967877ebaSShri Abhyankar     A       - matrix in aij,baij or sbaij (bs=1) format
90397b6df1SKris Buschelman     shift   - 0: C style output triple; 1: Fortran style output triple.
91bccb9932SShri Abhyankar     reuse   - MAT_INITIAL_MATRIX: spaces are allocated and values are set for the triple
92bccb9932SShri Abhyankar               MAT_REUSE_MATRIX:   only the values in v array are updated
93397b6df1SKris Buschelman   output:
94397b6df1SKris Buschelman     nnz     - dim of r, c, and v (number of local nonzero entries of A)
95397b6df1SKris Buschelman     r, c, v - row and col index, matrix values (matrix triples)
96397b6df1SKris Buschelman  */
9716ebf90aSShri Abhyankar 
9816ebf90aSShri Abhyankar #undef __FUNCT__
9916ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqaij"
100bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
101b24902e0SBarry Smith {
102185f6596SHong Zhang   const PetscInt   *ai,*aj,*ajj,M=A->rmap->n;
10367877ebaSShri Abhyankar   PetscInt         nz,rnz,i,j;
104dfbe8321SBarry Smith   PetscErrorCode   ierr;
105c1490034SHong Zhang   PetscInt         *row,*col;
10616ebf90aSShri Abhyankar   Mat_SeqAIJ       *aa=(Mat_SeqAIJ*)A->data;
107397b6df1SKris Buschelman 
108397b6df1SKris Buschelman   PetscFunctionBegin;
10916ebf90aSShri Abhyankar   *v=aa->a;
110bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
11116ebf90aSShri Abhyankar     nz = aa->nz; ai = aa->i; aj = aa->j;
11216ebf90aSShri Abhyankar     *nnz = nz;
113185f6596SHong Zhang     ierr = PetscMalloc(2*nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
114185f6596SHong Zhang     col  = row + nz;
115185f6596SHong Zhang 
11616ebf90aSShri Abhyankar     nz = 0;
11716ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
11816ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
11967877ebaSShri Abhyankar       ajj = aj + ai[i];
12067877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
12167877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz++] = ajj[j] + shift;
12216ebf90aSShri Abhyankar       }
12316ebf90aSShri Abhyankar     }
12416ebf90aSShri Abhyankar     *r = row; *c = col;
12516ebf90aSShri Abhyankar   }
12616ebf90aSShri Abhyankar   PetscFunctionReturn(0);
12716ebf90aSShri Abhyankar }
128397b6df1SKris Buschelman 
12916ebf90aSShri Abhyankar #undef __FUNCT__
13067877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqbaij_seqaij"
131bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqbaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
13267877ebaSShri Abhyankar {
13367877ebaSShri Abhyankar   Mat_SeqBAIJ        *aa=(Mat_SeqBAIJ*)A->data;
13467877ebaSShri Abhyankar   const PetscInt     *ai,*aj,*ajj,bs=A->rmap->bs,bs2=aa->bs2,M=A->rmap->N/bs;
1350ad0caddSJed Brown   PetscInt           nz,idx=0,rnz,i,j,k,m;
13667877ebaSShri Abhyankar   PetscErrorCode     ierr;
13767877ebaSShri Abhyankar   PetscInt           *row,*col;
13867877ebaSShri Abhyankar 
13967877ebaSShri Abhyankar   PetscFunctionBegin;
140cf3759fdSShri Abhyankar   *v = aa->a;
141bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
142cf3759fdSShri Abhyankar     ai = aa->i; aj = aa->j;
14367877ebaSShri Abhyankar     nz = bs2*aa->nz;
14467877ebaSShri Abhyankar     *nnz = nz;
145185f6596SHong Zhang     ierr = PetscMalloc(2*nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
146185f6596SHong Zhang     col  = row + nz;
147185f6596SHong Zhang 
14867877ebaSShri Abhyankar     for (i=0; i<M; i++) {
14967877ebaSShri Abhyankar       ajj = aj + ai[i];
15067877ebaSShri Abhyankar       rnz = ai[i+1] - ai[i];
15167877ebaSShri Abhyankar       for (k=0; k<rnz; k++) {
15267877ebaSShri Abhyankar 	for (j=0; j<bs; j++) {
15367877ebaSShri Abhyankar 	  for (m=0; m<bs; m++) {
15467877ebaSShri Abhyankar 	    row[idx]     = i*bs + m + shift;
155cf3759fdSShri Abhyankar 	    col[idx++]   = bs*(ajj[k]) + j + shift;
15667877ebaSShri Abhyankar 	  }
15767877ebaSShri Abhyankar 	}
15867877ebaSShri Abhyankar       }
15967877ebaSShri Abhyankar     }
160cf3759fdSShri Abhyankar     *r = row; *c = col;
16167877ebaSShri Abhyankar   }
16267877ebaSShri Abhyankar   PetscFunctionReturn(0);
16367877ebaSShri Abhyankar }
16467877ebaSShri Abhyankar 
16567877ebaSShri Abhyankar #undef __FUNCT__
16616ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqsbaij_seqsbaij"
167bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqsbaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
16816ebf90aSShri Abhyankar {
16967877ebaSShri Abhyankar   const PetscInt   *ai, *aj,*ajj,M=A->rmap->n;
17067877ebaSShri Abhyankar   PetscInt         nz,rnz,i,j;
17116ebf90aSShri Abhyankar   PetscErrorCode   ierr;
17216ebf90aSShri Abhyankar   PetscInt         *row,*col;
17316ebf90aSShri Abhyankar   Mat_SeqSBAIJ     *aa=(Mat_SeqSBAIJ*)A->data;
17416ebf90aSShri Abhyankar 
17516ebf90aSShri Abhyankar   PetscFunctionBegin;
176882afa5aSHong Zhang   *v = aa->a;
177bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
17816ebf90aSShri Abhyankar     nz = aa->nz;ai=aa->i; aj=aa->j;*v=aa->a;
17916ebf90aSShri Abhyankar     *nnz = nz;
180185f6596SHong Zhang     ierr = PetscMalloc(2*nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
181185f6596SHong Zhang     col  = row + nz;
182185f6596SHong Zhang 
18316ebf90aSShri Abhyankar     nz = 0;
18416ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
18516ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
18667877ebaSShri Abhyankar       ajj = aj + ai[i];
18767877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
18867877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz++] = ajj[j] + shift;
18916ebf90aSShri Abhyankar       }
19016ebf90aSShri Abhyankar     }
19116ebf90aSShri Abhyankar     *r = row; *c = col;
19216ebf90aSShri Abhyankar   }
19316ebf90aSShri Abhyankar   PetscFunctionReturn(0);
19416ebf90aSShri Abhyankar }
19516ebf90aSShri Abhyankar 
19616ebf90aSShri Abhyankar #undef __FUNCT__
19716ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqsbaij"
198bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
19916ebf90aSShri Abhyankar {
20067877ebaSShri Abhyankar   const PetscInt     *ai,*aj,*ajj,*adiag,M=A->rmap->n;
20167877ebaSShri Abhyankar   PetscInt           nz,rnz,i,j;
20267877ebaSShri Abhyankar   const PetscScalar  *av,*v1;
20316ebf90aSShri Abhyankar   PetscScalar        *val;
20416ebf90aSShri Abhyankar   PetscErrorCode     ierr;
20516ebf90aSShri Abhyankar   PetscInt           *row,*col;
20616ebf90aSShri Abhyankar   Mat_SeqSBAIJ       *aa=(Mat_SeqSBAIJ*)A->data;
20716ebf90aSShri Abhyankar 
20816ebf90aSShri Abhyankar   PetscFunctionBegin;
20916ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j;av=aa->a;
21016ebf90aSShri Abhyankar   adiag=aa->diag;
211bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
21216ebf90aSShri Abhyankar     nz = M + (aa->nz-M)/2;
21316ebf90aSShri Abhyankar     *nnz = nz;
214185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
215185f6596SHong Zhang     col  = row + nz;
216185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
217185f6596SHong Zhang 
21816ebf90aSShri Abhyankar     nz = 0;
21916ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
22016ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
22167877ebaSShri Abhyankar       ajj  = aj + adiag[i];
222cf3759fdSShri Abhyankar       v1   = av + adiag[i];
22367877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
22467877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz] = ajj[j] + shift; val[nz++] = v1[j];
22516ebf90aSShri Abhyankar       }
22616ebf90aSShri Abhyankar     }
22716ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
228397b6df1SKris Buschelman   } else {
22916ebf90aSShri Abhyankar     nz = 0; val = *v;
23016ebf90aSShri Abhyankar     for (i=0; i <M; i++) {
23116ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
23267877ebaSShri Abhyankar       ajj = aj + adiag[i];
23367877ebaSShri Abhyankar       v1  = av + adiag[i];
23467877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
23567877ebaSShri Abhyankar 	val[nz++] = v1[j];
23616ebf90aSShri Abhyankar       }
23716ebf90aSShri Abhyankar     }
23816ebf90aSShri Abhyankar   }
23916ebf90aSShri Abhyankar   PetscFunctionReturn(0);
24016ebf90aSShri Abhyankar }
24116ebf90aSShri Abhyankar 
24216ebf90aSShri Abhyankar #undef __FUNCT__
24316ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpisbaij_mpisbaij"
244bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpisbaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
24516ebf90aSShri Abhyankar {
24616ebf90aSShri Abhyankar   const PetscInt     *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
24716ebf90aSShri Abhyankar   PetscErrorCode     ierr;
24816ebf90aSShri Abhyankar   PetscInt           rstart,nz,i,j,jj,irow,countA,countB;
24916ebf90aSShri Abhyankar   PetscInt           *row,*col;
25016ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
25116ebf90aSShri Abhyankar   PetscScalar        *val;
252397b6df1SKris Buschelman   Mat_MPISBAIJ       *mat =  (Mat_MPISBAIJ*)A->data;
253397b6df1SKris Buschelman   Mat_SeqSBAIJ       *aa=(Mat_SeqSBAIJ*)(mat->A)->data;
254397b6df1SKris Buschelman   Mat_SeqBAIJ        *bb=(Mat_SeqBAIJ*)(mat->B)->data;
25516ebf90aSShri Abhyankar 
25616ebf90aSShri Abhyankar   PetscFunctionBegin;
257d0f46423SBarry Smith   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
258397b6df1SKris Buschelman   garray = mat->garray;
259397b6df1SKris Buschelman   av=aa->a; bv=bb->a;
260397b6df1SKris Buschelman 
261bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
26216ebf90aSShri Abhyankar     nz = aa->nz + bb->nz;
26316ebf90aSShri Abhyankar     *nnz = nz;
264185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
265185f6596SHong Zhang     col  = row + nz;
266185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
267185f6596SHong Zhang 
268397b6df1SKris Buschelman     *r = row; *c = col; *v = val;
269397b6df1SKris Buschelman   } else {
270397b6df1SKris Buschelman     row = *r; col = *c; val = *v;
271397b6df1SKris Buschelman   }
272397b6df1SKris Buschelman 
273028e57e8SHong Zhang   jj = 0; irow = rstart;
274397b6df1SKris Buschelman   for ( i=0; i<m; i++ ) {
275397b6df1SKris Buschelman     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
276397b6df1SKris Buschelman     countA = ai[i+1] - ai[i];
277397b6df1SKris Buschelman     countB = bi[i+1] - bi[i];
278397b6df1SKris Buschelman     bjj    = bj + bi[i];
27916ebf90aSShri Abhyankar     v1     = av + ai[i];
28016ebf90aSShri Abhyankar     v2     = bv + bi[i];
281397b6df1SKris Buschelman 
282397b6df1SKris Buschelman     /* A-part */
283397b6df1SKris Buschelman     for (j=0; j<countA; j++){
284bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
285397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
286397b6df1SKris Buschelman       }
28716ebf90aSShri Abhyankar       val[jj++] = v1[j];
288397b6df1SKris Buschelman     }
28916ebf90aSShri Abhyankar 
29016ebf90aSShri Abhyankar     /* B-part */
29116ebf90aSShri Abhyankar     for (j=0; j < countB; j++){
292bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
293397b6df1SKris Buschelman 	row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
294397b6df1SKris Buschelman       }
29516ebf90aSShri Abhyankar       val[jj++] = v2[j];
29616ebf90aSShri Abhyankar     }
29716ebf90aSShri Abhyankar     irow++;
29816ebf90aSShri Abhyankar   }
29916ebf90aSShri Abhyankar   PetscFunctionReturn(0);
30016ebf90aSShri Abhyankar }
30116ebf90aSShri Abhyankar 
30216ebf90aSShri Abhyankar #undef __FUNCT__
30316ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpiaij"
304bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
30516ebf90aSShri Abhyankar {
30616ebf90aSShri Abhyankar   const PetscInt     *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
30716ebf90aSShri Abhyankar   PetscErrorCode     ierr;
30816ebf90aSShri Abhyankar   PetscInt           rstart,nz,i,j,jj,irow,countA,countB;
30916ebf90aSShri Abhyankar   PetscInt           *row,*col;
31016ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
31116ebf90aSShri Abhyankar   PetscScalar        *val;
31216ebf90aSShri Abhyankar   Mat_MPIAIJ         *mat =  (Mat_MPIAIJ*)A->data;
31316ebf90aSShri Abhyankar   Mat_SeqAIJ         *aa=(Mat_SeqAIJ*)(mat->A)->data;
31416ebf90aSShri Abhyankar   Mat_SeqAIJ         *bb=(Mat_SeqAIJ*)(mat->B)->data;
31516ebf90aSShri Abhyankar 
31616ebf90aSShri Abhyankar   PetscFunctionBegin;
31716ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
31816ebf90aSShri Abhyankar   garray = mat->garray;
31916ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
32016ebf90aSShri Abhyankar 
321bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
32216ebf90aSShri Abhyankar     nz = aa->nz + bb->nz;
32316ebf90aSShri Abhyankar     *nnz = nz;
324185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
325185f6596SHong Zhang     col  = row + nz;
326185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
327185f6596SHong Zhang 
32816ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
32916ebf90aSShri Abhyankar   } else {
33016ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
33116ebf90aSShri Abhyankar   }
33216ebf90aSShri Abhyankar 
33316ebf90aSShri Abhyankar   jj = 0; irow = rstart;
33416ebf90aSShri Abhyankar   for ( i=0; i<m; i++ ) {
33516ebf90aSShri Abhyankar     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
33616ebf90aSShri Abhyankar     countA = ai[i+1] - ai[i];
33716ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
33816ebf90aSShri Abhyankar     bjj    = bj + bi[i];
33916ebf90aSShri Abhyankar     v1     = av + ai[i];
34016ebf90aSShri Abhyankar     v2     = bv + bi[i];
34116ebf90aSShri Abhyankar 
34216ebf90aSShri Abhyankar     /* A-part */
34316ebf90aSShri Abhyankar     for (j=0; j<countA; j++){
344bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX){
34516ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
34616ebf90aSShri Abhyankar       }
34716ebf90aSShri Abhyankar       val[jj++] = v1[j];
34816ebf90aSShri Abhyankar     }
34916ebf90aSShri Abhyankar 
35016ebf90aSShri Abhyankar     /* B-part */
35116ebf90aSShri Abhyankar     for (j=0; j < countB; j++){
352bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX){
35316ebf90aSShri Abhyankar 	row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
35416ebf90aSShri Abhyankar       }
35516ebf90aSShri Abhyankar       val[jj++] = v2[j];
35616ebf90aSShri Abhyankar     }
35716ebf90aSShri Abhyankar     irow++;
35816ebf90aSShri Abhyankar   }
35916ebf90aSShri Abhyankar   PetscFunctionReturn(0);
36016ebf90aSShri Abhyankar }
36116ebf90aSShri Abhyankar 
36216ebf90aSShri Abhyankar #undef __FUNCT__
36367877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpibaij_mpiaij"
364bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpibaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
36567877ebaSShri Abhyankar {
36667877ebaSShri Abhyankar   Mat_MPIBAIJ        *mat =  (Mat_MPIBAIJ*)A->data;
36767877ebaSShri Abhyankar   Mat_SeqBAIJ        *aa=(Mat_SeqBAIJ*)(mat->A)->data;
36867877ebaSShri Abhyankar   Mat_SeqBAIJ        *bb=(Mat_SeqBAIJ*)(mat->B)->data;
36967877ebaSShri Abhyankar   const PetscInt     *ai = aa->i, *bi = bb->i, *aj = aa->j, *bj = bb->j,*ajj, *bjj;
370d985c460SShri Abhyankar   const PetscInt     *garray = mat->garray,mbs=mat->mbs,rstart=A->rmap->rstart;
37167877ebaSShri Abhyankar   const PetscInt     bs = A->rmap->bs,bs2=mat->bs2;
37267877ebaSShri Abhyankar   PetscErrorCode     ierr;
37367877ebaSShri Abhyankar   PetscInt           nz,i,j,k,n,jj,irow,countA,countB,idx;
37467877ebaSShri Abhyankar   PetscInt           *row,*col;
37567877ebaSShri Abhyankar   const PetscScalar  *av=aa->a, *bv=bb->a,*v1,*v2;
37667877ebaSShri Abhyankar   PetscScalar        *val;
37767877ebaSShri Abhyankar 
37867877ebaSShri Abhyankar   PetscFunctionBegin;
37967877ebaSShri Abhyankar 
380bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
38167877ebaSShri Abhyankar     nz = bs2*(aa->nz + bb->nz);
38267877ebaSShri Abhyankar     *nnz = nz;
383185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
384185f6596SHong Zhang     col  = row + nz;
385185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
386185f6596SHong Zhang 
38767877ebaSShri Abhyankar     *r = row; *c = col; *v = val;
38867877ebaSShri Abhyankar   } else {
38967877ebaSShri Abhyankar     row = *r; col = *c; val = *v;
39067877ebaSShri Abhyankar   }
39167877ebaSShri Abhyankar 
392d985c460SShri Abhyankar   jj = 0; irow = rstart;
39367877ebaSShri Abhyankar   for ( i=0; i<mbs; i++ ) {
39467877ebaSShri Abhyankar     countA = ai[i+1] - ai[i];
39567877ebaSShri Abhyankar     countB = bi[i+1] - bi[i];
39667877ebaSShri Abhyankar     ajj    = aj + ai[i];
39767877ebaSShri Abhyankar     bjj    = bj + bi[i];
39867877ebaSShri Abhyankar     v1     = av + bs2*ai[i];
39967877ebaSShri Abhyankar     v2     = bv + bs2*bi[i];
40067877ebaSShri Abhyankar 
40167877ebaSShri Abhyankar     idx = 0;
40267877ebaSShri Abhyankar     /* A-part */
40367877ebaSShri Abhyankar     for (k=0; k<countA; k++){
40467877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
40567877ebaSShri Abhyankar 	for (n=0; n<bs; n++) {
406bccb9932SShri Abhyankar 	  if (reuse == MAT_INITIAL_MATRIX){
407d985c460SShri Abhyankar 	    row[jj] = irow + n + shift;
408d985c460SShri Abhyankar 	    col[jj] = rstart + bs*ajj[k] + j + shift;
40967877ebaSShri Abhyankar 	  }
41067877ebaSShri Abhyankar 	  val[jj++] = v1[idx++];
41167877ebaSShri Abhyankar 	}
41267877ebaSShri Abhyankar       }
41367877ebaSShri Abhyankar     }
41467877ebaSShri Abhyankar 
41567877ebaSShri Abhyankar     idx = 0;
41667877ebaSShri Abhyankar     /* B-part */
41767877ebaSShri Abhyankar     for (k=0; k<countB; k++){
41867877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
41967877ebaSShri Abhyankar 	for (n=0; n<bs; n++) {
420bccb9932SShri Abhyankar 	  if (reuse == MAT_INITIAL_MATRIX){
421d985c460SShri Abhyankar 	    row[jj] = irow + n + shift;
422d985c460SShri Abhyankar 	    col[jj] = bs*garray[bjj[k]] + j + shift;
42367877ebaSShri Abhyankar 	  }
424d985c460SShri Abhyankar 	  val[jj++] = v2[idx++];
42567877ebaSShri Abhyankar 	}
42667877ebaSShri Abhyankar       }
42767877ebaSShri Abhyankar     }
428d985c460SShri Abhyankar     irow += bs;
42967877ebaSShri Abhyankar   }
43067877ebaSShri Abhyankar   PetscFunctionReturn(0);
43167877ebaSShri Abhyankar }
43267877ebaSShri Abhyankar 
43367877ebaSShri Abhyankar #undef __FUNCT__
43416ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpisbaij"
435bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
43616ebf90aSShri Abhyankar {
43716ebf90aSShri Abhyankar   const PetscInt     *ai, *aj,*adiag, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
43816ebf90aSShri Abhyankar   PetscErrorCode     ierr;
439e0bace9bSHong Zhang   PetscInt           rstart,nz,nza,nzb,i,j,jj,irow,countA,countB;
44016ebf90aSShri Abhyankar   PetscInt           *row,*col;
44116ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
44216ebf90aSShri Abhyankar   PetscScalar        *val;
44316ebf90aSShri Abhyankar   Mat_MPIAIJ         *mat =  (Mat_MPIAIJ*)A->data;
44416ebf90aSShri Abhyankar   Mat_SeqAIJ         *aa=(Mat_SeqAIJ*)(mat->A)->data;
44516ebf90aSShri Abhyankar   Mat_SeqAIJ         *bb=(Mat_SeqAIJ*)(mat->B)->data;
44616ebf90aSShri Abhyankar 
44716ebf90aSShri Abhyankar   PetscFunctionBegin;
44816ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; adiag=aa->diag;
44916ebf90aSShri Abhyankar   bi=bb->i; bj=bb->j; garray = mat->garray;
45016ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
45116ebf90aSShri Abhyankar   rstart = A->rmap->rstart;
45216ebf90aSShri Abhyankar 
453bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
454e0bace9bSHong Zhang     nza = 0;    /* num of upper triangular entries in mat->A, including diagonals */
455e0bace9bSHong Zhang     nzb = 0;    /* num of upper triangular entries in mat->B */
45616ebf90aSShri Abhyankar     for (i=0; i<m; i++){
457e0bace9bSHong Zhang       nza    += (ai[i+1] - adiag[i]);
45816ebf90aSShri Abhyankar       countB  = bi[i+1] - bi[i];
45916ebf90aSShri Abhyankar       bjj     = bj + bi[i];
460e0bace9bSHong Zhang       for (j=0; j<countB; j++){
461e0bace9bSHong Zhang         if (garray[bjj[j]] > rstart) nzb++;
462e0bace9bSHong Zhang       }
463e0bace9bSHong Zhang     }
46416ebf90aSShri Abhyankar 
465e0bace9bSHong Zhang     nz = nza + nzb; /* total nz of upper triangular part of mat */
46616ebf90aSShri Abhyankar     *nnz = nz;
467185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
468185f6596SHong Zhang     col  = row + nz;
469185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
470185f6596SHong Zhang 
47116ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
47216ebf90aSShri Abhyankar   } else {
47316ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
47416ebf90aSShri Abhyankar   }
47516ebf90aSShri Abhyankar 
47616ebf90aSShri Abhyankar   jj = 0; irow = rstart;
47716ebf90aSShri Abhyankar   for ( i=0; i<m; i++ ) {
47816ebf90aSShri Abhyankar     ajj    = aj + adiag[i];                 /* ptr to the beginning of the diagonal of this row */
47916ebf90aSShri Abhyankar     v1     = av + adiag[i];
48016ebf90aSShri Abhyankar     countA = ai[i+1] - adiag[i];
48116ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
48216ebf90aSShri Abhyankar     bjj    = bj + bi[i];
48316ebf90aSShri Abhyankar     v2     = bv + bi[i];
48416ebf90aSShri Abhyankar 
48516ebf90aSShri Abhyankar      /* A-part */
48616ebf90aSShri Abhyankar     for (j=0; j<countA; j++){
487bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
48816ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
48916ebf90aSShri Abhyankar       }
49016ebf90aSShri Abhyankar       val[jj++] = v1[j];
49116ebf90aSShri Abhyankar     }
49216ebf90aSShri Abhyankar 
49316ebf90aSShri Abhyankar     /* B-part */
49416ebf90aSShri Abhyankar     for (j=0; j < countB; j++){
49516ebf90aSShri Abhyankar       if (garray[bjj[j]] > rstart) {
496bccb9932SShri Abhyankar 	if (reuse == MAT_INITIAL_MATRIX) {
49716ebf90aSShri Abhyankar 	  row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
49816ebf90aSShri Abhyankar 	}
49916ebf90aSShri Abhyankar 	val[jj++] = v2[j];
50016ebf90aSShri Abhyankar       }
501397b6df1SKris Buschelman     }
502397b6df1SKris Buschelman     irow++;
503397b6df1SKris Buschelman   }
504397b6df1SKris Buschelman   PetscFunctionReturn(0);
505397b6df1SKris Buschelman }
506397b6df1SKris Buschelman 
507397b6df1SKris Buschelman #undef __FUNCT__
5083924e44cSKris Buschelman #define __FUNCT__ "MatDestroy_MUMPS"
509dfbe8321SBarry Smith PetscErrorCode MatDestroy_MUMPS(Mat A)
510dfbe8321SBarry Smith {
511*a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
512dfbe8321SBarry Smith   PetscErrorCode ierr;
513b24902e0SBarry Smith 
514397b6df1SKris Buschelman   PetscFunctionBegin;
515*a5e57a09SHong Zhang   if (mumps->CleanUpMUMPS) {
516397b6df1SKris Buschelman     /* Terminate instance, deallocate memories */
517*a5e57a09SHong Zhang     ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
518*a5e57a09SHong Zhang     ierr = VecScatterDestroy(&mumps->scat_rhs);CHKERRQ(ierr);
519*a5e57a09SHong Zhang     ierr = VecDestroy(&mumps->b_seq);CHKERRQ(ierr);
520*a5e57a09SHong Zhang     ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
521*a5e57a09SHong Zhang     ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
522*a5e57a09SHong Zhang     ierr = PetscFree(mumps->id.perm_in);CHKERRQ(ierr);
523*a5e57a09SHong Zhang     ierr = PetscFree(mumps->irn);CHKERRQ(ierr);
524*a5e57a09SHong Zhang     mumps->id.job = JOB_END;
525*a5e57a09SHong Zhang     PetscMUMPS_c(&mumps->id);
526*a5e57a09SHong Zhang     ierr = MPI_Comm_free(&(mumps->comm_mumps));CHKERRQ(ierr);
527397b6df1SKris Buschelman   }
528*a5e57a09SHong Zhang   if (mumps->Destroy) {
529*a5e57a09SHong Zhang     ierr = (mumps->Destroy)(A);CHKERRQ(ierr);
530bf0cc555SLisandro Dalcin   }
531bf0cc555SLisandro Dalcin   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
532bf0cc555SLisandro Dalcin 
53397969023SHong Zhang   /* clear composed functions */
53497969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatFactorGetSolverPackage_C","",PETSC_NULL);CHKERRQ(ierr);
535f250808bSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatMumpsSetIcntl_C","",PETSC_NULL);CHKERRQ(ierr);
536397b6df1SKris Buschelman   PetscFunctionReturn(0);
537397b6df1SKris Buschelman }
538397b6df1SKris Buschelman 
539397b6df1SKris Buschelman #undef __FUNCT__
540f6c57405SHong Zhang #define __FUNCT__ "MatSolve_MUMPS"
541b24902e0SBarry Smith PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x)
542b24902e0SBarry Smith {
543*a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
544d54de34fSKris Buschelman   PetscScalar    *array;
54567877ebaSShri Abhyankar   Vec            b_seq;
546329ec9b3SHong Zhang   IS             is_iden,is_petsc;
547dfbe8321SBarry Smith   PetscErrorCode ierr;
548329ec9b3SHong Zhang   PetscInt       i;
549397b6df1SKris Buschelman 
550397b6df1SKris Buschelman   PetscFunctionBegin;
551*a5e57a09SHong Zhang   mumps->id.nrhs = 1;
552*a5e57a09SHong Zhang   b_seq = mumps->b_seq;
553*a5e57a09SHong Zhang   if (mumps->size > 1){
554329ec9b3SHong Zhang     /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */
555*a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
556*a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
557*a5e57a09SHong Zhang     if (!mumps->myid) {ierr = VecGetArray(b_seq,&array);CHKERRQ(ierr);}
558397b6df1SKris Buschelman   } else {  /* size == 1 */
559397b6df1SKris Buschelman     ierr = VecCopy(b,x);CHKERRQ(ierr);
560397b6df1SKris Buschelman     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
561397b6df1SKris Buschelman   }
562*a5e57a09SHong Zhang   if (!mumps->myid) { /* define rhs on the host */
563*a5e57a09SHong Zhang     mumps->id.nrhs = 1;
564397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
5652907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
566*a5e57a09SHong Zhang     mumps->id.rhs = (mumps_complex*)array;
5672907cef9SHong Zhang #else
568*a5e57a09SHong Zhang     mumps->id.rhs = (mumps_double_complex*)array;
5692907cef9SHong Zhang #endif
570397b6df1SKris Buschelman #else
571*a5e57a09SHong Zhang     mumps->id.rhs = array;
572397b6df1SKris Buschelman #endif
573397b6df1SKris Buschelman   }
574397b6df1SKris Buschelman 
575397b6df1SKris Buschelman   /* solve phase */
576329ec9b3SHong Zhang   /*-------------*/
577*a5e57a09SHong Zhang   mumps->id.job = JOB_SOLVE;
578*a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
579*a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
580397b6df1SKris Buschelman 
581*a5e57a09SHong Zhang   if (mumps->size > 1) { /* convert mumps distributed solution to petsc mpi x */
582*a5e57a09SHong Zhang     if (mumps->scat_sol && mumps->ICNTL9_pre != mumps->id.ICNTL(9)){
583*a5e57a09SHong Zhang       /* when id.ICNTL(9) changes, the contents of lsol_loc may change (not its size, lsol_loc), recreates scat_sol */
584*a5e57a09SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
585397b6df1SKris Buschelman     }
586*a5e57a09SHong Zhang     if (!mumps->scat_sol){ /* create scatter scat_sol */
587*a5e57a09SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,mumps->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */
588*a5e57a09SHong Zhang       for (i=0; i<mumps->id.lsol_loc; i++){
589*a5e57a09SHong Zhang         mumps->id.isol_loc[i] -= 1; /* change Fortran style to C style */
590*a5e57a09SHong Zhang       }
591*a5e57a09SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,mumps->id.lsol_loc,mumps->id.isol_loc,PETSC_COPY_VALUES,&is_petsc);CHKERRQ(ierr);  /* to */
592*a5e57a09SHong Zhang       ierr = VecScatterCreate(mumps->x_seq,is_iden,x,is_petsc,&mumps->scat_sol);CHKERRQ(ierr);
5936bf464f9SBarry Smith       ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
5946bf464f9SBarry Smith       ierr = ISDestroy(&is_petsc);CHKERRQ(ierr);
595*a5e57a09SHong Zhang       mumps->ICNTL9_pre = mumps->id.ICNTL(9); /* save current value of id.ICNTL(9) */
596397b6df1SKris Buschelman     }
597*a5e57a09SHong Zhang 
598*a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
599*a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
600329ec9b3SHong Zhang   }
601397b6df1SKris Buschelman   PetscFunctionReturn(0);
602397b6df1SKris Buschelman }
603397b6df1SKris Buschelman 
60451d5961aSHong Zhang #undef __FUNCT__
60551d5961aSHong Zhang #define __FUNCT__ "MatSolveTranspose_MUMPS"
60651d5961aSHong Zhang PetscErrorCode MatSolveTranspose_MUMPS(Mat A,Vec b,Vec x)
60751d5961aSHong Zhang {
608*a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
60951d5961aSHong Zhang   PetscErrorCode ierr;
61051d5961aSHong Zhang 
61151d5961aSHong Zhang   PetscFunctionBegin;
612*a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 0;
6130ad0caddSJed Brown   ierr = MatSolve_MUMPS(A,b,x);CHKERRQ(ierr);
614*a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 1;
61551d5961aSHong Zhang   PetscFunctionReturn(0);
61651d5961aSHong Zhang }
61751d5961aSHong Zhang 
618e0b74bf9SHong Zhang #undef __FUNCT__
619e0b74bf9SHong Zhang #define __FUNCT__ "MatMatSolve_MUMPS"
620e0b74bf9SHong Zhang PetscErrorCode MatMatSolve_MUMPS(Mat A,Mat B,Mat X)
621e0b74bf9SHong Zhang {
622bda8bf91SBarry Smith   PetscErrorCode ierr;
623bda8bf91SBarry Smith   PetscBool      flg;
624bda8bf91SBarry Smith 
625e0b74bf9SHong Zhang   PetscFunctionBegin;
626251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr);
627bda8bf91SBarry Smith   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
628251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr);
629bda8bf91SBarry Smith   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatMatSolve_MUMPS() is not implemented yet");
630e0b74bf9SHong Zhang   PetscFunctionReturn(0);
631e0b74bf9SHong Zhang }
632e0b74bf9SHong Zhang 
633ace3df97SHong Zhang #if !defined(PETSC_USE_COMPLEX)
634a58c3f20SHong Zhang /*
635a58c3f20SHong Zhang   input:
636a58c3f20SHong Zhang    F:        numeric factor
637a58c3f20SHong Zhang   output:
638a58c3f20SHong Zhang    nneg:     total number of negative pivots
639a58c3f20SHong Zhang    nzero:    0
640a58c3f20SHong Zhang    npos:     (global dimension of F) - nneg
641a58c3f20SHong Zhang */
642a58c3f20SHong Zhang 
643a58c3f20SHong Zhang #undef __FUNCT__
644a58c3f20SHong Zhang #define __FUNCT__ "MatGetInertia_SBAIJMUMPS"
645dfbe8321SBarry Smith PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos)
646a58c3f20SHong Zhang {
647*a5e57a09SHong Zhang   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
648dfbe8321SBarry Smith   PetscErrorCode ierr;
649c1490034SHong Zhang   PetscMPIInt    size;
650a58c3f20SHong Zhang 
651a58c3f20SHong Zhang   PetscFunctionBegin;
6527adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr);
653bcb30aebSHong Zhang   /* MUMPS 4.3.1 calls ScaLAPACK when ICNTL(13)=0 (default), which does not offer the possibility to compute the inertia of a dense matrix. Set ICNTL(13)=1 to skip ScaLAPACK */
654*a5e57a09SHong Zhang   if (size > 1 && mumps->id.ICNTL(13) != 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"ICNTL(13)=%d. -mat_mumps_icntl_13 must be set as 1 for correct global matrix inertia\n",mumps->id.INFOG(13));
655a58c3f20SHong Zhang   if (nneg){
656*a5e57a09SHong Zhang     if (!mumps->myid){
657*a5e57a09SHong Zhang       *nneg = mumps->id.INFOG(12);
658a58c3f20SHong Zhang     }
659*a5e57a09SHong Zhang     ierr = MPI_Bcast(nneg,1,MPI_INT,0,mumps->comm_mumps);CHKERRQ(ierr);
660a58c3f20SHong Zhang   }
661a58c3f20SHong Zhang   if (nzero) *nzero = 0;
662d0f46423SBarry Smith   if (npos)  *npos  = F->rmap->N - (*nneg);
663a58c3f20SHong Zhang   PetscFunctionReturn(0);
664a58c3f20SHong Zhang }
665ace3df97SHong Zhang #endif /* !defined(PETSC_USE_COMPLEX) */
666a58c3f20SHong Zhang 
667397b6df1SKris Buschelman #undef __FUNCT__
668f6c57405SHong Zhang #define __FUNCT__ "MatFactorNumeric_MUMPS"
6690481f469SBarry Smith PetscErrorCode MatFactorNumeric_MUMPS(Mat F,Mat A,const MatFactorInfo *info)
670af281ebdSHong Zhang {
671*a5e57a09SHong Zhang   Mat_MUMPS       *mumps =(Mat_MUMPS*)(F)->spptr;
6726849ba73SBarry Smith   PetscErrorCode  ierr;
673e09efc27SHong Zhang   Mat             F_diag;
674ace3abfcSBarry Smith   PetscBool       isMPIAIJ;
675397b6df1SKris Buschelman 
676397b6df1SKris Buschelman   PetscFunctionBegin;
677*a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_REUSE_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
678397b6df1SKris Buschelman 
679397b6df1SKris Buschelman   /* numerical factorization phase */
680329ec9b3SHong Zhang   /*-------------------------------*/
681*a5e57a09SHong Zhang   mumps->id.job = JOB_FACTNUMERIC;
682*a5e57a09SHong Zhang   if (!mumps->id.ICNTL(18)) {
683*a5e57a09SHong Zhang     if (!mumps->myid) {
684397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
6852907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
686*a5e57a09SHong Zhang       mumps->id.a = (mumps_complex*)mumps->val;
6872907cef9SHong Zhang #else
688*a5e57a09SHong Zhang       mumps->id.a = (mumps_double_complex*)mumps->val;
6892907cef9SHong Zhang #endif
690397b6df1SKris Buschelman #else
691*a5e57a09SHong Zhang       mumps->id.a = mumps->val;
692397b6df1SKris Buschelman #endif
693397b6df1SKris Buschelman     }
694397b6df1SKris Buschelman   } else {
695397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
6962907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
697*a5e57a09SHong Zhang     mumps->id.a_loc = (mumps_complex*)mumps->val;
6982907cef9SHong Zhang #else
699*a5e57a09SHong Zhang     mumps->id.a_loc = (mumps_double_complex*)mumps->val;
7002907cef9SHong Zhang #endif
701397b6df1SKris Buschelman #else
702*a5e57a09SHong Zhang     mumps->id.a_loc = mumps->val;
703397b6df1SKris Buschelman #endif
704397b6df1SKris Buschelman   }
705*a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
706*a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) {
707*a5e57a09SHong Zhang     if (mumps->id.INFO(1) == -13) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: Cannot allocate required memory %d megabytes\n",mumps->id.INFO(2));
708*a5e57a09SHong Zhang     else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: INFO(1)=%d, INFO(2)=%d\n",mumps->id.INFO(1),mumps->id.INFO(2));
709397b6df1SKris Buschelman   }
710*a5e57a09SHong Zhang   if (!mumps->myid && mumps->id.ICNTL(16) > 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"  mumps->id.ICNTL(16):=%d\n",mumps->id.INFOG(16));
711397b6df1SKris Buschelman 
712*a5e57a09SHong Zhang   if (mumps->size > 1){
713251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
714a214ac2aSShri Abhyankar     if (isMPIAIJ) {
715dcd589f8SShri Abhyankar       F_diag = ((Mat_MPIAIJ *)(F)->data)->A;
716e09efc27SHong Zhang     } else {
717dcd589f8SShri Abhyankar       F_diag = ((Mat_MPISBAIJ *)(F)->data)->A;
718e09efc27SHong Zhang     }
719e09efc27SHong Zhang     F_diag->assembled = PETSC_TRUE;
720*a5e57a09SHong Zhang     if (mumps->scat_sol){
721*a5e57a09SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
722*a5e57a09SHong Zhang       ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
723*a5e57a09SHong Zhang       ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
724329ec9b3SHong Zhang     }
7258ada1bb4SHong Zhang   }
726dcd589f8SShri Abhyankar   (F)->assembled   = PETSC_TRUE;
727*a5e57a09SHong Zhang   mumps->matstruc     = SAME_NONZERO_PATTERN;
728*a5e57a09SHong Zhang   mumps->CleanUpMUMPS = PETSC_TRUE;
72967877ebaSShri Abhyankar 
730*a5e57a09SHong Zhang   if (mumps->size > 1){
73167877ebaSShri Abhyankar     /* distributed solution */
732*a5e57a09SHong Zhang     if (!mumps->scat_sol){
73367877ebaSShri Abhyankar       /* Create x_seq=sol_loc for repeated use */
73467877ebaSShri Abhyankar       PetscInt    lsol_loc;
73567877ebaSShri Abhyankar       PetscScalar *sol_loc;
736*a5e57a09SHong Zhang       lsol_loc = mumps->id.INFO(23); /* length of sol_loc */
737*a5e57a09SHong Zhang       ierr = PetscMalloc2(lsol_loc,PetscScalar,&sol_loc,lsol_loc,PetscInt,&mumps->id.isol_loc);CHKERRQ(ierr);
738*a5e57a09SHong Zhang       mumps->id.lsol_loc = lsol_loc;
73967877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
7402907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
741*a5e57a09SHong Zhang       mumps->id.sol_loc  = (mumps_complex*)sol_loc;
7422907cef9SHong Zhang #else
743*a5e57a09SHong Zhang       mumps->id.sol_loc  = (mumps_double_complex*)sol_loc;
7442907cef9SHong Zhang #endif
74567877ebaSShri Abhyankar #else
746*a5e57a09SHong Zhang       mumps->id.sol_loc  = sol_loc;
74767877ebaSShri Abhyankar #endif
748*a5e57a09SHong Zhang       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lsol_loc,sol_loc,&mumps->x_seq);CHKERRQ(ierr);
74967877ebaSShri Abhyankar     }
75067877ebaSShri Abhyankar   }
751397b6df1SKris Buschelman   PetscFunctionReturn(0);
752397b6df1SKris Buschelman }
753397b6df1SKris Buschelman 
7549a2535b5SHong Zhang /* Sets MUMPS options from the options database */
755dcd589f8SShri Abhyankar #undef __FUNCT__
7569a2535b5SHong Zhang #define __FUNCT__ "PetscSetMUMPSFromOptions"
7579a2535b5SHong Zhang PetscErrorCode PetscSetMUMPSFromOptions(Mat F, Mat A)
758dcd589f8SShri Abhyankar {
7599a2535b5SHong Zhang   Mat_MUMPS        *mumps = (Mat_MUMPS*)F->spptr;
760dcd589f8SShri Abhyankar   PetscErrorCode   ierr;
761dcd589f8SShri Abhyankar   PetscInt         icntl;
762ace3abfcSBarry Smith   PetscBool        flg;
763dcd589f8SShri Abhyankar 
764dcd589f8SShri Abhyankar   PetscFunctionBegin;
765dcd589f8SShri Abhyankar   ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr);
7669a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_1","ICNTL(1): output stream for error messages","None",mumps->id.ICNTL(1),&icntl,&flg);CHKERRQ(ierr);
7679a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(1) = icntl;
7689a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_2","ICNTL(2): output stream for diagnostic printing, statistics, and warning","None",mumps->id.ICNTL(2),&icntl,&flg);CHKERRQ(ierr);
7699a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(2) = icntl;
7709a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_3","ICNTL(3): output stream for global information, collected on the host","None",mumps->id.ICNTL(3),&icntl,&flg);CHKERRQ(ierr);
7719a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(3) = icntl;
772dcd589f8SShri Abhyankar 
7739a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",mumps->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr);
7749a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(4) = icntl;
7759a2535b5SHong Zhang   if (mumps->id.ICNTL(4) || PetscLogPrintInfo ) mumps->id.ICNTL(3) = 6; /* resume MUMPS default id.ICNTL(3) = 6 */
7769a2535b5SHong Zhang 
7779a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_6","ICNTL(6): permuting and/or scaling the matrix (0 to 7)","None",mumps->id.ICNTL(6),&icntl,&flg);CHKERRQ(ierr);
7789a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(6) = icntl;
7799a2535b5SHong Zhang 
7809a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_7","ICNTL(7): matrix ordering (0 to 7). 3=Scotch, 4=PORD, 5=Metis","None",mumps->id.ICNTL(7),&icntl,&flg);CHKERRQ(ierr);
781dcd589f8SShri Abhyankar   if (flg) {
7829a2535b5SHong Zhang     if (icntl== 1 && mumps->size > 1){
783e32f2f54SBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"pivot order be set by the user in PERM_IN -- not supported by the PETSc/MUMPS interface\n");
784dcd589f8SShri Abhyankar     } else {
7859a2535b5SHong Zhang       mumps->id.ICNTL(7) = icntl;
786dcd589f8SShri Abhyankar     }
787dcd589f8SShri Abhyankar   }
788e0b74bf9SHong Zhang 
78970544d5fSHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_8","ICNTL(8): scaling strategy (-2 to 8 or 77)","None",mumps->id.ICNTL(8),&mumps->id.ICNTL(8),PETSC_NULL);CHKERRQ(ierr);
7909a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_10","ICNTL(10): max num of refinements","None",mumps->id.ICNTL(10),&mumps->id.ICNTL(10),PETSC_NULL);CHKERRQ(ierr);
7919a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_11","ICNTL(11): statistics related to the linear system solved (via -ksp_view)","None",mumps->id.ICNTL(11),&mumps->id.ICNTL(11),PETSC_NULL);CHKERRQ(ierr);
79270544d5fSHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_12","ICNTL(12): efficiency control: defines the ordering strategy with scaling constraints (0 to 3)","None",mumps->id.ICNTL(12),&mumps->id.ICNTL(12),PETSC_NULL);CHKERRQ(ierr);
7939a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_13","ICNTL(13): efficiency control: with or without ScaLAPACK","None",mumps->id.ICNTL(13),&mumps->id.ICNTL(13),PETSC_NULL);CHKERRQ(ierr);
7949a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_14","ICNTL(14): percentage of estimated workspace increase","None",mumps->id.ICNTL(14),&mumps->id.ICNTL(14),PETSC_NULL);CHKERRQ(ierr);
7959a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_19","ICNTL(19): Schur complement","None",mumps->id.ICNTL(19),&mumps->id.ICNTL(19),PETSC_NULL);CHKERRQ(ierr);
7969a2535b5SHong Zhang 
7979a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_22","ICNTL(22): in-core/out-of-core facility (0 or 1)","None",mumps->id.ICNTL(22),&mumps->id.ICNTL(22),PETSC_NULL);CHKERRQ(ierr);
7989a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_23","ICNTL(23): max size of the working memory (MB) that can allocate per processor","None",mumps->id.ICNTL(23),&mumps->id.ICNTL(23),PETSC_NULL);CHKERRQ(ierr);
7999a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_24","ICNTL(24): detection of null pivot rows (0 or 1)","None",mumps->id.ICNTL(24),&mumps->id.ICNTL(24),PETSC_NULL);CHKERRQ(ierr);
8009a2535b5SHong Zhang   if (mumps->id.ICNTL(24)){
8019a2535b5SHong Zhang     mumps->id.ICNTL(13) = 1; /* turn-off ScaLAPACK to help with the correct detection of null pivots */
802d7ebd59bSHong Zhang   }
803d7ebd59bSHong Zhang 
8049a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_25","ICNTL(25): computation of a null space basis","None",mumps->id.ICNTL(25),&mumps->id.ICNTL(25),PETSC_NULL);CHKERRQ(ierr);
8059a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_26","ICNTL(26): Schur options for right-hand side or solution vector","None",mumps->id.ICNTL(26),&mumps->id.ICNTL(26),PETSC_NULL);CHKERRQ(ierr);
8069a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_27","ICNTL(27): experimental parameter","None",mumps->id.ICNTL(27),&mumps->id.ICNTL(27),PETSC_NULL);CHKERRQ(ierr);
8079a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_28","ICNTL(28): use 1 for sequential analysis and ictnl(7) ordering, or 2 for parallel analysis and ictnl(29) ordering","None",mumps->id.ICNTL(28),&mumps->id.ICNTL(28),PETSC_NULL);CHKERRQ(ierr);
8089a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_29","ICNTL(29): parallel ordering 1 = ptscotch 2 = parmetis","None",mumps->id.ICNTL(29),&mumps->id.ICNTL(29),PETSC_NULL);CHKERRQ(ierr);
8099a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_30","ICNTL(30): compute user-specified set of entries in inv(A)","None",mumps->id.ICNTL(30),&mumps->id.ICNTL(30),PETSC_NULL);CHKERRQ(ierr);
8109a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_31","ICNTL(31): factors can be discarded in the solve phase","None",mumps->id.ICNTL(31),&mumps->id.ICNTL(31),PETSC_NULL);CHKERRQ(ierr);
8119a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_33","ICNTL(33): compute determinant","None",mumps->id.ICNTL(33),&mumps->id.ICNTL(33),PETSC_NULL);CHKERRQ(ierr);
812dcd589f8SShri Abhyankar 
8139a2535b5SHong Zhang   ierr = PetscOptionsReal("-mat_mumps_cntl_1","CNTL(1): relative pivoting threshold","None",mumps->id.CNTL(1),&mumps->id.CNTL(1),PETSC_NULL);CHKERRQ(ierr);
8149a2535b5SHong Zhang   ierr = PetscOptionsReal("-mat_mumps_cntl_2","CNTL(2): stopping criterion of refinement","None",mumps->id.CNTL(2),&mumps->id.CNTL(2),PETSC_NULL);CHKERRQ(ierr);
8159a2535b5SHong Zhang   ierr = PetscOptionsReal("-mat_mumps_cntl_3","CNTL(3): absolute pivoting threshold","None",mumps->id.CNTL(3),&mumps->id.CNTL(3),PETSC_NULL);CHKERRQ(ierr);
8169a2535b5SHong Zhang   ierr = PetscOptionsReal("-mat_mumps_cntl_4","CNTL(4): value for static pivoting","None",mumps->id.CNTL(4),&mumps->id.CNTL(4),PETSC_NULL);CHKERRQ(ierr);
8179a2535b5SHong Zhang   ierr = PetscOptionsReal("-mat_mumps_cntl_5","CNTL(5): fixation for null pivots","None",mumps->id.CNTL(5),&mumps->id.CNTL(5),PETSC_NULL);CHKERRQ(ierr);
818e5bb22a1SHong Zhang 
819e5bb22a1SHong Zhang   ierr = PetscOptionsString("-mat_mumps_ooc_tmpdir", "out of core directory", "None", mumps->id.ooc_tmpdir, mumps->id.ooc_tmpdir, 256, PETSC_NULL);
820dcd589f8SShri Abhyankar   PetscOptionsEnd();
821dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
822dcd589f8SShri Abhyankar }
823dcd589f8SShri Abhyankar 
824dcd589f8SShri Abhyankar #undef __FUNCT__
825dcd589f8SShri Abhyankar #define __FUNCT__ "PetscInitializeMUMPS"
826f697e70eSHong Zhang PetscErrorCode PetscInitializeMUMPS(Mat A,Mat_MUMPS* mumps)
827dcd589f8SShri Abhyankar {
828dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
829dcd589f8SShri Abhyankar 
830dcd589f8SShri Abhyankar   PetscFunctionBegin;
831f697e70eSHong Zhang   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &mumps->myid);
832f697e70eSHong Zhang   ierr = MPI_Comm_size(((PetscObject)A)->comm,&mumps->size);CHKERRQ(ierr);
833f697e70eSHong Zhang   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(mumps->comm_mumps));CHKERRQ(ierr);
834f697e70eSHong Zhang   mumps->id.comm_fortran = MPI_Comm_c2f(mumps->comm_mumps);
835f697e70eSHong Zhang 
836f697e70eSHong Zhang   mumps->id.job = JOB_INIT;
837f697e70eSHong Zhang   mumps->id.par = 1;  /* host participates factorizaton and solve */
838f697e70eSHong Zhang   mumps->id.sym = mumps->sym;
8392907cef9SHong Zhang   PetscMUMPS_c(&mumps->id);
840f697e70eSHong Zhang 
841f697e70eSHong Zhang   mumps->CleanUpMUMPS = PETSC_FALSE;
842f697e70eSHong Zhang   mumps->scat_rhs     = PETSC_NULL;
843f697e70eSHong Zhang   mumps->scat_sol     = PETSC_NULL;
8449a2535b5SHong Zhang 
84570544d5fSHong Zhang   /* set PETSc-MUMPS default options - override MUMPS default */
8469a2535b5SHong Zhang   mumps->id.ICNTL(3) = 0;
8479a2535b5SHong Zhang   mumps->id.ICNTL(4) = 0;
8489a2535b5SHong Zhang   if (mumps->size == 1){
8499a2535b5SHong Zhang     mumps->id.ICNTL(18) = 0;   /* centralized assembled matrix input */
8509a2535b5SHong Zhang   } else {
8519a2535b5SHong Zhang     mumps->id.ICNTL(18) = 3;   /* distributed assembled matrix input */
85270544d5fSHong Zhang     mumps->id.ICNTL(21) = 1;   /* distributed solution */
8539a2535b5SHong Zhang   }
854dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
855dcd589f8SShri Abhyankar }
856dcd589f8SShri Abhyankar 
857*a5e57a09SHong Zhang /* Note Petsc r(=c) permutation is used when mumps->id.ICNTL(7)==1 with centralized assembled matrix input; otherwise r and c are ignored */
858397b6df1SKris Buschelman #undef __FUNCT__
859f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS"
8600481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
861b24902e0SBarry Smith {
862*a5e57a09SHong Zhang   Mat_MUMPS          *mumps = (Mat_MUMPS*)F->spptr;
863dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
86467877ebaSShri Abhyankar   Vec                b;
86567877ebaSShri Abhyankar   IS                 is_iden;
86667877ebaSShri Abhyankar   const PetscInt     M = A->rmap->N;
867397b6df1SKris Buschelman 
868397b6df1SKris Buschelman   PetscFunctionBegin;
869*a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
870dcd589f8SShri Abhyankar 
8719a2535b5SHong Zhang   /* Set MUMPS options from the options database */
8729a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
873dcd589f8SShri Abhyankar 
874*a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
875dcd589f8SShri Abhyankar 
87667877ebaSShri Abhyankar   /* analysis phase */
87767877ebaSShri Abhyankar   /*----------------*/
878*a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
879*a5e57a09SHong Zhang   mumps->id.n = M;
880*a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)){
88167877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
882*a5e57a09SHong Zhang     if (!mumps->myid) {
883*a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
884*a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1){
88567877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
8862907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
887*a5e57a09SHong Zhang         mumps->id.a = (mumps_complex*)mumps->val;
8882907cef9SHong Zhang #else
889*a5e57a09SHong Zhang         mumps->id.a = (mumps_double_complex*)mumps->val;
8902907cef9SHong Zhang #endif
89167877ebaSShri Abhyankar #else
892*a5e57a09SHong Zhang         mumps->id.a = mumps->val;
89367877ebaSShri Abhyankar #endif
89467877ebaSShri Abhyankar       }
895*a5e57a09SHong Zhang       if (mumps->id.ICNTL(7) == 1){ /* use user-provide matrix ordering - assuming r = c ordering */
8965248a706SHong Zhang         /*
8975248a706SHong Zhang         PetscBool      flag;
8985248a706SHong Zhang         ierr = ISEqual(r,c,&flag);CHKERRQ(ierr);
8995248a706SHong Zhang         if (!flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"row_perm != col_perm");
9005248a706SHong Zhang         ierr = ISView(r,PETSC_VIEWER_STDOUT_SELF);
9015248a706SHong Zhang          */
902*a5e57a09SHong Zhang         if (!mumps->myid) {
903e0b74bf9SHong Zhang           const PetscInt *idx;
904e0b74bf9SHong Zhang           PetscInt i,*perm_in;
905e0b74bf9SHong Zhang           ierr = PetscMalloc(M*sizeof(PetscInt),&perm_in);CHKERRQ(ierr);
906e0b74bf9SHong Zhang           ierr = ISGetIndices(r,&idx);CHKERRQ(ierr);
907*a5e57a09SHong Zhang           mumps->id.perm_in = perm_in;
908e0b74bf9SHong Zhang           for (i=0; i<M; i++) perm_in[i] = idx[i]+1; /* perm_in[]: start from 1, not 0! */
909e0b74bf9SHong Zhang           ierr = ISRestoreIndices(r,&idx);CHKERRQ(ierr);
910e0b74bf9SHong Zhang         }
911e0b74bf9SHong Zhang       }
91267877ebaSShri Abhyankar     }
91367877ebaSShri Abhyankar     break;
91467877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
915*a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
916*a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
917*a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
91867877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
9192907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
920*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_complex*)mumps->val;
9212907cef9SHong Zhang #else
922*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_double_complex*)mumps->val;
9232907cef9SHong Zhang #endif
92467877ebaSShri Abhyankar #else
925*a5e57a09SHong Zhang       mumps->id.a_loc = mumps->val;
92667877ebaSShri Abhyankar #endif
92767877ebaSShri Abhyankar     }
92867877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
929*a5e57a09SHong Zhang     if (!mumps->myid){
930*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
93167877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
93267877ebaSShri Abhyankar     } else {
933*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
93467877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
93567877ebaSShri Abhyankar     }
93667877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
93767877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
93867877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
93967877ebaSShri Abhyankar 
940*a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
9416bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
9426bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
94367877ebaSShri Abhyankar     break;
94467877ebaSShri Abhyankar     }
945*a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
946*a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
94767877ebaSShri Abhyankar 
948719d5645SBarry Smith   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
949dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
95051d5961aSHong Zhang   F->ops->solvetranspose   = MatSolveTranspose_MUMPS;
95117f96c7aSHong Zhang   F->ops->matsolve         = 0; /* use MatMatSolve_Basic() until mumps supports distributed rhs */
952b24902e0SBarry Smith   PetscFunctionReturn(0);
953b24902e0SBarry Smith }
954b24902e0SBarry Smith 
955450b117fSShri Abhyankar /* Note the Petsc r and c permutations are ignored */
956450b117fSShri Abhyankar #undef __FUNCT__
957450b117fSShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_BAIJMUMPS"
958450b117fSShri Abhyankar PetscErrorCode MatLUFactorSymbolic_BAIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
959450b117fSShri Abhyankar {
960*a5e57a09SHong Zhang   Mat_MUMPS       *mumps = (Mat_MUMPS*)F->spptr;
961dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
96267877ebaSShri Abhyankar   Vec             b;
96367877ebaSShri Abhyankar   IS              is_iden;
96467877ebaSShri Abhyankar   const PetscInt  M = A->rmap->N;
965450b117fSShri Abhyankar 
966450b117fSShri Abhyankar   PetscFunctionBegin;
967*a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
968dcd589f8SShri Abhyankar 
9699a2535b5SHong Zhang   /* Set MUMPS options from the options database */
9709a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
971dcd589f8SShri Abhyankar 
972*a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
97367877ebaSShri Abhyankar 
97467877ebaSShri Abhyankar   /* analysis phase */
97567877ebaSShri Abhyankar   /*----------------*/
976*a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
977*a5e57a09SHong Zhang   mumps->id.n = M;
978*a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)){
97967877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
980*a5e57a09SHong Zhang     if (!mumps->myid) {
981*a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
982*a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1){
98367877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
9842907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
985*a5e57a09SHong Zhang         mumps->id.a = (mumps_complex*)mumps->val;
9862907cef9SHong Zhang #else
987*a5e57a09SHong Zhang         mumps->id.a = (mumps_double_complex*)mumps->val;
9882907cef9SHong Zhang #endif
98967877ebaSShri Abhyankar #else
990*a5e57a09SHong Zhang         mumps->id.a = mumps->val;
99167877ebaSShri Abhyankar #endif
99267877ebaSShri Abhyankar       }
99367877ebaSShri Abhyankar     }
99467877ebaSShri Abhyankar     break;
99567877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
996*a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
997*a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
998*a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
99967877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
10002907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
1001*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_complex*)mumps->val;
10022907cef9SHong Zhang #else
1003*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_double_complex*)mumps->val;
10042907cef9SHong Zhang #endif
100567877ebaSShri Abhyankar #else
1006*a5e57a09SHong Zhang       mumps->id.a_loc = mumps->val;
100767877ebaSShri Abhyankar #endif
100867877ebaSShri Abhyankar     }
100967877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1010*a5e57a09SHong Zhang     if (!mumps->myid){
1011*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
101267877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
101367877ebaSShri Abhyankar     } else {
1014*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
101567877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
101667877ebaSShri Abhyankar     }
101767877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
101867877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
101967877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
102067877ebaSShri Abhyankar 
1021*a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
10226bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
10236bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
102467877ebaSShri Abhyankar     break;
102567877ebaSShri Abhyankar     }
1026*a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1027*a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
102867877ebaSShri Abhyankar 
1029450b117fSShri Abhyankar   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
1030dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
103151d5961aSHong Zhang   F->ops->solvetranspose   = MatSolveTranspose_MUMPS;
1032450b117fSShri Abhyankar   PetscFunctionReturn(0);
1033450b117fSShri Abhyankar }
1034b24902e0SBarry Smith 
1035141f4205SHong Zhang /* Note the Petsc r permutation and factor info are ignored */
1036397b6df1SKris Buschelman #undef __FUNCT__
103767877ebaSShri Abhyankar #define __FUNCT__ "MatCholeskyFactorSymbolic_MUMPS"
103867877ebaSShri Abhyankar PetscErrorCode MatCholeskyFactorSymbolic_MUMPS(Mat F,Mat A,IS r,const MatFactorInfo *info)
1039b24902e0SBarry Smith {
1040*a5e57a09SHong Zhang   Mat_MUMPS          *mumps = (Mat_MUMPS*)F->spptr;
1041dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
104267877ebaSShri Abhyankar   Vec                b;
104367877ebaSShri Abhyankar   IS                 is_iden;
104467877ebaSShri Abhyankar   const PetscInt     M = A->rmap->N;
1045397b6df1SKris Buschelman 
1046397b6df1SKris Buschelman   PetscFunctionBegin;
1047*a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1048dcd589f8SShri Abhyankar 
10499a2535b5SHong Zhang   /* Set MUMPS options from the options database */
10509a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1051dcd589f8SShri Abhyankar 
1052*a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1 , MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1053dcd589f8SShri Abhyankar 
105467877ebaSShri Abhyankar   /* analysis phase */
105567877ebaSShri Abhyankar   /*----------------*/
1056*a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1057*a5e57a09SHong Zhang   mumps->id.n = M;
1058*a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)){
105967877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1060*a5e57a09SHong Zhang     if (!mumps->myid) {
1061*a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1062*a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1){
106367877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
10642907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
1065*a5e57a09SHong Zhang         mumps->id.a = (mumps_complex*)mumps->val;
10662907cef9SHong Zhang #else
1067*a5e57a09SHong Zhang         mumps->id.a = (mumps_double_complex*)mumps->val;
10682907cef9SHong Zhang #endif
106967877ebaSShri Abhyankar #else
1070*a5e57a09SHong Zhang         mumps->id.a = mumps->val;
107167877ebaSShri Abhyankar #endif
107267877ebaSShri Abhyankar       }
107367877ebaSShri Abhyankar     }
107467877ebaSShri Abhyankar     break;
107567877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1076*a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1077*a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1078*a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
107967877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
10802907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
1081*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_complex*)mumps->val;
10822907cef9SHong Zhang #else
1083*a5e57a09SHong Zhang       mumps->id.a_loc = (mumps_double_complex*)mumps->val;
10842907cef9SHong Zhang #endif
108567877ebaSShri Abhyankar #else
1086*a5e57a09SHong Zhang       mumps->id.a_loc = mumps->val;
108767877ebaSShri Abhyankar #endif
108867877ebaSShri Abhyankar     }
108967877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1090*a5e57a09SHong Zhang     if (!mumps->myid){
1091*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
109267877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
109367877ebaSShri Abhyankar     } else {
1094*a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
109567877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
109667877ebaSShri Abhyankar     }
109767877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
109867877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
109967877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
110067877ebaSShri Abhyankar 
1101*a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
11026bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
11036bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
110467877ebaSShri Abhyankar     break;
110567877ebaSShri Abhyankar     }
1106*a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1107*a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
110867877ebaSShri Abhyankar 
11092792810eSHong Zhang   F->ops->choleskyfactornumeric = MatFactorNumeric_MUMPS;
1110dcd589f8SShri Abhyankar   F->ops->solve                 = MatSolve_MUMPS;
111151d5961aSHong Zhang   F->ops->solvetranspose        = MatSolve_MUMPS;
111230c107b7SHong Zhang   F->ops->matsolve              = 0; /* use MatMatSolve_Basic() until mumps supports distributed rhs */
1113db4efbfdSBarry Smith #if !defined(PETSC_USE_COMPLEX)
111405aa0992SJose Roman   F->ops->getinertia            = MatGetInertia_SBAIJMUMPS;
111505aa0992SJose Roman #else
111605aa0992SJose Roman   F->ops->getinertia            = PETSC_NULL;
1117db4efbfdSBarry Smith #endif
1118b24902e0SBarry Smith   PetscFunctionReturn(0);
1119b24902e0SBarry Smith }
1120b24902e0SBarry Smith 
1121397b6df1SKris Buschelman #undef __FUNCT__
112264e6c443SBarry Smith #define __FUNCT__ "MatView_MUMPS"
112364e6c443SBarry Smith PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer)
112474ed9c26SBarry Smith {
1125f6c57405SHong Zhang   PetscErrorCode    ierr;
112664e6c443SBarry Smith   PetscBool         iascii;
112764e6c443SBarry Smith   PetscViewerFormat format;
1128*a5e57a09SHong Zhang   Mat_MUMPS         *mumps=(Mat_MUMPS*)A->spptr;
1129f6c57405SHong Zhang 
1130f6c57405SHong Zhang   PetscFunctionBegin;
113164e6c443SBarry Smith   /* check if matrix is mumps type */
113264e6c443SBarry Smith   if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0);
113364e6c443SBarry Smith 
1134251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
113564e6c443SBarry Smith   if (iascii) {
113664e6c443SBarry Smith     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
113764e6c443SBarry Smith     if (format == PETSC_VIEWER_ASCII_INFO){
113864e6c443SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr);
1139*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  SYM (matrix type):                   %d \n",mumps->id.sym);CHKERRQ(ierr);
1140*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  PAR (host participation):            %d \n",mumps->id.par);CHKERRQ(ierr);
1141*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(1) (output for error):         %d \n",mumps->id.ICNTL(1));CHKERRQ(ierr);
1142*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(2) (output of diagnostic msg): %d \n",mumps->id.ICNTL(2));CHKERRQ(ierr);
1143*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(3) (output for global info):   %d \n",mumps->id.ICNTL(3));CHKERRQ(ierr);
1144*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(4) (level of printing):        %d \n",mumps->id.ICNTL(4));CHKERRQ(ierr);
1145*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(5) (input mat struct):         %d \n",mumps->id.ICNTL(5));CHKERRQ(ierr);
1146*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(6) (matrix prescaling):        %d \n",mumps->id.ICNTL(6));CHKERRQ(ierr);
1147*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(7) (sequentia matrix ordering):%d \n",mumps->id.ICNTL(7));CHKERRQ(ierr);
1148*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(8) (scalling strategy):        %d \n",mumps->id.ICNTL(8));CHKERRQ(ierr);
1149*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(10) (max num of refinements):  %d \n",mumps->id.ICNTL(10));CHKERRQ(ierr);
1150*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(11) (error analysis):          %d \n",mumps->id.ICNTL(11));CHKERRQ(ierr);
1151*a5e57a09SHong Zhang       if (mumps->id.ICNTL(11)>0) {
1152*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(4) (inf norm of input mat):        %g\n",mumps->id.RINFOG(4));CHKERRQ(ierr);
1153*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(5) (inf norm of solution):         %g\n",mumps->id.RINFOG(5));CHKERRQ(ierr);
1154*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(6) (inf norm of residual):         %g\n",mumps->id.RINFOG(6));CHKERRQ(ierr);
1155*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(7),RINFOG(8) (backward error est): %g, %g\n",mumps->id.RINFOG(7),mumps->id.RINFOG(8));CHKERRQ(ierr);
1156*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(9) (error estimate):               %g \n",mumps->id.RINFOG(9));CHKERRQ(ierr);
1157*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(10),RINFOG(11)(condition numbers): %g, %g\n",mumps->id.RINFOG(10),mumps->id.RINFOG(11));CHKERRQ(ierr);
1158f6c57405SHong Zhang       }
1159*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(12) (efficiency control):                         %d \n",mumps->id.ICNTL(12));CHKERRQ(ierr);
1160*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(13) (efficiency control):                         %d \n",mumps->id.ICNTL(13));CHKERRQ(ierr);
1161*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(14) (percentage of estimated workspace increase): %d \n",mumps->id.ICNTL(14));CHKERRQ(ierr);
1162f6c57405SHong Zhang       /* ICNTL(15-17) not used */
1163*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(18) (input mat struct):                           %d \n",mumps->id.ICNTL(18));CHKERRQ(ierr);
1164*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(19) (Shur complement info):                       %d \n",mumps->id.ICNTL(19));CHKERRQ(ierr);
1165*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(20) (rhs sparse pattern):                         %d \n",mumps->id.ICNTL(20));CHKERRQ(ierr);
1166*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(21) (somumpstion struct):                            %d \n",mumps->id.ICNTL(21));CHKERRQ(ierr);
1167*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(22) (in-core/out-of-core facility):               %d \n",mumps->id.ICNTL(22));CHKERRQ(ierr);
1168*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(23) (max size of memory can be allocated locally):%d \n",mumps->id.ICNTL(23));CHKERRQ(ierr);
1169c0165424SHong Zhang 
1170*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(24) (detection of null pivot rows):               %d \n",mumps->id.ICNTL(24));CHKERRQ(ierr);
1171*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(25) (computation of a null space basis):          %d \n",mumps->id.ICNTL(25));CHKERRQ(ierr);
1172*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(26) (Schur options for rhs or solution):          %d \n",mumps->id.ICNTL(26));CHKERRQ(ierr);
1173*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(27) (experimental parameter):                     %d \n",mumps->id.ICNTL(27));CHKERRQ(ierr);
1174*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(28) (use parallel or sequential ordering):        %d \n",mumps->id.ICNTL(28));CHKERRQ(ierr);
1175*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(29) (parallel ordering):                          %d \n",mumps->id.ICNTL(29));CHKERRQ(ierr);
117642179a6aSHong Zhang 
1177*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(30) (user-specified set of entries in inv(A)):    %d \n",mumps->id.ICNTL(30));CHKERRQ(ierr);
1178*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(31) (factors is discarded in the solve phase):    %d \n",mumps->id.ICNTL(31));CHKERRQ(ierr);
1179*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(33) (compute determinant):                        %d \n",mumps->id.ICNTL(33));CHKERRQ(ierr);
1180f6c57405SHong Zhang 
1181*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(1) (relative pivoting threshold):      %g \n",mumps->id.CNTL(1));CHKERRQ(ierr);
1182*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(2) (stopping criterion of refinement): %g \n",mumps->id.CNTL(2));CHKERRQ(ierr);
1183*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(3) (absomumpste pivoting threshold):      %g \n",mumps->id.CNTL(3));CHKERRQ(ierr);
1184*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(4) (vamumpse of static pivoting):         %g \n",mumps->id.CNTL(4));CHKERRQ(ierr);
1185*a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(5) (fixation for null pivots):         %g \n",mumps->id.CNTL(5));CHKERRQ(ierr);
1186f6c57405SHong Zhang 
1187f6c57405SHong Zhang       /* infomation local to each processor */
118834ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);
11897b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
1190*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %g \n",mumps->myid,mumps->id.RINFO(1));CHKERRQ(ierr);
119134ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
119234ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);
1193*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(2));CHKERRQ(ierr);
119434ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
119534ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);
1196*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(3));CHKERRQ(ierr);
119734ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1198f6c57405SHong Zhang 
119934ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(15) (estimated size of (in MB) MUMPS internal data for running numerical factorization): \n");CHKERRQ(ierr);
1200*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"  [%d] %d \n",mumps->myid,mumps->id.INFO(15));CHKERRQ(ierr);
120134ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1202f6c57405SHong Zhang 
120334ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(16) (size of (in MB) MUMPS internal data used during numerical factorization): \n");CHKERRQ(ierr);
1204*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(16));CHKERRQ(ierr);
120534ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1206f6c57405SHong Zhang 
120734ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);
1208*a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(23));CHKERRQ(ierr);
120934ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
12107b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
1211f6c57405SHong Zhang 
1212*a5e57a09SHong Zhang       if (!mumps->myid){ /* information from the host */
1213*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",mumps->id.RINFOG(1));CHKERRQ(ierr);
1214*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",mumps->id.RINFOG(2));CHKERRQ(ierr);
1215*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",mumps->id.RINFOG(3));CHKERRQ(ierr);
1216*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  (RINFOG(12) RINFOG(13))*2^INFOG(34) (determinant): (%g,%g)*(2^%d)\n",mumps->id.RINFOG(12),mumps->id.RINFOG(13),mumps->id.INFOG(34));CHKERRQ(ierr);
1217f6c57405SHong Zhang 
1218*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(3));CHKERRQ(ierr);
1219*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(4));CHKERRQ(ierr);
1220*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(5) (estimated maximum front size in the complete tree): %d \n",mumps->id.INFOG(5));CHKERRQ(ierr);
1221*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(6) (number of nodes in the complete tree): %d \n",mumps->id.INFOG(6));CHKERRQ(ierr);
1222*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(7) (ordering option effectively use after analysis): %d \n",mumps->id.INFOG(7));CHKERRQ(ierr);
1223*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",mumps->id.INFOG(8));CHKERRQ(ierr);
1224*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(9) (total real/complex workspace to store the matrix factors after factorization): %d \n",mumps->id.INFOG(9));CHKERRQ(ierr);
1225*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(10) (total integer space store the matrix factors after factorization): %d \n",mumps->id.INFOG(10));CHKERRQ(ierr);
1226*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(11) (order of largest frontal matrix after factorization): %d \n",mumps->id.INFOG(11));CHKERRQ(ierr);
1227*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(12) (number of off-diagonal pivots): %d \n",mumps->id.INFOG(12));CHKERRQ(ierr);
1228*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(13) (number of delayed pivots after factorization): %d \n",mumps->id.INFOG(13));CHKERRQ(ierr);
1229*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(14) (number of memory compress after factorization): %d \n",mumps->id.INFOG(14));CHKERRQ(ierr);
1230*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(15) (number of steps of iterative refinement after solution): %d \n",mumps->id.INFOG(15));CHKERRQ(ierr);
1231*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(16) (estimated size (in MB) of all MUMPS internal data for factorization after analysis: value on the most memory consuming processor): %d \n",mumps->id.INFOG(16));CHKERRQ(ierr);
1232*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(17) (estimated size of all MUMPS internal data for factorization after analysis: sum over all processors): %d \n",mumps->id.INFOG(17));CHKERRQ(ierr);
1233*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(18) (size of all MUMPS internal data allocated during factorization: value on the most memory consuming processor): %d \n",mumps->id.INFOG(18));CHKERRQ(ierr);
1234*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(19) (size of all MUMPS internal data allocated during factorization: sum over all processors): %d \n",mumps->id.INFOG(19));CHKERRQ(ierr);
1235*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(20) (estimated number of entries in the factors): %d \n",mumps->id.INFOG(20));CHKERRQ(ierr);
1236*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(21) (size in MB of memory effectively used during factorization - value on the most memory consuming processor): %d \n",mumps->id.INFOG(21));CHKERRQ(ierr);
1237*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(22) (size in MB of memory effectively used during factorization - sum over all processors): %d \n",mumps->id.INFOG(22));CHKERRQ(ierr);
1238*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",mumps->id.INFOG(23));CHKERRQ(ierr);
1239*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",mumps->id.INFOG(24));CHKERRQ(ierr);
1240*a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",mumps->id.INFOG(25));CHKERRQ(ierr);
1241f6c57405SHong Zhang       }
1242f6c57405SHong Zhang     }
1243cb828f0fSHong Zhang   }
1244f6c57405SHong Zhang   PetscFunctionReturn(0);
1245f6c57405SHong Zhang }
1246f6c57405SHong Zhang 
124735bd34faSBarry Smith #undef __FUNCT__
124835bd34faSBarry Smith #define __FUNCT__ "MatGetInfo_MUMPS"
124935bd34faSBarry Smith PetscErrorCode MatGetInfo_MUMPS(Mat A,MatInfoType flag,MatInfo *info)
125035bd34faSBarry Smith {
1251cb828f0fSHong Zhang   Mat_MUMPS  *mumps =(Mat_MUMPS*)A->spptr;
125235bd34faSBarry Smith 
125335bd34faSBarry Smith   PetscFunctionBegin;
125435bd34faSBarry Smith   info->block_size        = 1.0;
1255cb828f0fSHong Zhang   info->nz_allocated      = mumps->id.INFOG(20);
1256cb828f0fSHong Zhang   info->nz_used           = mumps->id.INFOG(20);
125735bd34faSBarry Smith   info->nz_unneeded       = 0.0;
125835bd34faSBarry Smith   info->assemblies        = 0.0;
125935bd34faSBarry Smith   info->mallocs           = 0.0;
126035bd34faSBarry Smith   info->memory            = 0.0;
126135bd34faSBarry Smith   info->fill_ratio_given  = 0;
126235bd34faSBarry Smith   info->fill_ratio_needed = 0;
126335bd34faSBarry Smith   info->factor_mallocs    = 0;
126435bd34faSBarry Smith   PetscFunctionReturn(0);
126535bd34faSBarry Smith }
126635bd34faSBarry Smith 
12675ccb76cbSHong Zhang /* -------------------------------------------------------------------------------------------*/
12685ccb76cbSHong Zhang #undef __FUNCT__
12695ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl_MUMPS"
12705ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl_MUMPS(Mat F,PetscInt icntl,PetscInt ival)
12715ccb76cbSHong Zhang {
1272*a5e57a09SHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
12735ccb76cbSHong Zhang 
12745ccb76cbSHong Zhang   PetscFunctionBegin;
1275*a5e57a09SHong Zhang   mumps->id.ICNTL(icntl) = ival;
12765ccb76cbSHong Zhang   PetscFunctionReturn(0);
12775ccb76cbSHong Zhang }
12785ccb76cbSHong Zhang 
12795ccb76cbSHong Zhang #undef __FUNCT__
12805ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl"
12815ccb76cbSHong Zhang /*@
12825ccb76cbSHong Zhang   MatMumpsSetIcntl - Set MUMPS parameter ICNTL()
12835ccb76cbSHong Zhang 
12845ccb76cbSHong Zhang    Logically Collective on Mat
12855ccb76cbSHong Zhang 
12865ccb76cbSHong Zhang    Input Parameters:
12875ccb76cbSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
12885ccb76cbSHong Zhang .  icntl - index of MUMPS parameter array ICNTL()
12895ccb76cbSHong Zhang -  ival - value of MUMPS ICNTL(icntl)
12905ccb76cbSHong Zhang 
12915ccb76cbSHong Zhang   Options Database:
12925ccb76cbSHong Zhang .   -mat_mumps_icntl_<icntl> <ival>
12935ccb76cbSHong Zhang 
12945ccb76cbSHong Zhang    Level: beginner
12955ccb76cbSHong Zhang 
12965ccb76cbSHong Zhang    References: MUMPS Users' Guide
12975ccb76cbSHong Zhang 
12985ccb76cbSHong Zhang .seealso: MatGetFactor()
12995ccb76cbSHong Zhang @*/
13005ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl(Mat F,PetscInt icntl,PetscInt ival)
13015ccb76cbSHong Zhang {
13025ccb76cbSHong Zhang   PetscErrorCode ierr;
13035ccb76cbSHong Zhang 
13045ccb76cbSHong Zhang   PetscFunctionBegin;
13055ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
13065ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,ival,3);
13075ccb76cbSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsSetIcntl_C",(Mat,PetscInt,PetscInt),(F,icntl,ival));CHKERRQ(ierr);
13085ccb76cbSHong Zhang   PetscFunctionReturn(0);
13095ccb76cbSHong Zhang }
13105ccb76cbSHong Zhang 
131124b6179bSKris Buschelman /*MC
13122692d6eeSBarry Smith   MATSOLVERMUMPS -  A matrix type providing direct solvers (LU and Cholesky) for
131324b6179bSKris Buschelman   distributed and sequential matrices via the external package MUMPS.
131424b6179bSKris Buschelman 
131541c8de11SBarry Smith   Works with MATAIJ and MATSBAIJ matrices
131624b6179bSKris Buschelman 
131724b6179bSKris Buschelman   Options Database Keys:
1318fb8376fbSHong Zhang + -mat_mumps_icntl_4 <0,...,4> - print level
131924b6179bSKris Buschelman . -mat_mumps_icntl_6 <0,...,7> - matrix prescaling options (see MUMPS User's Guide)
132064e6c443SBarry Smith . -mat_mumps_icntl_7 <0,...,7> - matrix orderings (see MUMPS User's Guidec)
132124b6179bSKris Buschelman . -mat_mumps_icntl_9 <1,2> - A or A^T x=b to be solved: 1 denotes A, 2 denotes A^T
132224b6179bSKris Buschelman . -mat_mumps_icntl_10 <n> - maximum number of iterative refinements
132394b7f48cSBarry Smith . -mat_mumps_icntl_11 <n> - error analysis, a positive value returns statistics during -ksp_view
132424b6179bSKris Buschelman . -mat_mumps_icntl_12 <n> - efficiency control (see MUMPS User's Guide)
132524b6179bSKris Buschelman . -mat_mumps_icntl_13 <n> - efficiency control (see MUMPS User's Guide)
132624b6179bSKris Buschelman . -mat_mumps_icntl_14 <n> - efficiency control (see MUMPS User's Guide)
132724b6179bSKris Buschelman . -mat_mumps_icntl_15 <n> - efficiency control (see MUMPS User's Guide)
132824b6179bSKris Buschelman . -mat_mumps_cntl_1 <delta> - relative pivoting threshold
132924b6179bSKris Buschelman . -mat_mumps_cntl_2 <tol> - stopping criterion for refinement
133024b6179bSKris Buschelman - -mat_mumps_cntl_3 <adelta> - absolute pivoting threshold
133124b6179bSKris Buschelman 
133224b6179bSKris Buschelman   Level: beginner
133324b6179bSKris Buschelman 
133441c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
133541c8de11SBarry Smith 
133624b6179bSKris Buschelman M*/
133724b6179bSKris Buschelman 
13382877fffaSHong Zhang EXTERN_C_BEGIN
133935bd34faSBarry Smith #undef __FUNCT__
134035bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_mumps"
134135bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_mumps(Mat A,const MatSolverPackage *type)
134235bd34faSBarry Smith {
134335bd34faSBarry Smith   PetscFunctionBegin;
13442692d6eeSBarry Smith   *type = MATSOLVERMUMPS;
134535bd34faSBarry Smith   PetscFunctionReturn(0);
134635bd34faSBarry Smith }
134735bd34faSBarry Smith EXTERN_C_END
134835bd34faSBarry Smith 
134935bd34faSBarry Smith EXTERN_C_BEGIN
1350bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI AIJ matrices */
13512877fffaSHong Zhang #undef __FUNCT__
1352bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_aij_mumps"
1353bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_aij_mumps(Mat A,MatFactorType ftype,Mat *F)
13542877fffaSHong Zhang {
13552877fffaSHong Zhang   Mat            B;
13562877fffaSHong Zhang   PetscErrorCode ierr;
13572877fffaSHong Zhang   Mat_MUMPS      *mumps;
1358ace3abfcSBarry Smith   PetscBool      isSeqAIJ;
13592877fffaSHong Zhang 
13602877fffaSHong Zhang   PetscFunctionBegin;
13612877fffaSHong Zhang   /* Create the factorization matrix */
1362251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
13632877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
13642877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
13652877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1366bccb9932SShri Abhyankar   if (isSeqAIJ) {
13672877fffaSHong Zhang     ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
1368bccb9932SShri Abhyankar   } else {
1369bccb9932SShri Abhyankar     ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1370bccb9932SShri Abhyankar   }
13712877fffaSHong Zhang 
137216ebf90aSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
13732877fffaSHong Zhang   B->ops->view             = MatView_MUMPS;
137435bd34faSBarry Smith   B->ops->getinfo          = MatGetInfo_MUMPS;
137535bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
13765ccb76cbSHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl_MUMPS",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
1377450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1378450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
1379d5f3da31SBarry Smith     B->factortype = MAT_FACTOR_LU;
1380bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqaij;
1381bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpiaij;
1382746480a1SHong Zhang     mumps->sym = 0;
1383dcd589f8SShri Abhyankar   } else {
138467877ebaSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
1385450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_CHOLESKY;
1386bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqsbaij;
1387bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpisbaij;
13886fdc2a6dSBarry Smith     if (A->spd_set && A->spd) mumps->sym = 1;
13896fdc2a6dSBarry Smith     else                      mumps->sym = 2;
1390450b117fSShri Abhyankar   }
13912877fffaSHong Zhang 
13922877fffaSHong Zhang   mumps->isAIJ        = PETSC_TRUE;
1393bf0cc555SLisandro Dalcin   mumps->Destroy      = B->ops->destroy;
13942877fffaSHong Zhang   B->ops->destroy     = MatDestroy_MUMPS;
13952877fffaSHong Zhang   B->spptr            = (void*)mumps;
1396f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
1397746480a1SHong Zhang 
13982877fffaSHong Zhang   *F = B;
13992877fffaSHong Zhang   PetscFunctionReturn(0);
14002877fffaSHong Zhang }
14012877fffaSHong Zhang EXTERN_C_END
14022877fffaSHong Zhang 
1403bccb9932SShri Abhyankar 
14042877fffaSHong Zhang EXTERN_C_BEGIN
1405bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI SBAIJ matrices */
14062877fffaSHong Zhang #undef __FUNCT__
1407bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_sbaij_mumps"
1408bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_sbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
14092877fffaSHong Zhang {
14102877fffaSHong Zhang   Mat            B;
14112877fffaSHong Zhang   PetscErrorCode ierr;
14122877fffaSHong Zhang   Mat_MUMPS      *mumps;
1413ace3abfcSBarry Smith   PetscBool      isSeqSBAIJ;
14142877fffaSHong Zhang 
14152877fffaSHong Zhang   PetscFunctionBegin;
1416e7e72b3dSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
1417bccb9932SShri Abhyankar   if (A->rmap->bs > 1) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with block size > 1 with MUMPS Cholesky, use AIJ matrix instead");
1418251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
14192877fffaSHong Zhang   /* Create the factorization matrix */
14202877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
14212877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
14222877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
142316ebf90aSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1424bccb9932SShri Abhyankar   if (isSeqSBAIJ) {
1425bccb9932SShri Abhyankar     ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
142616ebf90aSShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_seqsbaij_seqsbaij;
1427dcd589f8SShri Abhyankar   } else {
1428bccb9932SShri Abhyankar     ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1429bccb9932SShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_mpisbaij_mpisbaij;
1430bccb9932SShri Abhyankar   }
1431bccb9932SShri Abhyankar 
143267877ebaSShri Abhyankar   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
1433bccb9932SShri Abhyankar   B->ops->view                   = MatView_MUMPS;
1434bccb9932SShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
1435f250808bSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1436f4762488SHong Zhang   B->factortype                  = MAT_FACTOR_CHOLESKY;
14376fdc2a6dSBarry Smith   if (A->spd_set && A->spd) mumps->sym = 1;
14386fdc2a6dSBarry Smith   else                      mumps->sym = 2;
1439a214ac2aSShri Abhyankar 
1440bccb9932SShri Abhyankar   mumps->isAIJ        = PETSC_FALSE;
1441bf0cc555SLisandro Dalcin   mumps->Destroy      = B->ops->destroy;
1442f3c0ef26SHong Zhang   B->ops->destroy     = MatDestroy_MUMPS;
14432877fffaSHong Zhang   B->spptr            = (void*)mumps;
1444f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
1445746480a1SHong Zhang 
14462877fffaSHong Zhang   *F = B;
14472877fffaSHong Zhang   PetscFunctionReturn(0);
14482877fffaSHong Zhang }
14492877fffaSHong Zhang EXTERN_C_END
145097969023SHong Zhang 
1451450b117fSShri Abhyankar EXTERN_C_BEGIN
1452450b117fSShri Abhyankar #undef __FUNCT__
1453bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_baij_mumps"
1454bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_baij_mumps(Mat A,MatFactorType ftype,Mat *F)
145567877ebaSShri Abhyankar {
145667877ebaSShri Abhyankar   Mat            B;
145767877ebaSShri Abhyankar   PetscErrorCode ierr;
145867877ebaSShri Abhyankar   Mat_MUMPS      *mumps;
1459ace3abfcSBarry Smith   PetscBool      isSeqBAIJ;
146067877ebaSShri Abhyankar 
146167877ebaSShri Abhyankar   PetscFunctionBegin;
146267877ebaSShri Abhyankar   /* Create the factorization matrix */
1463251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&isSeqBAIJ);CHKERRQ(ierr);
146467877ebaSShri Abhyankar   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
146567877ebaSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
146667877ebaSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1467bccb9932SShri Abhyankar   if (isSeqBAIJ) {
146867877ebaSShri Abhyankar     ierr = MatSeqBAIJSetPreallocation(B,A->rmap->bs,0,PETSC_NULL);CHKERRQ(ierr);
1469bccb9932SShri Abhyankar   } else {
147067877ebaSShri Abhyankar     ierr = MatMPIBAIJSetPreallocation(B,A->rmap->bs,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1471bccb9932SShri Abhyankar   }
1472450b117fSShri Abhyankar 
147367877ebaSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1474450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1475450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_BAIJMUMPS;
1476450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_LU;
1477bccb9932SShri Abhyankar     if (isSeqBAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqbaij_seqaij;
1478bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpibaij_mpiaij;
1479746480a1SHong Zhang     mumps->sym = 0;
1480746480a1SHong Zhang   } else {
1481746480a1SHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc BAIJ matrices with MUMPS Cholesky, use SBAIJ or AIJ matrix instead\n");
1482450b117fSShri Abhyankar   }
1483bccb9932SShri Abhyankar 
1484450b117fSShri Abhyankar   B->ops->view             = MatView_MUMPS;
1485450b117fSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
14865ccb76cbSHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl_MUMPS",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
1487450b117fSShri Abhyankar 
1488450b117fSShri Abhyankar   mumps->isAIJ        = PETSC_TRUE;
1489bf0cc555SLisandro Dalcin   mumps->Destroy      = B->ops->destroy;
1490450b117fSShri Abhyankar   B->ops->destroy     = MatDestroy_MUMPS;
1491450b117fSShri Abhyankar   B->spptr            = (void*)mumps;
1492f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
1493746480a1SHong Zhang 
1494450b117fSShri Abhyankar   *F = B;
1495450b117fSShri Abhyankar   PetscFunctionReturn(0);
1496450b117fSShri Abhyankar }
1497450b117fSShri Abhyankar EXTERN_C_END
1498a214ac2aSShri Abhyankar 
1499