xref: /petsc/src/mat/impls/aij/mpi/mumps/mumps.c (revision bccb993214ee4cc0008fb48715c77d528cac756e)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
21c2a3de1SBarry Smith 
3397b6df1SKris Buschelman /*
4c2b5dc30SHong Zhang     Provides an interface to the MUMPS sparse solver
5397b6df1SKris Buschelman */
64e1dd20eSHong Zhang #include "../src/mat/impls/aij/seq/aij.h"  /*I  "petscmat.h"  I*/
77c4f633dSBarry Smith #include "../src/mat/impls/aij/mpi/mpiaij.h"
87c4f633dSBarry Smith #include "../src/mat/impls/sbaij/seq/sbaij.h"
97c4f633dSBarry Smith #include "../src/mat/impls/sbaij/mpi/mpisbaij.h"
10450b117fSShri Abhyankar #include "../src/mat/impls/baij/seq/baij.h"
11450b117fSShri Abhyankar #include "../src/mat/impls/baij/mpi/mpibaij.h"
12397b6df1SKris Buschelman 
13397b6df1SKris Buschelman EXTERN_C_BEGIN
14397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
15397b6df1SKris Buschelman #include "zmumps_c.h"
16397b6df1SKris Buschelman #else
17397b6df1SKris Buschelman #include "dmumps_c.h"
18397b6df1SKris Buschelman #endif
19397b6df1SKris Buschelman EXTERN_C_END
20397b6df1SKris Buschelman #define JOB_INIT -1
21397b6df1SKris Buschelman #define JOB_END -2
22397b6df1SKris Buschelman /* macros s.t. indices match MUMPS documentation */
23397b6df1SKris Buschelman #define ICNTL(I) icntl[(I)-1]
24397b6df1SKris Buschelman #define CNTL(I) cntl[(I)-1]
25397b6df1SKris Buschelman #define INFOG(I) infog[(I)-1]
26a7aca84bSHong Zhang #define INFO(I) info[(I)-1]
27397b6df1SKris Buschelman #define RINFOG(I) rinfog[(I)-1]
28adc1d99fSHong Zhang #define RINFO(I) rinfo[(I)-1]
29397b6df1SKris Buschelman 
30397b6df1SKris Buschelman typedef struct {
31397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
32397b6df1SKris Buschelman   ZMUMPS_STRUC_C id;
33397b6df1SKris Buschelman #else
34397b6df1SKris Buschelman   DMUMPS_STRUC_C id;
35397b6df1SKris Buschelman #endif
36397b6df1SKris Buschelman   MatStructure   matstruc;
37c1490034SHong Zhang   PetscMPIInt    myid,size;
3816ebf90aSShri Abhyankar   PetscInt       *irn,*jcn,nz,sym,nSolve;
39397b6df1SKris Buschelman   PetscScalar    *val;
40397b6df1SKris Buschelman   MPI_Comm       comm_mumps;
41329ec9b3SHong Zhang   VecScatter     scat_rhs, scat_sol;
42cb828f0fSHong Zhang   PetscTruth     isAIJ,CleanUpMUMPS,mumpsview;
43329ec9b3SHong Zhang   Vec            b_seq,x_seq;
4467334b25SHong Zhang   PetscErrorCode (*MatDestroy)(Mat);
45*bccb9932SShri Abhyankar   PetscErrorCode (*ConvertToTriples)(Mat, int, MatReuse, int*, int**, int**, PetscScalar**);
46f0c56d0fSKris Buschelman } Mat_MUMPS;
47f0c56d0fSKris Buschelman 
48dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*);
49b24902e0SBarry Smith 
5067877ebaSShri Abhyankar 
5167877ebaSShri Abhyankar /* MatConvertToTriples_A_B */
5267877ebaSShri Abhyankar /*convert Petsc matrix to triples: row[nz], col[nz], val[nz] */
53397b6df1SKris Buschelman /*
54397b6df1SKris Buschelman   input:
5567877ebaSShri Abhyankar     A       - matrix in aij,baij or sbaij (bs=1) format
56397b6df1SKris Buschelman     shift   - 0: C style output triple; 1: Fortran style output triple.
57*bccb9932SShri Abhyankar     reuse   - MAT_INITIAL_MATRIX: spaces are allocated and values are set for the triple
58*bccb9932SShri Abhyankar               MAT_REUSE_MATRIX:   only the values in v array are updated
59397b6df1SKris Buschelman   output:
60397b6df1SKris Buschelman     nnz     - dim of r, c, and v (number of local nonzero entries of A)
61397b6df1SKris Buschelman     r, c, v - row and col index, matrix values (matrix triples)
62397b6df1SKris Buschelman  */
6316ebf90aSShri Abhyankar 
6416ebf90aSShri Abhyankar #undef __FUNCT__
6516ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqaij"
66*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
67b24902e0SBarry Smith {
6867877ebaSShri Abhyankar   const PetscInt   *ai,*aj,*ajj,M=A->rmap->n;;
6967877ebaSShri Abhyankar   PetscInt         nz,rnz,i,j;
70dfbe8321SBarry Smith   PetscErrorCode   ierr;
71c1490034SHong Zhang   PetscInt         *row,*col;
7216ebf90aSShri Abhyankar   Mat_SeqAIJ       *aa=(Mat_SeqAIJ*)A->data;
73397b6df1SKris Buschelman 
74397b6df1SKris Buschelman   PetscFunctionBegin;
7516ebf90aSShri Abhyankar   *v=aa->a;
76*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
7716ebf90aSShri Abhyankar     nz = aa->nz; ai = aa->i; aj = aa->j;
7816ebf90aSShri Abhyankar     *nnz = nz;
7916ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
8016ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &col);CHKERRQ(ierr);
8116ebf90aSShri Abhyankar     nz = 0;
8216ebf90aSShri Abhyankar     for(i=0; i<M; i++) {
8316ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
8467877ebaSShri Abhyankar       ajj = aj + ai[i];
8567877ebaSShri Abhyankar       for(j=0; j<rnz; j++) {
8667877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz++] = ajj[j] + shift;
8716ebf90aSShri Abhyankar       }
8816ebf90aSShri Abhyankar     }
8916ebf90aSShri Abhyankar     *r = row; *c = col;
9016ebf90aSShri Abhyankar   }
9116ebf90aSShri Abhyankar   PetscFunctionReturn(0);
9216ebf90aSShri Abhyankar }
93397b6df1SKris Buschelman 
9416ebf90aSShri Abhyankar #undef __FUNCT__
9567877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqbaij_seqaij"
96*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqbaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
9767877ebaSShri Abhyankar {
9867877ebaSShri Abhyankar   Mat_SeqBAIJ        *aa=(Mat_SeqBAIJ*)A->data;
9967877ebaSShri Abhyankar   const PetscInt     *ai,*aj,*ajj,bs=A->rmap->bs,bs2=aa->bs2,M=A->rmap->N/bs;
10067877ebaSShri Abhyankar   const PetscScalar  *av,*v1;
10167877ebaSShri Abhyankar   PetscScalar        *val;
10267877ebaSShri Abhyankar   PetscInt           nz,idx=0,rnz,i,j,k,m,ii;
10367877ebaSShri Abhyankar   PetscErrorCode     ierr;
10467877ebaSShri Abhyankar   PetscInt           *row,*col;
10567877ebaSShri Abhyankar 
10667877ebaSShri Abhyankar   PetscFunctionBegin;
10767877ebaSShri Abhyankar   ai = aa->i; aj = aa->j; av = aa->a;
108*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
10967877ebaSShri Abhyankar     nz = bs2*aa->nz;
11067877ebaSShri Abhyankar     *nnz = nz;
11167877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
11267877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &col);CHKERRQ(ierr);
11367877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
11467877ebaSShri Abhyankar     for(i=0; i<M; i++) {
11567877ebaSShri Abhyankar       ii = 0;
11667877ebaSShri Abhyankar       ajj = aj + ai[i];
11767877ebaSShri Abhyankar       v1  = av + bs2*ai[i];
11867877ebaSShri Abhyankar       rnz = ai[i+1] - ai[i];
11967877ebaSShri Abhyankar       for(k=0; k<rnz; k++) {
12067877ebaSShri Abhyankar 	for(j=0; j<bs; j++) {
12167877ebaSShri Abhyankar 	  for(m=0; m<bs; m++) {
12267877ebaSShri Abhyankar 	    row[idx]   = i*bs + m + shift;
12367877ebaSShri Abhyankar 	    col[idx]   = bs*(ajj[k]) + j + shift;
12467877ebaSShri Abhyankar 	    val[idx++] = v1[ii++];
12567877ebaSShri Abhyankar 	  }
12667877ebaSShri Abhyankar 	}
12767877ebaSShri Abhyankar       }
12867877ebaSShri Abhyankar     }
12967877ebaSShri Abhyankar     *r = row; *c = col; *v = val;
13067877ebaSShri Abhyankar   } else {
13167877ebaSShri Abhyankar     row = *r; col = *c; val = *v;
13267877ebaSShri Abhyankar     for(i=0; i<M; i++) {
13367877ebaSShri Abhyankar       ii = 0;
13467877ebaSShri Abhyankar       v1   = av + bs2*ai[i];
13567877ebaSShri Abhyankar       rnz  = ai[i+1] - ai[i];
13667877ebaSShri Abhyankar       for(k=0; k<rnz; k++){
13767877ebaSShri Abhyankar 	for(j=0; j<bs; j++) {
13867877ebaSShri Abhyankar 	  for(m=0; m<bs; m++) {
13967877ebaSShri Abhyankar 	    val[idx++] = v1[ii++];
14067877ebaSShri Abhyankar 	  }
14167877ebaSShri Abhyankar 	}
14267877ebaSShri Abhyankar       }
14367877ebaSShri Abhyankar     }
14467877ebaSShri Abhyankar   }
14567877ebaSShri Abhyankar   PetscFunctionReturn(0);
14667877ebaSShri Abhyankar }
14767877ebaSShri Abhyankar 
14867877ebaSShri Abhyankar #undef __FUNCT__
14916ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqsbaij_seqsbaij"
150*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqsbaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
15116ebf90aSShri Abhyankar {
15267877ebaSShri Abhyankar   const PetscInt   *ai, *aj,*ajj,M=A->rmap->n;
15367877ebaSShri Abhyankar   PetscInt         nz,rnz,i,j;
15416ebf90aSShri Abhyankar   PetscErrorCode   ierr;
15516ebf90aSShri Abhyankar   PetscInt         *row,*col;
15616ebf90aSShri Abhyankar   Mat_SeqSBAIJ     *aa=(Mat_SeqSBAIJ*)A->data;
15716ebf90aSShri Abhyankar 
15816ebf90aSShri Abhyankar   PetscFunctionBegin;
159*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
16016ebf90aSShri Abhyankar     nz = aa->nz;ai=aa->i; aj=aa->j;*v=aa->a;
16116ebf90aSShri Abhyankar     *nnz = nz;
16216ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
16316ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &col);CHKERRQ(ierr);
16416ebf90aSShri Abhyankar     nz = 0;
16516ebf90aSShri Abhyankar     for(i=0; i<M; i++) {
16616ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
16767877ebaSShri Abhyankar       ajj = aj + ai[i];
16867877ebaSShri Abhyankar       for(j=0; j<rnz; j++) {
16967877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz++] = ajj[j] + shift;
17016ebf90aSShri Abhyankar       }
17116ebf90aSShri Abhyankar     }
17216ebf90aSShri Abhyankar     *r = row; *c = col;
17316ebf90aSShri Abhyankar   }
17416ebf90aSShri Abhyankar   PetscFunctionReturn(0);
17516ebf90aSShri Abhyankar }
17616ebf90aSShri Abhyankar 
17716ebf90aSShri Abhyankar #undef __FUNCT__
17816ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqsbaij"
179*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
18016ebf90aSShri Abhyankar {
18167877ebaSShri Abhyankar   const PetscInt     *ai,*aj,*ajj,*adiag,M=A->rmap->n;
18267877ebaSShri Abhyankar   PetscInt           nz,rnz,i,j;
18367877ebaSShri Abhyankar   const PetscScalar  *av,*v1;
18416ebf90aSShri Abhyankar   PetscScalar        *val;
18516ebf90aSShri Abhyankar   PetscErrorCode     ierr;
18616ebf90aSShri Abhyankar   PetscInt           *row,*col;
18716ebf90aSShri Abhyankar   Mat_SeqSBAIJ       *aa=(Mat_SeqSBAIJ*)A->data;
18816ebf90aSShri Abhyankar 
18916ebf90aSShri Abhyankar   PetscFunctionBegin;
19016ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j;av=aa->a;
19116ebf90aSShri Abhyankar   adiag=aa->diag;
192*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
19316ebf90aSShri Abhyankar     nz = M + (aa->nz-M)/2;
19416ebf90aSShri Abhyankar     *nnz = nz;
19516ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &row);CHKERRQ(ierr);
19616ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt), &col);CHKERRQ(ierr);
19716ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscScalar), &val);CHKERRQ(ierr);
19816ebf90aSShri Abhyankar     nz = 0;
19916ebf90aSShri Abhyankar     for(i=0; i<M; i++) {
20016ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
20167877ebaSShri Abhyankar       ajj  = aj + adiag[i];
20267877ebaSShri Abhyankar       for(j=0; j<rnz; j++) {
20367877ebaSShri Abhyankar 	row[nz] = i+shift; col[nz] = ajj[j] + shift; val[nz++] = v1[j];
20416ebf90aSShri Abhyankar       }
20516ebf90aSShri Abhyankar     }
20616ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
207397b6df1SKris Buschelman   } else {
20816ebf90aSShri Abhyankar     nz = 0; val = *v;
20916ebf90aSShri Abhyankar     for(i=0; i <M; i++) {
21016ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
21167877ebaSShri Abhyankar       ajj = aj + adiag[i];
21267877ebaSShri Abhyankar       v1  = av + adiag[i];
21367877ebaSShri Abhyankar       for(j=0; j<rnz; j++) {
21467877ebaSShri Abhyankar 	val[nz++] = v1[j];
21516ebf90aSShri Abhyankar       }
21616ebf90aSShri Abhyankar     }
21716ebf90aSShri Abhyankar   }
21816ebf90aSShri Abhyankar   PetscFunctionReturn(0);
21916ebf90aSShri Abhyankar }
22016ebf90aSShri Abhyankar 
22116ebf90aSShri Abhyankar #undef __FUNCT__
22216ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpisbaij_mpisbaij"
223*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpisbaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
22416ebf90aSShri Abhyankar {
22516ebf90aSShri Abhyankar   const PetscInt     *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
22616ebf90aSShri Abhyankar   PetscErrorCode     ierr;
22716ebf90aSShri Abhyankar   PetscInt           rstart,nz,i,j,jj,irow,countA,countB;
22816ebf90aSShri Abhyankar   PetscInt           *row,*col;
22916ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
23016ebf90aSShri Abhyankar   PetscScalar        *val;
231397b6df1SKris Buschelman   Mat_MPISBAIJ       *mat =  (Mat_MPISBAIJ*)A->data;
232397b6df1SKris Buschelman   Mat_SeqSBAIJ       *aa=(Mat_SeqSBAIJ*)(mat->A)->data;
233397b6df1SKris Buschelman   Mat_SeqBAIJ        *bb=(Mat_SeqBAIJ*)(mat->B)->data;
23416ebf90aSShri Abhyankar 
23516ebf90aSShri Abhyankar   PetscFunctionBegin;
236d0f46423SBarry Smith   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
237397b6df1SKris Buschelman   garray = mat->garray;
238397b6df1SKris Buschelman   av=aa->a; bv=bb->a;
239397b6df1SKris Buschelman 
240*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
24116ebf90aSShri Abhyankar     nz = aa->nz + bb->nz;
24216ebf90aSShri Abhyankar     *nnz = nz;
2437c307921SBarry Smith     ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr);
2447c307921SBarry Smith     ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr);
245397b6df1SKris Buschelman     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
246397b6df1SKris Buschelman     *r = row; *c = col; *v = val;
247397b6df1SKris Buschelman   } else {
248397b6df1SKris Buschelman     row = *r; col = *c; val = *v;
249397b6df1SKris Buschelman   }
250397b6df1SKris Buschelman 
251028e57e8SHong Zhang   jj = 0; irow = rstart;
252397b6df1SKris Buschelman   for ( i=0; i<m; i++ ) {
253397b6df1SKris Buschelman     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
254397b6df1SKris Buschelman     countA = ai[i+1] - ai[i];
255397b6df1SKris Buschelman     countB = bi[i+1] - bi[i];
256397b6df1SKris Buschelman     bjj    = bj + bi[i];
25716ebf90aSShri Abhyankar     v1     = av + ai[i];
25816ebf90aSShri Abhyankar     v2     = bv + bi[i];
259397b6df1SKris Buschelman 
260397b6df1SKris Buschelman     /* A-part */
261397b6df1SKris Buschelman     for (j=0; j<countA; j++){
262*bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
263397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
264397b6df1SKris Buschelman       }
26516ebf90aSShri Abhyankar       val[jj++] = v1[j];
266397b6df1SKris Buschelman     }
26716ebf90aSShri Abhyankar 
26816ebf90aSShri Abhyankar     /* B-part */
26916ebf90aSShri Abhyankar     for(j=0; j < countB; j++){
270*bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
271397b6df1SKris Buschelman 	row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
272397b6df1SKris Buschelman       }
27316ebf90aSShri Abhyankar       val[jj++] = v2[j];
27416ebf90aSShri Abhyankar     }
27516ebf90aSShri Abhyankar     irow++;
27616ebf90aSShri Abhyankar   }
27716ebf90aSShri Abhyankar   PetscFunctionReturn(0);
27816ebf90aSShri Abhyankar }
27916ebf90aSShri Abhyankar 
28016ebf90aSShri Abhyankar #undef __FUNCT__
28116ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpiaij"
282*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
28316ebf90aSShri Abhyankar {
28416ebf90aSShri Abhyankar   const PetscInt     *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
28516ebf90aSShri Abhyankar   PetscErrorCode     ierr;
28616ebf90aSShri Abhyankar   PetscInt           rstart,nz,i,j,jj,irow,countA,countB;
28716ebf90aSShri Abhyankar   PetscInt           *row,*col;
28816ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
28916ebf90aSShri Abhyankar   PetscScalar        *val;
29016ebf90aSShri Abhyankar   Mat_MPIAIJ         *mat =  (Mat_MPIAIJ*)A->data;
29116ebf90aSShri Abhyankar   Mat_SeqAIJ         *aa=(Mat_SeqAIJ*)(mat->A)->data;
29216ebf90aSShri Abhyankar   Mat_SeqAIJ         *bb=(Mat_SeqAIJ*)(mat->B)->data;
29316ebf90aSShri Abhyankar 
29416ebf90aSShri Abhyankar   PetscFunctionBegin;
29516ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
29616ebf90aSShri Abhyankar   garray = mat->garray;
29716ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
29816ebf90aSShri Abhyankar 
299*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX){
30016ebf90aSShri Abhyankar     nz = aa->nz + bb->nz;
30116ebf90aSShri Abhyankar     *nnz = nz;
30216ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr);
30316ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr);
30416ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
30516ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
30616ebf90aSShri Abhyankar   } else {
30716ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
30816ebf90aSShri Abhyankar   }
30916ebf90aSShri Abhyankar 
31016ebf90aSShri Abhyankar   jj = 0; irow = rstart;
31116ebf90aSShri Abhyankar   for ( i=0; i<m; i++ ) {
31216ebf90aSShri Abhyankar     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
31316ebf90aSShri Abhyankar     countA = ai[i+1] - ai[i];
31416ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
31516ebf90aSShri Abhyankar     bjj    = bj + bi[i];
31616ebf90aSShri Abhyankar     v1     = av + ai[i];
31716ebf90aSShri Abhyankar     v2     = bv + bi[i];
31816ebf90aSShri Abhyankar 
31916ebf90aSShri Abhyankar     /* A-part */
32016ebf90aSShri Abhyankar     for (j=0; j<countA; j++){
321*bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX){
32216ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
32316ebf90aSShri Abhyankar       }
32416ebf90aSShri Abhyankar       val[jj++] = v1[j];
32516ebf90aSShri Abhyankar     }
32616ebf90aSShri Abhyankar 
32716ebf90aSShri Abhyankar     /* B-part */
32816ebf90aSShri Abhyankar     for(j=0; j < countB; j++){
329*bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX){
33016ebf90aSShri Abhyankar 	row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
33116ebf90aSShri Abhyankar       }
33216ebf90aSShri Abhyankar       val[jj++] = v2[j];
33316ebf90aSShri Abhyankar     }
33416ebf90aSShri Abhyankar     irow++;
33516ebf90aSShri Abhyankar   }
33616ebf90aSShri Abhyankar   PetscFunctionReturn(0);
33716ebf90aSShri Abhyankar }
33816ebf90aSShri Abhyankar 
33916ebf90aSShri Abhyankar #undef __FUNCT__
34067877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpibaij_mpiaij"
341*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpibaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
34267877ebaSShri Abhyankar {
34367877ebaSShri Abhyankar   Mat_MPIBAIJ        *mat =  (Mat_MPIBAIJ*)A->data;
34467877ebaSShri Abhyankar   Mat_SeqBAIJ        *aa=(Mat_SeqBAIJ*)(mat->A)->data;
34567877ebaSShri Abhyankar   Mat_SeqBAIJ        *bb=(Mat_SeqBAIJ*)(mat->B)->data;
34667877ebaSShri Abhyankar   const PetscInt     *ai = aa->i, *bi = bb->i, *aj = aa->j, *bj = bb->j,*ajj, *bjj;
34767877ebaSShri Abhyankar   const PetscInt     *garray = mat->garray,mbs=mat->mbs,rstartbs=mat->rstartbs;
34867877ebaSShri Abhyankar   const PetscInt     bs = A->rmap->bs,bs2=mat->bs2;
34967877ebaSShri Abhyankar   PetscErrorCode     ierr;
35067877ebaSShri Abhyankar   PetscInt           nz,i,j,k,n,jj,irow,countA,countB,idx;
35167877ebaSShri Abhyankar   PetscInt           *row,*col;
35267877ebaSShri Abhyankar   const PetscScalar  *av=aa->a, *bv=bb->a,*v1,*v2;
35367877ebaSShri Abhyankar   PetscScalar        *val;
35467877ebaSShri Abhyankar 
35567877ebaSShri Abhyankar   PetscFunctionBegin;
35667877ebaSShri Abhyankar 
357*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
35867877ebaSShri Abhyankar     nz = bs2*(aa->nz + bb->nz);
35967877ebaSShri Abhyankar     *nnz = nz;
36067877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr);
36167877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr);
36267877ebaSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
36367877ebaSShri Abhyankar     *r = row; *c = col; *v = val;
36467877ebaSShri Abhyankar   } else {
36567877ebaSShri Abhyankar     row = *r; col = *c; val = *v;
36667877ebaSShri Abhyankar   }
36767877ebaSShri Abhyankar 
36867877ebaSShri Abhyankar   jj = 0; irow = rstartbs;
36967877ebaSShri Abhyankar   for ( i=0; i<mbs; i++ ) {
37067877ebaSShri Abhyankar     countA = ai[i+1] - ai[i];
37167877ebaSShri Abhyankar     countB = bi[i+1] - bi[i];
37267877ebaSShri Abhyankar     ajj    = aj + ai[i];
37367877ebaSShri Abhyankar     bjj    = bj + bi[i];
37467877ebaSShri Abhyankar     v1     = av + bs2*ai[i];
37567877ebaSShri Abhyankar     v2     = bv + bs2*bi[i];
37667877ebaSShri Abhyankar 
37767877ebaSShri Abhyankar     idx = 0;
37867877ebaSShri Abhyankar     /* A-part */
37967877ebaSShri Abhyankar     for (k=0; k<countA; k++){
38067877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
38167877ebaSShri Abhyankar 	for (n=0; n<bs; n++) {
382*bccb9932SShri Abhyankar 	  if (reuse == MAT_INITIAL_MATRIX){
38367877ebaSShri Abhyankar 	    row[jj] = bs*irow + n + shift;
38467877ebaSShri Abhyankar 	    col[jj] = bs*(rstartbs + ajj[k]) + j + shift;
38567877ebaSShri Abhyankar 	  }
38667877ebaSShri Abhyankar 	  val[jj++] = v1[idx++];
38767877ebaSShri Abhyankar 	}
38867877ebaSShri Abhyankar       }
38967877ebaSShri Abhyankar     }
39067877ebaSShri Abhyankar 
39167877ebaSShri Abhyankar     idx = 0;
39267877ebaSShri Abhyankar     /* B-part */
39367877ebaSShri Abhyankar     for(k=0; k<countB; k++){
39467877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
39567877ebaSShri Abhyankar 	for (n=0; n<bs; n++) {
396*bccb9932SShri Abhyankar 	  if (reuse == MAT_INITIAL_MATRIX){
39767877ebaSShri Abhyankar 	    row[jj] = bs*irow + n + shift;
39867877ebaSShri Abhyankar 	    col[jj] = bs*(garray[bjj[k]]) + j + shift;
39967877ebaSShri Abhyankar 	  }
40067877ebaSShri Abhyankar 	  val[jj++] = bv[idx++];
40167877ebaSShri Abhyankar 	}
40267877ebaSShri Abhyankar       }
40367877ebaSShri Abhyankar     }
40467877ebaSShri Abhyankar     irow++;
40567877ebaSShri Abhyankar   }
40667877ebaSShri Abhyankar   PetscFunctionReturn(0);
40767877ebaSShri Abhyankar }
40867877ebaSShri Abhyankar 
40967877ebaSShri Abhyankar #undef __FUNCT__
41016ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpisbaij"
411*bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
41216ebf90aSShri Abhyankar {
41316ebf90aSShri Abhyankar   const PetscInt     *ai, *aj,*adiag, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
41416ebf90aSShri Abhyankar   PetscErrorCode     ierr;
41516ebf90aSShri Abhyankar   PetscInt           rstart,nz,nza,nzb_low,i,j,jj,irow,countA,countB;
41616ebf90aSShri Abhyankar   PetscInt           *row,*col;
41716ebf90aSShri Abhyankar   const PetscScalar  *av, *bv,*v1,*v2;
41816ebf90aSShri Abhyankar   PetscScalar        *val;
41916ebf90aSShri Abhyankar   Mat_MPIAIJ         *mat =  (Mat_MPIAIJ*)A->data;
42016ebf90aSShri Abhyankar   Mat_SeqAIJ         *aa=(Mat_SeqAIJ*)(mat->A)->data;
42116ebf90aSShri Abhyankar   Mat_SeqAIJ         *bb=(Mat_SeqAIJ*)(mat->B)->data;
42216ebf90aSShri Abhyankar 
42316ebf90aSShri Abhyankar   PetscFunctionBegin;
42416ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; adiag=aa->diag;
42516ebf90aSShri Abhyankar   bi=bb->i; bj=bb->j; garray = mat->garray;
42616ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
42716ebf90aSShri Abhyankar   rstart = A->rmap->rstart;
42816ebf90aSShri Abhyankar 
429*bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
43016ebf90aSShri Abhyankar     nza = 0;nzb_low = 0;
43116ebf90aSShri Abhyankar     for(i=0; i<m; i++){
43216ebf90aSShri Abhyankar       nza     = nza + (ai[i+1] - adiag[i]);
43316ebf90aSShri Abhyankar       countB  = bi[i+1] - bi[i];
43416ebf90aSShri Abhyankar       bjj     = bj + bi[i];
43516ebf90aSShri Abhyankar 
43616ebf90aSShri Abhyankar       j = 0;
43716ebf90aSShri Abhyankar       while(garray[bjj[j]] < rstart) {
43816ebf90aSShri Abhyankar 	if(j == countB) break;
43916ebf90aSShri Abhyankar 	j++;nzb_low++;
44016ebf90aSShri Abhyankar       }
44116ebf90aSShri Abhyankar     }
44216ebf90aSShri Abhyankar     /* Total nz = nz for the upper triangular A part + nz for the 2nd B part */
44316ebf90aSShri Abhyankar     nz = nza + (bb->nz - nzb_low);
44416ebf90aSShri Abhyankar     *nnz = nz;
44516ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr);
44616ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr);
44716ebf90aSShri Abhyankar     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
44816ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
44916ebf90aSShri Abhyankar   } else {
45016ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
45116ebf90aSShri Abhyankar   }
45216ebf90aSShri Abhyankar 
45316ebf90aSShri Abhyankar   jj = 0; irow = rstart;
45416ebf90aSShri Abhyankar   for ( i=0; i<m; i++ ) {
45516ebf90aSShri Abhyankar     ajj    = aj + adiag[i];                 /* ptr to the beginning of the diagonal of this row */
45616ebf90aSShri Abhyankar     v1     = av + adiag[i];
45716ebf90aSShri Abhyankar     countA = ai[i+1] - adiag[i];
45816ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
45916ebf90aSShri Abhyankar     bjj    = bj + bi[i];
46016ebf90aSShri Abhyankar     v2     = bv + bi[i];
46116ebf90aSShri Abhyankar 
46216ebf90aSShri Abhyankar      /* A-part */
46316ebf90aSShri Abhyankar     for (j=0; j<countA; j++){
464*bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
46516ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
46616ebf90aSShri Abhyankar       }
46716ebf90aSShri Abhyankar       val[jj++] = v1[j];
46816ebf90aSShri Abhyankar     }
46916ebf90aSShri Abhyankar 
47016ebf90aSShri Abhyankar     /* B-part */
47116ebf90aSShri Abhyankar     for(j=0; j < countB; j++){
47216ebf90aSShri Abhyankar       if (garray[bjj[j]] > rstart) {
473*bccb9932SShri Abhyankar 	if (reuse == MAT_INITIAL_MATRIX) {
47416ebf90aSShri Abhyankar 	  row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
47516ebf90aSShri Abhyankar 	}
47616ebf90aSShri Abhyankar 	val[jj++] = v2[j];
47716ebf90aSShri Abhyankar       }
478397b6df1SKris Buschelman     }
479397b6df1SKris Buschelman     irow++;
480397b6df1SKris Buschelman   }
481397b6df1SKris Buschelman   PetscFunctionReturn(0);
482397b6df1SKris Buschelman }
483397b6df1SKris Buschelman 
484397b6df1SKris Buschelman #undef __FUNCT__
4853924e44cSKris Buschelman #define __FUNCT__ "MatDestroy_MUMPS"
486dfbe8321SBarry Smith PetscErrorCode MatDestroy_MUMPS(Mat A)
487dfbe8321SBarry Smith {
488f0c56d0fSKris Buschelman   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
489dfbe8321SBarry Smith   PetscErrorCode ierr;
490c1490034SHong Zhang   PetscMPIInt    size=lu->size;
49167877ebaSShri Abhyankar   PetscTruth     isSeqBAIJ,isMPIBAIJ;
492b24902e0SBarry Smith 
493397b6df1SKris Buschelman   PetscFunctionBegin;
49467877ebaSShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQBAIJ,&isSeqBAIJ);CHKERRQ(ierr);
49567877ebaSShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATMPIBAIJ,&isMPIBAIJ);CHKERRQ(ierr);
496397b6df1SKris Buschelman   if (lu->CleanUpMUMPS) {
497397b6df1SKris Buschelman     /* Terminate instance, deallocate memories */
498329ec9b3SHong Zhang     if (size > 1){
49968653410SBarry Smith       ierr = PetscFree2(lu->id.sol_loc,lu->id.isol_loc);CHKERRQ(ierr);
500329ec9b3SHong Zhang       ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr);
501329ec9b3SHong Zhang       ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr);
5022750af12SHong Zhang       if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);}
5032750af12SHong Zhang       if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);}
504329ec9b3SHong Zhang       ierr = PetscFree(lu->val);CHKERRQ(ierr);
505329ec9b3SHong Zhang     }
50616ebf90aSShri Abhyankar     if( size == 1 && A->factortype == MAT_FACTOR_CHOLESKY && lu->isAIJ) {
507450b117fSShri Abhyankar       ierr = PetscFree(lu->val);CHKERRQ(ierr);
508450b117fSShri Abhyankar     }
50967877ebaSShri Abhyankar     if(isSeqBAIJ || isMPIBAIJ) {
51067877ebaSShri Abhyankar       ierr = PetscFree(lu->val);CHKERRQ(ierr);
51167877ebaSShri Abhyankar     }
512397b6df1SKris Buschelman     lu->id.job=JOB_END;
513397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
514397b6df1SKris Buschelman     zmumps_c(&lu->id);
515397b6df1SKris Buschelman #else
516397b6df1SKris Buschelman     dmumps_c(&lu->id);
517397b6df1SKris Buschelman #endif
518c338a77dSKris Buschelman     ierr = PetscFree(lu->irn);CHKERRQ(ierr);
519c338a77dSKris Buschelman     ierr = PetscFree(lu->jcn);CHKERRQ(ierr);
520397b6df1SKris Buschelman     ierr = MPI_Comm_free(&(lu->comm_mumps));CHKERRQ(ierr);
521397b6df1SKris Buschelman   }
52297969023SHong Zhang   /* clear composed functions */
52397969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatFactorGetSolverPackage_C","",PETSC_NULL);CHKERRQ(ierr);
52497969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatMumpsSetIcntl_C","",PETSC_NULL);CHKERRQ(ierr);
52567334b25SHong Zhang   ierr = (lu->MatDestroy)(A);CHKERRQ(ierr);
526397b6df1SKris Buschelman   PetscFunctionReturn(0);
527397b6df1SKris Buschelman }
528397b6df1SKris Buschelman 
529397b6df1SKris Buschelman #undef __FUNCT__
530f6c57405SHong Zhang #define __FUNCT__ "MatSolve_MUMPS"
531b24902e0SBarry Smith PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x)
532b24902e0SBarry Smith {
533f0c56d0fSKris Buschelman   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
534d54de34fSKris Buschelman   PetscScalar    *array;
53567877ebaSShri Abhyankar   Vec            b_seq;
536329ec9b3SHong Zhang   IS             is_iden,is_petsc;
537dfbe8321SBarry Smith   PetscErrorCode ierr;
538329ec9b3SHong Zhang   PetscInt       i;
539397b6df1SKris Buschelman 
540397b6df1SKris Buschelman   PetscFunctionBegin;
541329ec9b3SHong Zhang   lu->id.nrhs = 1;
54267877ebaSShri Abhyankar   b_seq = lu->b_seq;
543397b6df1SKris Buschelman   if (lu->size > 1){
544329ec9b3SHong Zhang     /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */
54567877ebaSShri Abhyankar     ierr = VecScatterBegin(lu->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
54667877ebaSShri Abhyankar     ierr = VecScatterEnd(lu->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
54767877ebaSShri Abhyankar     if (!lu->myid) {ierr = VecGetArray(b_seq,&array);CHKERRQ(ierr);}
548397b6df1SKris Buschelman   } else {  /* size == 1 */
549397b6df1SKris Buschelman     ierr = VecCopy(b,x);CHKERRQ(ierr);
550397b6df1SKris Buschelman     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
551397b6df1SKris Buschelman   }
552397b6df1SKris Buschelman   if (!lu->myid) { /* define rhs on the host */
5538278f211SHong Zhang     lu->id.nrhs = 1;
554397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
555397b6df1SKris Buschelman     lu->id.rhs = (mumps_double_complex*)array;
556397b6df1SKris Buschelman #else
557397b6df1SKris Buschelman     lu->id.rhs = array;
558397b6df1SKris Buschelman #endif
559397b6df1SKris Buschelman   }
560397b6df1SKris Buschelman 
561397b6df1SKris Buschelman   /* solve phase */
562329ec9b3SHong Zhang   /*-------------*/
563397b6df1SKris Buschelman   lu->id.job = 3;
564397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
565397b6df1SKris Buschelman   zmumps_c(&lu->id);
566397b6df1SKris Buschelman #else
567397b6df1SKris Buschelman   dmumps_c(&lu->id);
568397b6df1SKris Buschelman #endif
56965e19b50SBarry Smith   if (lu->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",lu->id.INFOG(1));
570397b6df1SKris Buschelman 
571329ec9b3SHong Zhang   if (lu->size > 1) { /* convert mumps distributed solution to petsc mpi x */
572329ec9b3SHong Zhang     if (!lu->nSolve){ /* create scatter scat_sol */
573329ec9b3SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,lu->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */
574329ec9b3SHong Zhang       for (i=0; i<lu->id.lsol_loc; i++){
575329ec9b3SHong Zhang         lu->id.isol_loc[i] -= 1; /* change Fortran style to C style */
576397b6df1SKris Buschelman       }
577329ec9b3SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,lu->id.lsol_loc,lu->id.isol_loc,&is_petsc);CHKERRQ(ierr);  /* to */
578329ec9b3SHong Zhang       ierr = VecScatterCreate(lu->x_seq,is_iden,x,is_petsc,&lu->scat_sol);CHKERRQ(ierr);
579329ec9b3SHong Zhang       ierr = ISDestroy(is_iden);CHKERRQ(ierr);
580329ec9b3SHong Zhang       ierr = ISDestroy(is_petsc);CHKERRQ(ierr);
581397b6df1SKris Buschelman     }
582ca9f406cSSatish Balay     ierr = VecScatterBegin(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
583ca9f406cSSatish Balay     ierr = VecScatterEnd(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
584329ec9b3SHong Zhang   }
585329ec9b3SHong Zhang   lu->nSolve++;
586397b6df1SKris Buschelman   PetscFunctionReturn(0);
587397b6df1SKris Buschelman }
588397b6df1SKris Buschelman 
589ace3df97SHong Zhang #if !defined(PETSC_USE_COMPLEX)
590a58c3f20SHong Zhang /*
591a58c3f20SHong Zhang   input:
592a58c3f20SHong Zhang    F:        numeric factor
593a58c3f20SHong Zhang   output:
594a58c3f20SHong Zhang    nneg:     total number of negative pivots
595a58c3f20SHong Zhang    nzero:    0
596a58c3f20SHong Zhang    npos:     (global dimension of F) - nneg
597a58c3f20SHong Zhang */
598a58c3f20SHong Zhang 
599a58c3f20SHong Zhang #undef __FUNCT__
600a58c3f20SHong Zhang #define __FUNCT__ "MatGetInertia_SBAIJMUMPS"
601dfbe8321SBarry Smith PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos)
602a58c3f20SHong Zhang {
603a58c3f20SHong Zhang   Mat_MUMPS      *lu =(Mat_MUMPS*)F->spptr;
604dfbe8321SBarry Smith   PetscErrorCode ierr;
605c1490034SHong Zhang   PetscMPIInt    size;
606a58c3f20SHong Zhang 
607a58c3f20SHong Zhang   PetscFunctionBegin;
6087adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr);
609bcb30aebSHong 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 */
61065e19b50SBarry Smith   if (size > 1 && lu->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",lu->id.INFOG(13));
611a58c3f20SHong Zhang   if (nneg){
612a58c3f20SHong Zhang     if (!lu->myid){
613a58c3f20SHong Zhang       *nneg = lu->id.INFOG(12);
614a58c3f20SHong Zhang     }
615bcb30aebSHong Zhang     ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_mumps);CHKERRQ(ierr);
616a58c3f20SHong Zhang   }
617a58c3f20SHong Zhang   if (nzero) *nzero = 0;
618d0f46423SBarry Smith   if (npos)  *npos  = F->rmap->N - (*nneg);
619a58c3f20SHong Zhang   PetscFunctionReturn(0);
620a58c3f20SHong Zhang }
621ace3df97SHong Zhang #endif /* !defined(PETSC_USE_COMPLEX) */
622a58c3f20SHong Zhang 
623397b6df1SKris Buschelman #undef __FUNCT__
624f6c57405SHong Zhang #define __FUNCT__ "MatFactorNumeric_MUMPS"
6250481f469SBarry Smith PetscErrorCode MatFactorNumeric_MUMPS(Mat F,Mat A,const MatFactorInfo *info)
626af281ebdSHong Zhang {
627dcd589f8SShri Abhyankar   Mat_MUMPS       *lu =(Mat_MUMPS*)(F)->spptr;
6286849ba73SBarry Smith   PetscErrorCode  ierr;
629*bccb9932SShri Abhyankar   MatReuse        reuse;
630e09efc27SHong Zhang   Mat             F_diag;
63116ebf90aSShri Abhyankar   PetscTruth      isMPIAIJ;
632397b6df1SKris Buschelman 
633397b6df1SKris Buschelman   PetscFunctionBegin;
634*bccb9932SShri Abhyankar   reuse = MAT_REUSE_MATRIX;
635*bccb9932SShri Abhyankar   ierr = (*lu->ConvertToTriples)(A, 1, reuse, &lu->nz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
636397b6df1SKris Buschelman 
637397b6df1SKris Buschelman   /* numerical factorization phase */
638329ec9b3SHong Zhang   /*-------------------------------*/
639329ec9b3SHong Zhang   lu->id.job = 2;
640958c9bccSBarry Smith   if(!lu->id.ICNTL(18)) {
641a7aca84bSHong Zhang     if (!lu->myid) {
642397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
643397b6df1SKris Buschelman       lu->id.a = (mumps_double_complex*)lu->val;
644397b6df1SKris Buschelman #else
645397b6df1SKris Buschelman       lu->id.a = lu->val;
646397b6df1SKris Buschelman #endif
647397b6df1SKris Buschelman     }
648397b6df1SKris Buschelman   } else {
649397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
650397b6df1SKris Buschelman     lu->id.a_loc = (mumps_double_complex*)lu->val;
651397b6df1SKris Buschelman #else
652397b6df1SKris Buschelman     lu->id.a_loc = lu->val;
653397b6df1SKris Buschelman #endif
654397b6df1SKris Buschelman   }
655397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
656397b6df1SKris Buschelman   zmumps_c(&lu->id);
657397b6df1SKris Buschelman #else
658397b6df1SKris Buschelman   dmumps_c(&lu->id);
659397b6df1SKris Buschelman #endif
660397b6df1SKris Buschelman   if (lu->id.INFOG(1) < 0) {
66165e19b50SBarry Smith     if (lu->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",lu->id.INFO(2));
66265e19b50SBarry Smith     else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: INFO(1)=%d, INFO(2)=%d\n",lu->id.INFO(1),lu->id.INFO(2));
663397b6df1SKris Buschelman   }
66465e19b50SBarry Smith   if (!lu->myid && lu->id.ICNTL(16) > 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"  lu->id.ICNTL(16):=%d\n",lu->id.INFOG(16));
665397b6df1SKris Buschelman 
6668ada1bb4SHong Zhang   if (lu->size > 1){
66716ebf90aSShri Abhyankar     ierr = PetscTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
668a214ac2aSShri Abhyankar     if(isMPIAIJ) {
669dcd589f8SShri Abhyankar       F_diag = ((Mat_MPIAIJ *)(F)->data)->A;
670e09efc27SHong Zhang     } else {
671dcd589f8SShri Abhyankar       F_diag = ((Mat_MPISBAIJ *)(F)->data)->A;
672e09efc27SHong Zhang     }
673e09efc27SHong Zhang     F_diag->assembled = PETSC_TRUE;
674329ec9b3SHong Zhang     if (lu->nSolve){
675329ec9b3SHong Zhang       ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);
6760e83c824SBarry Smith       ierr = PetscFree2(lu->id.sol_loc,lu->id.isol_loc);CHKERRQ(ierr);
677329ec9b3SHong Zhang       ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);
678329ec9b3SHong Zhang     }
6798ada1bb4SHong Zhang   }
680dcd589f8SShri Abhyankar   (F)->assembled   = PETSC_TRUE;
681397b6df1SKris Buschelman   lu->matstruc     = SAME_NONZERO_PATTERN;
682ace87b0dSHong Zhang   lu->CleanUpMUMPS = PETSC_TRUE;
683329ec9b3SHong Zhang   lu->nSolve       = 0;
68467877ebaSShri Abhyankar 
68567877ebaSShri Abhyankar   if (lu->size > 1){
68667877ebaSShri Abhyankar     /* distributed solution */
68767877ebaSShri Abhyankar     lu->id.ICNTL(21) = 1;
68867877ebaSShri Abhyankar     if (!lu->nSolve){
68967877ebaSShri Abhyankar       /* Create x_seq=sol_loc for repeated use */
69067877ebaSShri Abhyankar       PetscInt    lsol_loc;
69167877ebaSShri Abhyankar       PetscScalar *sol_loc;
69267877ebaSShri Abhyankar       lsol_loc = lu->id.INFO(23); /* length of sol_loc */
69367877ebaSShri Abhyankar       ierr = PetscMalloc2(lsol_loc,PetscScalar,&sol_loc,lsol_loc,PetscInt,&lu->id.isol_loc);CHKERRQ(ierr);
69467877ebaSShri Abhyankar       lu->id.lsol_loc = lsol_loc;
69567877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
69667877ebaSShri Abhyankar       lu->id.sol_loc  = (mumps_double_complex*)sol_loc;
69767877ebaSShri Abhyankar #else
69867877ebaSShri Abhyankar       lu->id.sol_loc  = sol_loc;
69967877ebaSShri Abhyankar #endif
70067877ebaSShri Abhyankar       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,lsol_loc,sol_loc,&lu->x_seq);CHKERRQ(ierr);
70167877ebaSShri Abhyankar     }
70267877ebaSShri Abhyankar   }
703397b6df1SKris Buschelman   PetscFunctionReturn(0);
704397b6df1SKris Buschelman }
705397b6df1SKris Buschelman 
706dcd589f8SShri Abhyankar #undef __FUNCT__
707dcd589f8SShri Abhyankar #define __FUNCT__ "PetscSetMUMPSOptions"
708dcd589f8SShri Abhyankar PetscErrorCode PetscSetMUMPSOptions(Mat F, Mat A)
709dcd589f8SShri Abhyankar {
710dcd589f8SShri Abhyankar   Mat_MUMPS        *lu = (Mat_MUMPS*)F->spptr;
711dcd589f8SShri Abhyankar   PetscErrorCode   ierr;
712dcd589f8SShri Abhyankar   PetscInt         icntl;
713dcd589f8SShri Abhyankar   PetscTruth       flg;
714dcd589f8SShri Abhyankar 
715dcd589f8SShri Abhyankar   PetscFunctionBegin;
716dcd589f8SShri Abhyankar   ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr);
717cb828f0fSHong Zhang   ierr = PetscOptionsTruth("-mat_mumps_view","View MUMPS parameters","None",lu->mumpsview,&lu->mumpsview,PETSC_NULL);CHKERRQ(ierr);
718dcd589f8SShri Abhyankar   if (lu->size == 1){
719dcd589f8SShri Abhyankar     lu->id.ICNTL(18) = 0;   /* centralized assembled matrix input */
720dcd589f8SShri Abhyankar   } else {
721dcd589f8SShri Abhyankar     lu->id.ICNTL(18) = 3;   /* distributed assembled matrix input */
722dcd589f8SShri Abhyankar   }
723dcd589f8SShri Abhyankar 
724dcd589f8SShri Abhyankar   icntl=-1;
725dcd589f8SShri Abhyankar   lu->id.ICNTL(4) = 0;  /* level of printing; overwrite mumps default ICNTL(4)=2 */
726dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",lu->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr);
727dcd589f8SShri Abhyankar   if ((flg && icntl > 0) || PetscLogPrintInfo) {
728dcd589f8SShri Abhyankar     lu->id.ICNTL(4)=icntl; /* and use mumps default icntl(i), i=1,2,3 */
729dcd589f8SShri Abhyankar   } else { /* no output */
730dcd589f8SShri Abhyankar     lu->id.ICNTL(1) = 0;  /* error message, default= 6 */
731dcd589f8SShri Abhyankar     lu->id.ICNTL(2) = 0;  /* output stream for diagnostic printing, statistics, and warning. default=0 */
732dcd589f8SShri Abhyankar     lu->id.ICNTL(3) = 0; /* output stream for global information, default=6 */
733dcd589f8SShri Abhyankar   }
734dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_6","ICNTL(6): column permutation and/or scaling to get a zero-free diagonal (0 to 7)","None",lu->id.ICNTL(6),&lu->id.ICNTL(6),PETSC_NULL);CHKERRQ(ierr);
735dcd589f8SShri Abhyankar   icntl=-1;
736dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_7","ICNTL(7): matrix ordering (0 to 7)","None",lu->id.ICNTL(7),&icntl,&flg);CHKERRQ(ierr);
737dcd589f8SShri Abhyankar   if (flg) {
738dcd589f8SShri Abhyankar     if (icntl== 1){
739e32f2f54SBarry 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");
740dcd589f8SShri Abhyankar     } else {
741dcd589f8SShri Abhyankar       lu->id.ICNTL(7) = icntl;
742dcd589f8SShri Abhyankar     }
743dcd589f8SShri Abhyankar   }
744dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_8","ICNTL(8): scaling strategy (-2 to 7 or 77)","None",lu->id.ICNTL(8),&lu->id.ICNTL(8),PETSC_NULL);CHKERRQ(ierr);
745dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_9","ICNTL(9): A or A^T x=b to be solved. 1: A; otherwise: A^T","None",lu->id.ICNTL(9),&lu->id.ICNTL(9),PETSC_NULL);CHKERRQ(ierr);
746dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_10","ICNTL(10): max num of refinements","None",lu->id.ICNTL(10),&lu->id.ICNTL(10),PETSC_NULL);CHKERRQ(ierr);
747dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_11","ICNTL(11): statistics related to the linear system solved (via -ksp_view)","None",lu->id.ICNTL(11),&lu->id.ICNTL(11),PETSC_NULL);CHKERRQ(ierr);
748dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_12","ICNTL(12): efficiency control: defines the ordering strategy with scaling constraints (0 to 3","None",lu->id.ICNTL(12),&lu->id.ICNTL(12),PETSC_NULL);CHKERRQ(ierr);
749dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_13","ICNTL(13): efficiency control: with or without ScaLAPACK","None",lu->id.ICNTL(13),&lu->id.ICNTL(13),PETSC_NULL);CHKERRQ(ierr);
750dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_14","ICNTL(14): percentage of estimated workspace increase","None",lu->id.ICNTL(14),&lu->id.ICNTL(14),PETSC_NULL);CHKERRQ(ierr);
751dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_19","ICNTL(19): Schur complement","None",lu->id.ICNTL(19),&lu->id.ICNTL(19),PETSC_NULL);CHKERRQ(ierr);
752dcd589f8SShri Abhyankar 
753dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_22","ICNTL(22): in-core/out-of-core facility (0 or 1)","None",lu->id.ICNTL(22),&lu->id.ICNTL(22),PETSC_NULL);CHKERRQ(ierr);
754dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_23","ICNTL(23): max size of the working memory (MB) that can allocate per processor","None",lu->id.ICNTL(23),&lu->id.ICNTL(23),PETSC_NULL);CHKERRQ(ierr);
755dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_24","ICNTL(24): detection of null pivot rows (0 or 1)","None",lu->id.ICNTL(24),&lu->id.ICNTL(24),PETSC_NULL);CHKERRQ(ierr);
756dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_25","ICNTL(25): computation of a null space basis","None",lu->id.ICNTL(25),&lu->id.ICNTL(25),PETSC_NULL);CHKERRQ(ierr);
757dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_26","ICNTL(26): Schur options for right-hand side or solution vector","None",lu->id.ICNTL(26),&lu->id.ICNTL(26),PETSC_NULL);CHKERRQ(ierr);
758dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_27","ICNTL(27): experimental parameter","None",lu->id.ICNTL(27),&lu->id.ICNTL(27),PETSC_NULL);CHKERRQ(ierr);
759dcd589f8SShri Abhyankar 
760dcd589f8SShri Abhyankar   ierr = PetscOptionsReal("-mat_mumps_cntl_1","CNTL(1): relative pivoting threshold","None",lu->id.CNTL(1),&lu->id.CNTL(1),PETSC_NULL);CHKERRQ(ierr);
761dcd589f8SShri Abhyankar   ierr = PetscOptionsReal("-mat_mumps_cntl_2","CNTL(2): stopping criterion of refinement","None",lu->id.CNTL(2),&lu->id.CNTL(2),PETSC_NULL);CHKERRQ(ierr);
762dcd589f8SShri Abhyankar   ierr = PetscOptionsReal("-mat_mumps_cntl_3","CNTL(3): absolute pivoting threshold","None",lu->id.CNTL(3),&lu->id.CNTL(3),PETSC_NULL);CHKERRQ(ierr);
763dcd589f8SShri Abhyankar   ierr = PetscOptionsReal("-mat_mumps_cntl_4","CNTL(4): value for static pivoting","None",lu->id.CNTL(4),&lu->id.CNTL(4),PETSC_NULL);CHKERRQ(ierr);
764dcd589f8SShri Abhyankar   ierr = PetscOptionsReal("-mat_mumps_cntl_5","CNTL(5): fixation for null pivots","None",lu->id.CNTL(5),&lu->id.CNTL(5),PETSC_NULL);CHKERRQ(ierr);
765dcd589f8SShri Abhyankar   PetscOptionsEnd();
766dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
767dcd589f8SShri Abhyankar }
768dcd589f8SShri Abhyankar 
769dcd589f8SShri Abhyankar #undef __FUNCT__
770dcd589f8SShri Abhyankar #define __FUNCT__ "PetscInitializeMUMPS"
771dcd589f8SShri Abhyankar PetscErrorCode PetscInitializeMUMPS(Mat F)
772dcd589f8SShri Abhyankar {
773dcd589f8SShri Abhyankar   Mat_MUMPS       *lu = (Mat_MUMPS*)F->spptr;
774dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
775dcd589f8SShri Abhyankar   PetscInt        icntl;
776dcd589f8SShri Abhyankar   PetscTruth      flg;
777dcd589f8SShri Abhyankar 
778dcd589f8SShri Abhyankar   PetscFunctionBegin;
779dcd589f8SShri Abhyankar   lu->id.job = JOB_INIT;
780dcd589f8SShri Abhyankar   lu->id.par=1;  /* host participates factorizaton and solve */
781dcd589f8SShri Abhyankar   lu->id.sym=lu->sym;
782dcd589f8SShri Abhyankar   if (lu->sym == 2){
783dcd589f8SShri Abhyankar     ierr = PetscOptionsInt("-mat_mumps_sym","SYM: (1,2)","None",lu->id.sym,&icntl,&flg);CHKERRQ(ierr);
784dcd589f8SShri Abhyankar     if (flg && icntl == 1) lu->id.sym=icntl;  /* matrix is spd */
785dcd589f8SShri Abhyankar   }
786dcd589f8SShri Abhyankar #if defined(PETSC_USE_COMPLEX)
787dcd589f8SShri Abhyankar   zmumps_c(&lu->id);
788dcd589f8SShri Abhyankar #else
789dcd589f8SShri Abhyankar   dmumps_c(&lu->id);
790dcd589f8SShri Abhyankar #endif
791dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
792dcd589f8SShri Abhyankar }
793dcd589f8SShri Abhyankar 
794397b6df1SKris Buschelman /* Note the Petsc r and c permutations are ignored */
795397b6df1SKris Buschelman #undef __FUNCT__
796f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS"
7970481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
798b24902e0SBarry Smith {
799719d5645SBarry Smith   Mat_MUMPS          *lu = (Mat_MUMPS*)F->spptr;
800dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
801*bccb9932SShri Abhyankar   MatReuse           reuse;
80267877ebaSShri Abhyankar   Vec                b;
80367877ebaSShri Abhyankar   IS                 is_iden;
80467877ebaSShri Abhyankar   const PetscInt     M = A->rmap->N;
805397b6df1SKris Buschelman 
806397b6df1SKris Buschelman   PetscFunctionBegin;
807b24902e0SBarry Smith   lu->sym                  = 0;
808b24902e0SBarry Smith   lu->matstruc             = DIFFERENT_NONZERO_PATTERN;
809dcd589f8SShri Abhyankar 
810dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
811dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
812dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
813dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
814dcd589f8SShri Abhyankar 
815dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
816dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
817dcd589f8SShri Abhyankar   /* Set MUMPS options */
818dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
819dcd589f8SShri Abhyankar 
820*bccb9932SShri Abhyankar   reuse = MAT_INITIAL_MATRIX;
821*bccb9932SShri Abhyankar   ierr = (*lu->ConvertToTriples)(A, 1, reuse, &lu->nz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
822dcd589f8SShri Abhyankar 
82367877ebaSShri Abhyankar   /* analysis phase */
82467877ebaSShri Abhyankar   /*----------------*/
82567877ebaSShri Abhyankar   lu->id.job = 1;
82667877ebaSShri Abhyankar   lu->id.n = M;
82767877ebaSShri Abhyankar   switch (lu->id.ICNTL(18)){
82867877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
82967877ebaSShri Abhyankar     if (!lu->myid) {
83067877ebaSShri Abhyankar       lu->id.nz =lu->nz; lu->id.irn=lu->irn; lu->id.jcn=lu->jcn;
83167877ebaSShri Abhyankar       if (lu->id.ICNTL(6)>1){
83267877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
83367877ebaSShri Abhyankar         lu->id.a = (mumps_double_complex*)lu->val;
83467877ebaSShri Abhyankar #else
83567877ebaSShri Abhyankar         lu->id.a = lu->val;
83667877ebaSShri Abhyankar #endif
83767877ebaSShri Abhyankar       }
83867877ebaSShri Abhyankar     }
83967877ebaSShri Abhyankar     break;
84067877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
84167877ebaSShri Abhyankar     lu->id.nz_loc = lu->nz;
84267877ebaSShri Abhyankar     lu->id.irn_loc=lu->irn; lu->id.jcn_loc=lu->jcn;
84367877ebaSShri Abhyankar     if (lu->id.ICNTL(6)>1) {
84467877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
84567877ebaSShri Abhyankar       lu->id.a_loc = (mumps_double_complex*)lu->val;
84667877ebaSShri Abhyankar #else
84767877ebaSShri Abhyankar       lu->id.a_loc = lu->val;
84867877ebaSShri Abhyankar #endif
84967877ebaSShri Abhyankar     }
85067877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
85167877ebaSShri Abhyankar     if (!lu->myid){
85267877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr);
85367877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
85467877ebaSShri Abhyankar     } else {
85567877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&lu->b_seq);CHKERRQ(ierr);
85667877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
85767877ebaSShri Abhyankar     }
85867877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
85967877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
86067877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
86167877ebaSShri Abhyankar 
86267877ebaSShri Abhyankar     ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr);
86367877ebaSShri Abhyankar     ierr = ISDestroy(is_iden);CHKERRQ(ierr);
86467877ebaSShri Abhyankar     ierr = VecDestroy(b);CHKERRQ(ierr);
86567877ebaSShri Abhyankar     break;
86667877ebaSShri Abhyankar     }
86767877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
86867877ebaSShri Abhyankar   zmumps_c(&lu->id);
86967877ebaSShri Abhyankar #else
87067877ebaSShri Abhyankar   dmumps_c(&lu->id);
87167877ebaSShri Abhyankar #endif
87267877ebaSShri Abhyankar   if (lu->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",lu->id.INFOG(1));
87367877ebaSShri Abhyankar 
874719d5645SBarry Smith   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
875dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
876b24902e0SBarry Smith   PetscFunctionReturn(0);
877b24902e0SBarry Smith }
878b24902e0SBarry Smith 
879450b117fSShri Abhyankar /* Note the Petsc r and c permutations are ignored */
880450b117fSShri Abhyankar #undef __FUNCT__
881450b117fSShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_BAIJMUMPS"
882450b117fSShri Abhyankar PetscErrorCode MatLUFactorSymbolic_BAIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
883450b117fSShri Abhyankar {
884dcd589f8SShri Abhyankar 
885450b117fSShri Abhyankar   Mat_MUMPS       *lu = (Mat_MUMPS*)F->spptr;
886dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
887*bccb9932SShri Abhyankar   MatReuse        reuse;
88867877ebaSShri Abhyankar   Vec             b;
88967877ebaSShri Abhyankar   IS              is_iden;
89067877ebaSShri Abhyankar   const PetscInt  M = A->rmap->N;
891450b117fSShri Abhyankar 
892450b117fSShri Abhyankar   PetscFunctionBegin;
893450b117fSShri Abhyankar   lu->sym                  = 0;
894450b117fSShri Abhyankar   lu->matstruc             = DIFFERENT_NONZERO_PATTERN;
895dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
896dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
897dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
898dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
899dcd589f8SShri Abhyankar 
900dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
901dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
902dcd589f8SShri Abhyankar   /* Set MUMPS options */
903dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
904dcd589f8SShri Abhyankar 
905*bccb9932SShri Abhyankar   reuse = MAT_INITIAL_MATRIX;
906*bccb9932SShri Abhyankar   ierr = (*lu->ConvertToTriples)(A, 1, reuse, &lu->nz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
90767877ebaSShri Abhyankar 
90867877ebaSShri Abhyankar   /* analysis phase */
90967877ebaSShri Abhyankar   /*----------------*/
91067877ebaSShri Abhyankar   lu->id.job = 1;
91167877ebaSShri Abhyankar   lu->id.n = M;
91267877ebaSShri Abhyankar   switch (lu->id.ICNTL(18)){
91367877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
91467877ebaSShri Abhyankar     if (!lu->myid) {
91567877ebaSShri Abhyankar       lu->id.nz =lu->nz; lu->id.irn=lu->irn; lu->id.jcn=lu->jcn;
91667877ebaSShri Abhyankar       if (lu->id.ICNTL(6)>1){
91767877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
91867877ebaSShri Abhyankar         lu->id.a = (mumps_double_complex*)lu->val;
91967877ebaSShri Abhyankar #else
92067877ebaSShri Abhyankar         lu->id.a = lu->val;
92167877ebaSShri Abhyankar #endif
92267877ebaSShri Abhyankar       }
92367877ebaSShri Abhyankar     }
92467877ebaSShri Abhyankar     break;
92567877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
92667877ebaSShri Abhyankar     lu->id.nz_loc = lu->nz;
92767877ebaSShri Abhyankar     lu->id.irn_loc=lu->irn; lu->id.jcn_loc=lu->jcn;
92867877ebaSShri Abhyankar     if (lu->id.ICNTL(6)>1) {
92967877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
93067877ebaSShri Abhyankar       lu->id.a_loc = (mumps_double_complex*)lu->val;
93167877ebaSShri Abhyankar #else
93267877ebaSShri Abhyankar       lu->id.a_loc = lu->val;
93367877ebaSShri Abhyankar #endif
93467877ebaSShri Abhyankar     }
93567877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
93667877ebaSShri Abhyankar     if (!lu->myid){
93767877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr);
93867877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
93967877ebaSShri Abhyankar     } else {
94067877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&lu->b_seq);CHKERRQ(ierr);
94167877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
94267877ebaSShri Abhyankar     }
94367877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
94467877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
94567877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
94667877ebaSShri Abhyankar 
94767877ebaSShri Abhyankar     ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr);
94867877ebaSShri Abhyankar     ierr = ISDestroy(is_iden);CHKERRQ(ierr);
94967877ebaSShri Abhyankar     ierr = VecDestroy(b);CHKERRQ(ierr);
95067877ebaSShri Abhyankar     break;
95167877ebaSShri Abhyankar     }
95267877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
95367877ebaSShri Abhyankar   zmumps_c(&lu->id);
95467877ebaSShri Abhyankar #else
95567877ebaSShri Abhyankar   dmumps_c(&lu->id);
95667877ebaSShri Abhyankar #endif
95767877ebaSShri Abhyankar   if (lu->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",lu->id.INFOG(1));
95867877ebaSShri Abhyankar 
959450b117fSShri Abhyankar   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
960dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
961450b117fSShri Abhyankar   PetscFunctionReturn(0);
962450b117fSShri Abhyankar }
963b24902e0SBarry Smith 
964397b6df1SKris Buschelman /* Note the Petsc r permutation is ignored */
965397b6df1SKris Buschelman #undef __FUNCT__
96667877ebaSShri Abhyankar #define __FUNCT__ "MatCholeskyFactorSymbolic_MUMPS"
96767877ebaSShri Abhyankar PetscErrorCode MatCholeskyFactorSymbolic_MUMPS(Mat F,Mat A,IS r,const MatFactorInfo *info)
968b24902e0SBarry Smith {
9692792810eSHong Zhang   Mat_MUMPS          *lu = (Mat_MUMPS*)F->spptr;
970dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
971*bccb9932SShri Abhyankar   MatReuse           reuse;
97267877ebaSShri Abhyankar   Vec                b;
97367877ebaSShri Abhyankar   IS                 is_iden;
97467877ebaSShri Abhyankar   const PetscInt     M = A->rmap->N;
975397b6df1SKris Buschelman 
976397b6df1SKris Buschelman   PetscFunctionBegin;
977b24902e0SBarry Smith   lu->sym                          = 2;
978b24902e0SBarry Smith   lu->matstruc                     = DIFFERENT_NONZERO_PATTERN;
979dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
980dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
981dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
982dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
983dcd589f8SShri Abhyankar 
984dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
985dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
986dcd589f8SShri Abhyankar   /* Set MUMPS options */
987dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
988dcd589f8SShri Abhyankar 
989*bccb9932SShri Abhyankar   reuse = MAT_INITIAL_MATRIX;
990*bccb9932SShri Abhyankar   ierr = (*lu->ConvertToTriples)(A, 1 , reuse, &lu->nz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
991dcd589f8SShri Abhyankar 
99267877ebaSShri Abhyankar   /* analysis phase */
99367877ebaSShri Abhyankar   /*----------------*/
99467877ebaSShri Abhyankar   lu->id.job = 1;
99567877ebaSShri Abhyankar   lu->id.n = M;
99667877ebaSShri Abhyankar   switch (lu->id.ICNTL(18)){
99767877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
99867877ebaSShri Abhyankar     if (!lu->myid) {
99967877ebaSShri Abhyankar       lu->id.nz =lu->nz; lu->id.irn=lu->irn; lu->id.jcn=lu->jcn;
100067877ebaSShri Abhyankar       if (lu->id.ICNTL(6)>1){
100167877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
100267877ebaSShri Abhyankar         lu->id.a = (mumps_double_complex*)lu->val;
100367877ebaSShri Abhyankar #else
100467877ebaSShri Abhyankar         lu->id.a = lu->val;
100567877ebaSShri Abhyankar #endif
100667877ebaSShri Abhyankar       }
100767877ebaSShri Abhyankar     }
100867877ebaSShri Abhyankar     break;
100967877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
101067877ebaSShri Abhyankar     lu->id.nz_loc = lu->nz;
101167877ebaSShri Abhyankar     lu->id.irn_loc=lu->irn; lu->id.jcn_loc=lu->jcn;
101267877ebaSShri Abhyankar     if (lu->id.ICNTL(6)>1) {
101367877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
101467877ebaSShri Abhyankar       lu->id.a_loc = (mumps_double_complex*)lu->val;
101567877ebaSShri Abhyankar #else
101667877ebaSShri Abhyankar       lu->id.a_loc = lu->val;
101767877ebaSShri Abhyankar #endif
101867877ebaSShri Abhyankar     }
101967877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
102067877ebaSShri Abhyankar     if (!lu->myid){
102167877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr);
102267877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
102367877ebaSShri Abhyankar     } else {
102467877ebaSShri Abhyankar       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&lu->b_seq);CHKERRQ(ierr);
102567877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
102667877ebaSShri Abhyankar     }
102767877ebaSShri Abhyankar     ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
102867877ebaSShri Abhyankar     ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
102967877ebaSShri Abhyankar     ierr = VecSetFromOptions(b);CHKERRQ(ierr);
103067877ebaSShri Abhyankar 
103167877ebaSShri Abhyankar     ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr);
103267877ebaSShri Abhyankar     ierr = ISDestroy(is_iden);CHKERRQ(ierr);
103367877ebaSShri Abhyankar     ierr = VecDestroy(b);CHKERRQ(ierr);
103467877ebaSShri Abhyankar     break;
103567877ebaSShri Abhyankar     }
103667877ebaSShri Abhyankar #if defined(PETSC_USE_COMPLEX)
103767877ebaSShri Abhyankar   zmumps_c(&lu->id);
103867877ebaSShri Abhyankar #else
103967877ebaSShri Abhyankar   dmumps_c(&lu->id);
104067877ebaSShri Abhyankar #endif
104167877ebaSShri Abhyankar   if (lu->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",lu->id.INFOG(1));
104267877ebaSShri Abhyankar 
10432792810eSHong Zhang   F->ops->choleskyfactornumeric =  MatFactorNumeric_MUMPS;
1044dcd589f8SShri Abhyankar   F->ops->solve                 =  MatSolve_MUMPS;
1045db4efbfdSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1046dcd589f8SShri Abhyankar   (F)->ops->getinertia          =  MatGetInertia_SBAIJMUMPS;
1047db4efbfdSBarry Smith #endif
1048b24902e0SBarry Smith   PetscFunctionReturn(0);
1049b24902e0SBarry Smith }
1050b24902e0SBarry Smith 
1051397b6df1SKris Buschelman #undef __FUNCT__
1052f6c57405SHong Zhang #define __FUNCT__ "MatFactorInfo_MUMPS"
105374ed9c26SBarry Smith PetscErrorCode MatFactorInfo_MUMPS(Mat A,PetscViewer viewer)
105474ed9c26SBarry Smith {
1055f6c57405SHong Zhang   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
1056f6c57405SHong Zhang   PetscErrorCode ierr;
1057f6c57405SHong Zhang 
1058f6c57405SHong Zhang   PetscFunctionBegin;
1059f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(1) (output for error):        %d \n",lu->id.ICNTL(1));CHKERRQ(ierr);
1060f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(2) (output of diagnostic msg):%d \n",lu->id.ICNTL(2));CHKERRQ(ierr);
1061f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(3) (output for global info):  %d \n",lu->id.ICNTL(3));CHKERRQ(ierr);
1062f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(4) (level of printing):       %d \n",lu->id.ICNTL(4));CHKERRQ(ierr);
1063f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(5) (input mat struct):        %d \n",lu->id.ICNTL(5));CHKERRQ(ierr);
1064f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(6) (matrix prescaling):       %d \n",lu->id.ICNTL(6));CHKERRQ(ierr);
1065f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(7) (matrix ordering):         %d \n",lu->id.ICNTL(7));CHKERRQ(ierr);
1066f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(8) (scalling strategy):       %d \n",lu->id.ICNTL(8));CHKERRQ(ierr);
1067f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(9) (A/A^T x=b is solved):     %d \n",lu->id.ICNTL(9));CHKERRQ(ierr);
1068f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(10) (max num of refinements): %d \n",lu->id.ICNTL(10));CHKERRQ(ierr);
1069f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(11) (error analysis):         %d \n",lu->id.ICNTL(11));CHKERRQ(ierr);
1070f6c57405SHong Zhang   if (!lu->myid && lu->id.ICNTL(11)>0) {
1071f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(4) (inf norm of input mat):        %g\n",lu->id.RINFOG(4));CHKERRQ(ierr);
1072f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(5) (inf norm of solution):         %g\n",lu->id.RINFOG(5));CHKERRQ(ierr);
1073f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(6) (inf norm of residual):         %g\n",lu->id.RINFOG(6));CHKERRQ(ierr);
1074f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(7),RINFOG(8) (backward error est): %g, %g\n",lu->id.RINFOG(7),lu->id.RINFOG(8));CHKERRQ(ierr);
1075f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(9) (error estimate):               %g \n",lu->id.RINFOG(9));CHKERRQ(ierr);
1076f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(10),RINFOG(11)(condition numbers): %g, %g\n",lu->id.RINFOG(10),lu->id.RINFOG(11));CHKERRQ(ierr);
1077f6c57405SHong Zhang 
1078f6c57405SHong Zhang   }
1079f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(12) (efficiency control):                         %d \n",lu->id.ICNTL(12));CHKERRQ(ierr);
1080f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(13) (efficiency control):                         %d \n",lu->id.ICNTL(13));CHKERRQ(ierr);
1081f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(14) (percentage of estimated workspace increase): %d \n",lu->id.ICNTL(14));CHKERRQ(ierr);
1082f6c57405SHong Zhang   /* ICNTL(15-17) not used */
1083f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(18) (input mat struct):                           %d \n",lu->id.ICNTL(18));CHKERRQ(ierr);
1084f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(19) (Shur complement info):                       %d \n",lu->id.ICNTL(19));CHKERRQ(ierr);
1085f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(20) (rhs sparse pattern):                         %d \n",lu->id.ICNTL(20));CHKERRQ(ierr);
1086f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(21) (solution struct):                            %d \n",lu->id.ICNTL(21));CHKERRQ(ierr);
1087c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(22) (in-core/out-of-core facility):               %d \n",lu->id.ICNTL(22));CHKERRQ(ierr);
1088c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(23) (max size of memory can be allocated locally):%d \n",lu->id.ICNTL(23));CHKERRQ(ierr);
1089c0165424SHong Zhang 
1090c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(24) (detection of null pivot rows):               %d \n",lu->id.ICNTL(24));CHKERRQ(ierr);
1091c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(25) (computation of a null space basis):          %d \n",lu->id.ICNTL(25));CHKERRQ(ierr);
1092c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(26) (Schur options for rhs or solution):          %d \n",lu->id.ICNTL(26));CHKERRQ(ierr);
1093c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(27) (experimental parameter):                     %d \n",lu->id.ICNTL(27));CHKERRQ(ierr);
1094f6c57405SHong Zhang 
1095f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(1) (relative pivoting threshold):      %g \n",lu->id.CNTL(1));CHKERRQ(ierr);
1096f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(2) (stopping criterion of refinement): %g \n",lu->id.CNTL(2));CHKERRQ(ierr);
1097f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(3) (absolute pivoting threshold):      %g \n",lu->id.CNTL(3));CHKERRQ(ierr);
1098f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(4) (value of static pivoting):         %g \n",lu->id.CNTL(4));CHKERRQ(ierr);
1099c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(5) (fixation for null pivots):         %g \n",lu->id.CNTL(5));CHKERRQ(ierr);
1100f6c57405SHong Zhang 
1101f6c57405SHong Zhang   /* infomation local to each processor */
1102f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);}
11037adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %g \n",lu->myid,lu->id.RINFO(1));CHKERRQ(ierr);
11047adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1105f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);}
11067adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d]  %g \n",lu->myid,lu->id.RINFO(2));CHKERRQ(ierr);
11077adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1108f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);}
11097adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d]  %g \n",lu->myid,lu->id.RINFO(3));CHKERRQ(ierr);
11107adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1111f6c57405SHong Zhang 
1112f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              INFO(15) (estimated size of (in MB) MUMPS internal data for running numerical factorization): \n");CHKERRQ(ierr);}
11137adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(15));CHKERRQ(ierr);
11147adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1115f6c57405SHong Zhang 
1116f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              INFO(16) (size of (in MB) MUMPS internal data used during numerical factorization): \n");CHKERRQ(ierr);}
11177adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(16));CHKERRQ(ierr);
11187adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1119f6c57405SHong Zhang 
1120f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);}
11217adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(23));CHKERRQ(ierr);
11227adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
1123f6c57405SHong Zhang 
1124f6c57405SHong Zhang   if (!lu->myid){ /* information from the host */
1125f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",lu->id.RINFOG(1));CHKERRQ(ierr);
1126f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",lu->id.RINFOG(2));CHKERRQ(ierr);
1127f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",lu->id.RINFOG(3));CHKERRQ(ierr);
1128f6c57405SHong Zhang 
1129f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(3));CHKERRQ(ierr);
1130f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(4));CHKERRQ(ierr);
1131f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(5) (estimated maximum front size in the complete tree): %d \n",lu->id.INFOG(5));CHKERRQ(ierr);
1132f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(6) (number of nodes in the complete tree): %d \n",lu->id.INFOG(6));CHKERRQ(ierr);
1133f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(7) (ordering option effectively uese after analysis): %d \n",lu->id.INFOG(7));CHKERRQ(ierr);
1134f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",lu->id.INFOG(8));CHKERRQ(ierr);
1135f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(9) (total real/complex workspace to store the matrix factors after factorization): %d \n",lu->id.INFOG(9));CHKERRQ(ierr);
1136f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(10) (total integer space store the matrix factors after factorization): %d \n",lu->id.INFOG(10));CHKERRQ(ierr);
1137f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(11) (order of largest frontal matrix after factorization): %d \n",lu->id.INFOG(11));CHKERRQ(ierr);
1138f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(12) (number of off-diagonal pivots): %d \n",lu->id.INFOG(12));CHKERRQ(ierr);
1139f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(13) (number of delayed pivots after factorization): %d \n",lu->id.INFOG(13));CHKERRQ(ierr);
1140f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(14) (number of memory compress after factorization): %d \n",lu->id.INFOG(14));CHKERRQ(ierr);
1141f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(15) (number of steps of iterative refinement after solution): %d \n",lu->id.INFOG(15));CHKERRQ(ierr);
1142f6c57405SHong 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",lu->id.INFOG(16));CHKERRQ(ierr);
1143f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(17) (estimated size of all MUMPS internal data for factorization after analysis: sum over all processors): %d \n",lu->id.INFOG(17));CHKERRQ(ierr);
1144f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(18) (size of all MUMPS internal data allocated during factorization: value on the most memory consuming processor): %d \n",lu->id.INFOG(18));CHKERRQ(ierr);
1145f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(19) (size of all MUMPS internal data allocated during factorization: sum over all processors): %d \n",lu->id.INFOG(19));CHKERRQ(ierr);
1146f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(20) (estimated number of entries in the factors): %d \n",lu->id.INFOG(20));CHKERRQ(ierr);
1147f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(21) (size in MB of memory effectively used during factorization - value on the most memory consuming processor): %d \n",lu->id.INFOG(21));CHKERRQ(ierr);
1148f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(22) (size in MB of memory effectively used during factorization - sum over all processors): %d \n",lu->id.INFOG(22));CHKERRQ(ierr);
1149f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",lu->id.INFOG(23));CHKERRQ(ierr);
1150f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",lu->id.INFOG(24));CHKERRQ(ierr);
1151f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",lu->id.INFOG(25));CHKERRQ(ierr);
1152f6c57405SHong Zhang   }
1153f6c57405SHong Zhang   PetscFunctionReturn(0);
1154f6c57405SHong Zhang }
1155f6c57405SHong Zhang 
1156f6c57405SHong Zhang #undef __FUNCT__
1157f6c57405SHong Zhang #define __FUNCT__ "MatView_MUMPS"
1158b24902e0SBarry Smith PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer)
1159b24902e0SBarry Smith {
1160f6c57405SHong Zhang   PetscErrorCode    ierr;
1161f6c57405SHong Zhang   PetscTruth        iascii;
1162f6c57405SHong Zhang   PetscViewerFormat format;
1163cb828f0fSHong Zhang   Mat_MUMPS         *mumps=(Mat_MUMPS*)A->spptr;
1164f6c57405SHong Zhang 
1165f6c57405SHong Zhang   PetscFunctionBegin;
1166cb828f0fSHong Zhang   /* check if matrix is mumps type */
1167cb828f0fSHong Zhang   if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0);
1168cb828f0fSHong Zhang 
1169f6c57405SHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
1170f6c57405SHong Zhang   if (iascii) {
1171f6c57405SHong Zhang     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1172cb828f0fSHong Zhang     if (format == PETSC_VIEWER_ASCII_INFO || mumps->mumpsview){
1173cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr);
1174cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  SYM (matrix type):                  %d \n",mumps->id.sym);CHKERRQ(ierr);
1175cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  PAR (host participation):           %d \n",mumps->id.par);CHKERRQ(ierr);
1176cb828f0fSHong Zhang       if (mumps->mumpsview){ /* View all MUMPS parameters */
1177f6c57405SHong Zhang         ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr);
1178f6c57405SHong Zhang       }
1179f6c57405SHong Zhang     }
1180cb828f0fSHong Zhang   }
1181f6c57405SHong Zhang   PetscFunctionReturn(0);
1182f6c57405SHong Zhang }
1183f6c57405SHong Zhang 
118435bd34faSBarry Smith #undef __FUNCT__
118535bd34faSBarry Smith #define __FUNCT__ "MatGetInfo_MUMPS"
118635bd34faSBarry Smith PetscErrorCode MatGetInfo_MUMPS(Mat A,MatInfoType flag,MatInfo *info)
118735bd34faSBarry Smith {
1188cb828f0fSHong Zhang   Mat_MUMPS  *mumps =(Mat_MUMPS*)A->spptr;
118935bd34faSBarry Smith 
119035bd34faSBarry Smith   PetscFunctionBegin;
119135bd34faSBarry Smith   info->block_size        = 1.0;
1192cb828f0fSHong Zhang   info->nz_allocated      = mumps->id.INFOG(20);
1193cb828f0fSHong Zhang   info->nz_used           = mumps->id.INFOG(20);
119435bd34faSBarry Smith   info->nz_unneeded       = 0.0;
119535bd34faSBarry Smith   info->assemblies        = 0.0;
119635bd34faSBarry Smith   info->mallocs           = 0.0;
119735bd34faSBarry Smith   info->memory            = 0.0;
119835bd34faSBarry Smith   info->fill_ratio_given  = 0;
119935bd34faSBarry Smith   info->fill_ratio_needed = 0;
120035bd34faSBarry Smith   info->factor_mallocs    = 0;
120135bd34faSBarry Smith   PetscFunctionReturn(0);
120235bd34faSBarry Smith }
120335bd34faSBarry Smith 
120424b6179bSKris Buschelman /*MC
120541c8de11SBarry Smith   MAT_SOLVER_MUMPS -  A matrix type providing direct solvers (LU and Cholesky) for
120624b6179bSKris Buschelman   distributed and sequential matrices via the external package MUMPS.
120724b6179bSKris Buschelman 
120841c8de11SBarry Smith   Works with MATAIJ and MATSBAIJ matrices
120924b6179bSKris Buschelman 
121024b6179bSKris Buschelman   Options Database Keys:
121141c8de11SBarry Smith + -mat_mumps_sym <0,1,2> - 0 the matrix is unsymmetric, 1 symmetric positive definite, 2 symmetric
121224b6179bSKris Buschelman . -mat_mumps_icntl_4 <0,...,4> - print level
121324b6179bSKris Buschelman . -mat_mumps_icntl_6 <0,...,7> - matrix prescaling options (see MUMPS User's Guide)
121424b6179bSKris Buschelman . -mat_mumps_icntl_7 <0,...,7> - matrix orderings (see MUMPS User's Guide)
121524b6179bSKris Buschelman . -mat_mumps_icntl_9 <1,2> - A or A^T x=b to be solved: 1 denotes A, 2 denotes A^T
121624b6179bSKris Buschelman . -mat_mumps_icntl_10 <n> - maximum number of iterative refinements
121794b7f48cSBarry Smith . -mat_mumps_icntl_11 <n> - error analysis, a positive value returns statistics during -ksp_view
121824b6179bSKris Buschelman . -mat_mumps_icntl_12 <n> - efficiency control (see MUMPS User's Guide)
121924b6179bSKris Buschelman . -mat_mumps_icntl_13 <n> - efficiency control (see MUMPS User's Guide)
122024b6179bSKris Buschelman . -mat_mumps_icntl_14 <n> - efficiency control (see MUMPS User's Guide)
122124b6179bSKris Buschelman . -mat_mumps_icntl_15 <n> - efficiency control (see MUMPS User's Guide)
122224b6179bSKris Buschelman . -mat_mumps_cntl_1 <delta> - relative pivoting threshold
122324b6179bSKris Buschelman . -mat_mumps_cntl_2 <tol> - stopping criterion for refinement
122424b6179bSKris Buschelman - -mat_mumps_cntl_3 <adelta> - absolute pivoting threshold
122524b6179bSKris Buschelman 
122624b6179bSKris Buschelman   Level: beginner
122724b6179bSKris Buschelman 
122841c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
122941c8de11SBarry Smith 
123024b6179bSKris Buschelman M*/
123124b6179bSKris Buschelman 
12322877fffaSHong Zhang EXTERN_C_BEGIN
123335bd34faSBarry Smith #undef __FUNCT__
123435bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_mumps"
123535bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_mumps(Mat A,const MatSolverPackage *type)
123635bd34faSBarry Smith {
123735bd34faSBarry Smith   PetscFunctionBegin;
123835bd34faSBarry Smith   *type = MAT_SOLVER_MUMPS;
123935bd34faSBarry Smith   PetscFunctionReturn(0);
124035bd34faSBarry Smith }
124135bd34faSBarry Smith EXTERN_C_END
124235bd34faSBarry Smith 
124335bd34faSBarry Smith EXTERN_C_BEGIN
1244*bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI AIJ matrices */
12452877fffaSHong Zhang #undef __FUNCT__
1246*bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_aij_mumps"
1247*bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_aij_mumps(Mat A,MatFactorType ftype,Mat *F)
12482877fffaSHong Zhang {
12492877fffaSHong Zhang   Mat            B;
12502877fffaSHong Zhang   PetscErrorCode ierr;
12512877fffaSHong Zhang   Mat_MUMPS      *mumps;
1252*bccb9932SShri Abhyankar   PetscTruth     isSeqAIJ;
12532877fffaSHong Zhang 
12542877fffaSHong Zhang   PetscFunctionBegin;
12552877fffaSHong Zhang   /* Create the factorization matrix */
1256*bccb9932SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
12572877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
12582877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
12592877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1260*bccb9932SShri Abhyankar   if (isSeqAIJ) {
12612877fffaSHong Zhang     ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
1262*bccb9932SShri Abhyankar   } else {
1263*bccb9932SShri Abhyankar     ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1264*bccb9932SShri Abhyankar   }
12652877fffaSHong Zhang 
126616ebf90aSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
12672877fffaSHong Zhang   B->ops->view             = MatView_MUMPS;
126835bd34faSBarry Smith   B->ops->getinfo          = MatGetInfo_MUMPS;
126935bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
127097969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1271450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1272450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
1273d5f3da31SBarry Smith     B->factortype = MAT_FACTOR_LU;
1274*bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqaij;
1275*bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpiaij;
1276dcd589f8SShri Abhyankar   } else {
127767877ebaSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
1278450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_CHOLESKY;
1279*bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqsbaij;
1280*bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpisbaij;
1281450b117fSShri Abhyankar   }
12822877fffaSHong Zhang 
12832877fffaSHong Zhang   mumps->CleanUpMUMPS              = PETSC_FALSE;
12842877fffaSHong Zhang   mumps->isAIJ                     = PETSC_TRUE;
12852877fffaSHong Zhang   mumps->scat_rhs                  = PETSC_NULL;
12862877fffaSHong Zhang   mumps->scat_sol                  = PETSC_NULL;
12872877fffaSHong Zhang   mumps->nSolve                    = 0;
12882877fffaSHong Zhang   mumps->MatDestroy                = B->ops->destroy;
12892877fffaSHong Zhang   B->ops->destroy                  = MatDestroy_MUMPS;
12902877fffaSHong Zhang   B->spptr                         = (void*)mumps;
12912877fffaSHong Zhang 
12922877fffaSHong Zhang   *F = B;
12932877fffaSHong Zhang   PetscFunctionReturn(0);
12942877fffaSHong Zhang }
12952877fffaSHong Zhang EXTERN_C_END
12962877fffaSHong Zhang 
1297*bccb9932SShri Abhyankar 
12982877fffaSHong Zhang EXTERN_C_BEGIN
1299*bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI SBAIJ matrices */
13002877fffaSHong Zhang #undef __FUNCT__
1301*bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_sbaij_mumps"
1302*bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_sbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
13032877fffaSHong Zhang {
13042877fffaSHong Zhang   Mat            B;
13052877fffaSHong Zhang   PetscErrorCode ierr;
13062877fffaSHong Zhang   Mat_MUMPS      *mumps;
1307*bccb9932SShri Abhyankar   PetscTruth     isSeqSBAIJ;
13082877fffaSHong Zhang 
13092877fffaSHong Zhang   PetscFunctionBegin;
1310e7e72b3dSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
1311*bccb9932SShri 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");
1312*bccb9932SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
13132877fffaSHong Zhang   /* Create the factorization matrix */
13142877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
13152877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
13162877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
131716ebf90aSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1318*bccb9932SShri Abhyankar   if (isSeqSBAIJ) {
1319*bccb9932SShri Abhyankar     ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
132016ebf90aSShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_seqsbaij_seqsbaij;
1321dcd589f8SShri Abhyankar   } else {
1322*bccb9932SShri Abhyankar     ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1323*bccb9932SShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_mpisbaij_mpisbaij;
1324*bccb9932SShri Abhyankar   }
1325*bccb9932SShri Abhyankar 
132667877ebaSShri Abhyankar   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
1327*bccb9932SShri Abhyankar   B->ops->view                   = MatView_MUMPS;
1328*bccb9932SShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
1329*bccb9932SShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1330f4762488SHong Zhang   B->factortype                   = MAT_FACTOR_CHOLESKY;
1331a214ac2aSShri Abhyankar 
1332a214ac2aSShri Abhyankar   mumps->CleanUpMUMPS              = PETSC_FALSE;
1333*bccb9932SShri Abhyankar   mumps->isAIJ                     = PETSC_FALSE;
13342877fffaSHong Zhang   mumps->scat_rhs                  = PETSC_NULL;
13352877fffaSHong Zhang   mumps->scat_sol                  = PETSC_NULL;
13362877fffaSHong Zhang   mumps->nSolve                    = 0;
1337f3c0ef26SHong Zhang   mumps->MatDestroy                = B->ops->destroy;
1338f3c0ef26SHong Zhang   B->ops->destroy                  = MatDestroy_MUMPS;
13392877fffaSHong Zhang   B->spptr                         = (void*)mumps;
1340f3c0ef26SHong Zhang 
13412877fffaSHong Zhang   *F = B;
13422877fffaSHong Zhang   PetscFunctionReturn(0);
13432877fffaSHong Zhang }
13442877fffaSHong Zhang EXTERN_C_END
134597969023SHong Zhang 
1346450b117fSShri Abhyankar EXTERN_C_BEGIN
1347450b117fSShri Abhyankar #undef __FUNCT__
1348*bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_baij_mumps"
1349*bccb9932SShri Abhyankar PetscErrorCode MatGetFactor_baij_mumps(Mat A,MatFactorType ftype,Mat *F)
135067877ebaSShri Abhyankar {
135167877ebaSShri Abhyankar   Mat            B;
135267877ebaSShri Abhyankar   PetscErrorCode ierr;
135367877ebaSShri Abhyankar   Mat_MUMPS      *mumps;
1354*bccb9932SShri Abhyankar   PetscTruth     isSeqBAIJ;
135567877ebaSShri Abhyankar 
135667877ebaSShri Abhyankar   PetscFunctionBegin;
135767877ebaSShri Abhyankar   /* Create the factorization matrix */
1358*bccb9932SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQBAIJ,&isSeqBAIJ);CHKERRQ(ierr);
135967877ebaSShri Abhyankar   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
136067877ebaSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
136167877ebaSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1362*bccb9932SShri Abhyankar   if (isSeqBAIJ) {
136367877ebaSShri Abhyankar     ierr = MatSeqBAIJSetPreallocation(B,A->rmap->bs,0,PETSC_NULL);CHKERRQ(ierr);
1364*bccb9932SShri Abhyankar   } else {
136567877ebaSShri Abhyankar     ierr = MatMPIBAIJSetPreallocation(B,A->rmap->bs,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1366*bccb9932SShri Abhyankar   }
1367450b117fSShri Abhyankar 
136867877ebaSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1369450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1370450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_BAIJMUMPS;
1371450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_LU;
1372*bccb9932SShri Abhyankar     if (isSeqBAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqbaij_seqaij;
1373*bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpibaij_mpiaij;
1374450b117fSShri Abhyankar   }
1375*bccb9932SShri Abhyankar   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc BAIJ matrices with MUMPS Cholesky, use SBAIJ or AIJ matrix instead\n");
1376*bccb9932SShri Abhyankar 
1377450b117fSShri Abhyankar   B->ops->view             = MatView_MUMPS;
1378450b117fSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
1379450b117fSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1380450b117fSShri Abhyankar 
1381450b117fSShri Abhyankar   mumps->CleanUpMUMPS              = PETSC_FALSE;
1382450b117fSShri Abhyankar   mumps->isAIJ                     = PETSC_TRUE;
1383450b117fSShri Abhyankar   mumps->scat_rhs                  = PETSC_NULL;
1384450b117fSShri Abhyankar   mumps->scat_sol                  = PETSC_NULL;
1385450b117fSShri Abhyankar   mumps->nSolve                    = 0;
1386450b117fSShri Abhyankar   mumps->MatDestroy                = B->ops->destroy;
1387450b117fSShri Abhyankar   B->ops->destroy                  = MatDestroy_MUMPS;
1388450b117fSShri Abhyankar   B->spptr                         = (void*)mumps;
1389450b117fSShri Abhyankar 
1390450b117fSShri Abhyankar   *F = B;
1391450b117fSShri Abhyankar   PetscFunctionReturn(0);
1392450b117fSShri Abhyankar }
1393450b117fSShri Abhyankar EXTERN_C_END
1394a214ac2aSShri Abhyankar 
139561288eaaSHong Zhang /* -------------------------------------------------------------------------------------------*/
139661288eaaSHong Zhang /*@
139761288eaaSHong Zhang   MatMumpsSetIcntl - Set MUMPS parameter ICNTL()
139861288eaaSHong Zhang 
139961288eaaSHong Zhang    Collective on Mat
140061288eaaSHong Zhang 
140161288eaaSHong Zhang    Input Parameters:
140261288eaaSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
140361288eaaSHong Zhang .  idx - index of MUMPS parameter array ICNTL()
140461288eaaSHong Zhang -  icntl - value of MUMPS ICNTL(imumps)
140561288eaaSHong Zhang 
140661288eaaSHong Zhang   Options Database:
140761288eaaSHong Zhang .   -mat_mumps_icntl_<idx> <icntl>
140861288eaaSHong Zhang 
140961288eaaSHong Zhang    Level: beginner
141061288eaaSHong Zhang 
141161288eaaSHong Zhang    References: MUMPS Users' Guide
141261288eaaSHong Zhang 
141361288eaaSHong Zhang .seealso: MatGetFactor()
141461288eaaSHong Zhang @*/
141597969023SHong Zhang #undef __FUNCT__
141697969023SHong Zhang #define __FUNCT__ "MatMumpsSetIcntl"
141786e5884dSMatthew Knepley PetscErrorCode MatMumpsSetIcntl(Mat F,PetscInt idx,PetscInt icntl)
141897969023SHong Zhang {
1419dcd589f8SShri Abhyankar   Mat_MUMPS      *lu =(Mat_MUMPS*)(F)->spptr;
142097969023SHong Zhang 
142197969023SHong Zhang   PetscFunctionBegin;
142261288eaaSHong Zhang   lu->id.ICNTL(idx) = icntl;
142397969023SHong Zhang   PetscFunctionReturn(0);
142497969023SHong Zhang }
142597969023SHong Zhang 
1426