xref: /petsc/src/mat/impls/aij/mpi/mumps/mumps.c (revision d4ed72bbe47df8d3eb83fd589394594abed431db)
11c2a3de1SBarry Smith 
2397b6df1SKris Buschelman /*
3c2b5dc30SHong Zhang     Provides an interface to the MUMPS sparse solver
4397b6df1SKris Buschelman */
551d5961aSHong Zhang 
6c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h> /*I  "petscmat.h"  I*/
7c6db04a5SJed Brown #include <../src/mat/impls/sbaij/mpi/mpisbaij.h>
8b5fa320bSStefano Zampini #include <petscblaslapack.h>
9397b6df1SKris Buschelman 
10397b6df1SKris Buschelman EXTERN_C_BEGIN
11397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
122907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
132907cef9SHong Zhang #include <cmumps_c.h>
142907cef9SHong Zhang #else
15c6db04a5SJed Brown #include <zmumps_c.h>
162907cef9SHong Zhang #endif
172907cef9SHong Zhang #else
182907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
192907cef9SHong Zhang #include <smumps_c.h>
20397b6df1SKris Buschelman #else
21c6db04a5SJed Brown #include <dmumps_c.h>
22397b6df1SKris Buschelman #endif
232907cef9SHong Zhang #endif
24397b6df1SKris Buschelman EXTERN_C_END
25397b6df1SKris Buschelman #define JOB_INIT -1
263d472b54SHong Zhang #define JOB_FACTSYMBOLIC 1
273d472b54SHong Zhang #define JOB_FACTNUMERIC 2
283d472b54SHong Zhang #define JOB_SOLVE 3
29397b6df1SKris Buschelman #define JOB_END -2
303d472b54SHong Zhang 
312907cef9SHong Zhang /* calls to MUMPS */
322907cef9SHong Zhang #if defined(PETSC_USE_COMPLEX)
332907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
342907cef9SHong Zhang #define PetscMUMPS_c cmumps_c
352907cef9SHong Zhang #else
362907cef9SHong Zhang #define PetscMUMPS_c zmumps_c
372907cef9SHong Zhang #endif
382907cef9SHong Zhang #else
392907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
402907cef9SHong Zhang #define PetscMUMPS_c smumps_c
412907cef9SHong Zhang #else
422907cef9SHong Zhang #define PetscMUMPS_c dmumps_c
432907cef9SHong Zhang #endif
442907cef9SHong Zhang #endif
452907cef9SHong Zhang 
46940cd9d6SSatish Balay /* declare MumpsScalar */
47940cd9d6SSatish Balay #if defined(PETSC_USE_COMPLEX)
48940cd9d6SSatish Balay #if defined(PETSC_USE_REAL_SINGLE)
49940cd9d6SSatish Balay #define MumpsScalar mumps_complex
50940cd9d6SSatish Balay #else
51940cd9d6SSatish Balay #define MumpsScalar mumps_double_complex
52940cd9d6SSatish Balay #endif
53940cd9d6SSatish Balay #else
54940cd9d6SSatish Balay #define MumpsScalar PetscScalar
55940cd9d6SSatish Balay #endif
563d472b54SHong Zhang 
57397b6df1SKris Buschelman /* macros s.t. indices match MUMPS documentation */
58397b6df1SKris Buschelman #define ICNTL(I) icntl[(I)-1]
59397b6df1SKris Buschelman #define CNTL(I) cntl[(I)-1]
60397b6df1SKris Buschelman #define INFOG(I) infog[(I)-1]
61a7aca84bSHong Zhang #define INFO(I) info[(I)-1]
62397b6df1SKris Buschelman #define RINFOG(I) rinfog[(I)-1]
63adc1d99fSHong Zhang #define RINFO(I) rinfo[(I)-1]
64397b6df1SKris Buschelman 
65397b6df1SKris Buschelman typedef struct {
66397b6df1SKris Buschelman #if defined(PETSC_USE_COMPLEX)
672907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
682907cef9SHong Zhang   CMUMPS_STRUC_C id;
692907cef9SHong Zhang #else
70397b6df1SKris Buschelman   ZMUMPS_STRUC_C id;
712907cef9SHong Zhang #endif
722907cef9SHong Zhang #else
732907cef9SHong Zhang #if defined(PETSC_USE_REAL_SINGLE)
742907cef9SHong Zhang   SMUMPS_STRUC_C id;
75397b6df1SKris Buschelman #else
76397b6df1SKris Buschelman   DMUMPS_STRUC_C id;
77397b6df1SKris Buschelman #endif
782907cef9SHong Zhang #endif
792907cef9SHong Zhang 
80397b6df1SKris Buschelman   MatStructure matstruc;
81c1490034SHong Zhang   PetscMPIInt  myid,size;
82a5e57a09SHong Zhang   PetscInt     *irn,*jcn,nz,sym;
83397b6df1SKris Buschelman   PetscScalar  *val;
84397b6df1SKris Buschelman   MPI_Comm     comm_mumps;
856f3cc6f9SBarry Smith   PetscBool    isAIJ;
86a5e57a09SHong Zhang   PetscInt     ICNTL9_pre;           /* check if ICNTL(9) is changed from previous MatSolve */
87801fbe65SHong Zhang   VecScatter   scat_rhs, scat_sol;   /* used by MatSolve() */
88801fbe65SHong Zhang   Vec          b_seq,x_seq;
89b34f08ffSHong Zhang   PetscInt     ninfo,*info;          /* display INFO */
90b5fa320bSStefano Zampini   PetscInt     sizeredrhs;
91b5fa320bSStefano Zampini   PetscInt     *schur_pivots;
9259ac8732SStefano Zampini   PetscInt     schur_B_lwork;
93b5fa320bSStefano Zampini   PetscScalar  *schur_work;
9459ac8732SStefano Zampini   PetscScalar  *schur_sol;
9559ac8732SStefano Zampini   PetscInt     schur_sizesol;
9659ac8732SStefano Zampini   PetscBool    schur_factored;
9759ac8732SStefano Zampini   PetscBool    schur_inverted;
982205254eSKarl Rupp 
99bf0cc555SLisandro Dalcin   PetscErrorCode (*Destroy)(Mat);
100bccb9932SShri Abhyankar   PetscErrorCode (*ConvertToTriples)(Mat, int, MatReuse, int*, int**, int**, PetscScalar**);
101f0c56d0fSKris Buschelman } Mat_MUMPS;
102f0c56d0fSKris Buschelman 
10309573ac7SBarry Smith extern PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*);
104b24902e0SBarry Smith 
10559ac8732SStefano Zampini #undef __FUNCT__
10659ac8732SStefano Zampini #define __FUNCT__ "MatMumpsResetSchur_Private"
10759ac8732SStefano Zampini static PetscErrorCode MatMumpsResetSchur_Private(Mat_MUMPS* mumps)
108b5fa320bSStefano Zampini {
109b5fa320bSStefano Zampini   PetscErrorCode ierr;
110b5fa320bSStefano Zampini 
111b5fa320bSStefano Zampini   PetscFunctionBegin;
11259ac8732SStefano Zampini   ierr = PetscFree2(mumps->id.listvar_schur,mumps->id.schur);CHKERRQ(ierr);
11359ac8732SStefano Zampini   ierr = PetscFree(mumps->id.redrhs);CHKERRQ(ierr);
11459ac8732SStefano Zampini   ierr = PetscFree(mumps->schur_sol);CHKERRQ(ierr);
11559ac8732SStefano Zampini   ierr = PetscFree(mumps->schur_pivots);CHKERRQ(ierr);
11659ac8732SStefano Zampini   ierr = PetscFree(mumps->schur_work);CHKERRQ(ierr);
11759ac8732SStefano Zampini   mumps->id.size_schur = 0;
11859ac8732SStefano Zampini   mumps->id.ICNTL(19) = 0;
11959ac8732SStefano Zampini   PetscFunctionReturn(0);
12059ac8732SStefano Zampini }
12159ac8732SStefano Zampini 
12259ac8732SStefano Zampini #undef __FUNCT__
12359ac8732SStefano Zampini #define __FUNCT__ "MatMumpsFactorSchur_Private"
12459ac8732SStefano Zampini static PetscErrorCode MatMumpsFactorSchur_Private(Mat_MUMPS* mumps)
12559ac8732SStefano Zampini {
12659ac8732SStefano Zampini   PetscBLASInt   B_N,B_ierr,B_slda;
12759ac8732SStefano Zampini   PetscErrorCode ierr;
12859ac8732SStefano Zampini 
12959ac8732SStefano Zampini   PetscFunctionBegin;
13059ac8732SStefano Zampini   if (mumps->schur_factored) {
13159ac8732SStefano Zampini     PetscFunctionReturn(0);
13259ac8732SStefano Zampini   }
13359ac8732SStefano Zampini   ierr = PetscBLASIntCast(mumps->id.size_schur,&B_N);CHKERRQ(ierr);
13459ac8732SStefano Zampini   ierr = PetscBLASIntCast(mumps->id.schur_lld,&B_slda);CHKERRQ(ierr);
13559ac8732SStefano Zampini   if (!mumps->sym) { /* MUMPS always return a full Schur matrix */
13659ac8732SStefano Zampini     if (!mumps->schur_pivots) {
13759ac8732SStefano Zampini       ierr = PetscMalloc1(B_N,&mumps->schur_pivots);CHKERRQ(ierr);
13859ac8732SStefano Zampini     }
13959ac8732SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
14059ac8732SStefano Zampini     PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&B_N,&B_N,(PetscScalar*)mumps->id.schur,&B_slda,mumps->schur_pivots,&B_ierr));
14159ac8732SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
14259ac8732SStefano Zampini     if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GETRF Lapack routine %d",(int)B_ierr);
14359ac8732SStefano Zampini   } else { /* either full or lower-triangular (not packed) */
14459ac8732SStefano Zampini     char ord[2];
14559ac8732SStefano Zampini     if (mumps->id.ICNTL(19) == 2 || mumps->id.ICNTL(19) == 3) { /* lower triangular stored by columns or full matrix */
14659ac8732SStefano Zampini       sprintf(ord,"L");
14759ac8732SStefano Zampini     } else { /* ICNTL(19) == 1 lower triangular stored by rows */
14859ac8732SStefano Zampini       sprintf(ord,"U");
14959ac8732SStefano Zampini     }
15059ac8732SStefano Zampini     if (mumps->id.sym == 2) {
15159ac8732SStefano Zampini       if (!mumps->schur_pivots) {
15259ac8732SStefano Zampini         PetscScalar  lwork;
15359ac8732SStefano Zampini 
15459ac8732SStefano Zampini         ierr = PetscMalloc1(B_N,&mumps->schur_pivots);CHKERRQ(ierr);
15559ac8732SStefano Zampini         mumps->schur_B_lwork=-1;
15659ac8732SStefano Zampini         ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
15759ac8732SStefano Zampini         PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_(ord,&B_N,(PetscScalar*)mumps->id.schur,&B_slda,mumps->schur_pivots,&lwork,&mumps->schur_B_lwork,&B_ierr));
15859ac8732SStefano Zampini         ierr = PetscFPTrapPop();CHKERRQ(ierr);
15959ac8732SStefano Zampini         if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYTRF Lapack routine %d",(int)B_ierr);
16059ac8732SStefano Zampini         ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&mumps->schur_B_lwork);CHKERRQ(ierr);
16159ac8732SStefano Zampini         ierr = PetscMalloc1(mumps->schur_B_lwork,&mumps->schur_work);CHKERRQ(ierr);
16259ac8732SStefano Zampini       }
16359ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
16459ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_(ord,&B_N,(PetscScalar*)mumps->id.schur,&B_slda,mumps->schur_pivots,mumps->schur_work,&mumps->schur_B_lwork,&B_ierr));
16559ac8732SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
16659ac8732SStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYTRF Lapack routine %d",(int)B_ierr);
16759ac8732SStefano Zampini     } else {
16859ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
16959ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_(ord,&B_N,(PetscScalar*)mumps->id.schur,&B_slda,&B_ierr));
17059ac8732SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
17159ac8732SStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in POTRF Lapack routine %d",(int)B_ierr);
17259ac8732SStefano Zampini     }
17359ac8732SStefano Zampini   }
17459ac8732SStefano Zampini   mumps->schur_factored = PETSC_TRUE;
17559ac8732SStefano Zampini   PetscFunctionReturn(0);
17659ac8732SStefano Zampini }
17759ac8732SStefano Zampini 
17859ac8732SStefano Zampini #undef __FUNCT__
17959ac8732SStefano Zampini #define __FUNCT__ "MatMumpsInvertSchur_Private"
18059ac8732SStefano Zampini static PetscErrorCode MatMumpsInvertSchur_Private(Mat_MUMPS* mumps)
18159ac8732SStefano Zampini {
18259ac8732SStefano Zampini   PetscBLASInt   B_N,B_ierr,B_slda;
18359ac8732SStefano Zampini   PetscErrorCode ierr;
18459ac8732SStefano Zampini 
18559ac8732SStefano Zampini   PetscFunctionBegin;
18659ac8732SStefano Zampini   ierr = MatMumpsFactorSchur_Private(mumps);CHKERRQ(ierr);
18759ac8732SStefano Zampini   ierr = PetscBLASIntCast(mumps->id.size_schur,&B_N);CHKERRQ(ierr);
18859ac8732SStefano Zampini   ierr = PetscBLASIntCast(mumps->id.schur_lld,&B_slda);CHKERRQ(ierr);
18959ac8732SStefano Zampini   if (!mumps->sym) { /* MUMPS always return a full Schur matrix */
19059ac8732SStefano Zampini     if (!mumps->schur_work) {
19159ac8732SStefano Zampini       PetscScalar lwork;
19259ac8732SStefano Zampini 
19359ac8732SStefano Zampini       mumps->schur_B_lwork = -1;
19459ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
19559ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&B_N,(PetscScalar*)mumps->id.schur,&B_N,mumps->schur_pivots,&lwork,&mumps->schur_B_lwork,&B_ierr));
19659ac8732SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
19759ac8732SStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GETRI Lapack routine %d",(int)B_ierr);
19859ac8732SStefano Zampini       ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&mumps->schur_B_lwork);CHKERRQ(ierr);
19959ac8732SStefano Zampini       ierr = PetscMalloc1(mumps->schur_B_lwork,&mumps->schur_work);CHKERRQ(ierr);
20059ac8732SStefano Zampini     }
20159ac8732SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
20259ac8732SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&B_N,(PetscScalar*)mumps->id.schur,&B_N,mumps->schur_pivots,mumps->schur_work,&mumps->schur_B_lwork,&B_ierr));
20359ac8732SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
20459ac8732SStefano Zampini     if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GETRI Lapack routine %d",(int)B_ierr);
20559ac8732SStefano Zampini   } else { /* either full or lower-triangular (not packed) */
20659ac8732SStefano Zampini     char ord[2];
20759ac8732SStefano Zampini     if (mumps->id.ICNTL(19) == 2 || mumps->id.ICNTL(19) == 3) { /* lower triangular stored by columns or full matrix */
20859ac8732SStefano Zampini       sprintf(ord,"L");
20959ac8732SStefano Zampini     } else { /* ICNTL(19) == 1 lower triangular stored by rows */
21059ac8732SStefano Zampini       sprintf(ord,"U");
21159ac8732SStefano Zampini     }
21259ac8732SStefano Zampini     if (mumps->id.sym == 2) {
21359ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
21459ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_(ord,&B_N,(PetscScalar*)mumps->id.schur,&B_N,mumps->schur_pivots,mumps->schur_work,&B_ierr));
21559ac8732SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
21659ac8732SStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYTRI Lapack routine %d",(int)B_ierr);
21759ac8732SStefano Zampini     } else {
21859ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
21959ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_(ord,&B_N,(PetscScalar*)mumps->id.schur,&B_N,&B_ierr));
22059ac8732SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
22159ac8732SStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in POTRI Lapack routine %d",(int)B_ierr);
22259ac8732SStefano Zampini     }
22359ac8732SStefano Zampini   }
22459ac8732SStefano Zampini   mumps->schur_inverted = PETSC_TRUE;
22559ac8732SStefano Zampini   PetscFunctionReturn(0);
22659ac8732SStefano Zampini }
22759ac8732SStefano Zampini 
22859ac8732SStefano Zampini #undef __FUNCT__
22959ac8732SStefano Zampini #define __FUNCT__ "MatMumpsSolveSchur_Private"
230e807eca7SStefano Zampini static PetscErrorCode MatMumpsSolveSchur_Private(Mat_MUMPS* mumps, PetscBool sol_in_redrhs)
23159ac8732SStefano Zampini {
23259ac8732SStefano Zampini   PetscBLASInt   B_N,B_Nrhs,B_ierr,B_slda,B_rlda;
23359ac8732SStefano Zampini   PetscScalar    one=1.,zero=0.;
23459ac8732SStefano Zampini   PetscErrorCode ierr;
23559ac8732SStefano Zampini 
23659ac8732SStefano Zampini   PetscFunctionBegin;
23759ac8732SStefano Zampini   ierr = MatMumpsFactorSchur_Private(mumps);CHKERRQ(ierr);
238b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.size_schur,&B_N);CHKERRQ(ierr);
239b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.schur_lld,&B_slda);CHKERRQ(ierr);
240b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.nrhs,&B_Nrhs);CHKERRQ(ierr);
241b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.lredrhs,&B_rlda);CHKERRQ(ierr);
24259ac8732SStefano Zampini   if (mumps->schur_inverted) {
24359ac8732SStefano Zampini     PetscInt sizesol = B_Nrhs*B_N;
24459ac8732SStefano Zampini     if (!mumps->schur_sol || sizesol > mumps->schur_sizesol) {
24559ac8732SStefano Zampini       ierr = PetscFree(mumps->schur_sol);CHKERRQ(ierr);
24659ac8732SStefano Zampini       ierr = PetscMalloc1(sizesol,&mumps->schur_sol);CHKERRQ(ierr);
24759ac8732SStefano Zampini       mumps->schur_sizesol = sizesol;
248b5fa320bSStefano Zampini     }
24959ac8732SStefano Zampini     if (!mumps->sym) {
25059ac8732SStefano Zampini       char type[2];
251b5fa320bSStefano Zampini       if (mumps->id.ICNTL(19) == 1) { /* stored by rows */
25259ac8732SStefano Zampini         if (!mumps->id.ICNTL(9)) { /* transpose solve */
25359ac8732SStefano Zampini           sprintf(type,"N");
254b5fa320bSStefano Zampini         } else {
25559ac8732SStefano Zampini           sprintf(type,"T");
256b5fa320bSStefano Zampini         }
25759ac8732SStefano Zampini       } else { /* stored by columns */
25859ac8732SStefano Zampini         if (!mumps->id.ICNTL(9)) { /* transpose solve */
25959ac8732SStefano Zampini           sprintf(type,"T");
26059ac8732SStefano Zampini         } else {
26159ac8732SStefano Zampini           sprintf(type,"N");
26259ac8732SStefano Zampini         }
26359ac8732SStefano Zampini       }
26459ac8732SStefano Zampini       PetscStackCallBLAS("BLASgemm",BLASgemm_(type,"N",&B_N,&B_Nrhs,&B_N,&one,(PetscScalar*)mumps->id.schur,&B_slda,(PetscScalar*)mumps->id.redrhs,&B_rlda,&zero,mumps->schur_sol,&B_rlda));
26559ac8732SStefano Zampini     } else {
26659ac8732SStefano Zampini       char ord[2];
26759ac8732SStefano Zampini       if (mumps->id.ICNTL(19) == 2 || mumps->id.ICNTL(19) == 3) { /* lower triangular stored by columns or full matrix */
26859ac8732SStefano Zampini         sprintf(ord,"L");
26959ac8732SStefano Zampini       } else { /* ICNTL(19) == 1 lower triangular stored by rows */
27059ac8732SStefano Zampini         sprintf(ord,"U");
27159ac8732SStefano Zampini       }
27259ac8732SStefano Zampini       PetscStackCallBLAS("BLASsymm",BLASsymm_("L",ord,&B_N,&B_Nrhs,&one,(PetscScalar*)mumps->id.schur,&B_slda,(PetscScalar*)mumps->id.redrhs,&B_rlda,&zero,mumps->schur_sol,&B_rlda));
27359ac8732SStefano Zampini     }
274e807eca7SStefano Zampini     if (sol_in_redrhs) {
27559ac8732SStefano Zampini       ierr = PetscMemcpy(mumps->id.redrhs,mumps->schur_sol,sizesol*sizeof(PetscScalar));CHKERRQ(ierr);
276e807eca7SStefano Zampini     }
277a12f35bfSStefano Zampini   } else { /* Schur complement has not been inverted */
278a12f35bfSStefano Zampini     MumpsScalar *orhs=NULL;
279a12f35bfSStefano Zampini 
280a12f35bfSStefano Zampini     if (!sol_in_redrhs) {
281a12f35bfSStefano Zampini       PetscInt sizesol = B_Nrhs*B_N;
282a12f35bfSStefano Zampini       if (!mumps->schur_sol || sizesol > mumps->schur_sizesol) {
283a12f35bfSStefano Zampini         ierr = PetscFree(mumps->schur_sol);CHKERRQ(ierr);
284a12f35bfSStefano Zampini         ierr = PetscMalloc1(sizesol,&mumps->schur_sol);CHKERRQ(ierr);
285a12f35bfSStefano Zampini         mumps->schur_sizesol = sizesol;
286a12f35bfSStefano Zampini       }
287a12f35bfSStefano Zampini       orhs = mumps->id.redrhs;
288a12f35bfSStefano Zampini       ierr = PetscMemcpy(mumps->schur_sol,mumps->id.redrhs,sizesol*sizeof(PetscScalar));CHKERRQ(ierr);
289a12f35bfSStefano Zampini       mumps->id.redrhs = (MumpsScalar*)mumps->schur_sol;
290a12f35bfSStefano Zampini     }
29159ac8732SStefano Zampini     if (!mumps->sym) { /* MUMPS always return a full Schur matrix */
29259ac8732SStefano Zampini       char type[2];
29359ac8732SStefano Zampini       if (mumps->id.ICNTL(19) == 1) { /* stored by rows */
29459ac8732SStefano Zampini         if (!mumps->id.ICNTL(9)) { /* transpose solve */
29559ac8732SStefano Zampini           sprintf(type,"N");
29659ac8732SStefano Zampini         } else {
29759ac8732SStefano Zampini           sprintf(type,"T");
29859ac8732SStefano Zampini         }
29959ac8732SStefano Zampini       } else { /* stored by columns */
30059ac8732SStefano Zampini         if (!mumps->id.ICNTL(9)) { /* transpose solve */
30159ac8732SStefano Zampini           sprintf(type,"T");
30259ac8732SStefano Zampini         } else {
30359ac8732SStefano Zampini           sprintf(type,"N");
30459ac8732SStefano Zampini         }
30559ac8732SStefano Zampini       }
30659ac8732SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
30759ac8732SStefano Zampini       PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(type,&B_N,&B_Nrhs,(PetscScalar*)mumps->id.schur,&B_slda,mumps->schur_pivots,(PetscScalar*)mumps->id.redrhs,&B_rlda,&B_ierr));
308b5fa320bSStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
309b5fa320bSStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GETRS Lapack routine %d",(int)B_ierr);
310b5fa320bSStefano Zampini     } else { /* either full or lower-triangular (not packed) */
311b5fa320bSStefano Zampini       char ord[2];
312b5fa320bSStefano Zampini       if (mumps->id.ICNTL(19) == 2 || mumps->id.ICNTL(19) == 3) { /* lower triangular stored by columns or full matrix */
313b5fa320bSStefano Zampini         sprintf(ord,"L");
314b5fa320bSStefano Zampini       } else { /* ICNTL(19) == 1 lower triangular stored by rows */
315b5fa320bSStefano Zampini         sprintf(ord,"U");
316b5fa320bSStefano Zampini       }
317b5fa320bSStefano Zampini       if (mumps->id.sym == 2) {
318b5fa320bSStefano Zampini         ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
31959ac8732SStefano Zampini         PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_(ord,&B_N,&B_Nrhs,(PetscScalar*)mumps->id.schur,&B_slda,mumps->schur_pivots,(PetscScalar*)mumps->id.redrhs,&B_rlda,&B_ierr));
320b5fa320bSStefano Zampini         ierr = PetscFPTrapPop();CHKERRQ(ierr);
321b5fa320bSStefano Zampini         if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYTRS Lapack routine %d",(int)B_ierr);
322b5fa320bSStefano Zampini       } else {
323b5fa320bSStefano Zampini         ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
32459ac8732SStefano Zampini         PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_(ord,&B_N,&B_Nrhs,(PetscScalar*)mumps->id.schur,&B_slda,(PetscScalar*)mumps->id.redrhs,&B_rlda,&B_ierr));
325b5fa320bSStefano Zampini         ierr = PetscFPTrapPop();CHKERRQ(ierr);
326b5fa320bSStefano Zampini         if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in POTRS Lapack routine %d",(int)B_ierr);
327b5fa320bSStefano Zampini       }
328b5fa320bSStefano Zampini     }
329e807eca7SStefano Zampini     if (!sol_in_redrhs) {
330a12f35bfSStefano Zampini       mumps->id.redrhs = orhs;
331e807eca7SStefano Zampini     }
33259ac8732SStefano Zampini   }
333b5fa320bSStefano Zampini   PetscFunctionReturn(0);
334b5fa320bSStefano Zampini }
335b5fa320bSStefano Zampini 
33659ac8732SStefano Zampini #undef __FUNCT__
33759ac8732SStefano Zampini #define __FUNCT__ "MatMumpsHandleSchur_Private"
338b8f61ee1SStefano Zampini static PetscErrorCode MatMumpsHandleSchur_Private(Mat_MUMPS* mumps, PetscBool expansion)
339b5fa320bSStefano Zampini {
340b5fa320bSStefano Zampini   PetscErrorCode ierr;
341b5fa320bSStefano Zampini 
342b5fa320bSStefano Zampini   PetscFunctionBegin;
343b5fa320bSStefano Zampini   if (!mumps->id.ICNTL(19)) { /* do nothing when Schur complement has not been computed */
344b5fa320bSStefano Zampini     PetscFunctionReturn(0);
345b5fa320bSStefano Zampini   }
346b8f61ee1SStefano Zampini   if (!expansion) { /* prepare for the condensation step */
347b5fa320bSStefano Zampini     PetscInt sizeredrhs = mumps->id.nrhs*mumps->id.size_schur;
348b5fa320bSStefano Zampini     /* allocate MUMPS internal array to store reduced right-hand sides */
349b5fa320bSStefano Zampini     if (!mumps->id.redrhs || sizeredrhs > mumps->sizeredrhs) {
350b5fa320bSStefano Zampini       ierr = PetscFree(mumps->id.redrhs);CHKERRQ(ierr);
351b5fa320bSStefano Zampini       mumps->id.lredrhs = mumps->id.size_schur;
352b5fa320bSStefano Zampini       ierr = PetscMalloc1(mumps->id.nrhs*mumps->id.lredrhs,&mumps->id.redrhs);CHKERRQ(ierr);
353b5fa320bSStefano Zampini       mumps->sizeredrhs = mumps->id.nrhs*mumps->id.lredrhs;
354b5fa320bSStefano Zampini     }
355b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = 1; /* condensation phase */
356b5fa320bSStefano Zampini   } else { /* prepare for the expansion step */
357b8f61ee1SStefano Zampini     /* solve Schur complement (this has to be done by the MUMPS user, so basically us) */
358e807eca7SStefano Zampini     ierr = MatMumpsSolveSchur_Private(mumps,PETSC_TRUE);CHKERRQ(ierr);
359b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = 2; /* expansion phase */
360b5fa320bSStefano Zampini     PetscMUMPS_c(&mumps->id);
361b5fa320bSStefano Zampini     if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
362b5fa320bSStefano Zampini     /* restore defaults */
363b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = -1;
364b5fa320bSStefano Zampini   }
365b5fa320bSStefano Zampini   PetscFunctionReturn(0);
366b5fa320bSStefano Zampini }
367b5fa320bSStefano Zampini 
368397b6df1SKris Buschelman /*
369d341cd04SHong Zhang   MatConvertToTriples_A_B - convert Petsc matrix to triples: row[nz], col[nz], val[nz]
370d341cd04SHong Zhang 
371397b6df1SKris Buschelman   input:
37267877ebaSShri Abhyankar     A       - matrix in aij,baij or sbaij (bs=1) format
373397b6df1SKris Buschelman     shift   - 0: C style output triple; 1: Fortran style output triple.
374bccb9932SShri Abhyankar     reuse   - MAT_INITIAL_MATRIX: spaces are allocated and values are set for the triple
375bccb9932SShri Abhyankar               MAT_REUSE_MATRIX:   only the values in v array are updated
376397b6df1SKris Buschelman   output:
377397b6df1SKris Buschelman     nnz     - dim of r, c, and v (number of local nonzero entries of A)
378397b6df1SKris Buschelman     r, c, v - row and col index, matrix values (matrix triples)
379eb9baa12SBarry Smith 
380eb9baa12SBarry Smith   The returned values r, c, and sometimes v are obtained in a single PetscMalloc(). Then in MatDestroy_MUMPS() it is
381eb9baa12SBarry Smith   freed with PetscFree((mumps->irn);  This is not ideal code, the fact that v is ONLY sometimes part of mumps->irn means
382eb9baa12SBarry Smith   that the PetscMalloc() cannot easily be replaced with a PetscMalloc3().
383eb9baa12SBarry Smith 
384397b6df1SKris Buschelman  */
38516ebf90aSShri Abhyankar 
38616ebf90aSShri Abhyankar #undef __FUNCT__
38716ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqaij"
388bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
389b24902e0SBarry Smith {
390185f6596SHong Zhang   const PetscInt *ai,*aj,*ajj,M=A->rmap->n;
39167877ebaSShri Abhyankar   PetscInt       nz,rnz,i,j;
392dfbe8321SBarry Smith   PetscErrorCode ierr;
393c1490034SHong Zhang   PetscInt       *row,*col;
39416ebf90aSShri Abhyankar   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)A->data;
395397b6df1SKris Buschelman 
396397b6df1SKris Buschelman   PetscFunctionBegin;
39716ebf90aSShri Abhyankar   *v=aa->a;
398bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
3992205254eSKarl Rupp     nz   = aa->nz;
4002205254eSKarl Rupp     ai   = aa->i;
4012205254eSKarl Rupp     aj   = aa->j;
40216ebf90aSShri Abhyankar     *nnz = nz;
403785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
404185f6596SHong Zhang     col  = row + nz;
405185f6596SHong Zhang 
40616ebf90aSShri Abhyankar     nz = 0;
40716ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
40816ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
40967877ebaSShri Abhyankar       ajj = aj + ai[i];
41067877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
41167877ebaSShri Abhyankar         row[nz] = i+shift; col[nz++] = ajj[j] + shift;
41216ebf90aSShri Abhyankar       }
41316ebf90aSShri Abhyankar     }
41416ebf90aSShri Abhyankar     *r = row; *c = col;
41516ebf90aSShri Abhyankar   }
41616ebf90aSShri Abhyankar   PetscFunctionReturn(0);
41716ebf90aSShri Abhyankar }
418397b6df1SKris Buschelman 
41916ebf90aSShri Abhyankar #undef __FUNCT__
42067877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqbaij_seqaij"
421bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqbaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
42267877ebaSShri Abhyankar {
42367877ebaSShri Abhyankar   Mat_SeqBAIJ    *aa=(Mat_SeqBAIJ*)A->data;
42433d57670SJed Brown   const PetscInt *ai,*aj,*ajj,bs2 = aa->bs2;
42533d57670SJed Brown   PetscInt       bs,M,nz,idx=0,rnz,i,j,k,m;
42667877ebaSShri Abhyankar   PetscErrorCode ierr;
42767877ebaSShri Abhyankar   PetscInt       *row,*col;
42867877ebaSShri Abhyankar 
42967877ebaSShri Abhyankar   PetscFunctionBegin;
43033d57670SJed Brown   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
43133d57670SJed Brown   M = A->rmap->N/bs;
432cf3759fdSShri Abhyankar   *v = aa->a;
433bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
434cf3759fdSShri Abhyankar     ai   = aa->i; aj = aa->j;
43567877ebaSShri Abhyankar     nz   = bs2*aa->nz;
43667877ebaSShri Abhyankar     *nnz = nz;
437785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
438185f6596SHong Zhang     col  = row + nz;
439185f6596SHong Zhang 
44067877ebaSShri Abhyankar     for (i=0; i<M; i++) {
44167877ebaSShri Abhyankar       ajj = aj + ai[i];
44267877ebaSShri Abhyankar       rnz = ai[i+1] - ai[i];
44367877ebaSShri Abhyankar       for (k=0; k<rnz; k++) {
44467877ebaSShri Abhyankar         for (j=0; j<bs; j++) {
44567877ebaSShri Abhyankar           for (m=0; m<bs; m++) {
44667877ebaSShri Abhyankar             row[idx]   = i*bs + m + shift;
447cf3759fdSShri Abhyankar             col[idx++] = bs*(ajj[k]) + j + shift;
44867877ebaSShri Abhyankar           }
44967877ebaSShri Abhyankar         }
45067877ebaSShri Abhyankar       }
45167877ebaSShri Abhyankar     }
452cf3759fdSShri Abhyankar     *r = row; *c = col;
45367877ebaSShri Abhyankar   }
45467877ebaSShri Abhyankar   PetscFunctionReturn(0);
45567877ebaSShri Abhyankar }
45667877ebaSShri Abhyankar 
45767877ebaSShri Abhyankar #undef __FUNCT__
45816ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqsbaij_seqsbaij"
459bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqsbaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
46016ebf90aSShri Abhyankar {
46167877ebaSShri Abhyankar   const PetscInt *ai, *aj,*ajj,M=A->rmap->n;
46267877ebaSShri Abhyankar   PetscInt       nz,rnz,i,j;
46316ebf90aSShri Abhyankar   PetscErrorCode ierr;
46416ebf90aSShri Abhyankar   PetscInt       *row,*col;
46516ebf90aSShri Abhyankar   Mat_SeqSBAIJ   *aa=(Mat_SeqSBAIJ*)A->data;
46616ebf90aSShri Abhyankar 
46716ebf90aSShri Abhyankar   PetscFunctionBegin;
468882afa5aSHong Zhang   *v = aa->a;
469bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
4702205254eSKarl Rupp     nz   = aa->nz;
4712205254eSKarl Rupp     ai   = aa->i;
4722205254eSKarl Rupp     aj   = aa->j;
4732205254eSKarl Rupp     *v   = aa->a;
47416ebf90aSShri Abhyankar     *nnz = nz;
475785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
476185f6596SHong Zhang     col  = row + nz;
477185f6596SHong Zhang 
47816ebf90aSShri Abhyankar     nz = 0;
47916ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
48016ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
48167877ebaSShri Abhyankar       ajj = aj + ai[i];
48267877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
48367877ebaSShri Abhyankar         row[nz] = i+shift; col[nz++] = ajj[j] + shift;
48416ebf90aSShri Abhyankar       }
48516ebf90aSShri Abhyankar     }
48616ebf90aSShri Abhyankar     *r = row; *c = col;
48716ebf90aSShri Abhyankar   }
48816ebf90aSShri Abhyankar   PetscFunctionReturn(0);
48916ebf90aSShri Abhyankar }
49016ebf90aSShri Abhyankar 
49116ebf90aSShri Abhyankar #undef __FUNCT__
49216ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqsbaij"
493bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
49416ebf90aSShri Abhyankar {
49567877ebaSShri Abhyankar   const PetscInt    *ai,*aj,*ajj,*adiag,M=A->rmap->n;
49667877ebaSShri Abhyankar   PetscInt          nz,rnz,i,j;
49767877ebaSShri Abhyankar   const PetscScalar *av,*v1;
49816ebf90aSShri Abhyankar   PetscScalar       *val;
49916ebf90aSShri Abhyankar   PetscErrorCode    ierr;
50016ebf90aSShri Abhyankar   PetscInt          *row,*col;
501829b1710SHong Zhang   Mat_SeqAIJ        *aa=(Mat_SeqAIJ*)A->data;
50229b521d4Sstefano_zampini   PetscBool         missing;
50316ebf90aSShri Abhyankar 
50416ebf90aSShri Abhyankar   PetscFunctionBegin;
50516ebf90aSShri Abhyankar   ai   =aa->i; aj=aa->j;av=aa->a;
50616ebf90aSShri Abhyankar   adiag=aa->diag;
50729b521d4Sstefano_zampini   ierr  = MatMissingDiagonal_SeqAIJ(A,&missing,&i);CHKERRQ(ierr);
508bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
509829b1710SHong Zhang     /* count nz in the uppper triangular part of A */
510829b1710SHong Zhang     nz = 0;
51129b521d4Sstefano_zampini     if (missing) {
51229b521d4Sstefano_zampini       for (i=0; i<M; i++) {
51329b521d4Sstefano_zampini         if (PetscUnlikely(adiag[i] >= ai[i+1])) {
51429b521d4Sstefano_zampini           for (j=ai[i];j<ai[i+1];j++) {
51529b521d4Sstefano_zampini             if (aj[j] < i) continue;
51629b521d4Sstefano_zampini             nz++;
51729b521d4Sstefano_zampini           }
51829b521d4Sstefano_zampini         } else {
51929b521d4Sstefano_zampini           nz += ai[i+1] - adiag[i];
52029b521d4Sstefano_zampini         }
52129b521d4Sstefano_zampini       }
52229b521d4Sstefano_zampini     } else {
523829b1710SHong Zhang       for (i=0; i<M; i++) nz += ai[i+1] - adiag[i];
52429b521d4Sstefano_zampini     }
52516ebf90aSShri Abhyankar     *nnz = nz;
526829b1710SHong Zhang 
527185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
528185f6596SHong Zhang     col  = row + nz;
529185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
530185f6596SHong Zhang 
53116ebf90aSShri Abhyankar     nz = 0;
53229b521d4Sstefano_zampini     if (missing) {
53329b521d4Sstefano_zampini       for (i=0; i<M; i++) {
53429b521d4Sstefano_zampini         if (PetscUnlikely(adiag[i] >= ai[i+1])) {
53529b521d4Sstefano_zampini           for (j=ai[i];j<ai[i+1];j++) {
53629b521d4Sstefano_zampini             if (aj[j] < i) continue;
53729b521d4Sstefano_zampini             row[nz] = i+shift;
53829b521d4Sstefano_zampini             col[nz] = aj[j]+shift;
53929b521d4Sstefano_zampini             val[nz] = av[j];
54029b521d4Sstefano_zampini             nz++;
54129b521d4Sstefano_zampini           }
54229b521d4Sstefano_zampini         } else {
54329b521d4Sstefano_zampini           rnz = ai[i+1] - adiag[i];
54429b521d4Sstefano_zampini           ajj = aj + adiag[i];
54529b521d4Sstefano_zampini           v1  = av + adiag[i];
54629b521d4Sstefano_zampini           for (j=0; j<rnz; j++) {
54729b521d4Sstefano_zampini             row[nz] = i+shift; col[nz] = ajj[j] + shift; val[nz++] = v1[j];
54829b521d4Sstefano_zampini           }
54929b521d4Sstefano_zampini         }
55029b521d4Sstefano_zampini       }
55129b521d4Sstefano_zampini     } else {
55216ebf90aSShri Abhyankar       for (i=0; i<M; i++) {
55316ebf90aSShri Abhyankar         rnz = ai[i+1] - adiag[i];
55467877ebaSShri Abhyankar         ajj = aj + adiag[i];
555cf3759fdSShri Abhyankar         v1  = av + adiag[i];
55667877ebaSShri Abhyankar         for (j=0; j<rnz; j++) {
55767877ebaSShri Abhyankar           row[nz] = i+shift; col[nz] = ajj[j] + shift; val[nz++] = v1[j];
55816ebf90aSShri Abhyankar         }
55916ebf90aSShri Abhyankar       }
56029b521d4Sstefano_zampini     }
56116ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
562397b6df1SKris Buschelman   } else {
56316ebf90aSShri Abhyankar     nz = 0; val = *v;
56429b521d4Sstefano_zampini     if (missing) {
56516ebf90aSShri Abhyankar       for (i=0; i <M; i++) {
56629b521d4Sstefano_zampini         if (PetscUnlikely(adiag[i] >= ai[i+1])) {
56729b521d4Sstefano_zampini           for (j=ai[i];j<ai[i+1];j++) {
56829b521d4Sstefano_zampini             if (aj[j] < i) continue;
56929b521d4Sstefano_zampini             val[nz++] = av[j];
57029b521d4Sstefano_zampini           }
57129b521d4Sstefano_zampini         } else {
57216ebf90aSShri Abhyankar           rnz = ai[i+1] - adiag[i];
57367877ebaSShri Abhyankar           v1  = av + adiag[i];
57467877ebaSShri Abhyankar           for (j=0; j<rnz; j++) {
57567877ebaSShri Abhyankar             val[nz++] = v1[j];
57616ebf90aSShri Abhyankar           }
57716ebf90aSShri Abhyankar         }
57816ebf90aSShri Abhyankar       }
57929b521d4Sstefano_zampini     } else {
58029b521d4Sstefano_zampini       for (i=0; i <M; i++) {
58129b521d4Sstefano_zampini         rnz = ai[i+1] - adiag[i];
58229b521d4Sstefano_zampini         v1  = av + adiag[i];
58329b521d4Sstefano_zampini         for (j=0; j<rnz; j++) {
58429b521d4Sstefano_zampini           val[nz++] = v1[j];
58529b521d4Sstefano_zampini         }
58629b521d4Sstefano_zampini       }
58729b521d4Sstefano_zampini     }
58829b521d4Sstefano_zampini   }
58916ebf90aSShri Abhyankar   PetscFunctionReturn(0);
59016ebf90aSShri Abhyankar }
59116ebf90aSShri Abhyankar 
59216ebf90aSShri Abhyankar #undef __FUNCT__
59316ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpisbaij_mpisbaij"
594bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpisbaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
59516ebf90aSShri Abhyankar {
59616ebf90aSShri Abhyankar   const PetscInt    *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
59716ebf90aSShri Abhyankar   PetscErrorCode    ierr;
59816ebf90aSShri Abhyankar   PetscInt          rstart,nz,i,j,jj,irow,countA,countB;
59916ebf90aSShri Abhyankar   PetscInt          *row,*col;
60016ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
60116ebf90aSShri Abhyankar   PetscScalar       *val;
602397b6df1SKris Buschelman   Mat_MPISBAIJ      *mat = (Mat_MPISBAIJ*)A->data;
603397b6df1SKris Buschelman   Mat_SeqSBAIJ      *aa  = (Mat_SeqSBAIJ*)(mat->A)->data;
604397b6df1SKris Buschelman   Mat_SeqBAIJ       *bb  = (Mat_SeqBAIJ*)(mat->B)->data;
60516ebf90aSShri Abhyankar 
60616ebf90aSShri Abhyankar   PetscFunctionBegin;
607d0f46423SBarry Smith   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
608397b6df1SKris Buschelman   av=aa->a; bv=bb->a;
609397b6df1SKris Buschelman 
6102205254eSKarl Rupp   garray = mat->garray;
6112205254eSKarl Rupp 
612bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
61316ebf90aSShri Abhyankar     nz   = aa->nz + bb->nz;
61416ebf90aSShri Abhyankar     *nnz = nz;
615185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
616185f6596SHong Zhang     col  = row + nz;
617185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
618185f6596SHong Zhang 
619397b6df1SKris Buschelman     *r = row; *c = col; *v = val;
620397b6df1SKris Buschelman   } else {
621397b6df1SKris Buschelman     row = *r; col = *c; val = *v;
622397b6df1SKris Buschelman   }
623397b6df1SKris Buschelman 
624028e57e8SHong Zhang   jj = 0; irow = rstart;
625397b6df1SKris Buschelman   for (i=0; i<m; i++) {
626397b6df1SKris Buschelman     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
627397b6df1SKris Buschelman     countA = ai[i+1] - ai[i];
628397b6df1SKris Buschelman     countB = bi[i+1] - bi[i];
629397b6df1SKris Buschelman     bjj    = bj + bi[i];
63016ebf90aSShri Abhyankar     v1     = av + ai[i];
63116ebf90aSShri Abhyankar     v2     = bv + bi[i];
632397b6df1SKris Buschelman 
633397b6df1SKris Buschelman     /* A-part */
634397b6df1SKris Buschelman     for (j=0; j<countA; j++) {
635bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
636397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
637397b6df1SKris Buschelman       }
63816ebf90aSShri Abhyankar       val[jj++] = v1[j];
639397b6df1SKris Buschelman     }
64016ebf90aSShri Abhyankar 
64116ebf90aSShri Abhyankar     /* B-part */
64216ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
643bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
644397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
645397b6df1SKris Buschelman       }
64616ebf90aSShri Abhyankar       val[jj++] = v2[j];
64716ebf90aSShri Abhyankar     }
64816ebf90aSShri Abhyankar     irow++;
64916ebf90aSShri Abhyankar   }
65016ebf90aSShri Abhyankar   PetscFunctionReturn(0);
65116ebf90aSShri Abhyankar }
65216ebf90aSShri Abhyankar 
65316ebf90aSShri Abhyankar #undef __FUNCT__
65416ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpiaij"
655bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
65616ebf90aSShri Abhyankar {
65716ebf90aSShri Abhyankar   const PetscInt    *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
65816ebf90aSShri Abhyankar   PetscErrorCode    ierr;
65916ebf90aSShri Abhyankar   PetscInt          rstart,nz,i,j,jj,irow,countA,countB;
66016ebf90aSShri Abhyankar   PetscInt          *row,*col;
66116ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
66216ebf90aSShri Abhyankar   PetscScalar       *val;
66316ebf90aSShri Abhyankar   Mat_MPIAIJ        *mat = (Mat_MPIAIJ*)A->data;
66416ebf90aSShri Abhyankar   Mat_SeqAIJ        *aa  = (Mat_SeqAIJ*)(mat->A)->data;
66516ebf90aSShri Abhyankar   Mat_SeqAIJ        *bb  = (Mat_SeqAIJ*)(mat->B)->data;
66616ebf90aSShri Abhyankar 
66716ebf90aSShri Abhyankar   PetscFunctionBegin;
66816ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
66916ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
67016ebf90aSShri Abhyankar 
6712205254eSKarl Rupp   garray = mat->garray;
6722205254eSKarl Rupp 
673bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
67416ebf90aSShri Abhyankar     nz   = aa->nz + bb->nz;
67516ebf90aSShri Abhyankar     *nnz = nz;
676185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
677185f6596SHong Zhang     col  = row + nz;
678185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
679185f6596SHong Zhang 
68016ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
68116ebf90aSShri Abhyankar   } else {
68216ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
68316ebf90aSShri Abhyankar   }
68416ebf90aSShri Abhyankar 
68516ebf90aSShri Abhyankar   jj = 0; irow = rstart;
68616ebf90aSShri Abhyankar   for (i=0; i<m; i++) {
68716ebf90aSShri Abhyankar     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
68816ebf90aSShri Abhyankar     countA = ai[i+1] - ai[i];
68916ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
69016ebf90aSShri Abhyankar     bjj    = bj + bi[i];
69116ebf90aSShri Abhyankar     v1     = av + ai[i];
69216ebf90aSShri Abhyankar     v2     = bv + bi[i];
69316ebf90aSShri Abhyankar 
69416ebf90aSShri Abhyankar     /* A-part */
69516ebf90aSShri Abhyankar     for (j=0; j<countA; j++) {
696bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
69716ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
69816ebf90aSShri Abhyankar       }
69916ebf90aSShri Abhyankar       val[jj++] = v1[j];
70016ebf90aSShri Abhyankar     }
70116ebf90aSShri Abhyankar 
70216ebf90aSShri Abhyankar     /* B-part */
70316ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
704bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
70516ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
70616ebf90aSShri Abhyankar       }
70716ebf90aSShri Abhyankar       val[jj++] = v2[j];
70816ebf90aSShri Abhyankar     }
70916ebf90aSShri Abhyankar     irow++;
71016ebf90aSShri Abhyankar   }
71116ebf90aSShri Abhyankar   PetscFunctionReturn(0);
71216ebf90aSShri Abhyankar }
71316ebf90aSShri Abhyankar 
71416ebf90aSShri Abhyankar #undef __FUNCT__
71567877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpibaij_mpiaij"
716bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpibaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
71767877ebaSShri Abhyankar {
71867877ebaSShri Abhyankar   Mat_MPIBAIJ       *mat    = (Mat_MPIBAIJ*)A->data;
71967877ebaSShri Abhyankar   Mat_SeqBAIJ       *aa     = (Mat_SeqBAIJ*)(mat->A)->data;
72067877ebaSShri Abhyankar   Mat_SeqBAIJ       *bb     = (Mat_SeqBAIJ*)(mat->B)->data;
72167877ebaSShri Abhyankar   const PetscInt    *ai     = aa->i, *bi = bb->i, *aj = aa->j, *bj = bb->j,*ajj, *bjj;
722d985c460SShri Abhyankar   const PetscInt    *garray = mat->garray,mbs=mat->mbs,rstart=A->rmap->rstart;
72333d57670SJed Brown   const PetscInt    bs2=mat->bs2;
72467877ebaSShri Abhyankar   PetscErrorCode    ierr;
72533d57670SJed Brown   PetscInt          bs,nz,i,j,k,n,jj,irow,countA,countB,idx;
72667877ebaSShri Abhyankar   PetscInt          *row,*col;
72767877ebaSShri Abhyankar   const PetscScalar *av=aa->a, *bv=bb->a,*v1,*v2;
72867877ebaSShri Abhyankar   PetscScalar       *val;
72967877ebaSShri Abhyankar 
73067877ebaSShri Abhyankar   PetscFunctionBegin;
73133d57670SJed Brown   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
732bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
73367877ebaSShri Abhyankar     nz   = bs2*(aa->nz + bb->nz);
73467877ebaSShri Abhyankar     *nnz = nz;
735185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
736185f6596SHong Zhang     col  = row + nz;
737185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
738185f6596SHong Zhang 
73967877ebaSShri Abhyankar     *r = row; *c = col; *v = val;
74067877ebaSShri Abhyankar   } else {
74167877ebaSShri Abhyankar     row = *r; col = *c; val = *v;
74267877ebaSShri Abhyankar   }
74367877ebaSShri Abhyankar 
744d985c460SShri Abhyankar   jj = 0; irow = rstart;
74567877ebaSShri Abhyankar   for (i=0; i<mbs; i++) {
74667877ebaSShri Abhyankar     countA = ai[i+1] - ai[i];
74767877ebaSShri Abhyankar     countB = bi[i+1] - bi[i];
74867877ebaSShri Abhyankar     ajj    = aj + ai[i];
74967877ebaSShri Abhyankar     bjj    = bj + bi[i];
75067877ebaSShri Abhyankar     v1     = av + bs2*ai[i];
75167877ebaSShri Abhyankar     v2     = bv + bs2*bi[i];
75267877ebaSShri Abhyankar 
75367877ebaSShri Abhyankar     idx = 0;
75467877ebaSShri Abhyankar     /* A-part */
75567877ebaSShri Abhyankar     for (k=0; k<countA; k++) {
75667877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
75767877ebaSShri Abhyankar         for (n=0; n<bs; n++) {
758bccb9932SShri Abhyankar           if (reuse == MAT_INITIAL_MATRIX) {
759d985c460SShri Abhyankar             row[jj] = irow + n + shift;
760d985c460SShri Abhyankar             col[jj] = rstart + bs*ajj[k] + j + shift;
76167877ebaSShri Abhyankar           }
76267877ebaSShri Abhyankar           val[jj++] = v1[idx++];
76367877ebaSShri Abhyankar         }
76467877ebaSShri Abhyankar       }
76567877ebaSShri Abhyankar     }
76667877ebaSShri Abhyankar 
76767877ebaSShri Abhyankar     idx = 0;
76867877ebaSShri Abhyankar     /* B-part */
76967877ebaSShri Abhyankar     for (k=0; k<countB; k++) {
77067877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
77167877ebaSShri Abhyankar         for (n=0; n<bs; n++) {
772bccb9932SShri Abhyankar           if (reuse == MAT_INITIAL_MATRIX) {
773d985c460SShri Abhyankar             row[jj] = irow + n + shift;
774d985c460SShri Abhyankar             col[jj] = bs*garray[bjj[k]] + j + shift;
77567877ebaSShri Abhyankar           }
776d985c460SShri Abhyankar           val[jj++] = v2[idx++];
77767877ebaSShri Abhyankar         }
77867877ebaSShri Abhyankar       }
77967877ebaSShri Abhyankar     }
780d985c460SShri Abhyankar     irow += bs;
78167877ebaSShri Abhyankar   }
78267877ebaSShri Abhyankar   PetscFunctionReturn(0);
78367877ebaSShri Abhyankar }
78467877ebaSShri Abhyankar 
78567877ebaSShri Abhyankar #undef __FUNCT__
78616ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpisbaij"
787bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
78816ebf90aSShri Abhyankar {
78916ebf90aSShri Abhyankar   const PetscInt    *ai, *aj,*adiag, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
79016ebf90aSShri Abhyankar   PetscErrorCode    ierr;
791e0bace9bSHong Zhang   PetscInt          rstart,nz,nza,nzb,i,j,jj,irow,countA,countB;
79216ebf90aSShri Abhyankar   PetscInt          *row,*col;
79316ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
79416ebf90aSShri Abhyankar   PetscScalar       *val;
79516ebf90aSShri Abhyankar   Mat_MPIAIJ        *mat =  (Mat_MPIAIJ*)A->data;
79616ebf90aSShri Abhyankar   Mat_SeqAIJ        *aa  =(Mat_SeqAIJ*)(mat->A)->data;
79716ebf90aSShri Abhyankar   Mat_SeqAIJ        *bb  =(Mat_SeqAIJ*)(mat->B)->data;
79816ebf90aSShri Abhyankar 
79916ebf90aSShri Abhyankar   PetscFunctionBegin;
80016ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; adiag=aa->diag;
80116ebf90aSShri Abhyankar   bi=bb->i; bj=bb->j; garray = mat->garray;
80216ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
8032205254eSKarl Rupp 
80416ebf90aSShri Abhyankar   rstart = A->rmap->rstart;
80516ebf90aSShri Abhyankar 
806bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
807e0bace9bSHong Zhang     nza = 0;    /* num of upper triangular entries in mat->A, including diagonals */
808e0bace9bSHong Zhang     nzb = 0;    /* num of upper triangular entries in mat->B */
80916ebf90aSShri Abhyankar     for (i=0; i<m; i++) {
810e0bace9bSHong Zhang       nza   += (ai[i+1] - adiag[i]);
81116ebf90aSShri Abhyankar       countB = bi[i+1] - bi[i];
81216ebf90aSShri Abhyankar       bjj    = bj + bi[i];
813e0bace9bSHong Zhang       for (j=0; j<countB; j++) {
814e0bace9bSHong Zhang         if (garray[bjj[j]] > rstart) nzb++;
815e0bace9bSHong Zhang       }
816e0bace9bSHong Zhang     }
81716ebf90aSShri Abhyankar 
818e0bace9bSHong Zhang     nz   = nza + nzb; /* total nz of upper triangular part of mat */
81916ebf90aSShri Abhyankar     *nnz = nz;
820185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
821185f6596SHong Zhang     col  = row + nz;
822185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
823185f6596SHong Zhang 
82416ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
82516ebf90aSShri Abhyankar   } else {
82616ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
82716ebf90aSShri Abhyankar   }
82816ebf90aSShri Abhyankar 
82916ebf90aSShri Abhyankar   jj = 0; irow = rstart;
83016ebf90aSShri Abhyankar   for (i=0; i<m; i++) {
83116ebf90aSShri Abhyankar     ajj    = aj + adiag[i];                 /* ptr to the beginning of the diagonal of this row */
83216ebf90aSShri Abhyankar     v1     = av + adiag[i];
83316ebf90aSShri Abhyankar     countA = ai[i+1] - adiag[i];
83416ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
83516ebf90aSShri Abhyankar     bjj    = bj + bi[i];
83616ebf90aSShri Abhyankar     v2     = bv + bi[i];
83716ebf90aSShri Abhyankar 
83816ebf90aSShri Abhyankar     /* A-part */
83916ebf90aSShri Abhyankar     for (j=0; j<countA; j++) {
840bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
84116ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
84216ebf90aSShri Abhyankar       }
84316ebf90aSShri Abhyankar       val[jj++] = v1[j];
84416ebf90aSShri Abhyankar     }
84516ebf90aSShri Abhyankar 
84616ebf90aSShri Abhyankar     /* B-part */
84716ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
84816ebf90aSShri Abhyankar       if (garray[bjj[j]] > rstart) {
849bccb9932SShri Abhyankar         if (reuse == MAT_INITIAL_MATRIX) {
85016ebf90aSShri Abhyankar           row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
85116ebf90aSShri Abhyankar         }
85216ebf90aSShri Abhyankar         val[jj++] = v2[j];
85316ebf90aSShri Abhyankar       }
854397b6df1SKris Buschelman     }
855397b6df1SKris Buschelman     irow++;
856397b6df1SKris Buschelman   }
857397b6df1SKris Buschelman   PetscFunctionReturn(0);
858397b6df1SKris Buschelman }
859397b6df1SKris Buschelman 
860397b6df1SKris Buschelman #undef __FUNCT__
86120be8e61SHong Zhang #define __FUNCT__ "MatGetDiagonal_MUMPS"
86220be8e61SHong Zhang PetscErrorCode MatGetDiagonal_MUMPS(Mat A,Vec v)
86320be8e61SHong Zhang {
86420be8e61SHong Zhang   PetscFunctionBegin;
86520be8e61SHong Zhang   SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type: MUMPS factor");
86620be8e61SHong Zhang   PetscFunctionReturn(0);
86720be8e61SHong Zhang }
86820be8e61SHong Zhang 
86920be8e61SHong Zhang #undef __FUNCT__
8703924e44cSKris Buschelman #define __FUNCT__ "MatDestroy_MUMPS"
871dfbe8321SBarry Smith PetscErrorCode MatDestroy_MUMPS(Mat A)
872dfbe8321SBarry Smith {
873a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
874dfbe8321SBarry Smith   PetscErrorCode ierr;
875b24902e0SBarry Smith 
876397b6df1SKris Buschelman   PetscFunctionBegin;
877a5e57a09SHong Zhang   ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
878a5e57a09SHong Zhang   ierr = VecScatterDestroy(&mumps->scat_rhs);CHKERRQ(ierr);
879a5e57a09SHong Zhang   ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
880801fbe65SHong Zhang   ierr = VecDestroy(&mumps->b_seq);CHKERRQ(ierr);
881a5e57a09SHong Zhang   ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
882a5e57a09SHong Zhang   ierr = PetscFree(mumps->id.perm_in);CHKERRQ(ierr);
883a5e57a09SHong Zhang   ierr = PetscFree(mumps->irn);CHKERRQ(ierr);
884b34f08ffSHong Zhang   ierr = PetscFree(mumps->info);CHKERRQ(ierr);
88559ac8732SStefano Zampini   ierr = MatMumpsResetSchur_Private(mumps);CHKERRQ(ierr);
886a5e57a09SHong Zhang   mumps->id.job = JOB_END;
887a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
8886f3cc6f9SBarry Smith   ierr = MPI_Comm_free(&mumps->comm_mumps);CHKERRQ(ierr);
889a5e57a09SHong Zhang   if (mumps->Destroy) {
890a5e57a09SHong Zhang     ierr = (mumps->Destroy)(A);CHKERRQ(ierr);
891bf0cc555SLisandro Dalcin   }
892bf0cc555SLisandro Dalcin   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
893bf0cc555SLisandro Dalcin 
89497969023SHong Zhang   /* clear composed functions */
895bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSolverPackage_C",NULL);CHKERRQ(ierr);
8965a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorSetSchurIS_C",NULL);CHKERRQ(ierr);
8975a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorInvertSchurComplement_C",NULL);CHKERRQ(ierr);
8985a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorCreateSchurComplement_C",NULL);CHKERRQ(ierr);
8995a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSchurComplement_C",NULL);CHKERRQ(ierr);
9005a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorSolveSchurComplement_C",NULL);CHKERRQ(ierr);
9015a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorSolveSchurComplementTranspose_C",NULL);CHKERRQ(ierr);
902bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsSetIcntl_C",NULL);CHKERRQ(ierr);
903bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetIcntl_C",NULL);CHKERRQ(ierr);
904bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsSetCntl_C",NULL);CHKERRQ(ierr);
905bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetCntl_C",NULL);CHKERRQ(ierr);
906ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetInfo_C",NULL);CHKERRQ(ierr);
907ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetInfog_C",NULL);CHKERRQ(ierr);
908ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetRinfo_C",NULL);CHKERRQ(ierr);
909ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetRinfog_C",NULL);CHKERRQ(ierr);
910397b6df1SKris Buschelman   PetscFunctionReturn(0);
911397b6df1SKris Buschelman }
912397b6df1SKris Buschelman 
913397b6df1SKris Buschelman #undef __FUNCT__
914f6c57405SHong Zhang #define __FUNCT__ "MatSolve_MUMPS"
915b24902e0SBarry Smith PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x)
916b24902e0SBarry Smith {
917a5e57a09SHong Zhang   Mat_MUMPS        *mumps=(Mat_MUMPS*)A->spptr;
918d54de34fSKris Buschelman   PetscScalar      *array;
91967877ebaSShri Abhyankar   Vec              b_seq;
920329ec9b3SHong Zhang   IS               is_iden,is_petsc;
921dfbe8321SBarry Smith   PetscErrorCode   ierr;
922329ec9b3SHong Zhang   PetscInt         i;
923cc86f929SStefano Zampini   PetscBool        second_solve = PETSC_FALSE;
924883f2eb9SBarry Smith   static PetscBool cite1 = PETSC_FALSE,cite2 = PETSC_FALSE;
925397b6df1SKris Buschelman 
926397b6df1SKris Buschelman   PetscFunctionBegin;
927883f2eb9SBarry Smith   ierr = PetscCitationsRegister("@article{MUMPS01,\n  author = {P.~R. Amestoy and I.~S. Duff and J.-Y. L'Excellent and J. Koster},\n  title = {A fully asynchronous multifrontal solver using distributed dynamic scheduling},\n  journal = {SIAM Journal on Matrix Analysis and Applications},\n  volume = {23},\n  number = {1},\n  pages = {15--41},\n  year = {2001}\n}\n",&cite1);CHKERRQ(ierr);
928883f2eb9SBarry Smith   ierr = PetscCitationsRegister("@article{MUMPS02,\n  author = {P.~R. Amestoy and A. Guermouche and J.-Y. L'Excellent and S. Pralet},\n  title = {Hybrid scheduling for the parallel solution of linear systems},\n  journal = {Parallel Computing},\n  volume = {32},\n  number = {2},\n  pages = {136--156},\n  year = {2006}\n}\n",&cite2);CHKERRQ(ierr);
9292aca8efcSHong Zhang 
930d8cd2189SHong Zhang   if (A->errortype) {
9312aca8efcSHong Zhang     ierr = PetscInfo2(A,"MatSolve is called with singular matrix factor, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
9322aca8efcSHong Zhang     ierr = VecSetInf(x);CHKERRQ(ierr);
9332aca8efcSHong Zhang     PetscFunctionReturn(0);
9342aca8efcSHong Zhang   }
9352aca8efcSHong Zhang 
936a5e57a09SHong Zhang   mumps->id.nrhs = 1;
937a5e57a09SHong Zhang   b_seq          = mumps->b_seq;
938a5e57a09SHong Zhang   if (mumps->size > 1) {
939329ec9b3SHong Zhang     /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */
940a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
941a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
942a5e57a09SHong Zhang     if (!mumps->myid) {ierr = VecGetArray(b_seq,&array);CHKERRQ(ierr);}
943397b6df1SKris Buschelman   } else {  /* size == 1 */
944397b6df1SKris Buschelman     ierr = VecCopy(b,x);CHKERRQ(ierr);
945397b6df1SKris Buschelman     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
946397b6df1SKris Buschelman   }
947a5e57a09SHong Zhang   if (!mumps->myid) { /* define rhs on the host */
948a5e57a09SHong Zhang     mumps->id.nrhs = 1;
949940cd9d6SSatish Balay     mumps->id.rhs = (MumpsScalar*)array;
950397b6df1SKris Buschelman   }
951397b6df1SKris Buschelman 
952cc86f929SStefano Zampini   /*
953cc86f929SStefano Zampini      handle condensation step of Schur complement (if any)
954cc86f929SStefano Zampini      We set by default ICNTL(26) == -1 when Schur indices have been provided by the user.
955cc86f929SStefano Zampini      According to MUMPS (5.0.0) manual, any value should be harmful during the factorization phase
956cc86f929SStefano Zampini      Unless the user provides a valid value for ICNTL(26), MatSolve and MatMatSolve routines solve the full system.
957cc86f929SStefano Zampini      This requires an extra call to PetscMUMPS_c and the computation of the factors for S
958cc86f929SStefano Zampini   */
959cc86f929SStefano Zampini   if (mumps->id.ICNTL(26) < 0 || mumps->id.ICNTL(26) > 2) {
960cc86f929SStefano Zampini     second_solve = PETSC_TRUE;
961b8f61ee1SStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps,PETSC_FALSE);CHKERRQ(ierr);
962cc86f929SStefano Zampini   }
963397b6df1SKris Buschelman   /* solve phase */
964329ec9b3SHong Zhang   /*-------------*/
965a5e57a09SHong Zhang   mumps->id.job = JOB_SOLVE;
966a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
967a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
968397b6df1SKris Buschelman 
969b5fa320bSStefano Zampini   /* handle expansion step of Schur complement (if any) */
970cc86f929SStefano Zampini   if (second_solve) {
971b8f61ee1SStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps,PETSC_TRUE);CHKERRQ(ierr);
972cc86f929SStefano Zampini   }
973b5fa320bSStefano Zampini 
974a5e57a09SHong Zhang   if (mumps->size > 1) { /* convert mumps distributed solution to petsc mpi x */
975a5e57a09SHong Zhang     if (mumps->scat_sol && mumps->ICNTL9_pre != mumps->id.ICNTL(9)) {
976a5e57a09SHong Zhang       /* when id.ICNTL(9) changes, the contents of lsol_loc may change (not its size, lsol_loc), recreates scat_sol */
977a5e57a09SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
978397b6df1SKris Buschelman     }
979a5e57a09SHong Zhang     if (!mumps->scat_sol) { /* create scatter scat_sol */
980a5e57a09SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,mumps->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */
981a5e57a09SHong Zhang       for (i=0; i<mumps->id.lsol_loc; i++) {
982a5e57a09SHong Zhang         mumps->id.isol_loc[i] -= 1; /* change Fortran style to C style */
983a5e57a09SHong Zhang       }
984a5e57a09SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,mumps->id.lsol_loc,mumps->id.isol_loc,PETSC_COPY_VALUES,&is_petsc);CHKERRQ(ierr);  /* to */
985a5e57a09SHong Zhang       ierr = VecScatterCreate(mumps->x_seq,is_iden,x,is_petsc,&mumps->scat_sol);CHKERRQ(ierr);
9866bf464f9SBarry Smith       ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
9876bf464f9SBarry Smith       ierr = ISDestroy(&is_petsc);CHKERRQ(ierr);
9882205254eSKarl Rupp 
989a5e57a09SHong Zhang       mumps->ICNTL9_pre = mumps->id.ICNTL(9); /* save current value of id.ICNTL(9) */
990397b6df1SKris Buschelman     }
991a5e57a09SHong Zhang 
992a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
993a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
994329ec9b3SHong Zhang   }
995397b6df1SKris Buschelman   PetscFunctionReturn(0);
996397b6df1SKris Buschelman }
997397b6df1SKris Buschelman 
99851d5961aSHong Zhang #undef __FUNCT__
99951d5961aSHong Zhang #define __FUNCT__ "MatSolveTranspose_MUMPS"
100051d5961aSHong Zhang PetscErrorCode MatSolveTranspose_MUMPS(Mat A,Vec b,Vec x)
100151d5961aSHong Zhang {
1002a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
100351d5961aSHong Zhang   PetscErrorCode ierr;
100451d5961aSHong Zhang 
100551d5961aSHong Zhang   PetscFunctionBegin;
1006a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 0;
10070ad0caddSJed Brown   ierr = MatSolve_MUMPS(A,b,x);CHKERRQ(ierr);
1008a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 1;
100951d5961aSHong Zhang   PetscFunctionReturn(0);
101051d5961aSHong Zhang }
101151d5961aSHong Zhang 
1012e0b74bf9SHong Zhang #undef __FUNCT__
1013e0b74bf9SHong Zhang #define __FUNCT__ "MatMatSolve_MUMPS"
1014e0b74bf9SHong Zhang PetscErrorCode MatMatSolve_MUMPS(Mat A,Mat B,Mat X)
1015e0b74bf9SHong Zhang {
1016bda8bf91SBarry Smith   PetscErrorCode ierr;
1017bda8bf91SBarry Smith   PetscBool      flg;
10184e34a73bSHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
1019334c5f61SHong Zhang   PetscInt       i,nrhs,M;
10202cd7d884SHong Zhang   PetscScalar    *array,*bray;
1021bda8bf91SBarry Smith 
1022e0b74bf9SHong Zhang   PetscFunctionBegin;
10230298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
1024801fbe65SHong Zhang   if (!flg) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
10250298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
1026801fbe65SHong Zhang   if (!flg) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
1027801fbe65SHong Zhang   if (B->rmap->n != X->rmap->n) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Matrix B and X must have same row distribution");
10284e34a73bSHong Zhang 
10292cd7d884SHong Zhang   ierr = MatGetSize(B,&M,&nrhs);CHKERRQ(ierr);
1030334c5f61SHong Zhang   mumps->id.nrhs = nrhs;
1031334c5f61SHong Zhang   mumps->id.lrhs = M;
10324e34a73bSHong Zhang 
10332cd7d884SHong Zhang   if (mumps->size == 1) {
10342cd7d884SHong Zhang     /* copy B to X */
10352cd7d884SHong Zhang     ierr = MatDenseGetArray(B,&bray);CHKERRQ(ierr);
10362cd7d884SHong Zhang     ierr = MatDenseGetArray(X,&array);CHKERRQ(ierr);
10376444a565SStefano Zampini     ierr = PetscMemcpy(array,bray,M*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
10382cd7d884SHong Zhang     ierr = MatDenseRestoreArray(B,&bray);CHKERRQ(ierr);
1039940cd9d6SSatish Balay     mumps->id.rhs = (MumpsScalar*)array;
1040b5fa320bSStefano Zampini     /* handle condensation step of Schur complement (if any) */
1041b8f61ee1SStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps,PETSC_FALSE);CHKERRQ(ierr);
1042801fbe65SHong Zhang 
10432cd7d884SHong Zhang     /* solve phase */
10442cd7d884SHong Zhang     /*-------------*/
10452cd7d884SHong Zhang     mumps->id.job = JOB_SOLVE;
10462cd7d884SHong Zhang     PetscMUMPS_c(&mumps->id);
10472cd7d884SHong Zhang     if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
1048b5fa320bSStefano Zampini 
1049b5fa320bSStefano Zampini     /* handle expansion step of Schur complement (if any) */
1050b8f61ee1SStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps,PETSC_TRUE);CHKERRQ(ierr);
10512cd7d884SHong Zhang     ierr = MatDenseRestoreArray(X,&array);CHKERRQ(ierr);
1052334c5f61SHong Zhang   } else {  /*--------- parallel case --------*/
105371aed81dSHong Zhang     PetscInt       lsol_loc,nlsol_loc,*isol_loc,*idx,*iidx,*idxx,*isol_loc_save;
10541070efccSSatish Balay     MumpsScalar    *sol_loc,*sol_loc_save;
1055801fbe65SHong Zhang     IS             is_to,is_from;
1056334c5f61SHong Zhang     PetscInt       k,proc,j,m;
1057801fbe65SHong Zhang     const PetscInt *rstart;
1058334c5f61SHong Zhang     Vec            v_mpi,b_seq,x_seq;
1059334c5f61SHong Zhang     VecScatter     scat_rhs,scat_sol;
1060801fbe65SHong Zhang 
1061801fbe65SHong Zhang     /* create x_seq to hold local solution */
106271aed81dSHong Zhang     isol_loc_save = mumps->id.isol_loc; /* save it for MatSovle() */
106371aed81dSHong Zhang     sol_loc_save  = mumps->id.sol_loc;
1064801fbe65SHong Zhang 
106571aed81dSHong Zhang     lsol_loc  = mumps->id.INFO(23);
106671aed81dSHong Zhang     nlsol_loc = nrhs*lsol_loc;     /* length of sol_loc */
106771aed81dSHong Zhang     ierr = PetscMalloc2(nlsol_loc,&sol_loc,nlsol_loc,&isol_loc);CHKERRQ(ierr);
1068940cd9d6SSatish Balay     mumps->id.sol_loc = (MumpsScalar*)sol_loc;
1069801fbe65SHong Zhang     mumps->id.isol_loc = isol_loc;
1070801fbe65SHong Zhang 
10711070efccSSatish Balay     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,nlsol_loc,(PetscScalar*)sol_loc,&x_seq);CHKERRQ(ierr);
10722cd7d884SHong Zhang 
107374f0fcc7SHong Zhang     /* copy rhs matrix B into vector v_mpi */
1074334c5f61SHong Zhang     ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);
1075801fbe65SHong Zhang     ierr = MatDenseGetArray(B,&bray);CHKERRQ(ierr);
107674f0fcc7SHong Zhang     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),1,nrhs*m,nrhs*M,(const PetscScalar*)bray,&v_mpi);CHKERRQ(ierr);
1077801fbe65SHong Zhang     ierr = MatDenseRestoreArray(B,&bray);CHKERRQ(ierr);
1078801fbe65SHong Zhang 
1079334c5f61SHong Zhang     /* scatter v_mpi to b_seq because MUMPS only supports centralized rhs */
108074f0fcc7SHong Zhang     /* idx: maps from k-th index of v_mpi to (i,j)-th global entry of B;
1081801fbe65SHong Zhang       iidx: inverse of idx, will be used by scattering xx_seq -> X       */
1082801fbe65SHong Zhang     ierr = PetscMalloc2(nrhs*M,&idx,nrhs*M,&iidx);CHKERRQ(ierr);
1083801fbe65SHong Zhang     ierr = MatGetOwnershipRanges(B,&rstart);CHKERRQ(ierr);
1084801fbe65SHong Zhang     k = 0;
1085801fbe65SHong Zhang     for (proc=0; proc<mumps->size; proc++){
1086801fbe65SHong Zhang       for (j=0; j<nrhs; j++){
1087801fbe65SHong Zhang         for (i=rstart[proc]; i<rstart[proc+1]; i++){
1088801fbe65SHong Zhang           iidx[j*M + i] = k;
1089801fbe65SHong Zhang           idx[k++]      = j*M + i;
1090801fbe65SHong Zhang         }
1091801fbe65SHong Zhang       }
10922cd7d884SHong Zhang     }
10932cd7d884SHong Zhang 
1094801fbe65SHong Zhang     if (!mumps->myid) {
1095334c5f61SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,nrhs*M,&b_seq);CHKERRQ(ierr);
1096801fbe65SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,nrhs*M,idx,PETSC_COPY_VALUES,&is_to);CHKERRQ(ierr);
1097801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,nrhs*M,0,1,&is_from);CHKERRQ(ierr);
1098801fbe65SHong Zhang     } else {
1099334c5f61SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&b_seq);CHKERRQ(ierr);
1100801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_to);CHKERRQ(ierr);
1101801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_from);CHKERRQ(ierr);
1102801fbe65SHong Zhang     }
1103334c5f61SHong Zhang     ierr = VecScatterCreate(v_mpi,is_from,b_seq,is_to,&scat_rhs);CHKERRQ(ierr);
1104334c5f61SHong Zhang     ierr = VecScatterBegin(scat_rhs,v_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1105801fbe65SHong Zhang     ierr = ISDestroy(&is_to);CHKERRQ(ierr);
1106801fbe65SHong Zhang     ierr = ISDestroy(&is_from);CHKERRQ(ierr);
1107334c5f61SHong Zhang     ierr = VecScatterEnd(scat_rhs,v_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1108801fbe65SHong Zhang 
1109801fbe65SHong Zhang     if (!mumps->myid) { /* define rhs on the host */
1110334c5f61SHong Zhang       ierr = VecGetArray(b_seq,&bray);CHKERRQ(ierr);
1111940cd9d6SSatish Balay       mumps->id.rhs = (MumpsScalar*)bray;
1112334c5f61SHong Zhang       ierr = VecRestoreArray(b_seq,&bray);CHKERRQ(ierr);
1113801fbe65SHong Zhang     }
1114801fbe65SHong Zhang 
1115801fbe65SHong Zhang     /* solve phase */
1116801fbe65SHong Zhang     /*-------------*/
1117801fbe65SHong Zhang     mumps->id.job = JOB_SOLVE;
1118801fbe65SHong Zhang     PetscMUMPS_c(&mumps->id);
1119801fbe65SHong Zhang     if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
1120801fbe65SHong Zhang 
1121334c5f61SHong Zhang     /* scatter mumps distributed solution to petsc vector v_mpi, which shares local arrays with solution matrix X */
112274f0fcc7SHong Zhang     ierr = MatDenseGetArray(X,&array);CHKERRQ(ierr);
112374f0fcc7SHong Zhang     ierr = VecPlaceArray(v_mpi,array);CHKERRQ(ierr);
1124801fbe65SHong Zhang 
1125334c5f61SHong Zhang     /* create scatter scat_sol */
112671aed81dSHong Zhang     ierr = PetscMalloc1(nlsol_loc,&idxx);CHKERRQ(ierr);
112771aed81dSHong Zhang     ierr = ISCreateStride(PETSC_COMM_SELF,nlsol_loc,0,1,&is_from);CHKERRQ(ierr);
112871aed81dSHong Zhang     for (i=0; i<lsol_loc; i++) {
1129334c5f61SHong Zhang       isol_loc[i] -= 1; /* change Fortran style to C style */
1130334c5f61SHong Zhang       idxx[i] = iidx[isol_loc[i]];
1131801fbe65SHong Zhang       for (j=1; j<nrhs; j++){
1132334c5f61SHong Zhang         idxx[j*lsol_loc+i] = iidx[isol_loc[i]+j*M];
1133801fbe65SHong Zhang       }
1134801fbe65SHong Zhang     }
113571aed81dSHong Zhang     ierr = ISCreateGeneral(PETSC_COMM_SELF,nlsol_loc,idxx,PETSC_COPY_VALUES,&is_to);CHKERRQ(ierr);
1136334c5f61SHong Zhang     ierr = VecScatterCreate(x_seq,is_from,v_mpi,is_to,&scat_sol);CHKERRQ(ierr);
1137334c5f61SHong Zhang     ierr = VecScatterBegin(scat_sol,x_seq,v_mpi,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1138801fbe65SHong Zhang     ierr = ISDestroy(&is_from);CHKERRQ(ierr);
1139801fbe65SHong Zhang     ierr = ISDestroy(&is_to);CHKERRQ(ierr);
1140334c5f61SHong Zhang     ierr = VecScatterEnd(scat_sol,x_seq,v_mpi,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1141801fbe65SHong Zhang     ierr = MatDenseRestoreArray(X,&array);CHKERRQ(ierr);
114271aed81dSHong Zhang 
114371aed81dSHong Zhang     /* free spaces */
114471aed81dSHong Zhang     mumps->id.sol_loc = sol_loc_save;
114571aed81dSHong Zhang     mumps->id.isol_loc = isol_loc_save;
114671aed81dSHong Zhang 
114771aed81dSHong Zhang     ierr = PetscFree2(sol_loc,isol_loc);CHKERRQ(ierr);
1148801fbe65SHong Zhang     ierr = PetscFree2(idx,iidx);CHKERRQ(ierr);
1149801fbe65SHong Zhang     ierr = PetscFree(idxx);CHKERRQ(ierr);
115071aed81dSHong Zhang     ierr = VecDestroy(&x_seq);CHKERRQ(ierr);
115174f0fcc7SHong Zhang     ierr = VecDestroy(&v_mpi);CHKERRQ(ierr);
1152334c5f61SHong Zhang     ierr = VecDestroy(&b_seq);CHKERRQ(ierr);
1153334c5f61SHong Zhang     ierr = VecScatterDestroy(&scat_rhs);CHKERRQ(ierr);
1154334c5f61SHong Zhang     ierr = VecScatterDestroy(&scat_sol);CHKERRQ(ierr);
1155801fbe65SHong Zhang   }
1156e0b74bf9SHong Zhang   PetscFunctionReturn(0);
1157e0b74bf9SHong Zhang }
1158e0b74bf9SHong Zhang 
1159ace3df97SHong Zhang #if !defined(PETSC_USE_COMPLEX)
1160a58c3f20SHong Zhang /*
1161a58c3f20SHong Zhang   input:
1162a58c3f20SHong Zhang    F:        numeric factor
1163a58c3f20SHong Zhang   output:
1164a58c3f20SHong Zhang    nneg:     total number of negative pivots
1165a58c3f20SHong Zhang    nzero:    0
1166a58c3f20SHong Zhang    npos:     (global dimension of F) - nneg
1167a58c3f20SHong Zhang */
1168a58c3f20SHong Zhang 
1169a58c3f20SHong Zhang #undef __FUNCT__
1170a58c3f20SHong Zhang #define __FUNCT__ "MatGetInertia_SBAIJMUMPS"
1171dfbe8321SBarry Smith PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos)
1172a58c3f20SHong Zhang {
1173a5e57a09SHong Zhang   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
1174dfbe8321SBarry Smith   PetscErrorCode ierr;
1175c1490034SHong Zhang   PetscMPIInt    size;
1176a58c3f20SHong Zhang 
1177a58c3f20SHong Zhang   PetscFunctionBegin;
1178ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)F),&size);CHKERRQ(ierr);
1179bcb30aebSHong 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 */
1180a5e57a09SHong Zhang   if (size > 1 && mumps->id.ICNTL(13) != 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"ICNTL(13)=%d. -mat_mumps_icntl_13 must be set as 1 for correct global matrix inertia\n",mumps->id.INFOG(13));
1181ed85ac9fSHong Zhang 
1182710ac8efSHong Zhang   if (nneg) *nneg = mumps->id.INFOG(12);
1183ed85ac9fSHong Zhang   if (nzero || npos) {
1184ed85ac9fSHong Zhang     if (mumps->id.ICNTL(24) != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"-mat_mumps_icntl_24 must be set as 1 for null pivot row detection");
1185710ac8efSHong Zhang     if (nzero) *nzero = mumps->id.INFOG(28);
1186710ac8efSHong Zhang     if (npos) *npos   = F->rmap->N - (mumps->id.INFOG(12) + mumps->id.INFOG(28));
1187a58c3f20SHong Zhang   }
1188a58c3f20SHong Zhang   PetscFunctionReturn(0);
1189a58c3f20SHong Zhang }
1190ace3df97SHong Zhang #endif /* !defined(PETSC_USE_COMPLEX) */
1191a58c3f20SHong Zhang 
1192397b6df1SKris Buschelman #undef __FUNCT__
1193f6c57405SHong Zhang #define __FUNCT__ "MatFactorNumeric_MUMPS"
11949a625307SHong Zhang PetscErrorCode MatFactorNumeric_MUMPS(Mat F,Mat A,const MatFactorInfo *info)
1195af281ebdSHong Zhang {
1196a5e57a09SHong Zhang   Mat_MUMPS      *mumps =(Mat_MUMPS*)(F)->spptr;
11976849ba73SBarry Smith   PetscErrorCode ierr;
1198e09efc27SHong Zhang   Mat            F_diag;
1199ace3abfcSBarry Smith   PetscBool      isMPIAIJ;
1200397b6df1SKris Buschelman 
1201397b6df1SKris Buschelman   PetscFunctionBegin;
12026baea169SHong Zhang   if (mumps->id.INFOG(1) < 0) {
12032aca8efcSHong Zhang     if (mumps->id.INFOG(1) == -6) {
12042aca8efcSHong Zhang       ierr = PetscInfo2(A,"MatFactorNumeric is called with singular matrix structure, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
12056baea169SHong Zhang     }
12066baea169SHong Zhang     ierr = PetscInfo2(A,"MatFactorNumeric is called after analysis phase fails, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
12072aca8efcSHong Zhang     PetscFunctionReturn(0);
12082aca8efcSHong Zhang   }
12096baea169SHong Zhang 
1210a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_REUSE_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1211397b6df1SKris Buschelman 
1212397b6df1SKris Buschelman   /* numerical factorization phase */
1213329ec9b3SHong Zhang   /*-------------------------------*/
1214a5e57a09SHong Zhang   mumps->id.job = JOB_FACTNUMERIC;
12154e34a73bSHong Zhang   if (!mumps->id.ICNTL(18)) { /* A is centralized */
1216a5e57a09SHong Zhang     if (!mumps->myid) {
1217940cd9d6SSatish Balay       mumps->id.a = (MumpsScalar*)mumps->val;
1218397b6df1SKris Buschelman     }
1219397b6df1SKris Buschelman   } else {
1220940cd9d6SSatish Balay     mumps->id.a_loc = (MumpsScalar*)mumps->val;
1221397b6df1SKris Buschelman   }
1222a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1223a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) {
1224c0d63f2fSHong Zhang     if (A->erroriffailure) {
1225c0d63f2fSHong Zhang       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));
1226c0d63f2fSHong Zhang     } else {
1227c0d63f2fSHong Zhang       if (mumps->id.INFOG(1) == -10) { /* numerically singular matrix */
12282aca8efcSHong Zhang         ierr = PetscInfo2(F,"matrix is numerically singular, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1229680c5173SHong Zhang         F->errortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
1230c0d63f2fSHong Zhang       } else if (mumps->id.INFOG(1) == -13) {
1231c0d63f2fSHong Zhang         ierr = PetscInfo2(F,"MUMPS in numerical factorization phase: INFOG(1)=%d, cannot allocate required memory %d megabytes\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1232680c5173SHong Zhang         F->errortype = MAT_FACTOR_OUTMEMORY;
1233c0d63f2fSHong Zhang       } else if (mumps->id.INFOG(1) == -8 || mumps->id.INFOG(1) == -9 || (-16 < mumps->id.INFOG(1) && mumps->id.INFOG(1) < -10) ) {
1234c0d63f2fSHong Zhang         ierr = PetscInfo2(F,"MUMPS in numerical factorization phase: INFOG(1)=%d, INFO(2)=%d, problem with workarray \n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1235680c5173SHong Zhang         F->errortype = MAT_FACTOR_OUTMEMORY;
12362aca8efcSHong Zhang       } else {
1237c0d63f2fSHong Zhang         ierr = PetscInfo2(F,"MUMPS in numerical factorization phase: INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1238680c5173SHong Zhang         F->errortype = MAT_FACTOR_OTHER;
12392aca8efcSHong Zhang       }
12402aca8efcSHong Zhang     }
1241397b6df1SKris Buschelman   }
1242a5e57a09SHong Zhang   if (!mumps->myid && mumps->id.ICNTL(16) > 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"  mumps->id.ICNTL(16):=%d\n",mumps->id.INFOG(16));
1243397b6df1SKris Buschelman 
1244dcd589f8SShri Abhyankar   (F)->assembled        = PETSC_TRUE;
1245a5e57a09SHong Zhang   mumps->matstruc       = SAME_NONZERO_PATTERN;
1246b5fa320bSStefano Zampini   mumps->schur_factored = PETSC_FALSE;
124759ac8732SStefano Zampini   mumps->schur_inverted = PETSC_FALSE;
124867877ebaSShri Abhyankar 
1249066565c5SStefano Zampini   /* just to be sure that ICNTL(19) value returned by a call from MatMumpsGetIcntl is always consistent */
1250066565c5SStefano Zampini   if (!mumps->sym && mumps->id.ICNTL(19) && mumps->id.ICNTL(19) != 1) mumps->id.ICNTL(19) = 3;
1251066565c5SStefano Zampini 
1252a5e57a09SHong Zhang   if (mumps->size > 1) {
125367877ebaSShri Abhyankar     PetscInt    lsol_loc;
125467877ebaSShri Abhyankar     PetscScalar *sol_loc;
12552205254eSKarl Rupp 
1256c2093ab7SHong Zhang     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
1257c2093ab7SHong Zhang     if (isMPIAIJ) F_diag = ((Mat_MPIAIJ*)(F)->data)->A;
1258c2093ab7SHong Zhang     else F_diag = ((Mat_MPISBAIJ*)(F)->data)->A;
1259c2093ab7SHong Zhang     F_diag->assembled = PETSC_TRUE;
1260c2093ab7SHong Zhang 
1261c2093ab7SHong Zhang     /* distributed solution; Create x_seq=sol_loc for repeated use */
1262c2093ab7SHong Zhang     if (mumps->x_seq) {
1263c2093ab7SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
1264c2093ab7SHong Zhang       ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
1265c2093ab7SHong Zhang       ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
1266c2093ab7SHong Zhang     }
1267a5e57a09SHong Zhang     lsol_loc = mumps->id.INFO(23); /* length of sol_loc */
1268dcca6d9dSJed Brown     ierr = PetscMalloc2(lsol_loc,&sol_loc,lsol_loc,&mumps->id.isol_loc);CHKERRQ(ierr);
1269a5e57a09SHong Zhang     mumps->id.lsol_loc = lsol_loc;
1270940cd9d6SSatish Balay     mumps->id.sol_loc = (MumpsScalar*)sol_loc;
1271a5e57a09SHong Zhang     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lsol_loc,sol_loc,&mumps->x_seq);CHKERRQ(ierr);
127267877ebaSShri Abhyankar   }
1273397b6df1SKris Buschelman   PetscFunctionReturn(0);
1274397b6df1SKris Buschelman }
1275397b6df1SKris Buschelman 
12769a2535b5SHong Zhang /* Sets MUMPS options from the options database */
1277dcd589f8SShri Abhyankar #undef __FUNCT__
12789a2535b5SHong Zhang #define __FUNCT__ "PetscSetMUMPSFromOptions"
12799a2535b5SHong Zhang PetscErrorCode PetscSetMUMPSFromOptions(Mat F, Mat A)
1280dcd589f8SShri Abhyankar {
12819a2535b5SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1282dcd589f8SShri Abhyankar   PetscErrorCode ierr;
1283b34f08ffSHong Zhang   PetscInt       icntl,info[40],i,ninfo=40;
1284ace3abfcSBarry Smith   PetscBool      flg;
1285dcd589f8SShri Abhyankar 
1286dcd589f8SShri Abhyankar   PetscFunctionBegin;
1287ce94432eSBarry Smith   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr);
12889a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_1","ICNTL(1): output stream for error messages","None",mumps->id.ICNTL(1),&icntl,&flg);CHKERRQ(ierr);
12899a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(1) = icntl;
12909a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_2","ICNTL(2): output stream for diagnostic printing, statistics, and warning","None",mumps->id.ICNTL(2),&icntl,&flg);CHKERRQ(ierr);
12919a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(2) = icntl;
12929a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_3","ICNTL(3): output stream for global information, collected on the host","None",mumps->id.ICNTL(3),&icntl,&flg);CHKERRQ(ierr);
12939a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(3) = icntl;
1294dcd589f8SShri Abhyankar 
12959a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",mumps->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr);
12969a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(4) = icntl;
12979a2535b5SHong Zhang   if (mumps->id.ICNTL(4) || PetscLogPrintInfo) mumps->id.ICNTL(3) = 6; /* resume MUMPS default id.ICNTL(3) = 6 */
12989a2535b5SHong Zhang 
1299d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_6","ICNTL(6): permutes to a zero-free diagonal and/or scale the matrix (0 to 7)","None",mumps->id.ICNTL(6),&icntl,&flg);CHKERRQ(ierr);
13009a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(6) = icntl;
13019a2535b5SHong Zhang 
1302d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_7","ICNTL(7): computes a symmetric permutation in sequential analysis (0 to 7). 3=Scotch, 4=PORD, 5=Metis","None",mumps->id.ICNTL(7),&icntl,&flg);CHKERRQ(ierr);
1303dcd589f8SShri Abhyankar   if (flg) {
13042205254eSKarl Rupp     if (icntl== 1 && mumps->size > 1) 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");
13052205254eSKarl Rupp     else mumps->id.ICNTL(7) = icntl;
1306dcd589f8SShri Abhyankar   }
1307e0b74bf9SHong Zhang 
13080298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_8","ICNTL(8): scaling strategy (-2 to 8 or 77)","None",mumps->id.ICNTL(8),&mumps->id.ICNTL(8),NULL);CHKERRQ(ierr);
1309d341cd04SHong Zhang   /* ierr = PetscOptionsInt("-mat_mumps_icntl_9","ICNTL(9): computes the solution using A or A^T","None",mumps->id.ICNTL(9),&mumps->id.ICNTL(9),NULL);CHKERRQ(ierr); handled by MatSolveTranspose_MUMPS() */
13100298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_10","ICNTL(10): max num of refinements","None",mumps->id.ICNTL(10),&mumps->id.ICNTL(10),NULL);CHKERRQ(ierr);
1311d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_11","ICNTL(11): statistics related to an error analysis (via -ksp_view)","None",mumps->id.ICNTL(11),&mumps->id.ICNTL(11),NULL);CHKERRQ(ierr);
1312d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_12","ICNTL(12): an ordering strategy for symmetric matrices (0 to 3)","None",mumps->id.ICNTL(12),&mumps->id.ICNTL(12),NULL);CHKERRQ(ierr);
1313d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_13","ICNTL(13): parallelism of the root node (enable ScaLAPACK) and its splitting","None",mumps->id.ICNTL(13),&mumps->id.ICNTL(13),NULL);CHKERRQ(ierr);
1314d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_14","ICNTL(14): percentage increase in the estimated working space","None",mumps->id.ICNTL(14),&mumps->id.ICNTL(14),NULL);CHKERRQ(ierr);
1315d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_19","ICNTL(19): computes the Schur complement","None",mumps->id.ICNTL(19),&mumps->id.ICNTL(19),NULL);CHKERRQ(ierr);
131659ac8732SStefano Zampini   if (mumps->id.ICNTL(19) <= 0 || mumps->id.ICNTL(19) > 3) { /* reset any schur data (if any) */
131759ac8732SStefano Zampini     ierr = MatMumpsResetSchur_Private(mumps);CHKERRQ(ierr);
131859ac8732SStefano Zampini   }
13194e34a73bSHong Zhang   /* ierr = PetscOptionsInt("-mat_mumps_icntl_20","ICNTL(20): the format (dense or sparse) of the right-hand sides","None",mumps->id.ICNTL(20),&mumps->id.ICNTL(20),NULL);CHKERRQ(ierr); -- sparse rhs is not supported in PETSc API */
1320d341cd04SHong Zhang   /* ierr = PetscOptionsInt("-mat_mumps_icntl_21","ICNTL(21): the distribution (centralized or distributed) of the solution vectors","None",mumps->id.ICNTL(21),&mumps->id.ICNTL(21),NULL);CHKERRQ(ierr); we only use distributed solution vector */
13219a2535b5SHong Zhang 
1322d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_22","ICNTL(22): in-core/out-of-core factorization and solve (0 or 1)","None",mumps->id.ICNTL(22),&mumps->id.ICNTL(22),NULL);CHKERRQ(ierr);
13230298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_23","ICNTL(23): max size of the working memory (MB) that can allocate per processor","None",mumps->id.ICNTL(23),&mumps->id.ICNTL(23),NULL);CHKERRQ(ierr);
13240298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_24","ICNTL(24): detection of null pivot rows (0 or 1)","None",mumps->id.ICNTL(24),&mumps->id.ICNTL(24),NULL);CHKERRQ(ierr);
13259a2535b5SHong Zhang   if (mumps->id.ICNTL(24)) {
13269a2535b5SHong Zhang     mumps->id.ICNTL(13) = 1; /* turn-off ScaLAPACK to help with the correct detection of null pivots */
1327d7ebd59bSHong Zhang   }
1328d7ebd59bSHong Zhang 
1329d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_25","ICNTL(25): compute a solution of a deficient matrix and a null space basis","None",mumps->id.ICNTL(25),&mumps->id.ICNTL(25),NULL);CHKERRQ(ierr);
1330d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_26","ICNTL(26): drives the solution phase if a Schur complement matrix","None",mumps->id.ICNTL(26),&mumps->id.ICNTL(26),NULL);CHKERRQ(ierr);
13312cd7d884SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_27","ICNTL(27): the blocking size for multiple right-hand sides","None",mumps->id.ICNTL(27),&mumps->id.ICNTL(27),NULL);CHKERRQ(ierr);
13320298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_28","ICNTL(28): use 1 for sequential analysis and ictnl(7) ordering, or 2 for parallel analysis and ictnl(29) ordering","None",mumps->id.ICNTL(28),&mumps->id.ICNTL(28),NULL);CHKERRQ(ierr);
1333d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_29","ICNTL(29): parallel ordering 1 = ptscotch, 2 = parmetis","None",mumps->id.ICNTL(29),&mumps->id.ICNTL(29),NULL);CHKERRQ(ierr);
13340298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_30","ICNTL(30): compute user-specified set of entries in inv(A)","None",mumps->id.ICNTL(30),&mumps->id.ICNTL(30),NULL);CHKERRQ(ierr);
1335d341cd04SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_31","ICNTL(31): indicates which factors may be discarded during factorization","None",mumps->id.ICNTL(31),&mumps->id.ICNTL(31),NULL);CHKERRQ(ierr);
13364e34a73bSHong Zhang   /* ierr = PetscOptionsInt("-mat_mumps_icntl_32","ICNTL(32): performs the forward elemination of the right-hand sides during factorization","None",mumps->id.ICNTL(32),&mumps->id.ICNTL(32),NULL);CHKERRQ(ierr);  -- not supported by PETSc API */
13370298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_33","ICNTL(33): compute determinant","None",mumps->id.ICNTL(33),&mumps->id.ICNTL(33),NULL);CHKERRQ(ierr);
1338dcd589f8SShri Abhyankar 
13390298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_1","CNTL(1): relative pivoting threshold","None",mumps->id.CNTL(1),&mumps->id.CNTL(1),NULL);CHKERRQ(ierr);
13400298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_2","CNTL(2): stopping criterion of refinement","None",mumps->id.CNTL(2),&mumps->id.CNTL(2),NULL);CHKERRQ(ierr);
13410298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_3","CNTL(3): absolute pivoting threshold","None",mumps->id.CNTL(3),&mumps->id.CNTL(3),NULL);CHKERRQ(ierr);
13420298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_4","CNTL(4): value for static pivoting","None",mumps->id.CNTL(4),&mumps->id.CNTL(4),NULL);CHKERRQ(ierr);
13430298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_5","CNTL(5): fixation for null pivots","None",mumps->id.CNTL(5),&mumps->id.CNTL(5),NULL);CHKERRQ(ierr);
1344e5bb22a1SHong Zhang 
13450298fd71SBarry Smith   ierr = PetscOptionsString("-mat_mumps_ooc_tmpdir", "out of core directory", "None", mumps->id.ooc_tmpdir, mumps->id.ooc_tmpdir, 256, NULL);
1346b34f08ffSHong Zhang 
134716d797efSHong Zhang   ierr = PetscOptionsIntArray("-mat_mumps_view_info","request INFO local to each processor","",info,&ninfo,NULL);CHKERRQ(ierr);
1348b34f08ffSHong Zhang   if (ninfo) {
1349b34f08ffSHong Zhang     if (ninfo > 40) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"number of INFO %d must <= 40\n",ninfo);
1350b34f08ffSHong Zhang     ierr = PetscMalloc1(ninfo,&mumps->info);CHKERRQ(ierr);
1351b34f08ffSHong Zhang     mumps->ninfo = ninfo;
1352b34f08ffSHong Zhang     for (i=0; i<ninfo; i++) {
13536c4ed002SBarry Smith       if (info[i] < 0 || info[i]>40) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index of INFO %d must between 1 and 40\n",ninfo);
13546c4ed002SBarry Smith       else {
1355b34f08ffSHong Zhang         mumps->info[i] = info[i];
1356b34f08ffSHong Zhang       }
1357b34f08ffSHong Zhang     }
1358b34f08ffSHong Zhang   }
1359b34f08ffSHong Zhang 
1360dcd589f8SShri Abhyankar   PetscOptionsEnd();
1361dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
1362dcd589f8SShri Abhyankar }
1363dcd589f8SShri Abhyankar 
1364dcd589f8SShri Abhyankar #undef __FUNCT__
1365dcd589f8SShri Abhyankar #define __FUNCT__ "PetscInitializeMUMPS"
1366f697e70eSHong Zhang PetscErrorCode PetscInitializeMUMPS(Mat A,Mat_MUMPS *mumps)
1367dcd589f8SShri Abhyankar {
1368dcd589f8SShri Abhyankar   PetscErrorCode ierr;
1369dcd589f8SShri Abhyankar 
1370dcd589f8SShri Abhyankar   PetscFunctionBegin;
1371ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &mumps->myid);
1372ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&mumps->size);CHKERRQ(ierr);
1373ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)A),&(mumps->comm_mumps));CHKERRQ(ierr);
13742205254eSKarl Rupp 
1375f697e70eSHong Zhang   mumps->id.comm_fortran = MPI_Comm_c2f(mumps->comm_mumps);
1376f697e70eSHong Zhang 
1377f697e70eSHong Zhang   mumps->id.job = JOB_INIT;
1378f697e70eSHong Zhang   mumps->id.par = 1;  /* host participates factorizaton and solve */
1379f697e70eSHong Zhang   mumps->id.sym = mumps->sym;
13802907cef9SHong Zhang   PetscMUMPS_c(&mumps->id);
1381f697e70eSHong Zhang 
13820298fd71SBarry Smith   mumps->scat_rhs     = NULL;
13830298fd71SBarry Smith   mumps->scat_sol     = NULL;
13849a2535b5SHong Zhang 
138570544d5fSHong Zhang   /* set PETSc-MUMPS default options - override MUMPS default */
13869a2535b5SHong Zhang   mumps->id.ICNTL(3) = 0;
13879a2535b5SHong Zhang   mumps->id.ICNTL(4) = 0;
13889a2535b5SHong Zhang   if (mumps->size == 1) {
13899a2535b5SHong Zhang     mumps->id.ICNTL(18) = 0;   /* centralized assembled matrix input */
13909a2535b5SHong Zhang   } else {
13919a2535b5SHong Zhang     mumps->id.ICNTL(18) = 3;   /* distributed assembled matrix input */
13924e34a73bSHong Zhang     mumps->id.ICNTL(20) = 0;   /* rhs is in dense format */
139370544d5fSHong Zhang     mumps->id.ICNTL(21) = 1;   /* distributed solution */
13949a2535b5SHong Zhang   }
13956444a565SStefano Zampini 
13966444a565SStefano Zampini   /* schur */
13976444a565SStefano Zampini   mumps->id.size_schur      = 0;
13986444a565SStefano Zampini   mumps->id.listvar_schur   = NULL;
13996444a565SStefano Zampini   mumps->id.schur           = NULL;
1400b5fa320bSStefano Zampini   mumps->sizeredrhs         = 0;
1401b5fa320bSStefano Zampini   mumps->schur_pivots       = NULL;
1402b5fa320bSStefano Zampini   mumps->schur_work         = NULL;
140359ac8732SStefano Zampini   mumps->schur_sol          = NULL;
140459ac8732SStefano Zampini   mumps->schur_sizesol      = 0;
140559ac8732SStefano Zampini   mumps->schur_factored     = PETSC_FALSE;
140659ac8732SStefano Zampini   mumps->schur_inverted     = PETSC_FALSE;
1407dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
1408dcd589f8SShri Abhyankar }
1409dcd589f8SShri Abhyankar 
14105cd7cf9dSHong Zhang #undef __FUNCT__
14115cd7cf9dSHong Zhang #define __FUNCT__ "MatFactorSymbolic_MUMPS_ReportIfError"
14129a625307SHong Zhang PetscErrorCode MatFactorSymbolic_MUMPS_ReportIfError(Mat F,Mat A,const MatFactorInfo *info,Mat_MUMPS *mumps)
14135cd7cf9dSHong Zhang {
14145cd7cf9dSHong Zhang   PetscErrorCode ierr;
14155cd7cf9dSHong Zhang 
14165cd7cf9dSHong Zhang   PetscFunctionBegin;
14175cd7cf9dSHong Zhang   if (mumps->id.INFOG(1) < 0) {
14185cd7cf9dSHong Zhang     if (A->erroriffailure) {
14195cd7cf9dSHong Zhang       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
14205cd7cf9dSHong Zhang     } else {
14215cd7cf9dSHong Zhang       if (mumps->id.INFOG(1) == -6) {
14225cd7cf9dSHong Zhang         ierr = PetscInfo2(F,"matrix is singular in structure, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1423680c5173SHong Zhang         F->errortype = MAT_FACTOR_STRUCT_ZEROPIVOT;
14245cd7cf9dSHong Zhang       } else if (mumps->id.INFOG(1) == -5 || mumps->id.INFOG(1) == -7) {
14255cd7cf9dSHong Zhang         ierr = PetscInfo2(F,"problem of workspace, INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1426680c5173SHong Zhang         F->errortype = MAT_FACTOR_OUTMEMORY;
14275cd7cf9dSHong Zhang       } else {
14285cd7cf9dSHong Zhang         ierr = PetscInfo2(F,"Error reported by MUMPS in analysis phase: INFOG(1)=%d, INFO(2)=%d\n",mumps->id.INFOG(1),mumps->id.INFO(2));CHKERRQ(ierr);
1429680c5173SHong Zhang         F->errortype = MAT_FACTOR_OTHER;
14305cd7cf9dSHong Zhang       }
14315cd7cf9dSHong Zhang     }
14325cd7cf9dSHong Zhang   }
14335cd7cf9dSHong Zhang   PetscFunctionReturn(0);
14345cd7cf9dSHong Zhang }
14355cd7cf9dSHong Zhang 
1436a5e57a09SHong Zhang /* Note Petsc r(=c) permutation is used when mumps->id.ICNTL(7)==1 with centralized assembled matrix input; otherwise r and c are ignored */
1437397b6df1SKris Buschelman #undef __FUNCT__
1438f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS"
14399a625307SHong Zhang PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1440b24902e0SBarry Smith {
1441a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1442dcd589f8SShri Abhyankar   PetscErrorCode ierr;
144367877ebaSShri Abhyankar   Vec            b;
144467877ebaSShri Abhyankar   IS             is_iden;
144567877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1446397b6df1SKris Buschelman 
1447397b6df1SKris Buschelman   PetscFunctionBegin;
1448a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1449dcd589f8SShri Abhyankar 
14509a2535b5SHong Zhang   /* Set MUMPS options from the options database */
14519a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1452dcd589f8SShri Abhyankar 
1453a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1454dcd589f8SShri Abhyankar 
145567877ebaSShri Abhyankar   /* analysis phase */
145667877ebaSShri Abhyankar   /*----------------*/
1457a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1458a5e57a09SHong Zhang   mumps->id.n   = M;
1459a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
146067877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1461a5e57a09SHong Zhang     if (!mumps->myid) {
1462a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1463a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1464940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
146567877ebaSShri Abhyankar       }
1466a5e57a09SHong Zhang       if (mumps->id.ICNTL(7) == 1) { /* use user-provide matrix ordering - assuming r = c ordering */
14675248a706SHong Zhang         /*
14685248a706SHong Zhang         PetscBool      flag;
14695248a706SHong Zhang         ierr = ISEqual(r,c,&flag);CHKERRQ(ierr);
14705248a706SHong Zhang         if (!flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"row_perm != col_perm");
14715248a706SHong Zhang         ierr = ISView(r,PETSC_VIEWER_STDOUT_SELF);
14725248a706SHong Zhang          */
1473a5e57a09SHong Zhang         if (!mumps->myid) {
1474e0b74bf9SHong Zhang           const PetscInt *idx;
1475e0b74bf9SHong Zhang           PetscInt       i,*perm_in;
14762205254eSKarl Rupp 
1477785e854fSJed Brown           ierr = PetscMalloc1(M,&perm_in);CHKERRQ(ierr);
1478e0b74bf9SHong Zhang           ierr = ISGetIndices(r,&idx);CHKERRQ(ierr);
14792205254eSKarl Rupp 
1480a5e57a09SHong Zhang           mumps->id.perm_in = perm_in;
1481e0b74bf9SHong Zhang           for (i=0; i<M; i++) perm_in[i] = idx[i]+1; /* perm_in[]: start from 1, not 0! */
1482e0b74bf9SHong Zhang           ierr = ISRestoreIndices(r,&idx);CHKERRQ(ierr);
1483e0b74bf9SHong Zhang         }
1484e0b74bf9SHong Zhang       }
148567877ebaSShri Abhyankar     }
148667877ebaSShri Abhyankar     break;
148767877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1488a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1489a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1490a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1491940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
149267877ebaSShri Abhyankar     }
149367877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1494a5e57a09SHong Zhang     if (!mumps->myid) {
14952cd7d884SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->rmap->N,&mumps->b_seq);CHKERRQ(ierr);
14962cd7d884SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->N,0,1,&is_iden);CHKERRQ(ierr);
149767877ebaSShri Abhyankar     } else {
1498a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
149967877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
150067877ebaSShri Abhyankar     }
15012a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1502a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
15036bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
15046bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
150567877ebaSShri Abhyankar     break;
150667877ebaSShri Abhyankar   }
1507a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
15085cd7cf9dSHong Zhang   ierr = MatFactorSymbolic_MUMPS_ReportIfError(F,A,info,mumps);CHKERRQ(ierr);
150967877ebaSShri Abhyankar 
1510719d5645SBarry Smith   F->ops->lufactornumeric = MatFactorNumeric_MUMPS;
1511dcd589f8SShri Abhyankar   F->ops->solve           = MatSolve_MUMPS;
151251d5961aSHong Zhang   F->ops->solvetranspose  = MatSolveTranspose_MUMPS;
15134e34a73bSHong Zhang   F->ops->matsolve        = MatMatSolve_MUMPS;
1514b24902e0SBarry Smith   PetscFunctionReturn(0);
1515b24902e0SBarry Smith }
1516b24902e0SBarry Smith 
1517450b117fSShri Abhyankar /* Note the Petsc r and c permutations are ignored */
1518450b117fSShri Abhyankar #undef __FUNCT__
1519450b117fSShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_BAIJMUMPS"
15209a625307SHong Zhang PetscErrorCode MatLUFactorSymbolic_BAIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1521450b117fSShri Abhyankar {
1522a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1523dcd589f8SShri Abhyankar   PetscErrorCode ierr;
152467877ebaSShri Abhyankar   Vec            b;
152567877ebaSShri Abhyankar   IS             is_iden;
152667877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1527450b117fSShri Abhyankar 
1528450b117fSShri Abhyankar   PetscFunctionBegin;
1529a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1530dcd589f8SShri Abhyankar 
15319a2535b5SHong Zhang   /* Set MUMPS options from the options database */
15329a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1533dcd589f8SShri Abhyankar 
1534a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
153567877ebaSShri Abhyankar 
153667877ebaSShri Abhyankar   /* analysis phase */
153767877ebaSShri Abhyankar   /*----------------*/
1538a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1539a5e57a09SHong Zhang   mumps->id.n   = M;
1540a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
154167877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1542a5e57a09SHong Zhang     if (!mumps->myid) {
1543a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1544a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1545940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
154667877ebaSShri Abhyankar       }
154767877ebaSShri Abhyankar     }
154867877ebaSShri Abhyankar     break;
154967877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1550a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1551a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1552a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1553940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
155467877ebaSShri Abhyankar     }
155567877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1556a5e57a09SHong Zhang     if (!mumps->myid) {
1557a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
155867877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
155967877ebaSShri Abhyankar     } else {
1560a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
156167877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
156267877ebaSShri Abhyankar     }
15632a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1564a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
15656bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
15666bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
156767877ebaSShri Abhyankar     break;
156867877ebaSShri Abhyankar   }
1569a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
15705cd7cf9dSHong Zhang   ierr = MatFactorSymbolic_MUMPS_ReportIfError(F,A,info,mumps);CHKERRQ(ierr);
157167877ebaSShri Abhyankar 
1572450b117fSShri Abhyankar   F->ops->lufactornumeric = MatFactorNumeric_MUMPS;
1573dcd589f8SShri Abhyankar   F->ops->solve           = MatSolve_MUMPS;
157451d5961aSHong Zhang   F->ops->solvetranspose  = MatSolveTranspose_MUMPS;
1575450b117fSShri Abhyankar   PetscFunctionReturn(0);
1576450b117fSShri Abhyankar }
1577b24902e0SBarry Smith 
1578141f4205SHong Zhang /* Note the Petsc r permutation and factor info are ignored */
1579397b6df1SKris Buschelman #undef __FUNCT__
158067877ebaSShri Abhyankar #define __FUNCT__ "MatCholeskyFactorSymbolic_MUMPS"
15819a625307SHong Zhang PetscErrorCode MatCholeskyFactorSymbolic_MUMPS(Mat F,Mat A,IS r,const MatFactorInfo *info)
1582b24902e0SBarry Smith {
1583a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1584dcd589f8SShri Abhyankar   PetscErrorCode ierr;
158567877ebaSShri Abhyankar   Vec            b;
158667877ebaSShri Abhyankar   IS             is_iden;
158767877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1588397b6df1SKris Buschelman 
1589397b6df1SKris Buschelman   PetscFunctionBegin;
1590a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1591dcd589f8SShri Abhyankar 
15929a2535b5SHong Zhang   /* Set MUMPS options from the options database */
15939a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1594dcd589f8SShri Abhyankar 
1595a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1596dcd589f8SShri Abhyankar 
159767877ebaSShri Abhyankar   /* analysis phase */
159867877ebaSShri Abhyankar   /*----------------*/
1599a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1600a5e57a09SHong Zhang   mumps->id.n   = M;
1601a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
160267877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1603a5e57a09SHong Zhang     if (!mumps->myid) {
1604a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1605a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1606940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
160767877ebaSShri Abhyankar       }
160867877ebaSShri Abhyankar     }
160967877ebaSShri Abhyankar     break;
161067877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1611a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1612a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1613a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1614940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
161567877ebaSShri Abhyankar     }
161667877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1617a5e57a09SHong Zhang     if (!mumps->myid) {
1618a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
161967877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
162067877ebaSShri Abhyankar     } else {
1621a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
162267877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
162367877ebaSShri Abhyankar     }
16242a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1625a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
16266bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
16276bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
162867877ebaSShri Abhyankar     break;
162967877ebaSShri Abhyankar   }
1630a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
16315cd7cf9dSHong Zhang   ierr = MatFactorSymbolic_MUMPS_ReportIfError(F,A,info,mumps);CHKERRQ(ierr);
16325cd7cf9dSHong Zhang 
163367877ebaSShri Abhyankar 
16342792810eSHong Zhang   F->ops->choleskyfactornumeric = MatFactorNumeric_MUMPS;
1635dcd589f8SShri Abhyankar   F->ops->solve                 = MatSolve_MUMPS;
163651d5961aSHong Zhang   F->ops->solvetranspose        = MatSolve_MUMPS;
16374e34a73bSHong Zhang   F->ops->matsolve              = MatMatSolve_MUMPS;
16384e34a73bSHong Zhang #if defined(PETSC_USE_COMPLEX)
16390298fd71SBarry Smith   F->ops->getinertia = NULL;
16404e34a73bSHong Zhang #else
16414e34a73bSHong Zhang   F->ops->getinertia = MatGetInertia_SBAIJMUMPS;
1642db4efbfdSBarry Smith #endif
1643b24902e0SBarry Smith   PetscFunctionReturn(0);
1644b24902e0SBarry Smith }
1645b24902e0SBarry Smith 
1646397b6df1SKris Buschelman #undef __FUNCT__
164764e6c443SBarry Smith #define __FUNCT__ "MatView_MUMPS"
164864e6c443SBarry Smith PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer)
164974ed9c26SBarry Smith {
1650f6c57405SHong Zhang   PetscErrorCode    ierr;
165164e6c443SBarry Smith   PetscBool         iascii;
165264e6c443SBarry Smith   PetscViewerFormat format;
1653a5e57a09SHong Zhang   Mat_MUMPS         *mumps=(Mat_MUMPS*)A->spptr;
1654f6c57405SHong Zhang 
1655f6c57405SHong Zhang   PetscFunctionBegin;
165664e6c443SBarry Smith   /* check if matrix is mumps type */
165764e6c443SBarry Smith   if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0);
165864e6c443SBarry Smith 
1659251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
166064e6c443SBarry Smith   if (iascii) {
166164e6c443SBarry Smith     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
166264e6c443SBarry Smith     if (format == PETSC_VIEWER_ASCII_INFO) {
166364e6c443SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr);
1664a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  SYM (matrix type):                   %d \n",mumps->id.sym);CHKERRQ(ierr);
1665a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  PAR (host participation):            %d \n",mumps->id.par);CHKERRQ(ierr);
1666a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(1) (output for error):         %d \n",mumps->id.ICNTL(1));CHKERRQ(ierr);
1667a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(2) (output of diagnostic msg): %d \n",mumps->id.ICNTL(2));CHKERRQ(ierr);
1668a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(3) (output for global info):   %d \n",mumps->id.ICNTL(3));CHKERRQ(ierr);
1669a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(4) (level of printing):        %d \n",mumps->id.ICNTL(4));CHKERRQ(ierr);
1670a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(5) (input mat struct):         %d \n",mumps->id.ICNTL(5));CHKERRQ(ierr);
1671a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(6) (matrix prescaling):        %d \n",mumps->id.ICNTL(6));CHKERRQ(ierr);
1672*d4ed72bbSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(7) (sequential matrix ordering):%d \n",mumps->id.ICNTL(7));CHKERRQ(ierr);
1673*d4ed72bbSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(8) (scaling strategy):        %d \n",mumps->id.ICNTL(8));CHKERRQ(ierr);
1674a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(10) (max num of refinements):  %d \n",mumps->id.ICNTL(10));CHKERRQ(ierr);
1675a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(11) (error analysis):          %d \n",mumps->id.ICNTL(11));CHKERRQ(ierr);
1676a5e57a09SHong Zhang       if (mumps->id.ICNTL(11)>0) {
1677a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(4) (inf norm of input mat):        %g\n",mumps->id.RINFOG(4));CHKERRQ(ierr);
1678a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(5) (inf norm of solution):         %g\n",mumps->id.RINFOG(5));CHKERRQ(ierr);
1679a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(6) (inf norm of residual):         %g\n",mumps->id.RINFOG(6));CHKERRQ(ierr);
1680a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(7),RINFOG(8) (backward error est): %g, %g\n",mumps->id.RINFOG(7),mumps->id.RINFOG(8));CHKERRQ(ierr);
1681a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(9) (error estimate):               %g \n",mumps->id.RINFOG(9));CHKERRQ(ierr);
1682a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(10),RINFOG(11)(condition numbers): %g, %g\n",mumps->id.RINFOG(10),mumps->id.RINFOG(11));CHKERRQ(ierr);
1683f6c57405SHong Zhang       }
1684a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(12) (efficiency control):                         %d \n",mumps->id.ICNTL(12));CHKERRQ(ierr);
1685a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(13) (efficiency control):                         %d \n",mumps->id.ICNTL(13));CHKERRQ(ierr);
1686a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(14) (percentage of estimated workspace increase): %d \n",mumps->id.ICNTL(14));CHKERRQ(ierr);
1687f6c57405SHong Zhang       /* ICNTL(15-17) not used */
1688a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(18) (input mat struct):                           %d \n",mumps->id.ICNTL(18));CHKERRQ(ierr);
1689*d4ed72bbSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(19) (Schur complement info):                       %d \n",mumps->id.ICNTL(19));CHKERRQ(ierr);
1690a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(20) (rhs sparse pattern):                         %d \n",mumps->id.ICNTL(20));CHKERRQ(ierr);
1691ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(21) (solution struct):                            %d \n",mumps->id.ICNTL(21));CHKERRQ(ierr);
1692a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(22) (in-core/out-of-core facility):               %d \n",mumps->id.ICNTL(22));CHKERRQ(ierr);
1693a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(23) (max size of memory can be allocated locally):%d \n",mumps->id.ICNTL(23));CHKERRQ(ierr);
1694c0165424SHong Zhang 
1695a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(24) (detection of null pivot rows):               %d \n",mumps->id.ICNTL(24));CHKERRQ(ierr);
1696a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(25) (computation of a null space basis):          %d \n",mumps->id.ICNTL(25));CHKERRQ(ierr);
1697a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(26) (Schur options for rhs or solution):          %d \n",mumps->id.ICNTL(26));CHKERRQ(ierr);
1698a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(27) (experimental parameter):                     %d \n",mumps->id.ICNTL(27));CHKERRQ(ierr);
1699a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(28) (use parallel or sequential ordering):        %d \n",mumps->id.ICNTL(28));CHKERRQ(ierr);
1700a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(29) (parallel ordering):                          %d \n",mumps->id.ICNTL(29));CHKERRQ(ierr);
170142179a6aSHong Zhang 
1702a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(30) (user-specified set of entries in inv(A)):    %d \n",mumps->id.ICNTL(30));CHKERRQ(ierr);
1703a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(31) (factors is discarded in the solve phase):    %d \n",mumps->id.ICNTL(31));CHKERRQ(ierr);
1704a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(33) (compute determinant):                        %d \n",mumps->id.ICNTL(33));CHKERRQ(ierr);
1705f6c57405SHong Zhang 
1706a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(1) (relative pivoting threshold):      %g \n",mumps->id.CNTL(1));CHKERRQ(ierr);
1707a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(2) (stopping criterion of refinement): %g \n",mumps->id.CNTL(2));CHKERRQ(ierr);
1708ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(3) (absolute pivoting threshold):      %g \n",mumps->id.CNTL(3));CHKERRQ(ierr);
1709ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(4) (value of static pivoting):         %g \n",mumps->id.CNTL(4));CHKERRQ(ierr);
1710a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(5) (fixation for null pivots):         %g \n",mumps->id.CNTL(5));CHKERRQ(ierr);
1711f6c57405SHong Zhang 
1712f6c57405SHong Zhang       /* infomation local to each processor */
171334ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);
17141575c14dSBarry Smith       ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
1715a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %g \n",mumps->myid,mumps->id.RINFO(1));CHKERRQ(ierr);
171634ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
171734ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);
1718a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(2));CHKERRQ(ierr);
171934ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
172034ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);
1721a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(3));CHKERRQ(ierr);
172234ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1723f6c57405SHong Zhang 
172434ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(15) (estimated size of (in MB) MUMPS internal data for running numerical factorization): \n");CHKERRQ(ierr);
1725a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"  [%d] %d \n",mumps->myid,mumps->id.INFO(15));CHKERRQ(ierr);
172634ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1727f6c57405SHong Zhang 
172834ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(16) (size of (in MB) MUMPS internal data used during numerical factorization): \n");CHKERRQ(ierr);
1729a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(16));CHKERRQ(ierr);
173034ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1731f6c57405SHong Zhang 
173234ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);
1733a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(23));CHKERRQ(ierr);
173434ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1735b34f08ffSHong Zhang 
1736b34f08ffSHong Zhang       if (mumps->ninfo && mumps->ninfo <= 40){
1737b34f08ffSHong Zhang         PetscInt i;
1738b34f08ffSHong Zhang         for (i=0; i<mumps->ninfo; i++){
1739b34f08ffSHong Zhang           ierr = PetscViewerASCIIPrintf(viewer, "  INFO(%d): \n",mumps->info[i]);CHKERRQ(ierr);
1740b34f08ffSHong Zhang           ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(mumps->info[i]));CHKERRQ(ierr);
1741b34f08ffSHong Zhang           ierr = PetscViewerFlush(viewer);
1742b34f08ffSHong Zhang         }
1743b34f08ffSHong Zhang       }
1744b34f08ffSHong Zhang 
1745b34f08ffSHong Zhang 
17461575c14dSBarry Smith       ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
1747f6c57405SHong Zhang 
1748a5e57a09SHong Zhang       if (!mumps->myid) { /* information from the host */
1749a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",mumps->id.RINFOG(1));CHKERRQ(ierr);
1750a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",mumps->id.RINFOG(2));CHKERRQ(ierr);
1751a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",mumps->id.RINFOG(3));CHKERRQ(ierr);
1752a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  (RINFOG(12) RINFOG(13))*2^INFOG(34) (determinant): (%g,%g)*(2^%d)\n",mumps->id.RINFOG(12),mumps->id.RINFOG(13),mumps->id.INFOG(34));CHKERRQ(ierr);
1753f6c57405SHong Zhang 
1754a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(3));CHKERRQ(ierr);
1755a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(4));CHKERRQ(ierr);
1756a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(5) (estimated maximum front size in the complete tree): %d \n",mumps->id.INFOG(5));CHKERRQ(ierr);
1757a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(6) (number of nodes in the complete tree): %d \n",mumps->id.INFOG(6));CHKERRQ(ierr);
1758a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(7) (ordering option effectively use after analysis): %d \n",mumps->id.INFOG(7));CHKERRQ(ierr);
1759a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",mumps->id.INFOG(8));CHKERRQ(ierr);
1760a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(9) (total real/complex workspace to store the matrix factors after factorization): %d \n",mumps->id.INFOG(9));CHKERRQ(ierr);
1761a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(10) (total integer space store the matrix factors after factorization): %d \n",mumps->id.INFOG(10));CHKERRQ(ierr);
1762a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(11) (order of largest frontal matrix after factorization): %d \n",mumps->id.INFOG(11));CHKERRQ(ierr);
1763a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(12) (number of off-diagonal pivots): %d \n",mumps->id.INFOG(12));CHKERRQ(ierr);
1764a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(13) (number of delayed pivots after factorization): %d \n",mumps->id.INFOG(13));CHKERRQ(ierr);
1765a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(14) (number of memory compress after factorization): %d \n",mumps->id.INFOG(14));CHKERRQ(ierr);
1766a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(15) (number of steps of iterative refinement after solution): %d \n",mumps->id.INFOG(15));CHKERRQ(ierr);
1767a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(16) (estimated size (in MB) of all MUMPS internal data for factorization after analysis: value on the most memory consuming processor): %d \n",mumps->id.INFOG(16));CHKERRQ(ierr);
1768a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(17) (estimated size of all MUMPS internal data for factorization after analysis: sum over all processors): %d \n",mumps->id.INFOG(17));CHKERRQ(ierr);
1769a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(18) (size of all MUMPS internal data allocated during factorization: value on the most memory consuming processor): %d \n",mumps->id.INFOG(18));CHKERRQ(ierr);
1770a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(19) (size of all MUMPS internal data allocated during factorization: sum over all processors): %d \n",mumps->id.INFOG(19));CHKERRQ(ierr);
1771a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(20) (estimated number of entries in the factors): %d \n",mumps->id.INFOG(20));CHKERRQ(ierr);
1772a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(21) (size in MB of memory effectively used during factorization - value on the most memory consuming processor): %d \n",mumps->id.INFOG(21));CHKERRQ(ierr);
1773a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(22) (size in MB of memory effectively used during factorization - sum over all processors): %d \n",mumps->id.INFOG(22));CHKERRQ(ierr);
1774a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",mumps->id.INFOG(23));CHKERRQ(ierr);
1775a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",mumps->id.INFOG(24));CHKERRQ(ierr);
1776a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",mumps->id.INFOG(25));CHKERRQ(ierr);
177740d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(28) (after factorization: number of null pivots encountered): %d\n",mumps->id.INFOG(28));CHKERRQ(ierr);
177840d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(29) (after factorization: effective number of entries in the factors (sum over all processors)): %d\n",mumps->id.INFOG(29));CHKERRQ(ierr);
177940d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(30, 31) (after solution: size in Mbytes of memory used during solution phase): %d, %d\n",mumps->id.INFOG(30),mumps->id.INFOG(31));CHKERRQ(ierr);
178040d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(32) (after analysis: type of analysis done): %d\n",mumps->id.INFOG(32));CHKERRQ(ierr);
178140d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(33) (value used for ICNTL(8)): %d\n",mumps->id.INFOG(33));CHKERRQ(ierr);
178240d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(34) (exponent of the determinant if determinant is requested): %d\n",mumps->id.INFOG(34));CHKERRQ(ierr);
1783f6c57405SHong Zhang       }
1784f6c57405SHong Zhang     }
1785cb828f0fSHong Zhang   }
1786f6c57405SHong Zhang   PetscFunctionReturn(0);
1787f6c57405SHong Zhang }
1788f6c57405SHong Zhang 
178935bd34faSBarry Smith #undef __FUNCT__
179035bd34faSBarry Smith #define __FUNCT__ "MatGetInfo_MUMPS"
179135bd34faSBarry Smith PetscErrorCode MatGetInfo_MUMPS(Mat A,MatInfoType flag,MatInfo *info)
179235bd34faSBarry Smith {
1793cb828f0fSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)A->spptr;
179435bd34faSBarry Smith 
179535bd34faSBarry Smith   PetscFunctionBegin;
179635bd34faSBarry Smith   info->block_size        = 1.0;
1797cb828f0fSHong Zhang   info->nz_allocated      = mumps->id.INFOG(20);
1798cb828f0fSHong Zhang   info->nz_used           = mumps->id.INFOG(20);
179935bd34faSBarry Smith   info->nz_unneeded       = 0.0;
180035bd34faSBarry Smith   info->assemblies        = 0.0;
180135bd34faSBarry Smith   info->mallocs           = 0.0;
180235bd34faSBarry Smith   info->memory            = 0.0;
180335bd34faSBarry Smith   info->fill_ratio_given  = 0;
180435bd34faSBarry Smith   info->fill_ratio_needed = 0;
180535bd34faSBarry Smith   info->factor_mallocs    = 0;
180635bd34faSBarry Smith   PetscFunctionReturn(0);
180735bd34faSBarry Smith }
180835bd34faSBarry Smith 
18095ccb76cbSHong Zhang /* -------------------------------------------------------------------------------------------*/
18105ccb76cbSHong Zhang #undef __FUNCT__
18118e7ba810SStefano Zampini #define __FUNCT__ "MatFactorSetSchurIS_MUMPS"
18128e7ba810SStefano Zampini PetscErrorCode MatFactorSetSchurIS_MUMPS(Mat F, IS is)
18136444a565SStefano Zampini {
18146444a565SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
18158e7ba810SStefano Zampini   const PetscInt *idxs;
18168e7ba810SStefano Zampini   PetscInt       size,i;
18176444a565SStefano Zampini   PetscErrorCode ierr;
18186444a565SStefano Zampini 
18196444a565SStefano Zampini   PetscFunctionBegin;
182059ac8732SStefano Zampini   if (mumps->size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MUMPS parallel Schur complements not yet supported from PETSc\n");
18218e7ba810SStefano Zampini   ierr = ISGetLocalSize(is,&size);CHKERRQ(ierr);
18226444a565SStefano Zampini   if (mumps->id.size_schur != size) {
18236444a565SStefano Zampini     ierr = PetscFree2(mumps->id.listvar_schur,mumps->id.schur);CHKERRQ(ierr);
18246444a565SStefano Zampini     mumps->id.size_schur = size;
18256444a565SStefano Zampini     mumps->id.schur_lld = size;
18266444a565SStefano Zampini     ierr = PetscMalloc2(size,&mumps->id.listvar_schur,size*size,&mumps->id.schur);CHKERRQ(ierr);
18276444a565SStefano Zampini   }
18288e7ba810SStefano Zampini   ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr);
18296444a565SStefano Zampini   ierr = PetscMemcpy(mumps->id.listvar_schur,idxs,size*sizeof(PetscInt));CHKERRQ(ierr);
18308e7ba810SStefano Zampini   /* MUMPS expects Fortran style indices */
18318e7ba810SStefano Zampini   for (i=0;i<size;i++) mumps->id.listvar_schur[i]++;
18328e7ba810SStefano Zampini   ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr);
183378a7176cSStefano Zampini   if (size) { /* turn on Schur switch if we the set of indices is not empty */
18346444a565SStefano Zampini     if (F->factortype == MAT_FACTOR_LU) {
183559ac8732SStefano Zampini       mumps->id.ICNTL(19) = 3; /* MUMPS returns full matrix */
18366444a565SStefano Zampini     } else {
183759ac8732SStefano Zampini       mumps->id.ICNTL(19) = 2; /* MUMPS returns lower triangular part */
18386444a565SStefano Zampini     }
183959ac8732SStefano Zampini     /* set a special value of ICNTL (not handled my MUMPS) to be used in the solve phase by PETSc */
1840b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = -1;
184178a7176cSStefano Zampini   }
18426444a565SStefano Zampini   PetscFunctionReturn(0);
18436444a565SStefano Zampini }
18446444a565SStefano Zampini 
18456444a565SStefano Zampini /* -------------------------------------------------------------------------------------------*/
18466444a565SStefano Zampini #undef __FUNCT__
18475a05ddb0SStefano Zampini #define __FUNCT__ "MatFactorCreateSchurComplement_MUMPS"
18485a05ddb0SStefano Zampini PetscErrorCode MatFactorCreateSchurComplement_MUMPS(Mat F,Mat* S)
18496444a565SStefano Zampini {
18506444a565SStefano Zampini   Mat            St;
18516444a565SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
18526444a565SStefano Zampini   PetscScalar    *array;
18536444a565SStefano Zampini #if defined(PETSC_USE_COMPLEX)
18548ac429a0SStefano Zampini   PetscScalar    im = PetscSqrtScalar((PetscScalar)-1.0);
18556444a565SStefano Zampini #endif
18566444a565SStefano Zampini   PetscErrorCode ierr;
18576444a565SStefano Zampini 
18586444a565SStefano Zampini   PetscFunctionBegin;
18595a05ddb0SStefano Zampini   if (!mumps->id.ICNTL(19)) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur complement mode not selected! You should call MatFactorSetSchurIS to enable it");
18605a05ddb0SStefano Zampini   else if (!mumps->id.size_schur) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur indices not set! You should call MatFactorSetSchurIS before");
18616f3cc6f9SBarry Smith 
18626444a565SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)F),&St);CHKERRQ(ierr);
18636444a565SStefano Zampini   ierr = MatSetSizes(St,PETSC_DECIDE,PETSC_DECIDE,mumps->id.size_schur,mumps->id.size_schur);CHKERRQ(ierr);
18646444a565SStefano Zampini   ierr = MatSetType(St,MATDENSE);CHKERRQ(ierr);
18656444a565SStefano Zampini   ierr = MatSetUp(St);CHKERRQ(ierr);
18666444a565SStefano Zampini   ierr = MatDenseGetArray(St,&array);CHKERRQ(ierr);
186759ac8732SStefano Zampini   if (!mumps->sym) { /* MUMPS always return a full matrix */
18686444a565SStefano Zampini     if (mumps->id.ICNTL(19) == 1) { /* stored by rows */
18696444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
18706444a565SStefano Zampini       for (i=0;i<N;i++) {
18716444a565SStefano Zampini         for (j=0;j<N;j++) {
18726444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
18736444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
18746444a565SStefano Zampini #else
18756444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
18766444a565SStefano Zampini #endif
18776444a565SStefano Zampini           array[j*N+i] = val;
18786444a565SStefano Zampini         }
18796444a565SStefano Zampini       }
18806444a565SStefano Zampini     } else { /* stored by columns */
18816444a565SStefano Zampini       ierr = PetscMemcpy(array,mumps->id.schur,mumps->id.size_schur*mumps->id.size_schur*sizeof(PetscScalar));CHKERRQ(ierr);
18826444a565SStefano Zampini     }
18836444a565SStefano Zampini   } else { /* either full or lower-triangular (not packed) */
18846444a565SStefano Zampini     if (mumps->id.ICNTL(19) == 2) { /* lower triangular stored by columns */
18856444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
18866444a565SStefano Zampini       for (i=0;i<N;i++) {
18876444a565SStefano Zampini         for (j=i;j<N;j++) {
18886444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
18896444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
18906444a565SStefano Zampini #else
18916444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
18926444a565SStefano Zampini #endif
18936444a565SStefano Zampini           array[i*N+j] = val;
18946444a565SStefano Zampini           array[j*N+i] = val;
18956444a565SStefano Zampini         }
18966444a565SStefano Zampini       }
18976444a565SStefano Zampini     } else if (mumps->id.ICNTL(19) == 3) { /* full matrix */
18986444a565SStefano Zampini       ierr = PetscMemcpy(array,mumps->id.schur,mumps->id.size_schur*mumps->id.size_schur*sizeof(PetscScalar));CHKERRQ(ierr);
18996444a565SStefano Zampini     } else { /* ICNTL(19) == 1 lower triangular stored by rows */
19006444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
19016444a565SStefano Zampini       for (i=0;i<N;i++) {
19026444a565SStefano Zampini         for (j=0;j<i+1;j++) {
19036444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
19046444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
19056444a565SStefano Zampini #else
19066444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
19076444a565SStefano Zampini #endif
19086444a565SStefano Zampini           array[i*N+j] = val;
19096444a565SStefano Zampini           array[j*N+i] = val;
19106444a565SStefano Zampini         }
19116444a565SStefano Zampini       }
19126444a565SStefano Zampini     }
19136444a565SStefano Zampini   }
19146444a565SStefano Zampini   ierr = MatDenseRestoreArray(St,&array);CHKERRQ(ierr);
19156444a565SStefano Zampini   *S = St;
19166444a565SStefano Zampini   PetscFunctionReturn(0);
19176444a565SStefano Zampini }
19186444a565SStefano Zampini 
191959ac8732SStefano Zampini /* -------------------------------------------------------------------------------------------*/
192059ac8732SStefano Zampini #undef __FUNCT__
19215a05ddb0SStefano Zampini #define __FUNCT__ "MatFactorGetSchurComplement_MUMPS"
19225a05ddb0SStefano Zampini PetscErrorCode MatFactorGetSchurComplement_MUMPS(Mat F,Mat* S)
192359ac8732SStefano Zampini {
192459ac8732SStefano Zampini   Mat            St;
192559ac8732SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
192659ac8732SStefano Zampini   PetscErrorCode ierr;
192759ac8732SStefano Zampini 
192859ac8732SStefano Zampini   PetscFunctionBegin;
19295a05ddb0SStefano Zampini   if (!mumps->id.ICNTL(19)) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur complement mode not selected! You should call MatFactorSetSchurIS to enable it");
19305a05ddb0SStefano Zampini   else if (!mumps->id.size_schur) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur indices not set! You should call MatFactorSetSchurIS before");
19316f3cc6f9SBarry Smith 
19327bc32933SStefano Zampini   /* It should be the responsibility of the user to handle different ICNTL(19) cases and factorization stages if they want to work with the raw data */
193359ac8732SStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)F),mumps->id.size_schur,mumps->id.size_schur,(PetscScalar*)mumps->id.schur,&St);CHKERRQ(ierr);
193459ac8732SStefano Zampini   *S = St;
193559ac8732SStefano Zampini   PetscFunctionReturn(0);
193659ac8732SStefano Zampini }
193759ac8732SStefano Zampini 
193859ac8732SStefano Zampini /* -------------------------------------------------------------------------------------------*/
193959ac8732SStefano Zampini #undef __FUNCT__
19405a05ddb0SStefano Zampini #define __FUNCT__ "MatFactorInvertSchurComplement_MUMPS"
19415a05ddb0SStefano Zampini PetscErrorCode MatFactorInvertSchurComplement_MUMPS(Mat F)
194259ac8732SStefano Zampini {
194359ac8732SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
194459ac8732SStefano Zampini   PetscErrorCode ierr;
194559ac8732SStefano Zampini 
194659ac8732SStefano Zampini   PetscFunctionBegin;
194759ac8732SStefano Zampini   if (!mumps->id.ICNTL(19)) { /* do nothing */
194859ac8732SStefano Zampini     PetscFunctionReturn(0);
194959ac8732SStefano Zampini   }
19505a05ddb0SStefano Zampini   if (!mumps->id.size_schur) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur indices not set! You should call MatFactorSetSchurIS before");
195159ac8732SStefano Zampini   ierr = MatMumpsInvertSchur_Private(mumps);CHKERRQ(ierr);
195259ac8732SStefano Zampini   PetscFunctionReturn(0);
195359ac8732SStefano Zampini }
195459ac8732SStefano Zampini 
19556444a565SStefano Zampini /* -------------------------------------------------------------------------------------------*/
19566444a565SStefano Zampini #undef __FUNCT__
19575a05ddb0SStefano Zampini #define __FUNCT__ "MatFactorSolveSchurComplement_MUMPS"
19585a05ddb0SStefano Zampini PetscErrorCode MatFactorSolveSchurComplement_MUMPS(Mat F, Vec rhs, Vec sol)
1959e807eca7SStefano Zampini {
1960e807eca7SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
1961e807eca7SStefano Zampini   MumpsScalar    *orhs;
1962e807eca7SStefano Zampini   PetscScalar    *osol,*nrhs,*nsol;
19639a3a5937SStefano Zampini   PetscInt       orhs_size,osol_size,olrhs_size;
1964e807eca7SStefano Zampini   PetscErrorCode ierr;
1965e807eca7SStefano Zampini 
1966e807eca7SStefano Zampini   PetscFunctionBegin;
19675a05ddb0SStefano Zampini   if (!mumps->id.ICNTL(19)) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur complement mode not selected! You should call MatFactorSetSchurIS to enable it");
19685a05ddb0SStefano Zampini   if (!mumps->id.size_schur) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur indices not set! You should call MatFactorSetSchurIS before");
19696f3cc6f9SBarry Smith 
1970e807eca7SStefano Zampini   /* swap pointers */
1971e807eca7SStefano Zampini   orhs = mumps->id.redrhs;
19729a3a5937SStefano Zampini   olrhs_size = mumps->id.lredrhs;
1973a12f35bfSStefano Zampini   orhs_size = mumps->sizeredrhs;
1974e807eca7SStefano Zampini   osol = mumps->schur_sol;
1975a12f35bfSStefano Zampini   osol_size = mumps->schur_sizesol;
1976e807eca7SStefano Zampini   ierr = VecGetArray(rhs,&nrhs);CHKERRQ(ierr);
1977e807eca7SStefano Zampini   ierr = VecGetArray(sol,&nsol);CHKERRQ(ierr);
1978e807eca7SStefano Zampini   mumps->id.redrhs = (MumpsScalar*)nrhs;
1979a12f35bfSStefano Zampini   ierr = VecGetLocalSize(rhs,&mumps->sizeredrhs);CHKERRQ(ierr);
19809a3a5937SStefano Zampini   mumps->id.lredrhs = mumps->sizeredrhs;
1981e807eca7SStefano Zampini   mumps->schur_sol = nsol;
1982a12f35bfSStefano Zampini   ierr = VecGetLocalSize(sol,&mumps->schur_sizesol);CHKERRQ(ierr);
1983a12f35bfSStefano Zampini 
1984e807eca7SStefano Zampini   /* solve Schur complement */
1985e807eca7SStefano Zampini   mumps->id.nrhs = 1;
1986e807eca7SStefano Zampini   ierr = MatMumpsSolveSchur_Private(mumps,PETSC_FALSE);CHKERRQ(ierr);
1987e807eca7SStefano Zampini   /* restore pointers */
1988e807eca7SStefano Zampini   ierr = VecRestoreArray(rhs,&nrhs);CHKERRQ(ierr);
1989e807eca7SStefano Zampini   ierr = VecRestoreArray(sol,&nsol);CHKERRQ(ierr);
1990e807eca7SStefano Zampini   mumps->id.redrhs = orhs;
19919a3a5937SStefano Zampini   mumps->id.lredrhs = olrhs_size;
1992a12f35bfSStefano Zampini   mumps->sizeredrhs = orhs_size;
1993e807eca7SStefano Zampini   mumps->schur_sol = osol;
1994a12f35bfSStefano Zampini   mumps->schur_sizesol = osol_size;
1995e807eca7SStefano Zampini   PetscFunctionReturn(0);
1996e807eca7SStefano Zampini }
1997e807eca7SStefano Zampini 
19987404bcfbSStefano Zampini /* -------------------------------------------------------------------------------------------*/
19997404bcfbSStefano Zampini #undef __FUNCT__
20005a05ddb0SStefano Zampini #define __FUNCT__ "MatFactorSolveSchurComplementTranspose_MUMPS"
20015a05ddb0SStefano Zampini PetscErrorCode MatFactorSolveSchurComplementTranspose_MUMPS(Mat F, Vec rhs, Vec sol)
20027404bcfbSStefano Zampini {
20037404bcfbSStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
20047404bcfbSStefano Zampini   MumpsScalar    *orhs;
20057404bcfbSStefano Zampini   PetscScalar    *osol,*nrhs,*nsol;
2006a12f35bfSStefano Zampini   PetscInt       orhs_size,osol_size;
20077404bcfbSStefano Zampini   PetscErrorCode ierr;
20087404bcfbSStefano Zampini 
20097404bcfbSStefano Zampini   PetscFunctionBegin;
20105a05ddb0SStefano Zampini   if (!mumps->id.ICNTL(19)) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur complement mode not selected! You should call MatFactorSetSchurIS to enable it");
20115a05ddb0SStefano Zampini   else if (!mumps->id.size_schur) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ORDER,"Schur indices not set! You should call MatFactorSetSchurIS before");
20126f3cc6f9SBarry Smith 
20137404bcfbSStefano Zampini   /* swap pointers */
20147404bcfbSStefano Zampini   orhs = mumps->id.redrhs;
2015a12f35bfSStefano Zampini   orhs_size = mumps->sizeredrhs;
20167404bcfbSStefano Zampini   osol = mumps->schur_sol;
2017a12f35bfSStefano Zampini   osol_size = mumps->schur_sizesol;
20187404bcfbSStefano Zampini   ierr = VecGetArray(rhs,&nrhs);CHKERRQ(ierr);
20197404bcfbSStefano Zampini   ierr = VecGetArray(sol,&nsol);CHKERRQ(ierr);
20207404bcfbSStefano Zampini   mumps->id.redrhs = (MumpsScalar*)nrhs;
2021a12f35bfSStefano Zampini   ierr = VecGetLocalSize(rhs,&mumps->sizeredrhs);CHKERRQ(ierr);
20227404bcfbSStefano Zampini   mumps->schur_sol = nsol;
2023a12f35bfSStefano Zampini   ierr = VecGetLocalSize(sol,&mumps->schur_sizesol);CHKERRQ(ierr);
2024a12f35bfSStefano Zampini 
20257404bcfbSStefano Zampini   /* solve Schur complement */
20267404bcfbSStefano Zampini   mumps->id.nrhs = 1;
20277404bcfbSStefano Zampini   mumps->id.ICNTL(9) = 0;
20287404bcfbSStefano Zampini   ierr = MatMumpsSolveSchur_Private(mumps,PETSC_FALSE);CHKERRQ(ierr);
20297404bcfbSStefano Zampini   mumps->id.ICNTL(9) = 1;
20307404bcfbSStefano Zampini   /* restore pointers */
20317404bcfbSStefano Zampini   ierr = VecRestoreArray(rhs,&nrhs);CHKERRQ(ierr);
20327404bcfbSStefano Zampini   ierr = VecRestoreArray(sol,&nsol);CHKERRQ(ierr);
20337404bcfbSStefano Zampini   mumps->id.redrhs = orhs;
2034a12f35bfSStefano Zampini   mumps->sizeredrhs = orhs_size;
20357404bcfbSStefano Zampini   mumps->schur_sol = osol;
2036a12f35bfSStefano Zampini   mumps->schur_sizesol = osol_size;
20377404bcfbSStefano Zampini   PetscFunctionReturn(0);
20387404bcfbSStefano Zampini }
20397404bcfbSStefano Zampini 
2040e807eca7SStefano Zampini /* -------------------------------------------------------------------------------------------*/
2041e807eca7SStefano Zampini #undef __FUNCT__
20425ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl_MUMPS"
20435ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl_MUMPS(Mat F,PetscInt icntl,PetscInt ival)
20445ccb76cbSHong Zhang {
2045a5e57a09SHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
20465ccb76cbSHong Zhang 
20475ccb76cbSHong Zhang   PetscFunctionBegin;
2048a5e57a09SHong Zhang   mumps->id.ICNTL(icntl) = ival;
20495ccb76cbSHong Zhang   PetscFunctionReturn(0);
20505ccb76cbSHong Zhang }
20515ccb76cbSHong Zhang 
20525ccb76cbSHong Zhang #undef __FUNCT__
2053bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetIcntl_MUMPS"
2054bc6112feSHong Zhang PetscErrorCode MatMumpsGetIcntl_MUMPS(Mat F,PetscInt icntl,PetscInt *ival)
2055bc6112feSHong Zhang {
2056bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2057bc6112feSHong Zhang 
2058bc6112feSHong Zhang   PetscFunctionBegin;
2059bc6112feSHong Zhang   *ival = mumps->id.ICNTL(icntl);
2060bc6112feSHong Zhang   PetscFunctionReturn(0);
2061bc6112feSHong Zhang }
2062bc6112feSHong Zhang 
2063bc6112feSHong Zhang #undef __FUNCT__
20645ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl"
20655ccb76cbSHong Zhang /*@
20665ccb76cbSHong Zhang   MatMumpsSetIcntl - Set MUMPS parameter ICNTL()
20675ccb76cbSHong Zhang 
20685ccb76cbSHong Zhang    Logically Collective on Mat
20695ccb76cbSHong Zhang 
20705ccb76cbSHong Zhang    Input Parameters:
20715ccb76cbSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
20725ccb76cbSHong Zhang .  icntl - index of MUMPS parameter array ICNTL()
20735ccb76cbSHong Zhang -  ival - value of MUMPS ICNTL(icntl)
20745ccb76cbSHong Zhang 
20755ccb76cbSHong Zhang   Options Database:
20765ccb76cbSHong Zhang .   -mat_mumps_icntl_<icntl> <ival>
20775ccb76cbSHong Zhang 
20785ccb76cbSHong Zhang    Level: beginner
20795ccb76cbSHong Zhang 
208096a0c994SBarry Smith    References:
208196a0c994SBarry Smith .     MUMPS Users' Guide
20825ccb76cbSHong Zhang 
20839fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
20845ccb76cbSHong Zhang  @*/
20855ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl(Mat F,PetscInt icntl,PetscInt ival)
20865ccb76cbSHong Zhang {
20875ccb76cbSHong Zhang   PetscErrorCode ierr;
20885ccb76cbSHong Zhang 
20895ccb76cbSHong Zhang   PetscFunctionBegin;
20902989dfd4SHong Zhang   PetscValidType(F,1);
20912989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
20925ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
20935ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,ival,3);
20945ccb76cbSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsSetIcntl_C",(Mat,PetscInt,PetscInt),(F,icntl,ival));CHKERRQ(ierr);
20955ccb76cbSHong Zhang   PetscFunctionReturn(0);
20965ccb76cbSHong Zhang }
20975ccb76cbSHong Zhang 
2098bc6112feSHong Zhang #undef __FUNCT__
2099bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetIcntl"
2100a21f80fcSHong Zhang /*@
2101a21f80fcSHong Zhang   MatMumpsGetIcntl - Get MUMPS parameter ICNTL()
2102a21f80fcSHong Zhang 
2103a21f80fcSHong Zhang    Logically Collective on Mat
2104a21f80fcSHong Zhang 
2105a21f80fcSHong Zhang    Input Parameters:
2106a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2107a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array ICNTL()
2108a21f80fcSHong Zhang 
2109a21f80fcSHong Zhang   Output Parameter:
2110a21f80fcSHong Zhang .  ival - value of MUMPS ICNTL(icntl)
2111a21f80fcSHong Zhang 
2112a21f80fcSHong Zhang    Level: beginner
2113a21f80fcSHong Zhang 
211496a0c994SBarry Smith    References:
211596a0c994SBarry Smith .     MUMPS Users' Guide
2116a21f80fcSHong Zhang 
21179fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2118a21f80fcSHong Zhang @*/
2119bc6112feSHong Zhang PetscErrorCode MatMumpsGetIcntl(Mat F,PetscInt icntl,PetscInt *ival)
2120bc6112feSHong Zhang {
2121bc6112feSHong Zhang   PetscErrorCode ierr;
2122bc6112feSHong Zhang 
2123bc6112feSHong Zhang   PetscFunctionBegin;
21242989dfd4SHong Zhang   PetscValidType(F,1);
21252989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2126bc6112feSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
2127bc6112feSHong Zhang   PetscValidIntPointer(ival,3);
21282989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetIcntl_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
2129bc6112feSHong Zhang   PetscFunctionReturn(0);
2130bc6112feSHong Zhang }
2131bc6112feSHong Zhang 
21328928b65cSHong Zhang /* -------------------------------------------------------------------------------------------*/
21338928b65cSHong Zhang #undef __FUNCT__
21348928b65cSHong Zhang #define __FUNCT__ "MatMumpsSetCntl_MUMPS"
21358928b65cSHong Zhang PetscErrorCode MatMumpsSetCntl_MUMPS(Mat F,PetscInt icntl,PetscReal val)
21368928b65cSHong Zhang {
21378928b65cSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
21388928b65cSHong Zhang 
21398928b65cSHong Zhang   PetscFunctionBegin;
21408928b65cSHong Zhang   mumps->id.CNTL(icntl) = val;
21418928b65cSHong Zhang   PetscFunctionReturn(0);
21428928b65cSHong Zhang }
21438928b65cSHong Zhang 
21448928b65cSHong Zhang #undef __FUNCT__
2145bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetCntl_MUMPS"
2146bc6112feSHong Zhang PetscErrorCode MatMumpsGetCntl_MUMPS(Mat F,PetscInt icntl,PetscReal *val)
2147bc6112feSHong Zhang {
2148bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2149bc6112feSHong Zhang 
2150bc6112feSHong Zhang   PetscFunctionBegin;
2151bc6112feSHong Zhang   *val = mumps->id.CNTL(icntl);
2152bc6112feSHong Zhang   PetscFunctionReturn(0);
2153bc6112feSHong Zhang }
2154bc6112feSHong Zhang 
2155bc6112feSHong Zhang #undef __FUNCT__
21568928b65cSHong Zhang #define __FUNCT__ "MatMumpsSetCntl"
21578928b65cSHong Zhang /*@
21588928b65cSHong Zhang   MatMumpsSetCntl - Set MUMPS parameter CNTL()
21598928b65cSHong Zhang 
21608928b65cSHong Zhang    Logically Collective on Mat
21618928b65cSHong Zhang 
21628928b65cSHong Zhang    Input Parameters:
21638928b65cSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
21648928b65cSHong Zhang .  icntl - index of MUMPS parameter array CNTL()
21658928b65cSHong Zhang -  val - value of MUMPS CNTL(icntl)
21668928b65cSHong Zhang 
21678928b65cSHong Zhang   Options Database:
21688928b65cSHong Zhang .   -mat_mumps_cntl_<icntl> <val>
21698928b65cSHong Zhang 
21708928b65cSHong Zhang    Level: beginner
21718928b65cSHong Zhang 
217296a0c994SBarry Smith    References:
217396a0c994SBarry Smith .     MUMPS Users' Guide
21748928b65cSHong Zhang 
21759fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
21768928b65cSHong Zhang @*/
21778928b65cSHong Zhang PetscErrorCode MatMumpsSetCntl(Mat F,PetscInt icntl,PetscReal val)
21788928b65cSHong Zhang {
21798928b65cSHong Zhang   PetscErrorCode ierr;
21808928b65cSHong Zhang 
21818928b65cSHong Zhang   PetscFunctionBegin;
21822989dfd4SHong Zhang   PetscValidType(F,1);
21832989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
21848928b65cSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
2185bc6112feSHong Zhang   PetscValidLogicalCollectiveReal(F,val,3);
21868928b65cSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsSetCntl_C",(Mat,PetscInt,PetscReal),(F,icntl,val));CHKERRQ(ierr);
21878928b65cSHong Zhang   PetscFunctionReturn(0);
21888928b65cSHong Zhang }
21898928b65cSHong Zhang 
2190bc6112feSHong Zhang #undef __FUNCT__
2191bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetCntl"
2192a21f80fcSHong Zhang /*@
2193a21f80fcSHong Zhang   MatMumpsGetCntl - Get MUMPS parameter CNTL()
2194a21f80fcSHong Zhang 
2195a21f80fcSHong Zhang    Logically Collective on Mat
2196a21f80fcSHong Zhang 
2197a21f80fcSHong Zhang    Input Parameters:
2198a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2199a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array CNTL()
2200a21f80fcSHong Zhang 
2201a21f80fcSHong Zhang   Output Parameter:
2202a21f80fcSHong Zhang .  val - value of MUMPS CNTL(icntl)
2203a21f80fcSHong Zhang 
2204a21f80fcSHong Zhang    Level: beginner
2205a21f80fcSHong Zhang 
220696a0c994SBarry Smith    References:
220796a0c994SBarry Smith .      MUMPS Users' Guide
2208a21f80fcSHong Zhang 
22099fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2210a21f80fcSHong Zhang @*/
2211bc6112feSHong Zhang PetscErrorCode MatMumpsGetCntl(Mat F,PetscInt icntl,PetscReal *val)
2212bc6112feSHong Zhang {
2213bc6112feSHong Zhang   PetscErrorCode ierr;
2214bc6112feSHong Zhang 
2215bc6112feSHong Zhang   PetscFunctionBegin;
22162989dfd4SHong Zhang   PetscValidType(F,1);
22172989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2218bc6112feSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
2219bc6112feSHong Zhang   PetscValidRealPointer(val,3);
22202989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetCntl_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
2221bc6112feSHong Zhang   PetscFunctionReturn(0);
2222bc6112feSHong Zhang }
2223bc6112feSHong Zhang 
2224bc6112feSHong Zhang #undef __FUNCT__
2225ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfo_MUMPS"
2226ca810319SHong Zhang PetscErrorCode MatMumpsGetInfo_MUMPS(Mat F,PetscInt icntl,PetscInt *info)
2227bc6112feSHong Zhang {
2228bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2229bc6112feSHong Zhang 
2230bc6112feSHong Zhang   PetscFunctionBegin;
2231bc6112feSHong Zhang   *info = mumps->id.INFO(icntl);
2232bc6112feSHong Zhang   PetscFunctionReturn(0);
2233bc6112feSHong Zhang }
2234bc6112feSHong Zhang 
2235bc6112feSHong Zhang #undef __FUNCT__
2236ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfog_MUMPS"
2237ca810319SHong Zhang PetscErrorCode MatMumpsGetInfog_MUMPS(Mat F,PetscInt icntl,PetscInt *infog)
2238bc6112feSHong Zhang {
2239bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2240bc6112feSHong Zhang 
2241bc6112feSHong Zhang   PetscFunctionBegin;
2242bc6112feSHong Zhang   *infog = mumps->id.INFOG(icntl);
2243bc6112feSHong Zhang   PetscFunctionReturn(0);
2244bc6112feSHong Zhang }
2245bc6112feSHong Zhang 
2246bc6112feSHong Zhang #undef __FUNCT__
2247ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfo_MUMPS"
2248ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfo_MUMPS(Mat F,PetscInt icntl,PetscReal *rinfo)
2249bc6112feSHong Zhang {
2250bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2251bc6112feSHong Zhang 
2252bc6112feSHong Zhang   PetscFunctionBegin;
2253bc6112feSHong Zhang   *rinfo = mumps->id.RINFO(icntl);
2254bc6112feSHong Zhang   PetscFunctionReturn(0);
2255bc6112feSHong Zhang }
2256bc6112feSHong Zhang 
2257bc6112feSHong Zhang #undef __FUNCT__
2258ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfog_MUMPS"
2259ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfog_MUMPS(Mat F,PetscInt icntl,PetscReal *rinfog)
2260bc6112feSHong Zhang {
2261bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
2262bc6112feSHong Zhang 
2263bc6112feSHong Zhang   PetscFunctionBegin;
2264bc6112feSHong Zhang   *rinfog = mumps->id.RINFOG(icntl);
2265bc6112feSHong Zhang   PetscFunctionReturn(0);
2266bc6112feSHong Zhang }
2267bc6112feSHong Zhang 
2268bc6112feSHong Zhang #undef __FUNCT__
2269ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfo"
2270a21f80fcSHong Zhang /*@
2271a21f80fcSHong Zhang   MatMumpsGetInfo - Get MUMPS parameter INFO()
2272a21f80fcSHong Zhang 
2273a21f80fcSHong Zhang    Logically Collective on Mat
2274a21f80fcSHong Zhang 
2275a21f80fcSHong Zhang    Input Parameters:
2276a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2277a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array INFO()
2278a21f80fcSHong Zhang 
2279a21f80fcSHong Zhang   Output Parameter:
2280a21f80fcSHong Zhang .  ival - value of MUMPS INFO(icntl)
2281a21f80fcSHong Zhang 
2282a21f80fcSHong Zhang    Level: beginner
2283a21f80fcSHong Zhang 
228496a0c994SBarry Smith    References:
228596a0c994SBarry Smith .      MUMPS Users' Guide
2286a21f80fcSHong Zhang 
22879fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2288a21f80fcSHong Zhang @*/
2289ca810319SHong Zhang PetscErrorCode MatMumpsGetInfo(Mat F,PetscInt icntl,PetscInt *ival)
2290bc6112feSHong Zhang {
2291bc6112feSHong Zhang   PetscErrorCode ierr;
2292bc6112feSHong Zhang 
2293bc6112feSHong Zhang   PetscFunctionBegin;
22942989dfd4SHong Zhang   PetscValidType(F,1);
22952989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2296ca810319SHong Zhang   PetscValidIntPointer(ival,3);
22972989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetInfo_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
2298bc6112feSHong Zhang   PetscFunctionReturn(0);
2299bc6112feSHong Zhang }
2300bc6112feSHong Zhang 
2301bc6112feSHong Zhang #undef __FUNCT__
2302ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfog"
2303a21f80fcSHong Zhang /*@
2304a21f80fcSHong Zhang   MatMumpsGetInfog - Get MUMPS parameter INFOG()
2305a21f80fcSHong Zhang 
2306a21f80fcSHong Zhang    Logically Collective on Mat
2307a21f80fcSHong Zhang 
2308a21f80fcSHong Zhang    Input Parameters:
2309a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2310a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array INFOG()
2311a21f80fcSHong Zhang 
2312a21f80fcSHong Zhang   Output Parameter:
2313a21f80fcSHong Zhang .  ival - value of MUMPS INFOG(icntl)
2314a21f80fcSHong Zhang 
2315a21f80fcSHong Zhang    Level: beginner
2316a21f80fcSHong Zhang 
231796a0c994SBarry Smith    References:
231896a0c994SBarry Smith .      MUMPS Users' Guide
2319a21f80fcSHong Zhang 
23209fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2321a21f80fcSHong Zhang @*/
2322ca810319SHong Zhang PetscErrorCode MatMumpsGetInfog(Mat F,PetscInt icntl,PetscInt *ival)
2323bc6112feSHong Zhang {
2324bc6112feSHong Zhang   PetscErrorCode ierr;
2325bc6112feSHong Zhang 
2326bc6112feSHong Zhang   PetscFunctionBegin;
23272989dfd4SHong Zhang   PetscValidType(F,1);
23282989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2329ca810319SHong Zhang   PetscValidIntPointer(ival,3);
23302989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetInfog_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
2331bc6112feSHong Zhang   PetscFunctionReturn(0);
2332bc6112feSHong Zhang }
2333bc6112feSHong Zhang 
2334bc6112feSHong Zhang #undef __FUNCT__
2335ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfo"
2336a21f80fcSHong Zhang /*@
2337a21f80fcSHong Zhang   MatMumpsGetRinfo - Get MUMPS parameter RINFO()
2338a21f80fcSHong Zhang 
2339a21f80fcSHong Zhang    Logically Collective on Mat
2340a21f80fcSHong Zhang 
2341a21f80fcSHong Zhang    Input Parameters:
2342a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2343a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array RINFO()
2344a21f80fcSHong Zhang 
2345a21f80fcSHong Zhang   Output Parameter:
2346a21f80fcSHong Zhang .  val - value of MUMPS RINFO(icntl)
2347a21f80fcSHong Zhang 
2348a21f80fcSHong Zhang    Level: beginner
2349a21f80fcSHong Zhang 
235096a0c994SBarry Smith    References:
235196a0c994SBarry Smith .       MUMPS Users' Guide
2352a21f80fcSHong Zhang 
23539fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2354a21f80fcSHong Zhang @*/
2355ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfo(Mat F,PetscInt icntl,PetscReal *val)
2356bc6112feSHong Zhang {
2357bc6112feSHong Zhang   PetscErrorCode ierr;
2358bc6112feSHong Zhang 
2359bc6112feSHong Zhang   PetscFunctionBegin;
23602989dfd4SHong Zhang   PetscValidType(F,1);
23612989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2362bc6112feSHong Zhang   PetscValidRealPointer(val,3);
23632989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetRinfo_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
2364bc6112feSHong Zhang   PetscFunctionReturn(0);
2365bc6112feSHong Zhang }
2366bc6112feSHong Zhang 
2367bc6112feSHong Zhang #undef __FUNCT__
2368ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfog"
2369a21f80fcSHong Zhang /*@
2370a21f80fcSHong Zhang   MatMumpsGetRinfog - Get MUMPS parameter RINFOG()
2371a21f80fcSHong Zhang 
2372a21f80fcSHong Zhang    Logically Collective on Mat
2373a21f80fcSHong Zhang 
2374a21f80fcSHong Zhang    Input Parameters:
2375a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2376a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array RINFOG()
2377a21f80fcSHong Zhang 
2378a21f80fcSHong Zhang   Output Parameter:
2379a21f80fcSHong Zhang .  val - value of MUMPS RINFOG(icntl)
2380a21f80fcSHong Zhang 
2381a21f80fcSHong Zhang    Level: beginner
2382a21f80fcSHong Zhang 
238396a0c994SBarry Smith    References:
238496a0c994SBarry Smith .      MUMPS Users' Guide
2385a21f80fcSHong Zhang 
23869fc87aa7SBarry Smith .seealso: MatGetFactor(), MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog()
2387a21f80fcSHong Zhang @*/
2388ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfog(Mat F,PetscInt icntl,PetscReal *val)
2389bc6112feSHong Zhang {
2390bc6112feSHong Zhang   PetscErrorCode ierr;
2391bc6112feSHong Zhang 
2392bc6112feSHong Zhang   PetscFunctionBegin;
23932989dfd4SHong Zhang   PetscValidType(F,1);
23942989dfd4SHong Zhang   if (!F->factortype) SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
2395bc6112feSHong Zhang   PetscValidRealPointer(val,3);
23962989dfd4SHong Zhang   ierr = PetscUseMethod(F,"MatMumpsGetRinfog_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
2397bc6112feSHong Zhang   PetscFunctionReturn(0);
2398bc6112feSHong Zhang }
2399bc6112feSHong Zhang 
240024b6179bSKris Buschelman /*MC
24012692d6eeSBarry Smith   MATSOLVERMUMPS -  A matrix type providing direct solvers (LU and Cholesky) for
240224b6179bSKris Buschelman   distributed and sequential matrices via the external package MUMPS.
240324b6179bSKris Buschelman 
240441c8de11SBarry Smith   Works with MATAIJ and MATSBAIJ matrices
240524b6179bSKris Buschelman 
2406c2b89b5dSBarry Smith   Use ./configure --download-mumps --download-scalapack --download-parmetis --download-metis --download-ptscotch  to have PETSc installed with MUMPS
2407c2b89b5dSBarry Smith 
2408c2b89b5dSBarry Smith   Use -pc_type cholesky or lu -pc_factor_mat_solver_package mumps to us this direct solver
2409c2b89b5dSBarry Smith 
241024b6179bSKris Buschelman   Options Database Keys:
24114422a9fcSPatrick Sanan +  -mat_mumps_icntl_1 - ICNTL(1): output stream for error messages
24124422a9fcSPatrick Sanan .  -mat_mumps_icntl_2 - ICNTL(2): output stream for diagnostic printing, statistics, and warning
24134422a9fcSPatrick Sanan .  -mat_mumps_icntl_3 -  ICNTL(3): output stream for global information, collected on the host
24144422a9fcSPatrick Sanan .  -mat_mumps_icntl_4 -  ICNTL(4): level of printing (0 to 4)
24154422a9fcSPatrick Sanan .  -mat_mumps_icntl_6 - ICNTL(6): permutes to a zero-free diagonal and/or scale the matrix (0 to 7)
24164422a9fcSPatrick Sanan .  -mat_mumps_icntl_7 - ICNTL(7): computes a symmetric permutation in sequential analysis (0 to 7). 3=Scotch, 4=PORD, 5=Metis
24174422a9fcSPatrick Sanan .  -mat_mumps_icntl_8  - ICNTL(8): scaling strategy (-2 to 8 or 77)
24184422a9fcSPatrick Sanan .  -mat_mumps_icntl_10  - ICNTL(10): max num of refinements
24194422a9fcSPatrick Sanan .  -mat_mumps_icntl_11  - ICNTL(11): statistics related to an error analysis (via -ksp_view)
24204422a9fcSPatrick Sanan .  -mat_mumps_icntl_12  - ICNTL(12): an ordering strategy for symmetric matrices (0 to 3)
24214422a9fcSPatrick Sanan .  -mat_mumps_icntl_13  - ICNTL(13): parallelism of the root node (enable ScaLAPACK) and its splitting
24224422a9fcSPatrick Sanan .  -mat_mumps_icntl_14  - ICNTL(14): percentage increase in the estimated working space
24234422a9fcSPatrick Sanan .  -mat_mumps_icntl_19  - ICNTL(19): computes the Schur complement
24244422a9fcSPatrick Sanan .  -mat_mumps_icntl_22  - ICNTL(22): in-core/out-of-core factorization and solve (0 or 1)
24254422a9fcSPatrick Sanan .  -mat_mumps_icntl_23  - ICNTL(23): max size of the working memory (MB) that can allocate per processor
24264422a9fcSPatrick Sanan .  -mat_mumps_icntl_24  - ICNTL(24): detection of null pivot rows (0 or 1)
24274422a9fcSPatrick Sanan .  -mat_mumps_icntl_25  - ICNTL(25): compute a solution of a deficient matrix and a null space basis
24284422a9fcSPatrick Sanan .  -mat_mumps_icntl_26  - ICNTL(26): drives the solution phase if a Schur complement matrix
24294422a9fcSPatrick Sanan .  -mat_mumps_icntl_28  - ICNTL(28): use 1 for sequential analysis and ictnl(7) ordering, or 2 for parallel analysis and ictnl(29) ordering
24304422a9fcSPatrick Sanan .  -mat_mumps_icntl_29 - ICNTL(29): parallel ordering 1 = ptscotch, 2 = parmetis
24314422a9fcSPatrick Sanan .  -mat_mumps_icntl_30 - ICNTL(30): compute user-specified set of entries in inv(A)
24324422a9fcSPatrick Sanan .  -mat_mumps_icntl_31 - ICNTL(31): indicates which factors may be discarded during factorization
24334422a9fcSPatrick Sanan .  -mat_mumps_icntl_33 - ICNTL(33): compute determinant
24344422a9fcSPatrick Sanan .  -mat_mumps_cntl_1  - CNTL(1): relative pivoting threshold
24354422a9fcSPatrick Sanan .  -mat_mumps_cntl_2  -  CNTL(2): stopping criterion of refinement
24364422a9fcSPatrick Sanan .  -mat_mumps_cntl_3 - CNTL(3): absolute pivoting threshold
24374422a9fcSPatrick Sanan .  -mat_mumps_cntl_4 - CNTL(4): value for static pivoting
24384422a9fcSPatrick Sanan -  -mat_mumps_cntl_5 - CNTL(5): fixation for null pivots
243924b6179bSKris Buschelman 
244024b6179bSKris Buschelman   Level: beginner
244124b6179bSKris Buschelman 
24429fc87aa7SBarry Smith     Notes: When a MUMPS factorization fails inside a KSP solve, for example with a KSP_DIVERGED_PCSETUP_FAILED, one can find the MUMPS information about the failure by calling
24439fc87aa7SBarry Smith $          KSPGetPC(ksp,&pc);
24449fc87aa7SBarry Smith $          PCFactorGetMatrix(pc,&mat);
24459fc87aa7SBarry Smith $          MatMumpsGetInfo(mat,....);
24469fc87aa7SBarry Smith $          MatMumpsGetInfog(mat,....); etc.
24479fc87aa7SBarry Smith            Or you can run with -ksp_error_if_not_converged and the program will be stopped and the information printed in the error message.
24489fc87aa7SBarry Smith 
24499fc87aa7SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage, MatMumpsSetICntl(), MatMumpsGetIcntl(), MatMumpsSetCntl(), MatMumpsGetCntl(), MatMumpsGetInfo(), MatMumpsGetInfog(), MatMumpsGetRinfo(), MatMumpsGetRinfog(), KSPGetPC(), PCGetFactor(), PCFactorGetMatrix()
245041c8de11SBarry Smith 
245124b6179bSKris Buschelman M*/
245224b6179bSKris Buschelman 
245335bd34faSBarry Smith #undef __FUNCT__
245435bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_mumps"
2455f7a08781SBarry Smith static PetscErrorCode MatFactorGetSolverPackage_mumps(Mat A,const MatSolverPackage *type)
245635bd34faSBarry Smith {
245735bd34faSBarry Smith   PetscFunctionBegin;
24582692d6eeSBarry Smith   *type = MATSOLVERMUMPS;
245935bd34faSBarry Smith   PetscFunctionReturn(0);
246035bd34faSBarry Smith }
246135bd34faSBarry Smith 
2462bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI AIJ matrices */
24632877fffaSHong Zhang #undef __FUNCT__
2464bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_aij_mumps"
2465cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_aij_mumps(Mat A,MatFactorType ftype,Mat *F)
24662877fffaSHong Zhang {
24672877fffaSHong Zhang   Mat            B;
24682877fffaSHong Zhang   PetscErrorCode ierr;
24692877fffaSHong Zhang   Mat_MUMPS      *mumps;
2470ace3abfcSBarry Smith   PetscBool      isSeqAIJ;
24712877fffaSHong Zhang 
24722877fffaSHong Zhang   PetscFunctionBegin;
24732877fffaSHong Zhang   /* Create the factorization matrix */
2474251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
2475ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
24762877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
24772877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2478bccb9932SShri Abhyankar   if (isSeqAIJ) {
24790298fd71SBarry Smith     ierr = MatSeqAIJSetPreallocation(B,0,NULL);CHKERRQ(ierr);
2480bccb9932SShri Abhyankar   } else {
24810298fd71SBarry Smith     ierr = MatMPIAIJSetPreallocation(B,0,NULL,0,NULL);CHKERRQ(ierr);
2482bccb9932SShri Abhyankar   }
24832877fffaSHong Zhang 
2484b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
24852205254eSKarl Rupp 
24862877fffaSHong Zhang   B->ops->view        = MatView_MUMPS;
248735bd34faSBarry Smith   B->ops->getinfo     = MatGetInfo_MUMPS;
248820be8e61SHong Zhang   B->ops->getdiagonal = MatGetDiagonal_MUMPS;
24892205254eSKarl Rupp 
2490bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
24915a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSetSchurIS_C",MatFactorSetSchurIS_MUMPS);CHKERRQ(ierr);
24925a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorInvertSchurComplement_C",MatFactorInvertSchurComplement_MUMPS);CHKERRQ(ierr);
24935a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorCreateSchurComplement_C",MatFactorCreateSchurComplement_MUMPS);CHKERRQ(ierr);
24945a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSchurComplement_C",MatFactorGetSchurComplement_MUMPS);CHKERRQ(ierr);
24955a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplement_C",MatFactorSolveSchurComplement_MUMPS);CHKERRQ(ierr);
24965a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplementTranspose_C",MatFactorSolveSchurComplementTranspose_MUMPS);CHKERRQ(ierr);
2497bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2498bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2499bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2500bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2501ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2502ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2503ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2504ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
25056444a565SStefano Zampini 
2506450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
2507450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
2508d5f3da31SBarry Smith     B->factortype            = MAT_FACTOR_LU;
2509bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqaij;
2510bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpiaij;
2511746480a1SHong Zhang     mumps->sym = 0;
2512dcd589f8SShri Abhyankar   } else {
251367877ebaSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
2514450b117fSShri Abhyankar     B->factortype                  = MAT_FACTOR_CHOLESKY;
2515bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqsbaij;
2516bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpisbaij;
251759ac8732SStefano Zampini #if defined(PETSC_USE_COMPLEX)
251859ac8732SStefano Zampini     mumps->sym = 2;
251959ac8732SStefano Zampini #else
25206fdc2a6dSBarry Smith     if (A->spd_set && A->spd) mumps->sym = 1;
25216fdc2a6dSBarry Smith     else                      mumps->sym = 2;
252259ac8732SStefano Zampini #endif
2523450b117fSShri Abhyankar   }
25242877fffaSHong Zhang 
252500c67f3bSHong Zhang   /* set solvertype */
252600c67f3bSHong Zhang   ierr = PetscFree(B->solvertype);CHKERRQ(ierr);
252700c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERMUMPS,&B->solvertype);CHKERRQ(ierr);
252800c67f3bSHong Zhang 
25292877fffaSHong Zhang   mumps->isAIJ    = PETSC_TRUE;
2530bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
25312877fffaSHong Zhang   B->ops->destroy = MatDestroy_MUMPS;
25322877fffaSHong Zhang   B->spptr        = (void*)mumps;
25332205254eSKarl Rupp 
2534f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2535746480a1SHong Zhang 
25362877fffaSHong Zhang   *F = B;
25372877fffaSHong Zhang   PetscFunctionReturn(0);
25382877fffaSHong Zhang }
25392877fffaSHong Zhang 
2540bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI SBAIJ matrices */
25412877fffaSHong Zhang #undef __FUNCT__
2542bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_sbaij_mumps"
2543cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_sbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
25442877fffaSHong Zhang {
25452877fffaSHong Zhang   Mat            B;
25462877fffaSHong Zhang   PetscErrorCode ierr;
25472877fffaSHong Zhang   Mat_MUMPS      *mumps;
2548ace3abfcSBarry Smith   PetscBool      isSeqSBAIJ;
25492877fffaSHong Zhang 
25502877fffaSHong Zhang   PetscFunctionBegin;
2551ce94432eSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
2552ce94432eSBarry Smith   if (A->rmap->bs > 1) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with block size > 1 with MUMPS Cholesky, use AIJ matrix instead");
2553251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
25542877fffaSHong Zhang   /* Create the factorization matrix */
2555ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
25562877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
25572877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2558b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
2559bccb9932SShri Abhyankar   if (isSeqSBAIJ) {
25600298fd71SBarry Smith     ierr = MatSeqSBAIJSetPreallocation(B,1,0,NULL);CHKERRQ(ierr);
25612205254eSKarl Rupp 
256216ebf90aSShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_seqsbaij_seqsbaij;
2563dcd589f8SShri Abhyankar   } else {
25640298fd71SBarry Smith     ierr = MatMPISBAIJSetPreallocation(B,1,0,NULL,0,NULL);CHKERRQ(ierr);
25652205254eSKarl Rupp 
2566bccb9932SShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_mpisbaij_mpisbaij;
2567bccb9932SShri Abhyankar   }
2568bccb9932SShri Abhyankar 
256967877ebaSShri Abhyankar   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
2570bccb9932SShri Abhyankar   B->ops->view                   = MatView_MUMPS;
257120be8e61SHong Zhang   B->ops->getdiagonal            = MatGetDiagonal_MUMPS;
25722205254eSKarl Rupp 
2573bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
25745a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSetSchurIS_C",MatFactorSetSchurIS_MUMPS);CHKERRQ(ierr);
25755a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorInvertSchurComplement_C",MatFactorInvertSchurComplement_MUMPS);CHKERRQ(ierr);
25765a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorCreateSchurComplement_C",MatFactorCreateSchurComplement_MUMPS);CHKERRQ(ierr);
25775a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSchurComplement_C",MatFactorGetSchurComplement_MUMPS);CHKERRQ(ierr);
25785a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplement_C",MatFactorSolveSchurComplement_MUMPS);CHKERRQ(ierr);
25795a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplementTranspose_C",MatFactorSolveSchurComplementTranspose_MUMPS);CHKERRQ(ierr);
2580b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2581b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2582b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2583b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2584ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2585ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2586ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2587ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
25882205254eSKarl Rupp 
2589f4762488SHong Zhang   B->factortype = MAT_FACTOR_CHOLESKY;
259059ac8732SStefano Zampini #if defined(PETSC_USE_COMPLEX)
259159ac8732SStefano Zampini   mumps->sym = 2;
259259ac8732SStefano Zampini #else
25936fdc2a6dSBarry Smith   if (A->spd_set && A->spd) mumps->sym = 1;
25946fdc2a6dSBarry Smith   else                      mumps->sym = 2;
259559ac8732SStefano Zampini #endif
2596a214ac2aSShri Abhyankar 
259700c67f3bSHong Zhang   /* set solvertype */
259800c67f3bSHong Zhang   ierr = PetscFree(B->solvertype);CHKERRQ(ierr);
259900c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERMUMPS,&B->solvertype);CHKERRQ(ierr);
260000c67f3bSHong Zhang 
2601bccb9932SShri Abhyankar   mumps->isAIJ    = PETSC_FALSE;
2602bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
2603f3c0ef26SHong Zhang   B->ops->destroy = MatDestroy_MUMPS;
26042877fffaSHong Zhang   B->spptr        = (void*)mumps;
26052205254eSKarl Rupp 
2606f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2607746480a1SHong Zhang 
26082877fffaSHong Zhang   *F = B;
26092877fffaSHong Zhang   PetscFunctionReturn(0);
26102877fffaSHong Zhang }
261197969023SHong Zhang 
2612450b117fSShri Abhyankar #undef __FUNCT__
2613bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_baij_mumps"
2614cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_baij_mumps(Mat A,MatFactorType ftype,Mat *F)
261567877ebaSShri Abhyankar {
261667877ebaSShri Abhyankar   Mat            B;
261767877ebaSShri Abhyankar   PetscErrorCode ierr;
261867877ebaSShri Abhyankar   Mat_MUMPS      *mumps;
2619ace3abfcSBarry Smith   PetscBool      isSeqBAIJ;
262067877ebaSShri Abhyankar 
262167877ebaSShri Abhyankar   PetscFunctionBegin;
262267877ebaSShri Abhyankar   /* Create the factorization matrix */
2623251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&isSeqBAIJ);CHKERRQ(ierr);
2624ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
262567877ebaSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
262667877ebaSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2627bccb9932SShri Abhyankar   if (isSeqBAIJ) {
26280298fd71SBarry Smith     ierr = MatSeqBAIJSetPreallocation(B,A->rmap->bs,0,NULL);CHKERRQ(ierr);
2629bccb9932SShri Abhyankar   } else {
26300298fd71SBarry Smith     ierr = MatMPIBAIJSetPreallocation(B,A->rmap->bs,0,NULL,0,NULL);CHKERRQ(ierr);
2631bccb9932SShri Abhyankar   }
2632450b117fSShri Abhyankar 
2633b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
2634450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
2635450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_BAIJMUMPS;
2636450b117fSShri Abhyankar     B->factortype            = MAT_FACTOR_LU;
2637bccb9932SShri Abhyankar     if (isSeqBAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqbaij_seqaij;
2638bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpibaij_mpiaij;
2639746480a1SHong Zhang     mumps->sym = 0;
2640f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc BAIJ matrices with MUMPS Cholesky, use SBAIJ or AIJ matrix instead\n");
2641bccb9932SShri Abhyankar 
2642450b117fSShri Abhyankar   B->ops->view        = MatView_MUMPS;
264320be8e61SHong Zhang   B->ops->getdiagonal = MatGetDiagonal_MUMPS;
26442205254eSKarl Rupp 
2645bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
26465a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSetSchurIS_C",MatFactorSetSchurIS_MUMPS);CHKERRQ(ierr);
26475a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorInvertSchurComplement_C",MatFactorInvertSchurComplement_MUMPS);CHKERRQ(ierr);
26485a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorCreateSchurComplement_C",MatFactorCreateSchurComplement_MUMPS);CHKERRQ(ierr);
26495a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSchurComplement_C",MatFactorGetSchurComplement_MUMPS);CHKERRQ(ierr);
26505a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplement_C",MatFactorSolveSchurComplement_MUMPS);CHKERRQ(ierr);
26515a05ddb0SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorSolveSchurComplementTranspose_C",MatFactorSolveSchurComplementTranspose_MUMPS);CHKERRQ(ierr);
2652bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2653bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2654bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2655bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2656ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2657ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2658ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2659ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
2660450b117fSShri Abhyankar 
266100c67f3bSHong Zhang   /* set solvertype */
266200c67f3bSHong Zhang   ierr = PetscFree(B->solvertype);CHKERRQ(ierr);
266300c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERMUMPS,&B->solvertype);CHKERRQ(ierr);
266400c67f3bSHong Zhang 
2665450b117fSShri Abhyankar   mumps->isAIJ    = PETSC_TRUE;
2666bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
2667450b117fSShri Abhyankar   B->ops->destroy = MatDestroy_MUMPS;
2668450b117fSShri Abhyankar   B->spptr        = (void*)mumps;
26692205254eSKarl Rupp 
2670f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2671746480a1SHong Zhang 
2672450b117fSShri Abhyankar   *F = B;
2673450b117fSShri Abhyankar   PetscFunctionReturn(0);
2674450b117fSShri Abhyankar }
267542c9c57cSBarry Smith 
267642c9c57cSBarry Smith #undef __FUNCT__
267742c9c57cSBarry Smith #define __FUNCT__ "MatSolverPackageRegister_MUMPS"
267829b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverPackageRegister_MUMPS(void)
267942c9c57cSBarry Smith {
268042c9c57cSBarry Smith   PetscErrorCode ierr;
268142c9c57cSBarry Smith 
268242c9c57cSBarry Smith   PetscFunctionBegin;
268342c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIAIJ,MAT_FACTOR_LU,MatGetFactor_aij_mumps);CHKERRQ(ierr);
268442c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_aij_mumps);CHKERRQ(ierr);
268542c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIBAIJ,MAT_FACTOR_LU,MatGetFactor_baij_mumps);CHKERRQ(ierr);
268642c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIBAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_baij_mumps);CHKERRQ(ierr);
268742c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPISBAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_sbaij_mumps);CHKERRQ(ierr);
268842c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQAIJ,MAT_FACTOR_LU,MatGetFactor_aij_mumps);CHKERRQ(ierr);
268942c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_aij_mumps);CHKERRQ(ierr);
269042c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQBAIJ,MAT_FACTOR_LU,MatGetFactor_baij_mumps);CHKERRQ(ierr);
269142c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQBAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_baij_mumps);CHKERRQ(ierr);
269242c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQSBAIJ,MAT_FACTOR_CHOLESKY,MatGetFactor_sbaij_mumps);CHKERRQ(ierr);
269342c9c57cSBarry Smith   PetscFunctionReturn(0);
269442c9c57cSBarry Smith }
269542c9c57cSBarry Smith 
2696