xref: /petsc/src/mat/impls/aij/mpi/mumps/mumps.c (revision 65e19b508233067d6906a3416498cb9734b3efd5)
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;
38329ec9b3SHong Zhang   PetscInt       *irn,*jcn,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);
45f0c56d0fSKris Buschelman } Mat_MUMPS;
46f0c56d0fSKris Buschelman 
47dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*);
48b24902e0SBarry Smith 
49397b6df1SKris Buschelman /* convert Petsc mpiaij matrix to triples: row[nz], col[nz], val[nz] */
50397b6df1SKris Buschelman /*
51397b6df1SKris Buschelman   input:
5275747be1SHong Zhang     A       - matrix in mpiaij or mpisbaij (bs=1) format
53397b6df1SKris Buschelman     shift   - 0: C style output triple; 1: Fortran style output triple.
54397b6df1SKris Buschelman     valOnly - FALSE: spaces are allocated and values are set for the triple
55397b6df1SKris Buschelman               TRUE:  only the values in v array are updated
56397b6df1SKris Buschelman   output:
57397b6df1SKris Buschelman     nnz     - dim of r, c, and v (number of local nonzero entries of A)
58397b6df1SKris Buschelman     r, c, v - row and col index, matrix values (matrix triples)
59397b6df1SKris Buschelman  */
60b24902e0SBarry Smith PetscErrorCode MatConvertToTriples(Mat A,int shift,PetscTruth valOnly,int *nnz,int **r, int **c, PetscScalar **v)
61b24902e0SBarry Smith {
62c1490034SHong Zhang   PetscInt       *ai, *aj, *bi, *bj, rstart,nz, *garray;
63dfbe8321SBarry Smith   PetscErrorCode ierr;
64d0f46423SBarry Smith   PetscInt       i,j,jj,jB,irow,m=A->rmap->n,*ajj,*bjj,countA,countB,colA_start,jcol;
65c1490034SHong Zhang   PetscInt       *row,*col;
66397b6df1SKris Buschelman   PetscScalar    *av, *bv,*val;
675c9eb25fSBarry Smith   PetscTruth     isAIJ;
68397b6df1SKris Buschelman 
69397b6df1SKris Buschelman   PetscFunctionBegin;
705c9eb25fSBarry Smith   ierr = PetscTypeCompare((PetscObject)A,MATMPIAIJ,&isAIJ);CHKERRQ(ierr);
715c9eb25fSBarry Smith   if (isAIJ){
72397b6df1SKris Buschelman     Mat_MPIAIJ    *mat =  (Mat_MPIAIJ*)A->data;
73397b6df1SKris Buschelman     Mat_SeqAIJ    *aa=(Mat_SeqAIJ*)(mat->A)->data;
74397b6df1SKris Buschelman     Mat_SeqAIJ    *bb=(Mat_SeqAIJ*)(mat->B)->data;
75397b6df1SKris Buschelman     nz = aa->nz + bb->nz;
76d0f46423SBarry Smith     ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
77397b6df1SKris Buschelman     garray = mat->garray;
78397b6df1SKris Buschelman     av=aa->a; bv=bb->a;
79397b6df1SKris Buschelman 
80397b6df1SKris Buschelman   } else {
81397b6df1SKris Buschelman     Mat_MPISBAIJ  *mat =  (Mat_MPISBAIJ*)A->data;
82397b6df1SKris Buschelman     Mat_SeqSBAIJ  *aa=(Mat_SeqSBAIJ*)(mat->A)->data;
83397b6df1SKris Buschelman     Mat_SeqBAIJ    *bb=(Mat_SeqBAIJ*)(mat->B)->data;
84e32f2f54SBarry Smith     if (A->rmap->bs > 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP," bs=%d is not supported yet\n", A->rmap->bs);
856c6c5352SBarry Smith     nz = aa->nz + bb->nz;
86d0f46423SBarry Smith     ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
87397b6df1SKris Buschelman     garray = mat->garray;
88397b6df1SKris Buschelman     av=aa->a; bv=bb->a;
89397b6df1SKris Buschelman   }
90397b6df1SKris Buschelman 
91397b6df1SKris Buschelman   if (!valOnly){
927c307921SBarry Smith     ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr);
937c307921SBarry Smith     ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr);
94397b6df1SKris Buschelman     ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr);
95397b6df1SKris Buschelman     *r = row; *c = col; *v = val;
96397b6df1SKris Buschelman   } else {
97397b6df1SKris Buschelman     row = *r; col = *c; val = *v;
98397b6df1SKris Buschelman   }
99397b6df1SKris Buschelman   *nnz = nz;
100397b6df1SKris Buschelman 
101028e57e8SHong Zhang   jj = 0; irow = rstart;
102397b6df1SKris Buschelman   for ( i=0; i<m; i++ ) {
103397b6df1SKris Buschelman     ajj = aj + ai[i];                 /* ptr to the beginning of this row */
104397b6df1SKris Buschelman     countA = ai[i+1] - ai[i];
105397b6df1SKris Buschelman     countB = bi[i+1] - bi[i];
106397b6df1SKris Buschelman     bjj = bj + bi[i];
107397b6df1SKris Buschelman 
108397b6df1SKris Buschelman     /* get jB, the starting local col index for the 2nd B-part */
109397b6df1SKris Buschelman     colA_start = rstart + ajj[0]; /* the smallest col index for A */
11075747be1SHong Zhang     j=-1;
11175747be1SHong Zhang     do {
11275747be1SHong Zhang       j++;
11375747be1SHong Zhang       if (j == countB) break;
114397b6df1SKris Buschelman       jcol = garray[bjj[j]];
11575747be1SHong Zhang     } while (jcol < colA_start);
11675747be1SHong Zhang     jB = j;
117397b6df1SKris Buschelman 
118397b6df1SKris Buschelman     /* B-part, smaller col index */
119397b6df1SKris Buschelman     colA_start = rstart + ajj[0]; /* the smallest col index for A */
120397b6df1SKris Buschelman     for (j=0; j<jB; j++){
121397b6df1SKris Buschelman       jcol = garray[bjj[j]];
122397b6df1SKris Buschelman       if (!valOnly){
123397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = jcol + shift;
12475747be1SHong Zhang 
125397b6df1SKris Buschelman       }
126397b6df1SKris Buschelman       val[jj++] = *bv++;
127397b6df1SKris Buschelman     }
128397b6df1SKris Buschelman     /* A-part */
129397b6df1SKris Buschelman     for (j=0; j<countA; j++){
130397b6df1SKris Buschelman       if (!valOnly){
131397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
132397b6df1SKris Buschelman       }
133397b6df1SKris Buschelman       val[jj++] = *av++;
134397b6df1SKris Buschelman     }
135397b6df1SKris Buschelman     /* B-part, larger col index */
136397b6df1SKris Buschelman     for (j=jB; j<countB; j++){
137397b6df1SKris Buschelman       if (!valOnly){
138397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
139397b6df1SKris Buschelman       }
140397b6df1SKris Buschelman       val[jj++] = *bv++;
141397b6df1SKris Buschelman     }
142397b6df1SKris Buschelman     irow++;
143397b6df1SKris Buschelman   }
144397b6df1SKris Buschelman   PetscFunctionReturn(0);
145397b6df1SKris Buschelman }
146397b6df1SKris Buschelman 
147397b6df1SKris Buschelman #undef __FUNCT__
1483924e44cSKris Buschelman #define __FUNCT__ "MatDestroy_MUMPS"
149dfbe8321SBarry Smith PetscErrorCode MatDestroy_MUMPS(Mat A)
150dfbe8321SBarry Smith {
151f0c56d0fSKris Buschelman   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
152dfbe8321SBarry Smith   PetscErrorCode ierr;
153c1490034SHong Zhang   PetscMPIInt    size=lu->size;
154b24902e0SBarry Smith 
155397b6df1SKris Buschelman   PetscFunctionBegin;
156397b6df1SKris Buschelman   if (lu->CleanUpMUMPS) {
157397b6df1SKris Buschelman     /* Terminate instance, deallocate memories */
158329ec9b3SHong Zhang     if (size > 1){
15968653410SBarry Smith       ierr = PetscFree2(lu->id.sol_loc,lu->id.isol_loc);CHKERRQ(ierr);
160329ec9b3SHong Zhang       ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr);
161329ec9b3SHong Zhang       ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr);
1622750af12SHong Zhang       if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);}
1632750af12SHong Zhang       if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);}
164329ec9b3SHong Zhang       ierr = PetscFree(lu->val);CHKERRQ(ierr);
165329ec9b3SHong Zhang     }
166450b117fSShri Abhyankar     if( size == 1 && (A)->factortype == MAT_FACTOR_CHOLESKY && lu->isAIJ) {
167450b117fSShri Abhyankar       ierr = PetscFree(lu->val);CHKERRQ(ierr);
168450b117fSShri Abhyankar     }
169397b6df1SKris Buschelman     lu->id.job=JOB_END;
170397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
171397b6df1SKris Buschelman     zmumps_c(&lu->id);
172397b6df1SKris Buschelman #else
173397b6df1SKris Buschelman     dmumps_c(&lu->id);
174397b6df1SKris Buschelman #endif
175c338a77dSKris Buschelman     ierr = PetscFree(lu->irn);CHKERRQ(ierr);
176c338a77dSKris Buschelman     ierr = PetscFree(lu->jcn);CHKERRQ(ierr);
177397b6df1SKris Buschelman     ierr = MPI_Comm_free(&(lu->comm_mumps));CHKERRQ(ierr);
178397b6df1SKris Buschelman   }
17997969023SHong Zhang   /* clear composed functions */
18097969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatFactorGetSolverPackage_C","",PETSC_NULL);CHKERRQ(ierr);
18197969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatMumpsSetIcntl_C","",PETSC_NULL);CHKERRQ(ierr);
18267334b25SHong Zhang   ierr = (lu->MatDestroy)(A);CHKERRQ(ierr);
183397b6df1SKris Buschelman   PetscFunctionReturn(0);
184397b6df1SKris Buschelman }
185397b6df1SKris Buschelman 
186397b6df1SKris Buschelman #undef __FUNCT__
187f6c57405SHong Zhang #define __FUNCT__ "MatSolve_MUMPS"
188b24902e0SBarry Smith PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x)
189b24902e0SBarry Smith {
190f0c56d0fSKris Buschelman   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
191d54de34fSKris Buschelman   PetscScalar    *array;
192397b6df1SKris Buschelman   Vec            x_seq;
193329ec9b3SHong Zhang   IS             is_iden,is_petsc;
194dfbe8321SBarry Smith   PetscErrorCode ierr;
195329ec9b3SHong Zhang   PetscInt       i;
196397b6df1SKris Buschelman 
197397b6df1SKris Buschelman   PetscFunctionBegin;
198329ec9b3SHong Zhang   lu->id.nrhs = 1;
199329ec9b3SHong Zhang   x_seq = lu->b_seq;
200397b6df1SKris Buschelman   if (lu->size > 1){
201329ec9b3SHong Zhang     /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */
202f6cfb2d1SLisandro Dalcin     ierr = VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
203f6cfb2d1SLisandro Dalcin     ierr = VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
204397b6df1SKris Buschelman     if (!lu->myid) {ierr = VecGetArray(x_seq,&array);CHKERRQ(ierr);}
205397b6df1SKris Buschelman   } else {  /* size == 1 */
206397b6df1SKris Buschelman     ierr = VecCopy(b,x);CHKERRQ(ierr);
207397b6df1SKris Buschelman     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
208397b6df1SKris Buschelman   }
209397b6df1SKris Buschelman   if (!lu->myid) { /* define rhs on the host */
2108278f211SHong Zhang     lu->id.nrhs = 1;
211397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
212397b6df1SKris Buschelman     lu->id.rhs = (mumps_double_complex*)array;
213397b6df1SKris Buschelman #else
214397b6df1SKris Buschelman     lu->id.rhs = array;
215397b6df1SKris Buschelman #endif
216397b6df1SKris Buschelman   }
217329ec9b3SHong Zhang   if (lu->size == 1){
218329ec9b3SHong Zhang     ierr = VecRestoreArray(x,&array);CHKERRQ(ierr);
219329ec9b3SHong Zhang   } else if (!lu->myid){
220329ec9b3SHong Zhang     ierr = VecRestoreArray(x_seq,&array);CHKERRQ(ierr);
221329ec9b3SHong Zhang   }
222329ec9b3SHong Zhang 
223329ec9b3SHong Zhang   if (lu->size > 1){
224329ec9b3SHong Zhang     /* distributed solution */
225329ec9b3SHong Zhang     lu->id.ICNTL(21) = 1;
226329ec9b3SHong Zhang     if (!lu->nSolve){
227329ec9b3SHong Zhang       /* Create x_seq=sol_loc for repeated use */
228329ec9b3SHong Zhang       PetscInt    lsol_loc;
229329ec9b3SHong Zhang       PetscScalar *sol_loc;
230329ec9b3SHong Zhang       lsol_loc = lu->id.INFO(23); /* length of sol_loc */
2310e83c824SBarry Smith       ierr = PetscMalloc2(lsol_loc,PetscScalar,&sol_loc,lsol_loc,PetscInt,&lu->id.isol_loc);CHKERRQ(ierr);
232329ec9b3SHong Zhang       lu->id.lsol_loc = lsol_loc;
23344ea04b1SSatish Balay #if defined(PETSC_USE_COMPLEX)
23444ea04b1SSatish Balay       lu->id.sol_loc  = (mumps_double_complex*)sol_loc;
23544ea04b1SSatish Balay #else
23644ea04b1SSatish Balay       lu->id.sol_loc  = sol_loc;
23744ea04b1SSatish Balay #endif
238329ec9b3SHong Zhang       ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,lsol_loc,sol_loc,&lu->x_seq);CHKERRQ(ierr);
239329ec9b3SHong Zhang     }
240329ec9b3SHong Zhang   }
241397b6df1SKris Buschelman 
242397b6df1SKris Buschelman   /* solve phase */
243329ec9b3SHong Zhang   /*-------------*/
244397b6df1SKris Buschelman   lu->id.job = 3;
245397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
246397b6df1SKris Buschelman   zmumps_c(&lu->id);
247397b6df1SKris Buschelman #else
248397b6df1SKris Buschelman   dmumps_c(&lu->id);
249397b6df1SKris Buschelman #endif
250*65e19b50SBarry 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));
251397b6df1SKris Buschelman 
252329ec9b3SHong Zhang   if (lu->size > 1) { /* convert mumps distributed solution to petsc mpi x */
253329ec9b3SHong Zhang     if (!lu->nSolve){ /* create scatter scat_sol */
254329ec9b3SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,lu->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */
255329ec9b3SHong Zhang       for (i=0; i<lu->id.lsol_loc; i++){
256329ec9b3SHong Zhang         lu->id.isol_loc[i] -= 1; /* change Fortran style to C style */
257397b6df1SKris Buschelman       }
258329ec9b3SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,lu->id.lsol_loc,lu->id.isol_loc,&is_petsc);CHKERRQ(ierr);  /* to */
259329ec9b3SHong Zhang       ierr = VecScatterCreate(lu->x_seq,is_iden,x,is_petsc,&lu->scat_sol);CHKERRQ(ierr);
260329ec9b3SHong Zhang       ierr = ISDestroy(is_iden);CHKERRQ(ierr);
261329ec9b3SHong Zhang       ierr = ISDestroy(is_petsc);CHKERRQ(ierr);
262397b6df1SKris Buschelman     }
263ca9f406cSSatish Balay     ierr = VecScatterBegin(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
264ca9f406cSSatish Balay     ierr = VecScatterEnd(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
265329ec9b3SHong Zhang   }
266329ec9b3SHong Zhang   lu->nSolve++;
267397b6df1SKris Buschelman   PetscFunctionReturn(0);
268397b6df1SKris Buschelman }
269397b6df1SKris Buschelman 
270ace3df97SHong Zhang #if !defined(PETSC_USE_COMPLEX)
271a58c3f20SHong Zhang /*
272a58c3f20SHong Zhang   input:
273a58c3f20SHong Zhang    F:        numeric factor
274a58c3f20SHong Zhang   output:
275a58c3f20SHong Zhang    nneg:     total number of negative pivots
276a58c3f20SHong Zhang    nzero:    0
277a58c3f20SHong Zhang    npos:     (global dimension of F) - nneg
278a58c3f20SHong Zhang */
279a58c3f20SHong Zhang 
280a58c3f20SHong Zhang #undef __FUNCT__
281a58c3f20SHong Zhang #define __FUNCT__ "MatGetInertia_SBAIJMUMPS"
282dfbe8321SBarry Smith PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos)
283a58c3f20SHong Zhang {
284a58c3f20SHong Zhang   Mat_MUMPS      *lu =(Mat_MUMPS*)F->spptr;
285dfbe8321SBarry Smith   PetscErrorCode ierr;
286c1490034SHong Zhang   PetscMPIInt    size;
287a58c3f20SHong Zhang 
288a58c3f20SHong Zhang   PetscFunctionBegin;
2897adad957SLisandro Dalcin   ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr);
290bcb30aebSHong 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 */
291*65e19b50SBarry 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));
292a58c3f20SHong Zhang   if (nneg){
293a58c3f20SHong Zhang     if (!lu->myid){
294a58c3f20SHong Zhang       *nneg = lu->id.INFOG(12);
295a58c3f20SHong Zhang     }
296bcb30aebSHong Zhang     ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_mumps);CHKERRQ(ierr);
297a58c3f20SHong Zhang   }
298a58c3f20SHong Zhang   if (nzero) *nzero = 0;
299d0f46423SBarry Smith   if (npos)  *npos  = F->rmap->N - (*nneg);
300a58c3f20SHong Zhang   PetscFunctionReturn(0);
301a58c3f20SHong Zhang }
302ace3df97SHong Zhang #endif /* !defined(PETSC_USE_COMPLEX) */
303a58c3f20SHong Zhang 
304397b6df1SKris Buschelman #undef __FUNCT__
305f6c57405SHong Zhang #define __FUNCT__ "MatFactorNumeric_MUMPS"
3060481f469SBarry Smith PetscErrorCode MatFactorNumeric_MUMPS(Mat F,Mat A,const MatFactorInfo *info)
307af281ebdSHong Zhang {
308dcd589f8SShri Abhyankar   Mat_MUMPS      *lu =(Mat_MUMPS*)(F)->spptr;
309450b117fSShri Abhyankar   Mat            newMat;
3106849ba73SBarry Smith   PetscErrorCode ierr;
311dcd589f8SShri Abhyankar   PetscInt       rnz,nnz,nz=0,i,M=A->rmap->N,*ai,*aj,*adiag,jidx;
312450b117fSShri Abhyankar   PetscScalar   *av;
313dcd589f8SShri Abhyankar   PetscTruth     valOnly;
314e09efc27SHong Zhang   Mat            F_diag;
315c349612cSHong Zhang   IS             is_iden;
316c349612cSHong Zhang   Vec            b;
317450b117fSShri Abhyankar   PetscTruth     isSeqAIJ,isSeqSBAIJ,isMPIAIJ;
318397b6df1SKris Buschelman 
319397b6df1SKris Buschelman   PetscFunctionBegin;
3205c9eb25fSBarry Smith   ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
3215c9eb25fSBarry Smith   ierr = PetscTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
322a214ac2aSShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
323a214ac2aSShri Abhyankar 
324397b6df1SKris Buschelman   /* define matrix A */
325397b6df1SKris Buschelman   switch (lu->id.ICNTL(18)){
326397b6df1SKris Buschelman   case 0:  /* centralized assembled matrix input (size=1) */
327397b6df1SKris Buschelman     if (!lu->myid) {
3285c9eb25fSBarry Smith       if (isSeqAIJ){
329397b6df1SKris Buschelman 	Mat_SeqAIJ   *aa = (Mat_SeqAIJ*)A->data;
330397b6df1SKris Buschelman 	nz               = aa->nz;
331450b117fSShri Abhyankar 	ai = aa->i; aj = aa->j; adiag = aa->diag; av = aa->a;
3325c9eb25fSBarry Smith       } else if (isSeqSBAIJ) {
333397b6df1SKris Buschelman         Mat_SeqSBAIJ *aa = (Mat_SeqSBAIJ*)A->data;
3346c6c5352SBarry Smith         nz                  =  aa->nz;
335450b117fSShri Abhyankar         ai = aa->i; aj = aa->j; av  = aa->a;
336e7e72b3dSBarry Smith       } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No mumps factorization for this matrix type");
337e7e72b3dSBarry Smith 
338dcd589f8SShri Abhyankar       if ((F)->factortype == MAT_FACTOR_CHOLESKY && isSeqAIJ) {
339450b117fSShri Abhyankar 	nz = 0;
340450b117fSShri Abhyankar 	for (i=0; i<M; i++){
341450b117fSShri Abhyankar 	  rnz = ai[i+1] - adiag[i];
342450b117fSShri Abhyankar 	  jidx = adiag[i];
343450b117fSShri Abhyankar 	  while (rnz--) {  /* Fortran row/col index! */
344450b117fSShri Abhyankar 	    lu->val[nz] = av[jidx]; jidx++; nz++;
345450b117fSShri Abhyankar 	  }
346450b117fSShri Abhyankar 	}
347450b117fSShri Abhyankar       } else {
348450b117fSShri Abhyankar 	lu->val = av;
349397b6df1SKris Buschelman       }
350450b117fSShri Abhyankar     }
351397b6df1SKris Buschelman     break;
352397b6df1SKris Buschelman   case 3:  /* distributed assembled matrix input (size>1) */
353397b6df1SKris Buschelman     valOnly = PETSC_TRUE; /* only update mat values, not row and col index */
354dcd589f8SShri Abhyankar 
355dcd589f8SShri Abhyankar     if(((F)->factortype == MAT_FACTOR_CHOLESKY) && isMPIAIJ) {
356a214ac2aSShri Abhyankar       /* Create an SBAIJ matrix and use this matrix to set the lu values */
357a214ac2aSShri Abhyankar       ierr = MatConvert(A,MATMPISBAIJ,MAT_INITIAL_MATRIX,&newMat);CHKERRQ(ierr);
358a214ac2aSShri Abhyankar       ierr = MatConvertToTriples(newMat,1,valOnly,&nnz,&lu->irn , &lu->jcn, &lu->val);CHKERRQ(ierr);
359a214ac2aSShri Abhyankar       ierr = MatDestroy(newMat);CHKERRQ(ierr);
360a214ac2aSShri Abhyankar     }
361a214ac2aSShri Abhyankar     else {
362397b6df1SKris Buschelman       ierr = MatConvertToTriples(A,1,valOnly, &nnz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
363a214ac2aSShri Abhyankar     }
364397b6df1SKris Buschelman     break;
365e32f2f54SBarry Smith   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix input format is not supported by MUMPS.");
366397b6df1SKris Buschelman   }
367397b6df1SKris Buschelman 
368397b6df1SKris Buschelman   /* analysis phase */
369329ec9b3SHong Zhang   /*----------------*/
370397b6df1SKris Buschelman   if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){
371329ec9b3SHong Zhang     lu->id.job = 1;
372329ec9b3SHong Zhang 
373397b6df1SKris Buschelman     lu->id.n = M;
374397b6df1SKris Buschelman     switch (lu->id.ICNTL(18)){
375397b6df1SKris Buschelman     case 0:  /* centralized assembled matrix input */
376397b6df1SKris Buschelman       if (!lu->myid) {
377397b6df1SKris Buschelman         lu->id.nz =nz; lu->id.irn=lu->irn; lu->id.jcn=lu->jcn;
378397b6df1SKris Buschelman         if (lu->id.ICNTL(6)>1){
379397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
380397b6df1SKris Buschelman           lu->id.a = (mumps_double_complex*)lu->val;
381397b6df1SKris Buschelman #else
382397b6df1SKris Buschelman           lu->id.a = lu->val;
383397b6df1SKris Buschelman #endif
384397b6df1SKris Buschelman         }
385397b6df1SKris Buschelman       }
386397b6df1SKris Buschelman       break;
387397b6df1SKris Buschelman     case 3:  /* distributed assembled matrix input (size>1) */
388397b6df1SKris Buschelman       lu->id.nz_loc = nnz;
389397b6df1SKris Buschelman       lu->id.irn_loc=lu->irn; lu->id.jcn_loc=lu->jcn;
390397b6df1SKris Buschelman       if (lu->id.ICNTL(6)>1) {
391397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
392397b6df1SKris Buschelman         lu->id.a_loc = (mumps_double_complex*)lu->val;
393397b6df1SKris Buschelman #else
394397b6df1SKris Buschelman         lu->id.a_loc = lu->val;
395397b6df1SKris Buschelman #endif
396397b6df1SKris Buschelman       }
397329ec9b3SHong Zhang       /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
398329ec9b3SHong Zhang       if (!lu->myid){
399d0f46423SBarry Smith         ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr);
400d0f46423SBarry Smith         ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
401329ec9b3SHong Zhang       } else {
402329ec9b3SHong Zhang         ierr = VecCreateSeq(PETSC_COMM_SELF,0,&lu->b_seq);CHKERRQ(ierr);
403329ec9b3SHong Zhang         ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
404329ec9b3SHong Zhang       }
4057adad957SLisandro Dalcin       ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr);
406d0f46423SBarry Smith       ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr);
407329ec9b3SHong Zhang       ierr = VecSetFromOptions(b);CHKERRQ(ierr);
408329ec9b3SHong Zhang 
409329ec9b3SHong Zhang       ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr);
410329ec9b3SHong Zhang       ierr = ISDestroy(is_iden);CHKERRQ(ierr);
411329ec9b3SHong Zhang       ierr = VecDestroy(b);CHKERRQ(ierr);
412397b6df1SKris Buschelman       break;
413397b6df1SKris Buschelman     }
414397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
415397b6df1SKris Buschelman     zmumps_c(&lu->id);
416397b6df1SKris Buschelman #else
417397b6df1SKris Buschelman     dmumps_c(&lu->id);
418397b6df1SKris Buschelman #endif
419*65e19b50SBarry Smith     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));
420397b6df1SKris Buschelman   }
421397b6df1SKris Buschelman 
422397b6df1SKris Buschelman   /* numerical factorization phase */
423329ec9b3SHong Zhang   /*-------------------------------*/
424329ec9b3SHong Zhang   lu->id.job = 2;
425958c9bccSBarry Smith   if(!lu->id.ICNTL(18)) {
426a7aca84bSHong Zhang     if (!lu->myid) {
427397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
428397b6df1SKris Buschelman       lu->id.a = (mumps_double_complex*)lu->val;
429397b6df1SKris Buschelman #else
430397b6df1SKris Buschelman       lu->id.a = lu->val;
431397b6df1SKris Buschelman #endif
432397b6df1SKris Buschelman     }
433397b6df1SKris Buschelman   } else {
434397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
435397b6df1SKris Buschelman     lu->id.a_loc = (mumps_double_complex*)lu->val;
436397b6df1SKris Buschelman #else
437397b6df1SKris Buschelman     lu->id.a_loc = lu->val;
438397b6df1SKris Buschelman #endif
439397b6df1SKris Buschelman   }
440397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
441397b6df1SKris Buschelman   zmumps_c(&lu->id);
442397b6df1SKris Buschelman #else
443397b6df1SKris Buschelman   dmumps_c(&lu->id);
444397b6df1SKris Buschelman #endif
445397b6df1SKris Buschelman   if (lu->id.INFOG(1) < 0) {
446*65e19b50SBarry 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));
447*65e19b50SBarry 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));
448397b6df1SKris Buschelman   }
449*65e19b50SBarry 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));
450397b6df1SKris Buschelman 
4518ada1bb4SHong Zhang   if (lu->size > 1){
452a214ac2aSShri Abhyankar     if(isMPIAIJ) {
453dcd589f8SShri Abhyankar       F_diag = ((Mat_MPIAIJ *)(F)->data)->A;
454e09efc27SHong Zhang     } else {
455dcd589f8SShri Abhyankar       F_diag = ((Mat_MPISBAIJ *)(F)->data)->A;
456e09efc27SHong Zhang     }
457e09efc27SHong Zhang     F_diag->assembled = PETSC_TRUE;
458329ec9b3SHong Zhang     if (lu->nSolve){
459329ec9b3SHong Zhang       ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);
4600e83c824SBarry Smith       ierr = PetscFree2(lu->id.sol_loc,lu->id.isol_loc);CHKERRQ(ierr);
461329ec9b3SHong Zhang       ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);
462329ec9b3SHong Zhang     }
4638ada1bb4SHong Zhang   }
464dcd589f8SShri Abhyankar   (F)->assembled   = PETSC_TRUE;
465397b6df1SKris Buschelman   lu->matstruc     = SAME_NONZERO_PATTERN;
466ace87b0dSHong Zhang   lu->CleanUpMUMPS = PETSC_TRUE;
467329ec9b3SHong Zhang   lu->nSolve       = 0;
468397b6df1SKris Buschelman   PetscFunctionReturn(0);
469397b6df1SKris Buschelman }
470397b6df1SKris Buschelman 
471dcd589f8SShri Abhyankar #undef __FUNCT__
472dcd589f8SShri Abhyankar #define __FUNCT__ "PetscSetMUMPSOptions"
473dcd589f8SShri Abhyankar PetscErrorCode PetscSetMUMPSOptions(Mat F, Mat A)
474dcd589f8SShri Abhyankar {
475dcd589f8SShri Abhyankar   Mat_MUMPS        *lu = (Mat_MUMPS*)F->spptr;
476dcd589f8SShri Abhyankar   PetscErrorCode   ierr;
477dcd589f8SShri Abhyankar   PetscInt         icntl;
478dcd589f8SShri Abhyankar   PetscTruth       flg;
479dcd589f8SShri Abhyankar 
480dcd589f8SShri Abhyankar   PetscFunctionBegin;
481dcd589f8SShri Abhyankar   ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr);
482cb828f0fSHong Zhang   ierr = PetscOptionsTruth("-mat_mumps_view","View MUMPS parameters","None",lu->mumpsview,&lu->mumpsview,PETSC_NULL);CHKERRQ(ierr);
483dcd589f8SShri Abhyankar   if (lu->size == 1){
484dcd589f8SShri Abhyankar     lu->id.ICNTL(18) = 0;   /* centralized assembled matrix input */
485dcd589f8SShri Abhyankar   } else {
486dcd589f8SShri Abhyankar     lu->id.ICNTL(18) = 3;   /* distributed assembled matrix input */
487dcd589f8SShri Abhyankar   }
488dcd589f8SShri Abhyankar 
489dcd589f8SShri Abhyankar   icntl=-1;
490dcd589f8SShri Abhyankar   lu->id.ICNTL(4) = 0;  /* level of printing; overwrite mumps default ICNTL(4)=2 */
491dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",lu->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr);
492dcd589f8SShri Abhyankar   if ((flg && icntl > 0) || PetscLogPrintInfo) {
493dcd589f8SShri Abhyankar     lu->id.ICNTL(4)=icntl; /* and use mumps default icntl(i), i=1,2,3 */
494dcd589f8SShri Abhyankar   } else { /* no output */
495dcd589f8SShri Abhyankar     lu->id.ICNTL(1) = 0;  /* error message, default= 6 */
496dcd589f8SShri Abhyankar     lu->id.ICNTL(2) = 0;  /* output stream for diagnostic printing, statistics, and warning. default=0 */
497dcd589f8SShri Abhyankar     lu->id.ICNTL(3) = 0; /* output stream for global information, default=6 */
498dcd589f8SShri Abhyankar   }
499dcd589f8SShri 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);
500dcd589f8SShri Abhyankar   icntl=-1;
501dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_7","ICNTL(7): matrix ordering (0 to 7)","None",lu->id.ICNTL(7),&icntl,&flg);CHKERRQ(ierr);
502dcd589f8SShri Abhyankar   if (flg) {
503dcd589f8SShri Abhyankar     if (icntl== 1){
504e32f2f54SBarry 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");
505dcd589f8SShri Abhyankar     } else {
506dcd589f8SShri Abhyankar       lu->id.ICNTL(7) = icntl;
507dcd589f8SShri Abhyankar     }
508dcd589f8SShri Abhyankar   }
509dcd589f8SShri 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);
510dcd589f8SShri 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);
511dcd589f8SShri 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);
512dcd589f8SShri 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);
513dcd589f8SShri 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);
514dcd589f8SShri 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);
515dcd589f8SShri 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);
516dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_19","ICNTL(19): Schur complement","None",lu->id.ICNTL(19),&lu->id.ICNTL(19),PETSC_NULL);CHKERRQ(ierr);
517dcd589f8SShri Abhyankar 
518dcd589f8SShri 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);
519dcd589f8SShri 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);
520dcd589f8SShri 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);
521dcd589f8SShri 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);
522dcd589f8SShri 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);
523dcd589f8SShri Abhyankar   ierr = PetscOptionsInt("-mat_mumps_icntl_27","ICNTL(27): experimental parameter","None",lu->id.ICNTL(27),&lu->id.ICNTL(27),PETSC_NULL);CHKERRQ(ierr);
524dcd589f8SShri Abhyankar 
525dcd589f8SShri 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);
526dcd589f8SShri 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);
527dcd589f8SShri 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);
528dcd589f8SShri 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);
529dcd589f8SShri 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);
530dcd589f8SShri Abhyankar   PetscOptionsEnd();
531dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
532dcd589f8SShri Abhyankar }
533dcd589f8SShri Abhyankar 
534dcd589f8SShri Abhyankar #undef __FUNCT__
535dcd589f8SShri Abhyankar #define __FUNCT__ "PetscInitializeMUMPS"
536dcd589f8SShri Abhyankar PetscErrorCode PetscInitializeMUMPS(Mat F)
537dcd589f8SShri Abhyankar {
538dcd589f8SShri Abhyankar   Mat_MUMPS       *lu = (Mat_MUMPS*)F->spptr;
539dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
540dcd589f8SShri Abhyankar   PetscInt        icntl;
541dcd589f8SShri Abhyankar   PetscTruth      flg;
542dcd589f8SShri Abhyankar 
543dcd589f8SShri Abhyankar   PetscFunctionBegin;
544dcd589f8SShri Abhyankar   lu->id.job = JOB_INIT;
545dcd589f8SShri Abhyankar   lu->id.par=1;  /* host participates factorizaton and solve */
546dcd589f8SShri Abhyankar   lu->id.sym=lu->sym;
547dcd589f8SShri Abhyankar   if (lu->sym == 2){
548dcd589f8SShri Abhyankar     ierr = PetscOptionsInt("-mat_mumps_sym","SYM: (1,2)","None",lu->id.sym,&icntl,&flg);CHKERRQ(ierr);
549dcd589f8SShri Abhyankar     if (flg && icntl == 1) lu->id.sym=icntl;  /* matrix is spd */
550dcd589f8SShri Abhyankar   }
551dcd589f8SShri Abhyankar #if defined(PETSC_USE_COMPLEX)
552dcd589f8SShri Abhyankar   zmumps_c(&lu->id);
553dcd589f8SShri Abhyankar #else
554dcd589f8SShri Abhyankar   dmumps_c(&lu->id);
555dcd589f8SShri Abhyankar #endif
556dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
557dcd589f8SShri Abhyankar }
558dcd589f8SShri Abhyankar 
559397b6df1SKris Buschelman /* Note the Petsc r and c permutations are ignored */
560397b6df1SKris Buschelman #undef __FUNCT__
561f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS"
5620481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
563b24902e0SBarry Smith {
564719d5645SBarry Smith   Mat_MUMPS          *lu = (Mat_MUMPS*)F->spptr;
565dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
566dcd589f8SShri Abhyankar   PetscTruth         isSeqAIJ,isMPIAIJ;
567dcd589f8SShri Abhyankar   PetscInt           nz=0,M=A->rmap->N,rnz,i,nnz;
568dcd589f8SShri Abhyankar   const PetscInt     *ai,*aj;
569dcd589f8SShri Abhyankar   PetscTruth         valOnly;
570397b6df1SKris Buschelman 
571397b6df1SKris Buschelman   PetscFunctionBegin;
572b24902e0SBarry Smith   lu->sym                  = 0;
573b24902e0SBarry Smith   lu->matstruc             = DIFFERENT_NONZERO_PATTERN;
574dcd589f8SShri Abhyankar 
575dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
576dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
577dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
578dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
579dcd589f8SShri Abhyankar 
580dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
581dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
582dcd589f8SShri Abhyankar   /* Set MUMPS options */
583dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
584dcd589f8SShri Abhyankar 
585dcd589f8SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
586dcd589f8SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
587dcd589f8SShri Abhyankar   switch (lu->id.ICNTL(18)){
588dcd589f8SShri Abhyankar   case 0:  /* centralized assembled matrix input (size=1) */
589dcd589f8SShri Abhyankar     if (!lu->myid) {
590dcd589f8SShri Abhyankar       Mat_SeqAIJ   *aa = (Mat_SeqAIJ*)A->data;
591dcd589f8SShri Abhyankar       nz               = aa->nz;
592dcd589f8SShri Abhyankar       ai = aa->i; aj = aa->j; lu->val = aa->a;
593dcd589f8SShri Abhyankar       ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->irn);CHKERRQ(ierr);
594dcd589f8SShri Abhyankar       ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->jcn);CHKERRQ(ierr);
595dcd589f8SShri Abhyankar       nz = 0;
596dcd589f8SShri Abhyankar       for (i=0; i<M; i++){
597dcd589f8SShri Abhyankar 	rnz = ai[i+1] - ai[i];
598dcd589f8SShri Abhyankar 	while (rnz--) {  /* Fortran row/col index! */
599dcd589f8SShri Abhyankar 	  lu->irn[nz] = i+1; lu->jcn[nz] = (*aj)+1; aj++; nz++;
600dcd589f8SShri Abhyankar 	}
601dcd589f8SShri Abhyankar       }
602dcd589f8SShri Abhyankar     }
603dcd589f8SShri Abhyankar     break;
604dcd589f8SShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
605dcd589f8SShri Abhyankar     valOnly = PETSC_FALSE;
606dcd589f8SShri Abhyankar     ierr = MatConvertToTriples(A,1,valOnly, &nnz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
607dcd589f8SShri Abhyankar     break;
608e32f2f54SBarry Smith   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix input format is not supported by MUMPS.");
609dcd589f8SShri Abhyankar   }
610dcd589f8SShri Abhyankar 
611719d5645SBarry Smith   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
612dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
613b24902e0SBarry Smith   PetscFunctionReturn(0);
614b24902e0SBarry Smith }
615b24902e0SBarry Smith 
616450b117fSShri Abhyankar /* Note the Petsc r and c permutations are ignored */
617450b117fSShri Abhyankar #undef __FUNCT__
618450b117fSShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_BAIJMUMPS"
619450b117fSShri Abhyankar PetscErrorCode MatLUFactorSymbolic_BAIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
620450b117fSShri Abhyankar {
621dcd589f8SShri Abhyankar 
622450b117fSShri Abhyankar   Mat_MUMPS       *lu = (Mat_MUMPS*)F->spptr;
623dcd589f8SShri Abhyankar   PetscErrorCode  ierr;
624450b117fSShri Abhyankar 
625450b117fSShri Abhyankar   PetscFunctionBegin;
626450b117fSShri Abhyankar   lu->sym                  = 0;
627450b117fSShri Abhyankar   lu->matstruc             = DIFFERENT_NONZERO_PATTERN;
628dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
629dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
630dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
631dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
632dcd589f8SShri Abhyankar 
633dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
634dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
635dcd589f8SShri Abhyankar   /* Set MUMPS options */
636dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
637dcd589f8SShri Abhyankar 
638450b117fSShri Abhyankar   F->ops->lufactornumeric  = MatFactorNumeric_MUMPS;
639dcd589f8SShri Abhyankar   F->ops->solve            = MatSolve_MUMPS;
640450b117fSShri Abhyankar   PetscFunctionReturn(0);
641450b117fSShri Abhyankar }
642b24902e0SBarry Smith 
643397b6df1SKris Buschelman /* Note the Petsc r permutation is ignored */
644397b6df1SKris Buschelman #undef __FUNCT__
645f0c56d0fSKris Buschelman #define __FUNCT__ "MatCholeskyFactorSymbolic_SBAIJMUMPS"
6460481f469SBarry Smith PetscErrorCode MatCholeskyFactorSymbolic_SBAIJMUMPS(Mat F,Mat A,IS r,const MatFactorInfo *info)
647b24902e0SBarry Smith {
6482792810eSHong Zhang   Mat_MUMPS          *lu = (Mat_MUMPS*)F->spptr;
649dcd589f8SShri Abhyankar   Mat                newMat;
650dcd589f8SShri Abhyankar   PetscErrorCode     ierr;
651dcd589f8SShri Abhyankar   PetscInt           nz=0,M=A->rmap->N,rnz,i,nnz,jidx;
652dcd589f8SShri Abhyankar   const PetscInt     *ai,*aj,*adiag;
653dcd589f8SShri Abhyankar   PetscScalar        *av;
654dcd589f8SShri Abhyankar   PetscTruth         valOnly,isSeqAIJ,isMPIAIJ;
655dcd589f8SShri Abhyankar 
656397b6df1SKris Buschelman 
657397b6df1SKris Buschelman   PetscFunctionBegin;
658b24902e0SBarry Smith   lu->sym                          = 2;
659b24902e0SBarry Smith   lu->matstruc                     = DIFFERENT_NONZERO_PATTERN;
660dcd589f8SShri Abhyankar   ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid);
661dcd589f8SShri Abhyankar   ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr);
662dcd589f8SShri Abhyankar   ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr);
663dcd589f8SShri Abhyankar   lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps);
664dcd589f8SShri Abhyankar 
665dcd589f8SShri Abhyankar   /* Initialize a MUMPS instance */
666dcd589f8SShri Abhyankar   ierr = PetscInitializeMUMPS(F);CHKERRQ(ierr);
667dcd589f8SShri Abhyankar   /* Set MUMPS options */
668dcd589f8SShri Abhyankar   ierr = PetscSetMUMPSOptions(F,A);CHKERRQ(ierr);
669dcd589f8SShri Abhyankar 
670dcd589f8SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
671dcd589f8SShri Abhyankar   ierr = PetscTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
672dcd589f8SShri Abhyankar   switch (lu->id.ICNTL(18)){
673dcd589f8SShri Abhyankar   case 0:  /* centralized assembled matrix input (size=1) */
674dcd589f8SShri Abhyankar     if (!lu->myid) {
675dcd589f8SShri Abhyankar       if(isSeqAIJ) {
676dcd589f8SShri Abhyankar 	Mat_SeqAIJ   *aa = (Mat_SeqAIJ*)A->data;
677dcd589f8SShri Abhyankar 	nz               = aa->nz;
678dcd589f8SShri Abhyankar 	ai = aa->i; aj = aa->j; adiag = aa->diag; av = aa->a;
679dcd589f8SShri Abhyankar       } else {
680dcd589f8SShri Abhyankar 	Mat_SeqSBAIJ *aa = (Mat_SeqSBAIJ*)A->data;
681dcd589f8SShri Abhyankar 	nz               = aa->nz;
682dcd589f8SShri Abhyankar 	ai = aa->i; aj = aa->j; adiag = aa->diag; av = aa->a;
683dcd589f8SShri Abhyankar       }
684dcd589f8SShri Abhyankar       if ((F)->factortype == MAT_FACTOR_CHOLESKY && isSeqAIJ) {
685dcd589f8SShri Abhyankar 	nz = M + (nz - M)/2;  /* nz for upper triangle */
686dcd589f8SShri Abhyankar 	ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->irn);CHKERRQ(ierr);
687dcd589f8SShri Abhyankar 	ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->jcn);CHKERRQ(ierr);
688dcd589f8SShri Abhyankar 	ierr = PetscMalloc(nz*sizeof(PetscScalar),&lu->val);CHKERRQ(ierr);
689dcd589f8SShri Abhyankar 	nz = 0;
690dcd589f8SShri Abhyankar 	for (i=0; i<M; i++){
691dcd589f8SShri Abhyankar 	  rnz = ai[i+1] - adiag[i];
692dcd589f8SShri Abhyankar 	  jidx = adiag[i];
693dcd589f8SShri Abhyankar 	  while (rnz--) {  /* Fortran row/col index! */
694dcd589f8SShri Abhyankar 	    lu->irn[nz] = i+1; lu->jcn[nz] = aj[jidx]+1;
695dcd589f8SShri Abhyankar 	    lu->val[nz] = av[jidx]; jidx++; nz++;
696dcd589f8SShri Abhyankar 	  }
697dcd589f8SShri Abhyankar 	}
698dcd589f8SShri Abhyankar       } else {
699dcd589f8SShri Abhyankar 	lu->val = av;
700dcd589f8SShri Abhyankar 	ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->irn);CHKERRQ(ierr);
701dcd589f8SShri Abhyankar 	ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->jcn);CHKERRQ(ierr);
702dcd589f8SShri Abhyankar 	nz = 0;
703dcd589f8SShri Abhyankar 	for (i=0; i<M; i++){
704dcd589f8SShri Abhyankar 	  rnz = ai[i+1] - ai[i];
705dcd589f8SShri Abhyankar 	  while (rnz--) {  /* Fortran row/col index! */
706dcd589f8SShri Abhyankar 	    lu->irn[nz] = i+1; lu->jcn[nz] = (*aj)+1; aj++; nz++;
707dcd589f8SShri Abhyankar 	  }
708dcd589f8SShri Abhyankar 	}
709dcd589f8SShri Abhyankar       }
710dcd589f8SShri Abhyankar     }
711dcd589f8SShri Abhyankar     break;
712dcd589f8SShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
713dcd589f8SShri Abhyankar     valOnly = PETSC_FALSE;
714dcd589f8SShri Abhyankar     if(((F)->factortype == MAT_FACTOR_CHOLESKY) && isMPIAIJ) {
715dcd589f8SShri Abhyankar       /* Create an SBAIJ matrix and use this matrix to set the lu values */
716dcd589f8SShri Abhyankar       ierr = MatConvert(A,MATMPISBAIJ,MAT_INITIAL_MATRIX,&newMat);CHKERRQ(ierr);
717dcd589f8SShri Abhyankar       ierr = MatConvertToTriples(newMat,1,valOnly,&nnz,&lu->irn , &lu->jcn, &lu->val);CHKERRQ(ierr);
718dcd589f8SShri Abhyankar       ierr = MatDestroy(newMat);CHKERRQ(ierr);
719dcd589f8SShri Abhyankar     } else {
720dcd589f8SShri Abhyankar       ierr = MatConvertToTriples(A,1,valOnly, &nnz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr);
721dcd589f8SShri Abhyankar     }
722dcd589f8SShri Abhyankar     break;
723e32f2f54SBarry Smith   default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix input format is not supported by MUMPS.");
724dcd589f8SShri Abhyankar   }
725dcd589f8SShri Abhyankar 
7262792810eSHong Zhang   F->ops->choleskyfactornumeric =  MatFactorNumeric_MUMPS;
727dcd589f8SShri Abhyankar   F->ops->solve                 =  MatSolve_MUMPS;
728db4efbfdSBarry Smith #if !defined(PETSC_USE_COMPLEX)
729dcd589f8SShri Abhyankar   (F)->ops->getinertia          =  MatGetInertia_SBAIJMUMPS;
730db4efbfdSBarry Smith #endif
731b24902e0SBarry Smith   PetscFunctionReturn(0);
732b24902e0SBarry Smith }
733b24902e0SBarry Smith 
734397b6df1SKris Buschelman #undef __FUNCT__
735f6c57405SHong Zhang #define __FUNCT__ "MatFactorInfo_MUMPS"
73674ed9c26SBarry Smith PetscErrorCode MatFactorInfo_MUMPS(Mat A,PetscViewer viewer)
73774ed9c26SBarry Smith {
738f6c57405SHong Zhang   Mat_MUMPS      *lu=(Mat_MUMPS*)A->spptr;
739f6c57405SHong Zhang   PetscErrorCode ierr;
740f6c57405SHong Zhang 
741f6c57405SHong Zhang   PetscFunctionBegin;
742f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(1) (output for error):        %d \n",lu->id.ICNTL(1));CHKERRQ(ierr);
743f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(2) (output of diagnostic msg):%d \n",lu->id.ICNTL(2));CHKERRQ(ierr);
744f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(3) (output for global info):  %d \n",lu->id.ICNTL(3));CHKERRQ(ierr);
745f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(4) (level of printing):       %d \n",lu->id.ICNTL(4));CHKERRQ(ierr);
746f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(5) (input mat struct):        %d \n",lu->id.ICNTL(5));CHKERRQ(ierr);
747f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(6) (matrix prescaling):       %d \n",lu->id.ICNTL(6));CHKERRQ(ierr);
748f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(7) (matrix ordering):         %d \n",lu->id.ICNTL(7));CHKERRQ(ierr);
749f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(8) (scalling strategy):       %d \n",lu->id.ICNTL(8));CHKERRQ(ierr);
750f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(9) (A/A^T x=b is solved):     %d \n",lu->id.ICNTL(9));CHKERRQ(ierr);
751f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(10) (max num of refinements): %d \n",lu->id.ICNTL(10));CHKERRQ(ierr);
752f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(11) (error analysis):         %d \n",lu->id.ICNTL(11));CHKERRQ(ierr);
753f6c57405SHong Zhang   if (!lu->myid && lu->id.ICNTL(11)>0) {
754f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(4) (inf norm of input mat):        %g\n",lu->id.RINFOG(4));CHKERRQ(ierr);
755f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(5) (inf norm of solution):         %g\n",lu->id.RINFOG(5));CHKERRQ(ierr);
756f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(6) (inf norm of residual):         %g\n",lu->id.RINFOG(6));CHKERRQ(ierr);
757f6c57405SHong 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);
758f6c57405SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"        RINFOG(9) (error estimate):               %g \n",lu->id.RINFOG(9));CHKERRQ(ierr);
759f6c57405SHong 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);
760f6c57405SHong Zhang 
761f6c57405SHong Zhang   }
762f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(12) (efficiency control):                         %d \n",lu->id.ICNTL(12));CHKERRQ(ierr);
763f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(13) (efficiency control):                         %d \n",lu->id.ICNTL(13));CHKERRQ(ierr);
764f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(14) (percentage of estimated workspace increase): %d \n",lu->id.ICNTL(14));CHKERRQ(ierr);
765f6c57405SHong Zhang   /* ICNTL(15-17) not used */
766f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(18) (input mat struct):                           %d \n",lu->id.ICNTL(18));CHKERRQ(ierr);
767f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(19) (Shur complement info):                       %d \n",lu->id.ICNTL(19));CHKERRQ(ierr);
768f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(20) (rhs sparse pattern):                         %d \n",lu->id.ICNTL(20));CHKERRQ(ierr);
769f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(21) (solution struct):                            %d \n",lu->id.ICNTL(21));CHKERRQ(ierr);
770c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(22) (in-core/out-of-core facility):               %d \n",lu->id.ICNTL(22));CHKERRQ(ierr);
771c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(23) (max size of memory can be allocated locally):%d \n",lu->id.ICNTL(23));CHKERRQ(ierr);
772c0165424SHong Zhang 
773c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(24) (detection of null pivot rows):               %d \n",lu->id.ICNTL(24));CHKERRQ(ierr);
774c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(25) (computation of a null space basis):          %d \n",lu->id.ICNTL(25));CHKERRQ(ierr);
775c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(26) (Schur options for rhs or solution):          %d \n",lu->id.ICNTL(26));CHKERRQ(ierr);
776c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(27) (experimental parameter):                     %d \n",lu->id.ICNTL(27));CHKERRQ(ierr);
777f6c57405SHong Zhang 
778f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(1) (relative pivoting threshold):      %g \n",lu->id.CNTL(1));CHKERRQ(ierr);
779f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(2) (stopping criterion of refinement): %g \n",lu->id.CNTL(2));CHKERRQ(ierr);
780f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(3) (absolute pivoting threshold):      %g \n",lu->id.CNTL(3));CHKERRQ(ierr);
781f6c57405SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(4) (value of static pivoting):         %g \n",lu->id.CNTL(4));CHKERRQ(ierr);
782c0165424SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(5) (fixation for null pivots):         %g \n",lu->id.CNTL(5));CHKERRQ(ierr);
783f6c57405SHong Zhang 
784f6c57405SHong Zhang   /* infomation local to each processor */
785f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);}
7867adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %g \n",lu->myid,lu->id.RINFO(1));CHKERRQ(ierr);
7877adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
788f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);}
7897adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d]  %g \n",lu->myid,lu->id.RINFO(2));CHKERRQ(ierr);
7907adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
791f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);}
7927adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d]  %g \n",lu->myid,lu->id.RINFO(3));CHKERRQ(ierr);
7937adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
794f6c57405SHong Zhang 
795f6c57405SHong 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);}
7967adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(15));CHKERRQ(ierr);
7977adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
798f6c57405SHong Zhang 
799f6c57405SHong 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);}
8007adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(16));CHKERRQ(ierr);
8017adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
802f6c57405SHong Zhang 
803f6c57405SHong Zhang   if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, "              INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);}
8047adad957SLisandro Dalcin   ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm,"              [%d] %d \n",lu->myid,lu->id.INFO(23));CHKERRQ(ierr);
8057adad957SLisandro Dalcin   ierr = PetscSynchronizedFlush(((PetscObject)A)->comm);
806f6c57405SHong Zhang 
807f6c57405SHong Zhang   if (!lu->myid){ /* information from the host */
808f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",lu->id.RINFOG(1));CHKERRQ(ierr);
809f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",lu->id.RINFOG(2));CHKERRQ(ierr);
810f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",lu->id.RINFOG(3));CHKERRQ(ierr);
811f6c57405SHong Zhang 
812f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(3));CHKERRQ(ierr);
813f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(4));CHKERRQ(ierr);
814f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(5) (estimated maximum front size in the complete tree): %d \n",lu->id.INFOG(5));CHKERRQ(ierr);
815f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(6) (number of nodes in the complete tree): %d \n",lu->id.INFOG(6));CHKERRQ(ierr);
816f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(7) (ordering option effectively uese after analysis): %d \n",lu->id.INFOG(7));CHKERRQ(ierr);
817f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",lu->id.INFOG(8));CHKERRQ(ierr);
818f6c57405SHong 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);
819f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(10) (total integer space store the matrix factors after factorization): %d \n",lu->id.INFOG(10));CHKERRQ(ierr);
820f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(11) (order of largest frontal matrix after factorization): %d \n",lu->id.INFOG(11));CHKERRQ(ierr);
821f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(12) (number of off-diagonal pivots): %d \n",lu->id.INFOG(12));CHKERRQ(ierr);
822f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(13) (number of delayed pivots after factorization): %d \n",lu->id.INFOG(13));CHKERRQ(ierr);
823f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(14) (number of memory compress after factorization): %d \n",lu->id.INFOG(14));CHKERRQ(ierr);
824f6c57405SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(15) (number of steps of iterative refinement after solution): %d \n",lu->id.INFOG(15));CHKERRQ(ierr);
825f6c57405SHong 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);
826f6c57405SHong 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);
827f6c57405SHong 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);
828f6c57405SHong 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);
829f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(20) (estimated number of entries in the factors): %d \n",lu->id.INFOG(20));CHKERRQ(ierr);
830f6c57405SHong 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);
831f6c57405SHong 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);
832f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",lu->id.INFOG(23));CHKERRQ(ierr);
833f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",lu->id.INFOG(24));CHKERRQ(ierr);
834f6c57405SHong Zhang      ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",lu->id.INFOG(25));CHKERRQ(ierr);
835f6c57405SHong Zhang   }
836f6c57405SHong Zhang   PetscFunctionReturn(0);
837f6c57405SHong Zhang }
838f6c57405SHong Zhang 
839f6c57405SHong Zhang #undef __FUNCT__
840f6c57405SHong Zhang #define __FUNCT__ "MatView_MUMPS"
841b24902e0SBarry Smith PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer)
842b24902e0SBarry Smith {
843f6c57405SHong Zhang   PetscErrorCode    ierr;
844f6c57405SHong Zhang   PetscTruth        iascii;
845f6c57405SHong Zhang   PetscViewerFormat format;
846cb828f0fSHong Zhang   Mat_MUMPS         *mumps=(Mat_MUMPS*)A->spptr;
847f6c57405SHong Zhang 
848f6c57405SHong Zhang   PetscFunctionBegin;
849cb828f0fSHong Zhang   /* check if matrix is mumps type */
850cb828f0fSHong Zhang   if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0);
851cb828f0fSHong Zhang 
852f6c57405SHong Zhang   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
853f6c57405SHong Zhang   if (iascii) {
854f6c57405SHong Zhang     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
855cb828f0fSHong Zhang     if (format == PETSC_VIEWER_ASCII_INFO || mumps->mumpsview){
856cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr);
857cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  SYM (matrix type):                  %d \n",mumps->id.sym);CHKERRQ(ierr);
858cb828f0fSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  PAR (host participation):           %d \n",mumps->id.par);CHKERRQ(ierr);
859cb828f0fSHong Zhang       if (mumps->mumpsview){ /* View all MUMPS parameters */
860f6c57405SHong Zhang         ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr);
861f6c57405SHong Zhang       }
862f6c57405SHong Zhang     }
863cb828f0fSHong Zhang   }
864f6c57405SHong Zhang   PetscFunctionReturn(0);
865f6c57405SHong Zhang }
866f6c57405SHong Zhang 
86735bd34faSBarry Smith #undef __FUNCT__
86835bd34faSBarry Smith #define __FUNCT__ "MatGetInfo_MUMPS"
86935bd34faSBarry Smith PetscErrorCode MatGetInfo_MUMPS(Mat A,MatInfoType flag,MatInfo *info)
87035bd34faSBarry Smith {
871cb828f0fSHong Zhang   Mat_MUMPS  *mumps =(Mat_MUMPS*)A->spptr;
87235bd34faSBarry Smith 
87335bd34faSBarry Smith   PetscFunctionBegin;
87435bd34faSBarry Smith   info->block_size        = 1.0;
875cb828f0fSHong Zhang   info->nz_allocated      = mumps->id.INFOG(20);
876cb828f0fSHong Zhang   info->nz_used           = mumps->id.INFOG(20);
87735bd34faSBarry Smith   info->nz_unneeded       = 0.0;
87835bd34faSBarry Smith   info->assemblies        = 0.0;
87935bd34faSBarry Smith   info->mallocs           = 0.0;
88035bd34faSBarry Smith   info->memory            = 0.0;
88135bd34faSBarry Smith   info->fill_ratio_given  = 0;
88235bd34faSBarry Smith   info->fill_ratio_needed = 0;
88335bd34faSBarry Smith   info->factor_mallocs    = 0;
88435bd34faSBarry Smith   PetscFunctionReturn(0);
88535bd34faSBarry Smith }
88635bd34faSBarry Smith 
88724b6179bSKris Buschelman /*MC
88841c8de11SBarry Smith   MAT_SOLVER_MUMPS -  A matrix type providing direct solvers (LU and Cholesky) for
88924b6179bSKris Buschelman   distributed and sequential matrices via the external package MUMPS.
89024b6179bSKris Buschelman 
89141c8de11SBarry Smith   Works with MATAIJ and MATSBAIJ matrices
89224b6179bSKris Buschelman 
89324b6179bSKris Buschelman   Options Database Keys:
89441c8de11SBarry Smith + -mat_mumps_sym <0,1,2> - 0 the matrix is unsymmetric, 1 symmetric positive definite, 2 symmetric
89524b6179bSKris Buschelman . -mat_mumps_icntl_4 <0,...,4> - print level
89624b6179bSKris Buschelman . -mat_mumps_icntl_6 <0,...,7> - matrix prescaling options (see MUMPS User's Guide)
89724b6179bSKris Buschelman . -mat_mumps_icntl_7 <0,...,7> - matrix orderings (see MUMPS User's Guide)
89824b6179bSKris Buschelman . -mat_mumps_icntl_9 <1,2> - A or A^T x=b to be solved: 1 denotes A, 2 denotes A^T
89924b6179bSKris Buschelman . -mat_mumps_icntl_10 <n> - maximum number of iterative refinements
90094b7f48cSBarry Smith . -mat_mumps_icntl_11 <n> - error analysis, a positive value returns statistics during -ksp_view
90124b6179bSKris Buschelman . -mat_mumps_icntl_12 <n> - efficiency control (see MUMPS User's Guide)
90224b6179bSKris Buschelman . -mat_mumps_icntl_13 <n> - efficiency control (see MUMPS User's Guide)
90324b6179bSKris Buschelman . -mat_mumps_icntl_14 <n> - efficiency control (see MUMPS User's Guide)
90424b6179bSKris Buschelman . -mat_mumps_icntl_15 <n> - efficiency control (see MUMPS User's Guide)
90524b6179bSKris Buschelman . -mat_mumps_cntl_1 <delta> - relative pivoting threshold
90624b6179bSKris Buschelman . -mat_mumps_cntl_2 <tol> - stopping criterion for refinement
90724b6179bSKris Buschelman - -mat_mumps_cntl_3 <adelta> - absolute pivoting threshold
90824b6179bSKris Buschelman 
90924b6179bSKris Buschelman   Level: beginner
91024b6179bSKris Buschelman 
91141c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
91241c8de11SBarry Smith 
91324b6179bSKris Buschelman M*/
91424b6179bSKris Buschelman 
9152877fffaSHong Zhang EXTERN_C_BEGIN
91635bd34faSBarry Smith #undef __FUNCT__
91735bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_mumps"
91835bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_mumps(Mat A,const MatSolverPackage *type)
91935bd34faSBarry Smith {
92035bd34faSBarry Smith   PetscFunctionBegin;
92135bd34faSBarry Smith   *type = MAT_SOLVER_MUMPS;
92235bd34faSBarry Smith   PetscFunctionReturn(0);
92335bd34faSBarry Smith }
92435bd34faSBarry Smith EXTERN_C_END
92535bd34faSBarry Smith 
92635bd34faSBarry Smith EXTERN_C_BEGIN
9272877fffaSHong Zhang /*
9282877fffaSHong Zhang     The seq and mpi versions of this function are the same
9292877fffaSHong Zhang */
9302877fffaSHong Zhang #undef __FUNCT__
9312877fffaSHong Zhang #define __FUNCT__ "MatGetFactor_seqaij_mumps"
9322877fffaSHong Zhang PetscErrorCode MatGetFactor_seqaij_mumps(Mat A,MatFactorType ftype,Mat *F)
9332877fffaSHong Zhang {
9342877fffaSHong Zhang   Mat            B;
9352877fffaSHong Zhang   PetscErrorCode ierr;
9362877fffaSHong Zhang   Mat_MUMPS      *mumps;
9372877fffaSHong Zhang 
9382877fffaSHong Zhang   PetscFunctionBegin;
9392877fffaSHong Zhang   /* Create the factorization matrix */
9402877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
9412877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
9422877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
9432877fffaSHong Zhang   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
9442877fffaSHong Zhang 
9452877fffaSHong Zhang   B->ops->view             = MatView_MUMPS;
94635bd34faSBarry Smith   B->ops->getinfo          = MatGetInfo_MUMPS;
94735bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
94897969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
949450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
950450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
951d5f3da31SBarry Smith     B->factortype = MAT_FACTOR_LU;
952dcd589f8SShri Abhyankar   } else {
953450b117fSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJMUMPS;
954450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_CHOLESKY;
955450b117fSShri Abhyankar   }
9562877fffaSHong Zhang 
9572877fffaSHong Zhang   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
9582877fffaSHong Zhang   mumps->CleanUpMUMPS              = PETSC_FALSE;
9592877fffaSHong Zhang   mumps->isAIJ                     = PETSC_TRUE;
9602877fffaSHong Zhang   mumps->scat_rhs                  = PETSC_NULL;
9612877fffaSHong Zhang   mumps->scat_sol                  = PETSC_NULL;
9622877fffaSHong Zhang   mumps->nSolve                    = 0;
9632877fffaSHong Zhang   mumps->MatDestroy                = B->ops->destroy;
9642877fffaSHong Zhang   B->ops->destroy                  = MatDestroy_MUMPS;
9652877fffaSHong Zhang   B->spptr                         = (void*)mumps;
9662877fffaSHong Zhang 
9672877fffaSHong Zhang   *F = B;
9682877fffaSHong Zhang   PetscFunctionReturn(0);
9692877fffaSHong Zhang }
9702877fffaSHong Zhang EXTERN_C_END
9712877fffaSHong Zhang 
9722877fffaSHong Zhang EXTERN_C_BEGIN
9732877fffaSHong Zhang #undef __FUNCT__
9742877fffaSHong Zhang #define __FUNCT__ "MatGetFactor_seqsbaij_mumps"
9752877fffaSHong Zhang PetscErrorCode MatGetFactor_seqsbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
9762877fffaSHong Zhang {
9772877fffaSHong Zhang   Mat            B;
9782877fffaSHong Zhang   PetscErrorCode ierr;
9792877fffaSHong Zhang   Mat_MUMPS      *mumps;
9802877fffaSHong Zhang 
9812877fffaSHong Zhang   PetscFunctionBegin;
982e7e72b3dSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
9832877fffaSHong Zhang   /* Create the factorization matrix */
9842877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
9852877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
9862877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
9872877fffaSHong Zhang   ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
9882877fffaSHong Zhang   ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
9892877fffaSHong Zhang 
9902877fffaSHong Zhang   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJMUMPS;
9912877fffaSHong Zhang   B->ops->view                   = MatView_MUMPS;
99235bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
99397969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
994d5f3da31SBarry Smith   B->factortype                   = MAT_FACTOR_CHOLESKY;
9952877fffaSHong Zhang 
9962877fffaSHong Zhang   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
9972877fffaSHong Zhang   mumps->CleanUpMUMPS              = PETSC_FALSE;
998450b117fSShri Abhyankar   mumps->isAIJ                     = PETSC_FALSE;
9992877fffaSHong Zhang   mumps->scat_rhs                  = PETSC_NULL;
10002877fffaSHong Zhang   mumps->scat_sol                  = PETSC_NULL;
10012877fffaSHong Zhang   mumps->nSolve                    = 0;
10022877fffaSHong Zhang   mumps->MatDestroy                = B->ops->destroy;
10032877fffaSHong Zhang   B->ops->destroy                  = MatDestroy_MUMPS;
10042877fffaSHong Zhang   B->spptr                         = (void*)mumps;
1005f3c0ef26SHong Zhang 
10062877fffaSHong Zhang   *F = B;
10072877fffaSHong Zhang   PetscFunctionReturn(0);
10082877fffaSHong Zhang }
10092877fffaSHong Zhang EXTERN_C_END
10102877fffaSHong Zhang 
10112877fffaSHong Zhang EXTERN_C_BEGIN
10122877fffaSHong Zhang #undef __FUNCT__
10132877fffaSHong Zhang #define __FUNCT__ "MatGetFactor_mpisbaij_mumps"
10142877fffaSHong Zhang PetscErrorCode MatGetFactor_mpisbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
10152877fffaSHong Zhang {
10162877fffaSHong Zhang   Mat            B;
10172877fffaSHong Zhang   PetscErrorCode ierr;
10182877fffaSHong Zhang   Mat_MUMPS      *mumps;
10192877fffaSHong Zhang 
10202877fffaSHong Zhang   PetscFunctionBegin;
1021e7e72b3dSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
10222877fffaSHong Zhang   /* Create the factorization matrix */
10232877fffaSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
10242877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
10252877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
10262877fffaSHong Zhang   ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr);
10272877fffaSHong Zhang   ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
10282877fffaSHong Zhang 
10292877fffaSHong Zhang   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJMUMPS;
10302877fffaSHong Zhang   B->ops->view                   = MatView_MUMPS;
103135bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
103297969023SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1033d5f3da31SBarry Smith   B->factortype                  = MAT_FACTOR_CHOLESKY;
10342877fffaSHong Zhang 
10352877fffaSHong Zhang   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
10362877fffaSHong Zhang   mumps->CleanUpMUMPS              = PETSC_FALSE;
1037a214ac2aSShri Abhyankar   mumps->isAIJ                     = PETSC_FALSE;
1038a214ac2aSShri Abhyankar   mumps->scat_rhs                  = PETSC_NULL;
1039a214ac2aSShri Abhyankar   mumps->scat_sol                  = PETSC_NULL;
1040a214ac2aSShri Abhyankar   mumps->nSolve                    = 0;
1041a214ac2aSShri Abhyankar   mumps->MatDestroy                = B->ops->destroy;
1042a214ac2aSShri Abhyankar   B->ops->destroy                  = MatDestroy_MUMPS;
1043a214ac2aSShri Abhyankar   B->spptr                         = (void*)mumps;
1044a214ac2aSShri Abhyankar 
1045a214ac2aSShri Abhyankar   *F = B;
1046a214ac2aSShri Abhyankar   PetscFunctionReturn(0);
1047a214ac2aSShri Abhyankar }
1048a214ac2aSShri Abhyankar EXTERN_C_END
1049a214ac2aSShri Abhyankar 
1050a214ac2aSShri Abhyankar EXTERN_C_BEGIN
1051a214ac2aSShri Abhyankar #undef __FUNCT__
1052a214ac2aSShri Abhyankar #define __FUNCT__ "MatGetFactor_mpiaij_mumps"
1053a214ac2aSShri Abhyankar PetscErrorCode MatGetFactor_mpiaij_mumps(Mat A,MatFactorType ftype,Mat *F)
1054a214ac2aSShri Abhyankar {
1055a214ac2aSShri Abhyankar   Mat            B;
1056a214ac2aSShri Abhyankar   PetscErrorCode ierr;
1057a214ac2aSShri Abhyankar   Mat_MUMPS      *mumps;
1058a214ac2aSShri Abhyankar 
1059a214ac2aSShri Abhyankar   PetscFunctionBegin;
1060a214ac2aSShri Abhyankar   /* Create the factorization matrix */
1061a214ac2aSShri Abhyankar   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
1062a214ac2aSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
1063a214ac2aSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1064a214ac2aSShri Abhyankar   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
1065a214ac2aSShri Abhyankar   ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1066a214ac2aSShri Abhyankar 
1067a214ac2aSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1068a214ac2aSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
1069f4762488SHong Zhang     B->factortype = MAT_FACTOR_LU;
1070dcd589f8SShri Abhyankar   } else {
1071a214ac2aSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJMUMPS;
1072f4762488SHong Zhang     B->factortype = MAT_FACTOR_CHOLESKY;
1073450b117fSShri Abhyankar   }
1074a214ac2aSShri Abhyankar 
1075a214ac2aSShri Abhyankar   B->ops->view             = MatView_MUMPS;
1076a214ac2aSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
1077a214ac2aSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1078a214ac2aSShri Abhyankar 
1079a214ac2aSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1080a214ac2aSShri Abhyankar   mumps->CleanUpMUMPS              = PETSC_FALSE;
10812877fffaSHong Zhang   mumps->isAIJ                     = PETSC_TRUE;
10822877fffaSHong Zhang   mumps->scat_rhs                  = PETSC_NULL;
10832877fffaSHong Zhang   mumps->scat_sol                  = PETSC_NULL;
10842877fffaSHong Zhang   mumps->nSolve                    = 0;
1085f3c0ef26SHong Zhang   mumps->MatDestroy                = B->ops->destroy;
1086f3c0ef26SHong Zhang   B->ops->destroy                  = MatDestroy_MUMPS;
10872877fffaSHong Zhang   B->spptr                         = (void*)mumps;
1088f3c0ef26SHong Zhang 
10892877fffaSHong Zhang   *F = B;
10902877fffaSHong Zhang   PetscFunctionReturn(0);
10912877fffaSHong Zhang }
10922877fffaSHong Zhang EXTERN_C_END
109397969023SHong Zhang 
1094450b117fSShri Abhyankar EXTERN_C_BEGIN
1095450b117fSShri Abhyankar #undef __FUNCT__
1096450b117fSShri Abhyankar #define __FUNCT__ "MatGetFactor_mpibaij_mumps"
1097450b117fSShri Abhyankar PetscErrorCode MatGetFactor_mpibaij_mumps(Mat A,MatFactorType ftype,Mat *F)
1098450b117fSShri Abhyankar {
1099450b117fSShri Abhyankar   Mat            B;
1100450b117fSShri Abhyankar   PetscErrorCode ierr;
1101450b117fSShri Abhyankar   Mat_MUMPS      *mumps;
1102450b117fSShri Abhyankar 
1103450b117fSShri Abhyankar   PetscFunctionBegin;
1104450b117fSShri Abhyankar   /* Create the factorization matrix */
1105450b117fSShri Abhyankar   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
1106450b117fSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
1107450b117fSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
1108450b117fSShri Abhyankar   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
1109450b117fSShri Abhyankar   ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1110450b117fSShri Abhyankar 
1111450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
1112450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_BAIJMUMPS;
1113450b117fSShri Abhyankar     B->factortype = MAT_FACTOR_LU;
1114450b117fSShri Abhyankar   }
1115e7e72b3dSBarry Smith   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cholesky factorization for Petsc BAIJ matrices not supported yet\n");
1116450b117fSShri Abhyankar   B->ops->view             = MatView_MUMPS;
1117450b117fSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_mumps",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
1118450b117fSShri Abhyankar   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMumpsSetIcntl_C","MatMumpsSetIcntl",MatMumpsSetIcntl);CHKERRQ(ierr);
1119450b117fSShri Abhyankar 
1120450b117fSShri Abhyankar   ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr);
1121450b117fSShri Abhyankar   mumps->CleanUpMUMPS              = PETSC_FALSE;
1122450b117fSShri Abhyankar   mumps->isAIJ                     = PETSC_TRUE;
1123450b117fSShri Abhyankar   mumps->scat_rhs                  = PETSC_NULL;
1124450b117fSShri Abhyankar   mumps->scat_sol                  = PETSC_NULL;
1125450b117fSShri Abhyankar   mumps->nSolve                    = 0;
1126450b117fSShri Abhyankar   mumps->MatDestroy                = B->ops->destroy;
1127450b117fSShri Abhyankar   B->ops->destroy                  = MatDestroy_MUMPS;
1128450b117fSShri Abhyankar   B->spptr                         = (void*)mumps;
1129450b117fSShri Abhyankar 
1130450b117fSShri Abhyankar   *F = B;
1131450b117fSShri Abhyankar   PetscFunctionReturn(0);
1132450b117fSShri Abhyankar }
1133450b117fSShri Abhyankar EXTERN_C_END
1134a214ac2aSShri Abhyankar 
113561288eaaSHong Zhang /* -------------------------------------------------------------------------------------------*/
113661288eaaSHong Zhang /*@
113761288eaaSHong Zhang   MatMumpsSetIcntl - Set MUMPS parameter ICNTL()
113861288eaaSHong Zhang 
113961288eaaSHong Zhang    Collective on Mat
114061288eaaSHong Zhang 
114161288eaaSHong Zhang    Input Parameters:
114261288eaaSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
114361288eaaSHong Zhang .  idx - index of MUMPS parameter array ICNTL()
114461288eaaSHong Zhang -  icntl - value of MUMPS ICNTL(imumps)
114561288eaaSHong Zhang 
114661288eaaSHong Zhang   Options Database:
114761288eaaSHong Zhang .   -mat_mumps_icntl_<idx> <icntl>
114861288eaaSHong Zhang 
114961288eaaSHong Zhang    Level: beginner
115061288eaaSHong Zhang 
115161288eaaSHong Zhang    References: MUMPS Users' Guide
115261288eaaSHong Zhang 
115361288eaaSHong Zhang .seealso: MatGetFactor()
115461288eaaSHong Zhang @*/
115597969023SHong Zhang #undef __FUNCT__
115697969023SHong Zhang #define __FUNCT__ "MatMumpsSetIcntl"
115786e5884dSMatthew Knepley PetscErrorCode MatMumpsSetIcntl(Mat F,PetscInt idx,PetscInt icntl)
115897969023SHong Zhang {
1159dcd589f8SShri Abhyankar   Mat_MUMPS      *lu =(Mat_MUMPS*)(F)->spptr;
116097969023SHong Zhang 
116197969023SHong Zhang   PetscFunctionBegin;
116261288eaaSHong Zhang   lu->id.ICNTL(idx) = icntl;
116397969023SHong Zhang   PetscFunctionReturn(0);
116497969023SHong Zhang }
116597969023SHong Zhang 
1166