xref: /petsc/src/mat/impls/aij/mpi/mumps/mumps.c (revision b5fa320b275400347f0c91cf9cdb748ffcb8cd57)
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>
8*b5fa320bSStefano 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;
8564e6c443SBarry Smith   PetscBool    isAIJ,CleanUpMUMPS;
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 */
90*b5fa320bSStefano Zampini   PetscBool    schur_factored;
91*b5fa320bSStefano Zampini   PetscBool    schur_second_solve;
92*b5fa320bSStefano Zampini   PetscInt     sizeredrhs;
93*b5fa320bSStefano Zampini   PetscInt     *schur_pivots;
94*b5fa320bSStefano Zampini   PetscScalar  *schur_work;
952205254eSKarl Rupp 
96bf0cc555SLisandro Dalcin   PetscErrorCode (*Destroy)(Mat);
97bccb9932SShri Abhyankar   PetscErrorCode (*ConvertToTriples)(Mat, int, MatReuse, int*, int**, int**, PetscScalar**);
98f0c56d0fSKris Buschelman } Mat_MUMPS;
99f0c56d0fSKris Buschelman 
10009573ac7SBarry Smith extern PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*);
101b24902e0SBarry Smith 
102*b5fa320bSStefano Zampini static PetscErrorCode MatMumpsSolveSchur_Private(Mat_MUMPS* mumps)
103*b5fa320bSStefano Zampini {
104*b5fa320bSStefano Zampini #if !defined(PETSC_USE_COMPLEX)
105*b5fa320bSStefano Zampini   PetscBLASInt   B_N,B_Nrhs,B_ierr,B_slda,B_rlda;
106*b5fa320bSStefano Zampini   PetscErrorCode ierr;
107*b5fa320bSStefano Zampini 
108*b5fa320bSStefano Zampini   PetscFunctionBegin;
109*b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.size_schur,&B_N);CHKERRQ(ierr);
110*b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.schur_lld,&B_slda);CHKERRQ(ierr);
111*b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.nrhs,&B_Nrhs);CHKERRQ(ierr);
112*b5fa320bSStefano Zampini   ierr = PetscBLASIntCast(mumps->id.lredrhs,&B_rlda);CHKERRQ(ierr);
113*b5fa320bSStefano Zampini   if (mumps->sym == 0) { /* MUMPS always return a full Schur matrix */
114*b5fa320bSStefano Zampini     if (!mumps->schur_factored) {
115*b5fa320bSStefano Zampini       if (!mumps->schur_pivots) {
116*b5fa320bSStefano Zampini         ierr = PetscMalloc2(B_N,&mumps->schur_pivots,0,&mumps->schur_work);CHKERRQ(ierr);
117*b5fa320bSStefano Zampini       }
118*b5fa320bSStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
119*b5fa320bSStefano Zampini       PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&B_N,&B_N,mumps->id.schur,&B_N,mumps->schur_pivots,&B_ierr));
120*b5fa320bSStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
121*b5fa320bSStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GETRF Lapack routine %d",(int)B_ierr);
122*b5fa320bSStefano Zampini       mumps->schur_factored = PETSC_TRUE;
123*b5fa320bSStefano Zampini     }
124*b5fa320bSStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
125*b5fa320bSStefano Zampini     if (mumps->id.ICNTL(19) == 1) { /* stored by rows */
126*b5fa320bSStefano Zampini       PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&B_N,&B_Nrhs,mumps->id.schur,&B_slda,mumps->schur_pivots,mumps->id.redrhs,&B_rlda,&B_ierr));
127*b5fa320bSStefano Zampini     } else {
128*b5fa320bSStefano Zampini       PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&B_N,&B_Nrhs,mumps->id.schur,&B_slda,mumps->schur_pivots,mumps->id.redrhs,&B_rlda,&B_ierr));
129*b5fa320bSStefano Zampini     }
130*b5fa320bSStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
131*b5fa320bSStefano Zampini     if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GETRS Lapack routine %d",(int)B_ierr);
132*b5fa320bSStefano Zampini   } else { /* either full or lower-triangular (not packed) */
133*b5fa320bSStefano Zampini     char ord[2];
134*b5fa320bSStefano Zampini     if (mumps->id.ICNTL(19) == 2 || mumps->id.ICNTL(19) == 3) { /* lower triangular stored by columns or full matrix */
135*b5fa320bSStefano Zampini       sprintf(ord,"L");
136*b5fa320bSStefano Zampini     } else { /* ICNTL(19) == 1 lower triangular stored by rows */
137*b5fa320bSStefano Zampini       sprintf(ord,"U");
138*b5fa320bSStefano Zampini     }
139*b5fa320bSStefano Zampini     if (!mumps->schur_factored) {
140*b5fa320bSStefano Zampini       if (mumps->id.sym == 2) {
141*b5fa320bSStefano Zampini         if (!mumps->schur_pivots) {
142*b5fa320bSStefano Zampini           PetscScalar  lwork;
143*b5fa320bSStefano Zampini           PetscBLASInt B_lwork=-1;
144*b5fa320bSStefano Zampini 
145*b5fa320bSStefano Zampini           ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
146*b5fa320bSStefano Zampini           PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_(ord,&B_N,mumps->id.schur,&B_N,mumps->schur_pivots,&lwork,&B_lwork,&B_ierr));
147*b5fa320bSStefano Zampini           ierr = PetscFPTrapPop();CHKERRQ(ierr);
148*b5fa320bSStefano Zampini           if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYTRF Lapack routine %d",(int)B_ierr);
149*b5fa320bSStefano Zampini           ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr);
150*b5fa320bSStefano Zampini           ierr = PetscMalloc2(B_N,&mumps->schur_pivots,B_lwork,&mumps->schur_work);CHKERRQ(ierr);
151*b5fa320bSStefano Zampini         }
152*b5fa320bSStefano Zampini         ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
153*b5fa320bSStefano Zampini         PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_(ord,&B_N,mumps->id.schur,&B_N,mumps->schur_pivots,mumps->schur_work,&B_N,&B_ierr));
154*b5fa320bSStefano Zampini         ierr = PetscFPTrapPop();CHKERRQ(ierr);
155*b5fa320bSStefano Zampini         if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYTRF Lapack routine %d",(int)B_ierr);
156*b5fa320bSStefano Zampini       } else {
157*b5fa320bSStefano Zampini         ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
158*b5fa320bSStefano Zampini         PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_(ord,&B_N,mumps->id.schur,&B_N,&B_ierr));
159*b5fa320bSStefano Zampini         ierr = PetscFPTrapPop();CHKERRQ(ierr);
160*b5fa320bSStefano Zampini         if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in POTRF Lapack routine %d",(int)B_ierr);
161*b5fa320bSStefano Zampini       }
162*b5fa320bSStefano Zampini       mumps->schur_factored = PETSC_TRUE;
163*b5fa320bSStefano Zampini     }
164*b5fa320bSStefano Zampini     if (mumps->id.sym == 2) {
165*b5fa320bSStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
166*b5fa320bSStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_(ord,&B_N,&B_Nrhs,mumps->id.schur,&B_slda,mumps->schur_pivots,mumps->id.redrhs,&B_rlda,&B_ierr));
167*b5fa320bSStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
168*b5fa320bSStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYTRS Lapack routine %d",(int)B_ierr);
169*b5fa320bSStefano Zampini     } else {
170*b5fa320bSStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
171*b5fa320bSStefano Zampini       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_(ord,&B_N,&B_Nrhs,mumps->id.schur,&B_slda,mumps->id.redrhs,&B_rlda,&B_ierr));
172*b5fa320bSStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
173*b5fa320bSStefano Zampini       if (B_ierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in POTRS Lapack routine %d",(int)B_ierr);
174*b5fa320bSStefano Zampini     }
175*b5fa320bSStefano Zampini   }
176*b5fa320bSStefano Zampini   PetscFunctionReturn(0);
177*b5fa320bSStefano Zampini #else
178*b5fa320bSStefano Zampini   PetscFunctionBegin;
179*b5fa320bSStefano Zampini   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Support for full solve with Schur complement not yet implemented for complexes\n");
180*b5fa320bSStefano Zampini   PetscFunctionReturn(0);
181*b5fa320bSStefano Zampini #endif /* for complexes need an extra copy */
182*b5fa320bSStefano Zampini }
183*b5fa320bSStefano Zampini 
184*b5fa320bSStefano Zampini static PetscErrorCode MatMumpsHandleSchur_Private(Mat_MUMPS* mumps)
185*b5fa320bSStefano Zampini {
186*b5fa320bSStefano Zampini   PetscErrorCode ierr;
187*b5fa320bSStefano Zampini 
188*b5fa320bSStefano Zampini   PetscFunctionBegin;
189*b5fa320bSStefano Zampini   if (!mumps->id.ICNTL(19)) { /* do nothing when Schur complement has not been computed */
190*b5fa320bSStefano Zampini     PetscFunctionReturn(0);
191*b5fa320bSStefano Zampini   }
192*b5fa320bSStefano Zampini   if (!mumps->schur_second_solve) { /* prepare for the condensation step */
193*b5fa320bSStefano Zampini     /* check if schur complement has been computed
194*b5fa320bSStefano Zampini        We set by default ICNTL(26) == -1 when Schur indices are provided by the user.
195*b5fa320bSStefano Zampini        According to MUMPS (5.0.0) manual, any value should be harmful during the factorization phase
196*b5fa320bSStefano Zampini        Unless the user provides a valid value for ICNTL(26), MatSolve and MatMatSolve routines solve the full system.
197*b5fa320bSStefano Zampini        This requires an extra call to PetscMUMPS_c and the computation of the factors for S, handled setting double_schur_solve to PETSC_TRUE */
198*b5fa320bSStefano Zampini     if (mumps->id.ICNTL(26) < 0 || mumps->id.ICNTL(26) > 2) {
199*b5fa320bSStefano Zampini       PetscInt sizeredrhs = mumps->id.nrhs*mumps->id.size_schur;
200*b5fa320bSStefano Zampini       /* allocate MUMPS internal array to store reduced right-hand sides */
201*b5fa320bSStefano Zampini       if (!mumps->id.redrhs || sizeredrhs > mumps->sizeredrhs) {
202*b5fa320bSStefano Zampini         ierr = PetscFree(mumps->id.redrhs);CHKERRQ(ierr);
203*b5fa320bSStefano Zampini         mumps->id.lredrhs = mumps->id.size_schur;
204*b5fa320bSStefano Zampini         ierr = PetscMalloc1(mumps->id.nrhs*mumps->id.lredrhs,&mumps->id.redrhs);CHKERRQ(ierr);
205*b5fa320bSStefano Zampini         mumps->sizeredrhs = mumps->id.nrhs*mumps->id.lredrhs;
206*b5fa320bSStefano Zampini       }
207*b5fa320bSStefano Zampini       mumps->schur_second_solve = PETSC_TRUE;
208*b5fa320bSStefano Zampini       mumps->id.ICNTL(26) = 1; /* condensation phase */
209*b5fa320bSStefano Zampini     }
210*b5fa320bSStefano Zampini   } else { /* prepare for the expansion step */
211*b5fa320bSStefano Zampini     /* solve Schur complement (this should be done by the MUMPS user, so basically us) */
212*b5fa320bSStefano Zampini     ierr = MatMumpsSolveSchur_Private(mumps);CHKERRQ(ierr);
213*b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = 2; /* expansion phase */
214*b5fa320bSStefano Zampini     PetscMUMPS_c(&mumps->id);
215*b5fa320bSStefano 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));
216*b5fa320bSStefano Zampini     /* restore defaults */
217*b5fa320bSStefano Zampini     mumps->id.ICNTL(26) = -1;
218*b5fa320bSStefano Zampini     mumps->schur_second_solve = PETSC_FALSE;
219*b5fa320bSStefano Zampini   }
220*b5fa320bSStefano Zampini   PetscFunctionReturn(0);
221*b5fa320bSStefano Zampini }
222*b5fa320bSStefano Zampini 
223397b6df1SKris Buschelman /*
224d341cd04SHong Zhang   MatConvertToTriples_A_B - convert Petsc matrix to triples: row[nz], col[nz], val[nz]
225d341cd04SHong Zhang 
226397b6df1SKris Buschelman   input:
22767877ebaSShri Abhyankar     A       - matrix in aij,baij or sbaij (bs=1) format
228397b6df1SKris Buschelman     shift   - 0: C style output triple; 1: Fortran style output triple.
229bccb9932SShri Abhyankar     reuse   - MAT_INITIAL_MATRIX: spaces are allocated and values are set for the triple
230bccb9932SShri Abhyankar               MAT_REUSE_MATRIX:   only the values in v array are updated
231397b6df1SKris Buschelman   output:
232397b6df1SKris Buschelman     nnz     - dim of r, c, and v (number of local nonzero entries of A)
233397b6df1SKris Buschelman     r, c, v - row and col index, matrix values (matrix triples)
234eb9baa12SBarry Smith 
235eb9baa12SBarry Smith   The returned values r, c, and sometimes v are obtained in a single PetscMalloc(). Then in MatDestroy_MUMPS() it is
236eb9baa12SBarry Smith   freed with PetscFree((mumps->irn);  This is not ideal code, the fact that v is ONLY sometimes part of mumps->irn means
237eb9baa12SBarry Smith   that the PetscMalloc() cannot easily be replaced with a PetscMalloc3().
238eb9baa12SBarry Smith 
239397b6df1SKris Buschelman  */
24016ebf90aSShri Abhyankar 
24116ebf90aSShri Abhyankar #undef __FUNCT__
24216ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqaij"
243bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
244b24902e0SBarry Smith {
245185f6596SHong Zhang   const PetscInt *ai,*aj,*ajj,M=A->rmap->n;
24667877ebaSShri Abhyankar   PetscInt       nz,rnz,i,j;
247dfbe8321SBarry Smith   PetscErrorCode ierr;
248c1490034SHong Zhang   PetscInt       *row,*col;
24916ebf90aSShri Abhyankar   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)A->data;
250397b6df1SKris Buschelman 
251397b6df1SKris Buschelman   PetscFunctionBegin;
25216ebf90aSShri Abhyankar   *v=aa->a;
253bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
2542205254eSKarl Rupp     nz   = aa->nz;
2552205254eSKarl Rupp     ai   = aa->i;
2562205254eSKarl Rupp     aj   = aa->j;
25716ebf90aSShri Abhyankar     *nnz = nz;
258785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
259185f6596SHong Zhang     col  = row + nz;
260185f6596SHong Zhang 
26116ebf90aSShri Abhyankar     nz = 0;
26216ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
26316ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
26467877ebaSShri Abhyankar       ajj = aj + ai[i];
26567877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
26667877ebaSShri Abhyankar         row[nz] = i+shift; col[nz++] = ajj[j] + shift;
26716ebf90aSShri Abhyankar       }
26816ebf90aSShri Abhyankar     }
26916ebf90aSShri Abhyankar     *r = row; *c = col;
27016ebf90aSShri Abhyankar   }
27116ebf90aSShri Abhyankar   PetscFunctionReturn(0);
27216ebf90aSShri Abhyankar }
273397b6df1SKris Buschelman 
27416ebf90aSShri Abhyankar #undef __FUNCT__
27567877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqbaij_seqaij"
276bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqbaij_seqaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
27767877ebaSShri Abhyankar {
27867877ebaSShri Abhyankar   Mat_SeqBAIJ    *aa=(Mat_SeqBAIJ*)A->data;
27933d57670SJed Brown   const PetscInt *ai,*aj,*ajj,bs2 = aa->bs2;
28033d57670SJed Brown   PetscInt       bs,M,nz,idx=0,rnz,i,j,k,m;
28167877ebaSShri Abhyankar   PetscErrorCode ierr;
28267877ebaSShri Abhyankar   PetscInt       *row,*col;
28367877ebaSShri Abhyankar 
28467877ebaSShri Abhyankar   PetscFunctionBegin;
28533d57670SJed Brown   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
28633d57670SJed Brown   M = A->rmap->N/bs;
287cf3759fdSShri Abhyankar   *v = aa->a;
288bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
289cf3759fdSShri Abhyankar     ai   = aa->i; aj = aa->j;
29067877ebaSShri Abhyankar     nz   = bs2*aa->nz;
29167877ebaSShri Abhyankar     *nnz = nz;
292785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
293185f6596SHong Zhang     col  = row + nz;
294185f6596SHong Zhang 
29567877ebaSShri Abhyankar     for (i=0; i<M; i++) {
29667877ebaSShri Abhyankar       ajj = aj + ai[i];
29767877ebaSShri Abhyankar       rnz = ai[i+1] - ai[i];
29867877ebaSShri Abhyankar       for (k=0; k<rnz; k++) {
29967877ebaSShri Abhyankar         for (j=0; j<bs; j++) {
30067877ebaSShri Abhyankar           for (m=0; m<bs; m++) {
30167877ebaSShri Abhyankar             row[idx]   = i*bs + m + shift;
302cf3759fdSShri Abhyankar             col[idx++] = bs*(ajj[k]) + j + shift;
30367877ebaSShri Abhyankar           }
30467877ebaSShri Abhyankar         }
30567877ebaSShri Abhyankar       }
30667877ebaSShri Abhyankar     }
307cf3759fdSShri Abhyankar     *r = row; *c = col;
30867877ebaSShri Abhyankar   }
30967877ebaSShri Abhyankar   PetscFunctionReturn(0);
31067877ebaSShri Abhyankar }
31167877ebaSShri Abhyankar 
31267877ebaSShri Abhyankar #undef __FUNCT__
31316ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqsbaij_seqsbaij"
314bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqsbaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
31516ebf90aSShri Abhyankar {
31667877ebaSShri Abhyankar   const PetscInt *ai, *aj,*ajj,M=A->rmap->n;
31767877ebaSShri Abhyankar   PetscInt       nz,rnz,i,j;
31816ebf90aSShri Abhyankar   PetscErrorCode ierr;
31916ebf90aSShri Abhyankar   PetscInt       *row,*col;
32016ebf90aSShri Abhyankar   Mat_SeqSBAIJ   *aa=(Mat_SeqSBAIJ*)A->data;
32116ebf90aSShri Abhyankar 
32216ebf90aSShri Abhyankar   PetscFunctionBegin;
323882afa5aSHong Zhang   *v = aa->a;
324bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
3252205254eSKarl Rupp     nz   = aa->nz;
3262205254eSKarl Rupp     ai   = aa->i;
3272205254eSKarl Rupp     aj   = aa->j;
3282205254eSKarl Rupp     *v   = aa->a;
32916ebf90aSShri Abhyankar     *nnz = nz;
330785e854fSJed Brown     ierr = PetscMalloc1(2*nz, &row);CHKERRQ(ierr);
331185f6596SHong Zhang     col  = row + nz;
332185f6596SHong Zhang 
33316ebf90aSShri Abhyankar     nz = 0;
33416ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
33516ebf90aSShri Abhyankar       rnz = ai[i+1] - ai[i];
33667877ebaSShri Abhyankar       ajj = aj + ai[i];
33767877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
33867877ebaSShri Abhyankar         row[nz] = i+shift; col[nz++] = ajj[j] + shift;
33916ebf90aSShri Abhyankar       }
34016ebf90aSShri Abhyankar     }
34116ebf90aSShri Abhyankar     *r = row; *c = col;
34216ebf90aSShri Abhyankar   }
34316ebf90aSShri Abhyankar   PetscFunctionReturn(0);
34416ebf90aSShri Abhyankar }
34516ebf90aSShri Abhyankar 
34616ebf90aSShri Abhyankar #undef __FUNCT__
34716ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_seqaij_seqsbaij"
348bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_seqaij_seqsbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
34916ebf90aSShri Abhyankar {
35067877ebaSShri Abhyankar   const PetscInt    *ai,*aj,*ajj,*adiag,M=A->rmap->n;
35167877ebaSShri Abhyankar   PetscInt          nz,rnz,i,j;
35267877ebaSShri Abhyankar   const PetscScalar *av,*v1;
35316ebf90aSShri Abhyankar   PetscScalar       *val;
35416ebf90aSShri Abhyankar   PetscErrorCode    ierr;
35516ebf90aSShri Abhyankar   PetscInt          *row,*col;
356829b1710SHong Zhang   Mat_SeqAIJ        *aa=(Mat_SeqAIJ*)A->data;
35716ebf90aSShri Abhyankar 
35816ebf90aSShri Abhyankar   PetscFunctionBegin;
35916ebf90aSShri Abhyankar   ai   =aa->i; aj=aa->j;av=aa->a;
36016ebf90aSShri Abhyankar   adiag=aa->diag;
361bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
362829b1710SHong Zhang     /* count nz in the uppper triangular part of A */
363829b1710SHong Zhang     nz = 0;
364829b1710SHong Zhang     for (i=0; i<M; i++) nz += ai[i+1] - adiag[i];
36516ebf90aSShri Abhyankar     *nnz = nz;
366829b1710SHong Zhang 
367185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
368185f6596SHong Zhang     col  = row + nz;
369185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
370185f6596SHong Zhang 
37116ebf90aSShri Abhyankar     nz = 0;
37216ebf90aSShri Abhyankar     for (i=0; i<M; i++) {
37316ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
37467877ebaSShri Abhyankar       ajj = aj + adiag[i];
375cf3759fdSShri Abhyankar       v1  = av + adiag[i];
37667877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
37767877ebaSShri Abhyankar         row[nz] = i+shift; col[nz] = ajj[j] + shift; val[nz++] = v1[j];
37816ebf90aSShri Abhyankar       }
37916ebf90aSShri Abhyankar     }
38016ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
381397b6df1SKris Buschelman   } else {
38216ebf90aSShri Abhyankar     nz = 0; val = *v;
38316ebf90aSShri Abhyankar     for (i=0; i <M; i++) {
38416ebf90aSShri Abhyankar       rnz = ai[i+1] - adiag[i];
38567877ebaSShri Abhyankar       ajj = aj + adiag[i];
38667877ebaSShri Abhyankar       v1  = av + adiag[i];
38767877ebaSShri Abhyankar       for (j=0; j<rnz; j++) {
38867877ebaSShri Abhyankar         val[nz++] = v1[j];
38916ebf90aSShri Abhyankar       }
39016ebf90aSShri Abhyankar     }
39116ebf90aSShri Abhyankar   }
39216ebf90aSShri Abhyankar   PetscFunctionReturn(0);
39316ebf90aSShri Abhyankar }
39416ebf90aSShri Abhyankar 
39516ebf90aSShri Abhyankar #undef __FUNCT__
39616ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpisbaij_mpisbaij"
397bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpisbaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
39816ebf90aSShri Abhyankar {
39916ebf90aSShri Abhyankar   const PetscInt    *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
40016ebf90aSShri Abhyankar   PetscErrorCode    ierr;
40116ebf90aSShri Abhyankar   PetscInt          rstart,nz,i,j,jj,irow,countA,countB;
40216ebf90aSShri Abhyankar   PetscInt          *row,*col;
40316ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
40416ebf90aSShri Abhyankar   PetscScalar       *val;
405397b6df1SKris Buschelman   Mat_MPISBAIJ      *mat = (Mat_MPISBAIJ*)A->data;
406397b6df1SKris Buschelman   Mat_SeqSBAIJ      *aa  = (Mat_SeqSBAIJ*)(mat->A)->data;
407397b6df1SKris Buschelman   Mat_SeqBAIJ       *bb  = (Mat_SeqBAIJ*)(mat->B)->data;
40816ebf90aSShri Abhyankar 
40916ebf90aSShri Abhyankar   PetscFunctionBegin;
410d0f46423SBarry Smith   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
411397b6df1SKris Buschelman   av=aa->a; bv=bb->a;
412397b6df1SKris Buschelman 
4132205254eSKarl Rupp   garray = mat->garray;
4142205254eSKarl Rupp 
415bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
41616ebf90aSShri Abhyankar     nz   = aa->nz + bb->nz;
41716ebf90aSShri Abhyankar     *nnz = nz;
418185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
419185f6596SHong Zhang     col  = row + nz;
420185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
421185f6596SHong Zhang 
422397b6df1SKris Buschelman     *r = row; *c = col; *v = val;
423397b6df1SKris Buschelman   } else {
424397b6df1SKris Buschelman     row = *r; col = *c; val = *v;
425397b6df1SKris Buschelman   }
426397b6df1SKris Buschelman 
427028e57e8SHong Zhang   jj = 0; irow = rstart;
428397b6df1SKris Buschelman   for (i=0; i<m; i++) {
429397b6df1SKris Buschelman     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
430397b6df1SKris Buschelman     countA = ai[i+1] - ai[i];
431397b6df1SKris Buschelman     countB = bi[i+1] - bi[i];
432397b6df1SKris Buschelman     bjj    = bj + bi[i];
43316ebf90aSShri Abhyankar     v1     = av + ai[i];
43416ebf90aSShri Abhyankar     v2     = bv + bi[i];
435397b6df1SKris Buschelman 
436397b6df1SKris Buschelman     /* A-part */
437397b6df1SKris Buschelman     for (j=0; j<countA; j++) {
438bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
439397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
440397b6df1SKris Buschelman       }
44116ebf90aSShri Abhyankar       val[jj++] = v1[j];
442397b6df1SKris Buschelman     }
44316ebf90aSShri Abhyankar 
44416ebf90aSShri Abhyankar     /* B-part */
44516ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
446bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
447397b6df1SKris Buschelman         row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
448397b6df1SKris Buschelman       }
44916ebf90aSShri Abhyankar       val[jj++] = v2[j];
45016ebf90aSShri Abhyankar     }
45116ebf90aSShri Abhyankar     irow++;
45216ebf90aSShri Abhyankar   }
45316ebf90aSShri Abhyankar   PetscFunctionReturn(0);
45416ebf90aSShri Abhyankar }
45516ebf90aSShri Abhyankar 
45616ebf90aSShri Abhyankar #undef __FUNCT__
45716ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpiaij"
458bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
45916ebf90aSShri Abhyankar {
46016ebf90aSShri Abhyankar   const PetscInt    *ai, *aj, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
46116ebf90aSShri Abhyankar   PetscErrorCode    ierr;
46216ebf90aSShri Abhyankar   PetscInt          rstart,nz,i,j,jj,irow,countA,countB;
46316ebf90aSShri Abhyankar   PetscInt          *row,*col;
46416ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
46516ebf90aSShri Abhyankar   PetscScalar       *val;
46616ebf90aSShri Abhyankar   Mat_MPIAIJ        *mat = (Mat_MPIAIJ*)A->data;
46716ebf90aSShri Abhyankar   Mat_SeqAIJ        *aa  = (Mat_SeqAIJ*)(mat->A)->data;
46816ebf90aSShri Abhyankar   Mat_SeqAIJ        *bb  = (Mat_SeqAIJ*)(mat->B)->data;
46916ebf90aSShri Abhyankar 
47016ebf90aSShri Abhyankar   PetscFunctionBegin;
47116ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
47216ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
47316ebf90aSShri Abhyankar 
4742205254eSKarl Rupp   garray = mat->garray;
4752205254eSKarl Rupp 
476bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
47716ebf90aSShri Abhyankar     nz   = aa->nz + bb->nz;
47816ebf90aSShri Abhyankar     *nnz = nz;
479185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
480185f6596SHong Zhang     col  = row + nz;
481185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
482185f6596SHong Zhang 
48316ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
48416ebf90aSShri Abhyankar   } else {
48516ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
48616ebf90aSShri Abhyankar   }
48716ebf90aSShri Abhyankar 
48816ebf90aSShri Abhyankar   jj = 0; irow = rstart;
48916ebf90aSShri Abhyankar   for (i=0; i<m; i++) {
49016ebf90aSShri Abhyankar     ajj    = aj + ai[i];                 /* ptr to the beginning of this row */
49116ebf90aSShri Abhyankar     countA = ai[i+1] - ai[i];
49216ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
49316ebf90aSShri Abhyankar     bjj    = bj + bi[i];
49416ebf90aSShri Abhyankar     v1     = av + ai[i];
49516ebf90aSShri Abhyankar     v2     = bv + bi[i];
49616ebf90aSShri Abhyankar 
49716ebf90aSShri Abhyankar     /* A-part */
49816ebf90aSShri Abhyankar     for (j=0; j<countA; j++) {
499bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
50016ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
50116ebf90aSShri Abhyankar       }
50216ebf90aSShri Abhyankar       val[jj++] = v1[j];
50316ebf90aSShri Abhyankar     }
50416ebf90aSShri Abhyankar 
50516ebf90aSShri Abhyankar     /* B-part */
50616ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
507bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
50816ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
50916ebf90aSShri Abhyankar       }
51016ebf90aSShri Abhyankar       val[jj++] = v2[j];
51116ebf90aSShri Abhyankar     }
51216ebf90aSShri Abhyankar     irow++;
51316ebf90aSShri Abhyankar   }
51416ebf90aSShri Abhyankar   PetscFunctionReturn(0);
51516ebf90aSShri Abhyankar }
51616ebf90aSShri Abhyankar 
51716ebf90aSShri Abhyankar #undef __FUNCT__
51867877ebaSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpibaij_mpiaij"
519bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpibaij_mpiaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
52067877ebaSShri Abhyankar {
52167877ebaSShri Abhyankar   Mat_MPIBAIJ       *mat    = (Mat_MPIBAIJ*)A->data;
52267877ebaSShri Abhyankar   Mat_SeqBAIJ       *aa     = (Mat_SeqBAIJ*)(mat->A)->data;
52367877ebaSShri Abhyankar   Mat_SeqBAIJ       *bb     = (Mat_SeqBAIJ*)(mat->B)->data;
52467877ebaSShri Abhyankar   const PetscInt    *ai     = aa->i, *bi = bb->i, *aj = aa->j, *bj = bb->j,*ajj, *bjj;
525d985c460SShri Abhyankar   const PetscInt    *garray = mat->garray,mbs=mat->mbs,rstart=A->rmap->rstart;
52633d57670SJed Brown   const PetscInt    bs2=mat->bs2;
52767877ebaSShri Abhyankar   PetscErrorCode    ierr;
52833d57670SJed Brown   PetscInt          bs,nz,i,j,k,n,jj,irow,countA,countB,idx;
52967877ebaSShri Abhyankar   PetscInt          *row,*col;
53067877ebaSShri Abhyankar   const PetscScalar *av=aa->a, *bv=bb->a,*v1,*v2;
53167877ebaSShri Abhyankar   PetscScalar       *val;
53267877ebaSShri Abhyankar 
53367877ebaSShri Abhyankar   PetscFunctionBegin;
53433d57670SJed Brown   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
535bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
53667877ebaSShri Abhyankar     nz   = bs2*(aa->nz + bb->nz);
53767877ebaSShri Abhyankar     *nnz = nz;
538185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
539185f6596SHong Zhang     col  = row + nz;
540185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
541185f6596SHong Zhang 
54267877ebaSShri Abhyankar     *r = row; *c = col; *v = val;
54367877ebaSShri Abhyankar   } else {
54467877ebaSShri Abhyankar     row = *r; col = *c; val = *v;
54567877ebaSShri Abhyankar   }
54667877ebaSShri Abhyankar 
547d985c460SShri Abhyankar   jj = 0; irow = rstart;
54867877ebaSShri Abhyankar   for (i=0; i<mbs; i++) {
54967877ebaSShri Abhyankar     countA = ai[i+1] - ai[i];
55067877ebaSShri Abhyankar     countB = bi[i+1] - bi[i];
55167877ebaSShri Abhyankar     ajj    = aj + ai[i];
55267877ebaSShri Abhyankar     bjj    = bj + bi[i];
55367877ebaSShri Abhyankar     v1     = av + bs2*ai[i];
55467877ebaSShri Abhyankar     v2     = bv + bs2*bi[i];
55567877ebaSShri Abhyankar 
55667877ebaSShri Abhyankar     idx = 0;
55767877ebaSShri Abhyankar     /* A-part */
55867877ebaSShri Abhyankar     for (k=0; k<countA; k++) {
55967877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
56067877ebaSShri Abhyankar         for (n=0; n<bs; n++) {
561bccb9932SShri Abhyankar           if (reuse == MAT_INITIAL_MATRIX) {
562d985c460SShri Abhyankar             row[jj] = irow + n + shift;
563d985c460SShri Abhyankar             col[jj] = rstart + bs*ajj[k] + j + shift;
56467877ebaSShri Abhyankar           }
56567877ebaSShri Abhyankar           val[jj++] = v1[idx++];
56667877ebaSShri Abhyankar         }
56767877ebaSShri Abhyankar       }
56867877ebaSShri Abhyankar     }
56967877ebaSShri Abhyankar 
57067877ebaSShri Abhyankar     idx = 0;
57167877ebaSShri Abhyankar     /* B-part */
57267877ebaSShri Abhyankar     for (k=0; k<countB; k++) {
57367877ebaSShri Abhyankar       for (j=0; j<bs; j++) {
57467877ebaSShri Abhyankar         for (n=0; n<bs; n++) {
575bccb9932SShri Abhyankar           if (reuse == MAT_INITIAL_MATRIX) {
576d985c460SShri Abhyankar             row[jj] = irow + n + shift;
577d985c460SShri Abhyankar             col[jj] = bs*garray[bjj[k]] + j + shift;
57867877ebaSShri Abhyankar           }
579d985c460SShri Abhyankar           val[jj++] = v2[idx++];
58067877ebaSShri Abhyankar         }
58167877ebaSShri Abhyankar       }
58267877ebaSShri Abhyankar     }
583d985c460SShri Abhyankar     irow += bs;
58467877ebaSShri Abhyankar   }
58567877ebaSShri Abhyankar   PetscFunctionReturn(0);
58667877ebaSShri Abhyankar }
58767877ebaSShri Abhyankar 
58867877ebaSShri Abhyankar #undef __FUNCT__
58916ebf90aSShri Abhyankar #define __FUNCT__ "MatConvertToTriples_mpiaij_mpisbaij"
590bccb9932SShri Abhyankar PetscErrorCode MatConvertToTriples_mpiaij_mpisbaij(Mat A,int shift,MatReuse reuse,int *nnz,int **r, int **c, PetscScalar **v)
59116ebf90aSShri Abhyankar {
59216ebf90aSShri Abhyankar   const PetscInt    *ai, *aj,*adiag, *bi, *bj,*garray,m=A->rmap->n,*ajj,*bjj;
59316ebf90aSShri Abhyankar   PetscErrorCode    ierr;
594e0bace9bSHong Zhang   PetscInt          rstart,nz,nza,nzb,i,j,jj,irow,countA,countB;
59516ebf90aSShri Abhyankar   PetscInt          *row,*col;
59616ebf90aSShri Abhyankar   const PetscScalar *av, *bv,*v1,*v2;
59716ebf90aSShri Abhyankar   PetscScalar       *val;
59816ebf90aSShri Abhyankar   Mat_MPIAIJ        *mat =  (Mat_MPIAIJ*)A->data;
59916ebf90aSShri Abhyankar   Mat_SeqAIJ        *aa  =(Mat_SeqAIJ*)(mat->A)->data;
60016ebf90aSShri Abhyankar   Mat_SeqAIJ        *bb  =(Mat_SeqAIJ*)(mat->B)->data;
60116ebf90aSShri Abhyankar 
60216ebf90aSShri Abhyankar   PetscFunctionBegin;
60316ebf90aSShri Abhyankar   ai=aa->i; aj=aa->j; adiag=aa->diag;
60416ebf90aSShri Abhyankar   bi=bb->i; bj=bb->j; garray = mat->garray;
60516ebf90aSShri Abhyankar   av=aa->a; bv=bb->a;
6062205254eSKarl Rupp 
60716ebf90aSShri Abhyankar   rstart = A->rmap->rstart;
60816ebf90aSShri Abhyankar 
609bccb9932SShri Abhyankar   if (reuse == MAT_INITIAL_MATRIX) {
610e0bace9bSHong Zhang     nza = 0;    /* num of upper triangular entries in mat->A, including diagonals */
611e0bace9bSHong Zhang     nzb = 0;    /* num of upper triangular entries in mat->B */
61216ebf90aSShri Abhyankar     for (i=0; i<m; i++) {
613e0bace9bSHong Zhang       nza   += (ai[i+1] - adiag[i]);
61416ebf90aSShri Abhyankar       countB = bi[i+1] - bi[i];
61516ebf90aSShri Abhyankar       bjj    = bj + bi[i];
616e0bace9bSHong Zhang       for (j=0; j<countB; j++) {
617e0bace9bSHong Zhang         if (garray[bjj[j]] > rstart) nzb++;
618e0bace9bSHong Zhang       }
619e0bace9bSHong Zhang     }
62016ebf90aSShri Abhyankar 
621e0bace9bSHong Zhang     nz   = nza + nzb; /* total nz of upper triangular part of mat */
62216ebf90aSShri Abhyankar     *nnz = nz;
623185f6596SHong Zhang     ierr = PetscMalloc((2*nz*sizeof(PetscInt)+nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
624185f6596SHong Zhang     col  = row + nz;
625185f6596SHong Zhang     val  = (PetscScalar*)(col + nz);
626185f6596SHong Zhang 
62716ebf90aSShri Abhyankar     *r = row; *c = col; *v = val;
62816ebf90aSShri Abhyankar   } else {
62916ebf90aSShri Abhyankar     row = *r; col = *c; val = *v;
63016ebf90aSShri Abhyankar   }
63116ebf90aSShri Abhyankar 
63216ebf90aSShri Abhyankar   jj = 0; irow = rstart;
63316ebf90aSShri Abhyankar   for (i=0; i<m; i++) {
63416ebf90aSShri Abhyankar     ajj    = aj + adiag[i];                 /* ptr to the beginning of the diagonal of this row */
63516ebf90aSShri Abhyankar     v1     = av + adiag[i];
63616ebf90aSShri Abhyankar     countA = ai[i+1] - adiag[i];
63716ebf90aSShri Abhyankar     countB = bi[i+1] - bi[i];
63816ebf90aSShri Abhyankar     bjj    = bj + bi[i];
63916ebf90aSShri Abhyankar     v2     = bv + bi[i];
64016ebf90aSShri Abhyankar 
64116ebf90aSShri Abhyankar     /* A-part */
64216ebf90aSShri Abhyankar     for (j=0; j<countA; j++) {
643bccb9932SShri Abhyankar       if (reuse == MAT_INITIAL_MATRIX) {
64416ebf90aSShri Abhyankar         row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift;
64516ebf90aSShri Abhyankar       }
64616ebf90aSShri Abhyankar       val[jj++] = v1[j];
64716ebf90aSShri Abhyankar     }
64816ebf90aSShri Abhyankar 
64916ebf90aSShri Abhyankar     /* B-part */
65016ebf90aSShri Abhyankar     for (j=0; j < countB; j++) {
65116ebf90aSShri Abhyankar       if (garray[bjj[j]] > rstart) {
652bccb9932SShri Abhyankar         if (reuse == MAT_INITIAL_MATRIX) {
65316ebf90aSShri Abhyankar           row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift;
65416ebf90aSShri Abhyankar         }
65516ebf90aSShri Abhyankar         val[jj++] = v2[j];
65616ebf90aSShri Abhyankar       }
657397b6df1SKris Buschelman     }
658397b6df1SKris Buschelman     irow++;
659397b6df1SKris Buschelman   }
660397b6df1SKris Buschelman   PetscFunctionReturn(0);
661397b6df1SKris Buschelman }
662397b6df1SKris Buschelman 
663397b6df1SKris Buschelman #undef __FUNCT__
66420be8e61SHong Zhang #define __FUNCT__ "MatGetDiagonal_MUMPS"
66520be8e61SHong Zhang PetscErrorCode MatGetDiagonal_MUMPS(Mat A,Vec v)
66620be8e61SHong Zhang {
66720be8e61SHong Zhang   PetscFunctionBegin;
66820be8e61SHong Zhang   SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type: MUMPS factor");
66920be8e61SHong Zhang   PetscFunctionReturn(0);
67020be8e61SHong Zhang }
67120be8e61SHong Zhang 
67220be8e61SHong Zhang #undef __FUNCT__
6733924e44cSKris Buschelman #define __FUNCT__ "MatDestroy_MUMPS"
674dfbe8321SBarry Smith PetscErrorCode MatDestroy_MUMPS(Mat A)
675dfbe8321SBarry Smith {
676a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
677dfbe8321SBarry Smith   PetscErrorCode ierr;
678b24902e0SBarry Smith 
679397b6df1SKris Buschelman   PetscFunctionBegin;
680a5e57a09SHong Zhang   if (mumps->CleanUpMUMPS) {
681397b6df1SKris Buschelman     /* Terminate instance, deallocate memories */
682a5e57a09SHong Zhang     ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
683a5e57a09SHong Zhang     ierr = VecScatterDestroy(&mumps->scat_rhs);CHKERRQ(ierr);
684a5e57a09SHong Zhang     ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
685801fbe65SHong Zhang     ierr = VecDestroy(&mumps->b_seq);CHKERRQ(ierr);
686a5e57a09SHong Zhang     ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
687a5e57a09SHong Zhang     ierr = PetscFree(mumps->id.perm_in);CHKERRQ(ierr);
688a5e57a09SHong Zhang     ierr = PetscFree(mumps->irn);CHKERRQ(ierr);
6896444a565SStefano Zampini     ierr = PetscFree2(mumps->id.listvar_schur,mumps->id.schur);CHKERRQ(ierr);
690*b5fa320bSStefano Zampini     ierr = PetscFree(mumps->id.redrhs);CHKERRQ(ierr);
691*b5fa320bSStefano Zampini     ierr = PetscFree2(mumps->schur_pivots,mumps->schur_work);CHKERRQ(ierr);
692b34f08ffSHong Zhang     ierr = PetscFree(mumps->info);CHKERRQ(ierr);
6932205254eSKarl Rupp 
694a5e57a09SHong Zhang     mumps->id.job = JOB_END;
695a5e57a09SHong Zhang     PetscMUMPS_c(&mumps->id);
696a5e57a09SHong Zhang     ierr = MPI_Comm_free(&(mumps->comm_mumps));CHKERRQ(ierr);
697397b6df1SKris Buschelman   }
698a5e57a09SHong Zhang   if (mumps->Destroy) {
699a5e57a09SHong Zhang     ierr = (mumps->Destroy)(A);CHKERRQ(ierr);
700bf0cc555SLisandro Dalcin   }
701bf0cc555SLisandro Dalcin   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
702bf0cc555SLisandro Dalcin 
70397969023SHong Zhang   /* clear composed functions */
704bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSolverPackage_C",NULL);CHKERRQ(ierr);
705bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsSetIcntl_C",NULL);CHKERRQ(ierr);
706bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetIcntl_C",NULL);CHKERRQ(ierr);
707bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsSetCntl_C",NULL);CHKERRQ(ierr);
708bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetCntl_C",NULL);CHKERRQ(ierr);
709bc6112feSHong Zhang 
710ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetInfo_C",NULL);CHKERRQ(ierr);
711ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetInfog_C",NULL);CHKERRQ(ierr);
712ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetRinfo_C",NULL);CHKERRQ(ierr);
713ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetRinfog_C",NULL);CHKERRQ(ierr);
7146444a565SStefano Zampini 
7156444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsSetSchurIndices_C",NULL);CHKERRQ(ierr);
7166444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)A,"MatMumpsGetSchurComplement_C",NULL);CHKERRQ(ierr);
717397b6df1SKris Buschelman   PetscFunctionReturn(0);
718397b6df1SKris Buschelman }
719397b6df1SKris Buschelman 
720397b6df1SKris Buschelman #undef __FUNCT__
721f6c57405SHong Zhang #define __FUNCT__ "MatSolve_MUMPS"
722b24902e0SBarry Smith PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x)
723b24902e0SBarry Smith {
724a5e57a09SHong Zhang   Mat_MUMPS        *mumps=(Mat_MUMPS*)A->spptr;
725d54de34fSKris Buschelman   PetscScalar      *array;
72667877ebaSShri Abhyankar   Vec              b_seq;
727329ec9b3SHong Zhang   IS               is_iden,is_petsc;
728dfbe8321SBarry Smith   PetscErrorCode   ierr;
729329ec9b3SHong Zhang   PetscInt         i;
730883f2eb9SBarry Smith   static PetscBool cite1 = PETSC_FALSE,cite2 = PETSC_FALSE;
731397b6df1SKris Buschelman 
732397b6df1SKris Buschelman   PetscFunctionBegin;
733883f2eb9SBarry 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);
734883f2eb9SBarry 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);
735a5e57a09SHong Zhang   mumps->id.nrhs = 1;
736a5e57a09SHong Zhang   b_seq          = mumps->b_seq;
737a5e57a09SHong Zhang   if (mumps->size > 1) {
738329ec9b3SHong Zhang     /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */
739a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
740a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_rhs,b,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
741a5e57a09SHong Zhang     if (!mumps->myid) {ierr = VecGetArray(b_seq,&array);CHKERRQ(ierr);}
742397b6df1SKris Buschelman   } else {  /* size == 1 */
743397b6df1SKris Buschelman     ierr = VecCopy(b,x);CHKERRQ(ierr);
744397b6df1SKris Buschelman     ierr = VecGetArray(x,&array);CHKERRQ(ierr);
745397b6df1SKris Buschelman   }
746a5e57a09SHong Zhang   if (!mumps->myid) { /* define rhs on the host */
747a5e57a09SHong Zhang     mumps->id.nrhs = 1;
748940cd9d6SSatish Balay     mumps->id.rhs = (MumpsScalar*)array;
749397b6df1SKris Buschelman   }
750397b6df1SKris Buschelman 
751*b5fa320bSStefano Zampini   /* handle condensation step of Schur complement (if any) */
752*b5fa320bSStefano Zampini   ierr = MatMumpsHandleSchur_Private(mumps);CHKERRQ(ierr);
753*b5fa320bSStefano Zampini 
754397b6df1SKris Buschelman   /* solve phase */
755329ec9b3SHong Zhang   /*-------------*/
756a5e57a09SHong Zhang   mumps->id.job = JOB_SOLVE;
757a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
758a5e57a09SHong 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));
759397b6df1SKris Buschelman 
760*b5fa320bSStefano Zampini   /* handle expansion step of Schur complement (if any) */
761*b5fa320bSStefano Zampini   ierr = MatMumpsHandleSchur_Private(mumps);CHKERRQ(ierr);
762*b5fa320bSStefano Zampini 
763a5e57a09SHong Zhang   if (mumps->size > 1) { /* convert mumps distributed solution to petsc mpi x */
764a5e57a09SHong Zhang     if (mumps->scat_sol && mumps->ICNTL9_pre != mumps->id.ICNTL(9)) {
765a5e57a09SHong Zhang       /* when id.ICNTL(9) changes, the contents of lsol_loc may change (not its size, lsol_loc), recreates scat_sol */
766a5e57a09SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
767397b6df1SKris Buschelman     }
768a5e57a09SHong Zhang     if (!mumps->scat_sol) { /* create scatter scat_sol */
769a5e57a09SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,mumps->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */
770a5e57a09SHong Zhang       for (i=0; i<mumps->id.lsol_loc; i++) {
771a5e57a09SHong Zhang         mumps->id.isol_loc[i] -= 1; /* change Fortran style to C style */
772a5e57a09SHong Zhang       }
773a5e57a09SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,mumps->id.lsol_loc,mumps->id.isol_loc,PETSC_COPY_VALUES,&is_petsc);CHKERRQ(ierr);  /* to */
774a5e57a09SHong Zhang       ierr = VecScatterCreate(mumps->x_seq,is_iden,x,is_petsc,&mumps->scat_sol);CHKERRQ(ierr);
7756bf464f9SBarry Smith       ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
7766bf464f9SBarry Smith       ierr = ISDestroy(&is_petsc);CHKERRQ(ierr);
7772205254eSKarl Rupp 
778a5e57a09SHong Zhang       mumps->ICNTL9_pre = mumps->id.ICNTL(9); /* save current value of id.ICNTL(9) */
779397b6df1SKris Buschelman     }
780a5e57a09SHong Zhang 
781a5e57a09SHong Zhang     ierr = VecScatterBegin(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
782a5e57a09SHong Zhang     ierr = VecScatterEnd(mumps->scat_sol,mumps->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
783329ec9b3SHong Zhang   }
784397b6df1SKris Buschelman   PetscFunctionReturn(0);
785397b6df1SKris Buschelman }
786397b6df1SKris Buschelman 
78751d5961aSHong Zhang #undef __FUNCT__
78851d5961aSHong Zhang #define __FUNCT__ "MatSolveTranspose_MUMPS"
78951d5961aSHong Zhang PetscErrorCode MatSolveTranspose_MUMPS(Mat A,Vec b,Vec x)
79051d5961aSHong Zhang {
791a5e57a09SHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
79251d5961aSHong Zhang   PetscErrorCode ierr;
79351d5961aSHong Zhang 
79451d5961aSHong Zhang   PetscFunctionBegin;
795a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 0;
7960ad0caddSJed Brown   ierr = MatSolve_MUMPS(A,b,x);CHKERRQ(ierr);
797a5e57a09SHong Zhang   mumps->id.ICNTL(9) = 1;
79851d5961aSHong Zhang   PetscFunctionReturn(0);
79951d5961aSHong Zhang }
80051d5961aSHong Zhang 
801e0b74bf9SHong Zhang #undef __FUNCT__
802e0b74bf9SHong Zhang #define __FUNCT__ "MatMatSolve_MUMPS"
803e0b74bf9SHong Zhang PetscErrorCode MatMatSolve_MUMPS(Mat A,Mat B,Mat X)
804e0b74bf9SHong Zhang {
805bda8bf91SBarry Smith   PetscErrorCode ierr;
806bda8bf91SBarry Smith   PetscBool      flg;
8074e34a73bSHong Zhang   Mat_MUMPS      *mumps=(Mat_MUMPS*)A->spptr;
808334c5f61SHong Zhang   PetscInt       i,nrhs,M;
8092cd7d884SHong Zhang   PetscScalar    *array,*bray;
810bda8bf91SBarry Smith 
811e0b74bf9SHong Zhang   PetscFunctionBegin;
8120298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
813801fbe65SHong Zhang   if (!flg) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
8140298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
815801fbe65SHong Zhang   if (!flg) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
816801fbe65SHong 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");
8174e34a73bSHong Zhang 
8182cd7d884SHong Zhang   ierr = MatGetSize(B,&M,&nrhs);CHKERRQ(ierr);
819334c5f61SHong Zhang   mumps->id.nrhs = nrhs;
820334c5f61SHong Zhang   mumps->id.lrhs = M;
8214e34a73bSHong Zhang 
8222cd7d884SHong Zhang   if (mumps->size == 1) {
8232cd7d884SHong Zhang     /* copy B to X */
8242cd7d884SHong Zhang     ierr = MatDenseGetArray(B,&bray);CHKERRQ(ierr);
8252cd7d884SHong Zhang     ierr = MatDenseGetArray(X,&array);CHKERRQ(ierr);
8266444a565SStefano Zampini     ierr = PetscMemcpy(array,bray,M*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
8272cd7d884SHong Zhang     ierr = MatDenseRestoreArray(B,&bray);CHKERRQ(ierr);
828940cd9d6SSatish Balay     mumps->id.rhs = (MumpsScalar*)array;
829*b5fa320bSStefano Zampini     /* handle condensation step of Schur complement (if any) */
830*b5fa320bSStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps);CHKERRQ(ierr);
831801fbe65SHong Zhang 
8322cd7d884SHong Zhang     /* solve phase */
8332cd7d884SHong Zhang     /*-------------*/
8342cd7d884SHong Zhang     mumps->id.job = JOB_SOLVE;
8352cd7d884SHong Zhang     PetscMUMPS_c(&mumps->id);
8362cd7d884SHong 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));
837*b5fa320bSStefano Zampini 
838*b5fa320bSStefano Zampini     /* handle expansion step of Schur complement (if any) */
839*b5fa320bSStefano Zampini     ierr = MatMumpsHandleSchur_Private(mumps);CHKERRQ(ierr);
8402cd7d884SHong Zhang     ierr = MatDenseRestoreArray(X,&array);CHKERRQ(ierr);
841334c5f61SHong Zhang   } else {  /*--------- parallel case --------*/
84271aed81dSHong Zhang     PetscInt       lsol_loc,nlsol_loc,*isol_loc,*idx,*iidx,*idxx,*isol_loc_save;
8431070efccSSatish Balay     MumpsScalar    *sol_loc,*sol_loc_save;
844801fbe65SHong Zhang     IS             is_to,is_from;
845334c5f61SHong Zhang     PetscInt       k,proc,j,m;
846801fbe65SHong Zhang     const PetscInt *rstart;
847334c5f61SHong Zhang     Vec            v_mpi,b_seq,x_seq;
848334c5f61SHong Zhang     VecScatter     scat_rhs,scat_sol;
849801fbe65SHong Zhang 
850801fbe65SHong Zhang     /* create x_seq to hold local solution */
85171aed81dSHong Zhang     isol_loc_save = mumps->id.isol_loc; /* save it for MatSovle() */
85271aed81dSHong Zhang     sol_loc_save  = mumps->id.sol_loc;
853801fbe65SHong Zhang 
85471aed81dSHong Zhang     lsol_loc  = mumps->id.INFO(23);
85571aed81dSHong Zhang     nlsol_loc = nrhs*lsol_loc;     /* length of sol_loc */
85671aed81dSHong Zhang     ierr = PetscMalloc2(nlsol_loc,&sol_loc,nlsol_loc,&isol_loc);CHKERRQ(ierr);
857940cd9d6SSatish Balay     mumps->id.sol_loc = (MumpsScalar*)sol_loc;
858801fbe65SHong Zhang     mumps->id.isol_loc = isol_loc;
859801fbe65SHong Zhang 
8601070efccSSatish Balay     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,nlsol_loc,(PetscScalar*)sol_loc,&x_seq);CHKERRQ(ierr);
8612cd7d884SHong Zhang 
86274f0fcc7SHong Zhang     /* copy rhs matrix B into vector v_mpi */
863334c5f61SHong Zhang     ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);
864801fbe65SHong Zhang     ierr = MatDenseGetArray(B,&bray);CHKERRQ(ierr);
86574f0fcc7SHong Zhang     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),1,nrhs*m,nrhs*M,(const PetscScalar*)bray,&v_mpi);CHKERRQ(ierr);
866801fbe65SHong Zhang     ierr = MatDenseRestoreArray(B,&bray);CHKERRQ(ierr);
867801fbe65SHong Zhang 
868334c5f61SHong Zhang     /* scatter v_mpi to b_seq because MUMPS only supports centralized rhs */
86974f0fcc7SHong Zhang     /* idx: maps from k-th index of v_mpi to (i,j)-th global entry of B;
870801fbe65SHong Zhang       iidx: inverse of idx, will be used by scattering xx_seq -> X       */
871801fbe65SHong Zhang     ierr = PetscMalloc2(nrhs*M,&idx,nrhs*M,&iidx);CHKERRQ(ierr);
872801fbe65SHong Zhang     ierr = MatGetOwnershipRanges(B,&rstart);CHKERRQ(ierr);
873801fbe65SHong Zhang     k = 0;
874801fbe65SHong Zhang     for (proc=0; proc<mumps->size; proc++){
875801fbe65SHong Zhang       for (j=0; j<nrhs; j++){
876801fbe65SHong Zhang         for (i=rstart[proc]; i<rstart[proc+1]; i++){
877801fbe65SHong Zhang           iidx[j*M + i] = k;
878801fbe65SHong Zhang           idx[k++]      = j*M + i;
879801fbe65SHong Zhang         }
880801fbe65SHong Zhang       }
8812cd7d884SHong Zhang     }
8822cd7d884SHong Zhang 
883801fbe65SHong Zhang     if (!mumps->myid) {
884334c5f61SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,nrhs*M,&b_seq);CHKERRQ(ierr);
885801fbe65SHong Zhang       ierr = ISCreateGeneral(PETSC_COMM_SELF,nrhs*M,idx,PETSC_COPY_VALUES,&is_to);CHKERRQ(ierr);
886801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,nrhs*M,0,1,&is_from);CHKERRQ(ierr);
887801fbe65SHong Zhang     } else {
888334c5f61SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&b_seq);CHKERRQ(ierr);
889801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_to);CHKERRQ(ierr);
890801fbe65SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_from);CHKERRQ(ierr);
891801fbe65SHong Zhang     }
892334c5f61SHong Zhang     ierr = VecScatterCreate(v_mpi,is_from,b_seq,is_to,&scat_rhs);CHKERRQ(ierr);
893334c5f61SHong Zhang     ierr = VecScatterBegin(scat_rhs,v_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
894801fbe65SHong Zhang     ierr = ISDestroy(&is_to);CHKERRQ(ierr);
895801fbe65SHong Zhang     ierr = ISDestroy(&is_from);CHKERRQ(ierr);
896334c5f61SHong Zhang     ierr = VecScatterEnd(scat_rhs,v_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
897801fbe65SHong Zhang 
898801fbe65SHong Zhang     if (!mumps->myid) { /* define rhs on the host */
899334c5f61SHong Zhang       ierr = VecGetArray(b_seq,&bray);CHKERRQ(ierr);
900940cd9d6SSatish Balay       mumps->id.rhs = (MumpsScalar*)bray;
901334c5f61SHong Zhang       ierr = VecRestoreArray(b_seq,&bray);CHKERRQ(ierr);
902801fbe65SHong Zhang     }
903801fbe65SHong Zhang 
904801fbe65SHong Zhang     /* solve phase */
905801fbe65SHong Zhang     /*-------------*/
906801fbe65SHong Zhang     mumps->id.job = JOB_SOLVE;
907801fbe65SHong Zhang     PetscMUMPS_c(&mumps->id);
908801fbe65SHong 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));
909801fbe65SHong Zhang 
910334c5f61SHong Zhang     /* scatter mumps distributed solution to petsc vector v_mpi, which shares local arrays with solution matrix X */
91174f0fcc7SHong Zhang     ierr = MatDenseGetArray(X,&array);CHKERRQ(ierr);
91274f0fcc7SHong Zhang     ierr = VecPlaceArray(v_mpi,array);CHKERRQ(ierr);
913801fbe65SHong Zhang 
914334c5f61SHong Zhang     /* create scatter scat_sol */
91571aed81dSHong Zhang     ierr = PetscMalloc1(nlsol_loc,&idxx);CHKERRQ(ierr);
91671aed81dSHong Zhang     ierr = ISCreateStride(PETSC_COMM_SELF,nlsol_loc,0,1,&is_from);CHKERRQ(ierr);
91771aed81dSHong Zhang     for (i=0; i<lsol_loc; i++) {
918334c5f61SHong Zhang       isol_loc[i] -= 1; /* change Fortran style to C style */
919334c5f61SHong Zhang       idxx[i] = iidx[isol_loc[i]];
920801fbe65SHong Zhang       for (j=1; j<nrhs; j++){
921334c5f61SHong Zhang         idxx[j*lsol_loc+i] = iidx[isol_loc[i]+j*M];
922801fbe65SHong Zhang       }
923801fbe65SHong Zhang     }
92471aed81dSHong Zhang     ierr = ISCreateGeneral(PETSC_COMM_SELF,nlsol_loc,idxx,PETSC_COPY_VALUES,&is_to);CHKERRQ(ierr);
925334c5f61SHong Zhang     ierr = VecScatterCreate(x_seq,is_from,v_mpi,is_to,&scat_sol);CHKERRQ(ierr);
926334c5f61SHong Zhang     ierr = VecScatterBegin(scat_sol,x_seq,v_mpi,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
927801fbe65SHong Zhang     ierr = ISDestroy(&is_from);CHKERRQ(ierr);
928801fbe65SHong Zhang     ierr = ISDestroy(&is_to);CHKERRQ(ierr);
929334c5f61SHong Zhang     ierr = VecScatterEnd(scat_sol,x_seq,v_mpi,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
930801fbe65SHong Zhang     ierr = MatDenseRestoreArray(X,&array);CHKERRQ(ierr);
93171aed81dSHong Zhang 
93271aed81dSHong Zhang     /* free spaces */
93371aed81dSHong Zhang     mumps->id.sol_loc = sol_loc_save;
93471aed81dSHong Zhang     mumps->id.isol_loc = isol_loc_save;
93571aed81dSHong Zhang 
93671aed81dSHong Zhang     ierr = PetscFree2(sol_loc,isol_loc);CHKERRQ(ierr);
937801fbe65SHong Zhang     ierr = PetscFree2(idx,iidx);CHKERRQ(ierr);
938801fbe65SHong Zhang     ierr = PetscFree(idxx);CHKERRQ(ierr);
93971aed81dSHong Zhang     ierr = VecDestroy(&x_seq);CHKERRQ(ierr);
94074f0fcc7SHong Zhang     ierr = VecDestroy(&v_mpi);CHKERRQ(ierr);
941334c5f61SHong Zhang     ierr = VecDestroy(&b_seq);CHKERRQ(ierr);
942334c5f61SHong Zhang     ierr = VecScatterDestroy(&scat_rhs);CHKERRQ(ierr);
943334c5f61SHong Zhang     ierr = VecScatterDestroy(&scat_sol);CHKERRQ(ierr);
944801fbe65SHong Zhang   }
945e0b74bf9SHong Zhang   PetscFunctionReturn(0);
946e0b74bf9SHong Zhang }
947e0b74bf9SHong Zhang 
948ace3df97SHong Zhang #if !defined(PETSC_USE_COMPLEX)
949a58c3f20SHong Zhang /*
950a58c3f20SHong Zhang   input:
951a58c3f20SHong Zhang    F:        numeric factor
952a58c3f20SHong Zhang   output:
953a58c3f20SHong Zhang    nneg:     total number of negative pivots
954a58c3f20SHong Zhang    nzero:    0
955a58c3f20SHong Zhang    npos:     (global dimension of F) - nneg
956a58c3f20SHong Zhang */
957a58c3f20SHong Zhang 
958a58c3f20SHong Zhang #undef __FUNCT__
959a58c3f20SHong Zhang #define __FUNCT__ "MatGetInertia_SBAIJMUMPS"
960dfbe8321SBarry Smith PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos)
961a58c3f20SHong Zhang {
962a5e57a09SHong Zhang   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
963dfbe8321SBarry Smith   PetscErrorCode ierr;
964c1490034SHong Zhang   PetscMPIInt    size;
965a58c3f20SHong Zhang 
966a58c3f20SHong Zhang   PetscFunctionBegin;
967ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)F),&size);CHKERRQ(ierr);
968bcb30aebSHong 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 */
969a5e57a09SHong 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));
970ed85ac9fSHong Zhang 
971710ac8efSHong Zhang   if (nneg) *nneg = mumps->id.INFOG(12);
972ed85ac9fSHong Zhang   if (nzero || npos) {
973ed85ac9fSHong 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");
974710ac8efSHong Zhang     if (nzero) *nzero = mumps->id.INFOG(28);
975710ac8efSHong Zhang     if (npos) *npos   = F->rmap->N - (mumps->id.INFOG(12) + mumps->id.INFOG(28));
976a58c3f20SHong Zhang   }
977a58c3f20SHong Zhang   PetscFunctionReturn(0);
978a58c3f20SHong Zhang }
979ace3df97SHong Zhang #endif /* !defined(PETSC_USE_COMPLEX) */
980a58c3f20SHong Zhang 
981397b6df1SKris Buschelman #undef __FUNCT__
982f6c57405SHong Zhang #define __FUNCT__ "MatFactorNumeric_MUMPS"
9830481f469SBarry Smith PetscErrorCode MatFactorNumeric_MUMPS(Mat F,Mat A,const MatFactorInfo *info)
984af281ebdSHong Zhang {
985a5e57a09SHong Zhang   Mat_MUMPS      *mumps =(Mat_MUMPS*)(F)->spptr;
9866849ba73SBarry Smith   PetscErrorCode ierr;
987e09efc27SHong Zhang   Mat            F_diag;
988ace3abfcSBarry Smith   PetscBool      isMPIAIJ;
989397b6df1SKris Buschelman 
990397b6df1SKris Buschelman   PetscFunctionBegin;
991a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_REUSE_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
992397b6df1SKris Buschelman 
993397b6df1SKris Buschelman   /* numerical factorization phase */
994329ec9b3SHong Zhang   /*-------------------------------*/
995a5e57a09SHong Zhang   mumps->id.job = JOB_FACTNUMERIC;
9964e34a73bSHong Zhang   if (!mumps->id.ICNTL(18)) { /* A is centralized */
997a5e57a09SHong Zhang     if (!mumps->myid) {
998940cd9d6SSatish Balay       mumps->id.a = (MumpsScalar*)mumps->val;
999397b6df1SKris Buschelman     }
1000397b6df1SKris Buschelman   } else {
1001940cd9d6SSatish Balay     mumps->id.a_loc = (MumpsScalar*)mumps->val;
1002397b6df1SKris Buschelman   }
1003a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1004a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) {
1005151787a6SHong Zhang     if (mumps->id.INFO(1) == -13) {
1006151787a6SHong Zhang       if (mumps->id.INFO(2) < 0) {
1007151787a6SHong Zhang         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: Cannot allocate required memory %d megabytes\n",-mumps->id.INFO(2));
1008151787a6SHong Zhang       } else {
1009151787a6SHong Zhang         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: Cannot allocate required memory %d bytes\n",mumps->id.INFO(2));
1010151787a6SHong Zhang       }
1011151787a6SHong Zhang     } else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: INFO(1)=%d, INFO(2)=%d\n",mumps->id.INFO(1),mumps->id.INFO(2));
1012397b6df1SKris Buschelman   }
1013a5e57a09SHong 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));
1014397b6df1SKris Buschelman 
1015dcd589f8SShri Abhyankar   (F)->assembled        = PETSC_TRUE;
1016a5e57a09SHong Zhang   mumps->matstruc       = SAME_NONZERO_PATTERN;
1017a5e57a09SHong Zhang   mumps->CleanUpMUMPS   = PETSC_TRUE;
1018*b5fa320bSStefano Zampini   mumps->schur_factored = PETSC_FALSE;
101967877ebaSShri Abhyankar 
1020a5e57a09SHong Zhang   if (mumps->size > 1) {
102167877ebaSShri Abhyankar     PetscInt    lsol_loc;
102267877ebaSShri Abhyankar     PetscScalar *sol_loc;
10232205254eSKarl Rupp 
1024c2093ab7SHong Zhang     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ);CHKERRQ(ierr);
1025c2093ab7SHong Zhang     if (isMPIAIJ) F_diag = ((Mat_MPIAIJ*)(F)->data)->A;
1026c2093ab7SHong Zhang     else F_diag = ((Mat_MPISBAIJ*)(F)->data)->A;
1027c2093ab7SHong Zhang     F_diag->assembled = PETSC_TRUE;
1028c2093ab7SHong Zhang 
1029c2093ab7SHong Zhang     /* distributed solution; Create x_seq=sol_loc for repeated use */
1030c2093ab7SHong Zhang     if (mumps->x_seq) {
1031c2093ab7SHong Zhang       ierr = VecScatterDestroy(&mumps->scat_sol);CHKERRQ(ierr);
1032c2093ab7SHong Zhang       ierr = PetscFree2(mumps->id.sol_loc,mumps->id.isol_loc);CHKERRQ(ierr);
1033c2093ab7SHong Zhang       ierr = VecDestroy(&mumps->x_seq);CHKERRQ(ierr);
1034c2093ab7SHong Zhang     }
1035a5e57a09SHong Zhang     lsol_loc = mumps->id.INFO(23); /* length of sol_loc */
1036dcca6d9dSJed Brown     ierr = PetscMalloc2(lsol_loc,&sol_loc,lsol_loc,&mumps->id.isol_loc);CHKERRQ(ierr);
1037a5e57a09SHong Zhang     mumps->id.lsol_loc = lsol_loc;
1038940cd9d6SSatish Balay     mumps->id.sol_loc = (MumpsScalar*)sol_loc;
1039a5e57a09SHong Zhang     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lsol_loc,sol_loc,&mumps->x_seq);CHKERRQ(ierr);
104067877ebaSShri Abhyankar   }
1041397b6df1SKris Buschelman   PetscFunctionReturn(0);
1042397b6df1SKris Buschelman }
1043397b6df1SKris Buschelman 
10449a2535b5SHong Zhang /* Sets MUMPS options from the options database */
1045dcd589f8SShri Abhyankar #undef __FUNCT__
10469a2535b5SHong Zhang #define __FUNCT__ "PetscSetMUMPSFromOptions"
10479a2535b5SHong Zhang PetscErrorCode PetscSetMUMPSFromOptions(Mat F, Mat A)
1048dcd589f8SShri Abhyankar {
10499a2535b5SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1050dcd589f8SShri Abhyankar   PetscErrorCode ierr;
1051b34f08ffSHong Zhang   PetscInt       icntl,info[40],i,ninfo=40;
1052ace3abfcSBarry Smith   PetscBool      flg;
1053dcd589f8SShri Abhyankar 
1054dcd589f8SShri Abhyankar   PetscFunctionBegin;
1055ce94432eSBarry Smith   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr);
10569a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_1","ICNTL(1): output stream for error messages","None",mumps->id.ICNTL(1),&icntl,&flg);CHKERRQ(ierr);
10579a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(1) = icntl;
10589a2535b5SHong 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);
10599a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(2) = icntl;
10609a2535b5SHong 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);
10619a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(3) = icntl;
1062dcd589f8SShri Abhyankar 
10639a2535b5SHong Zhang   ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",mumps->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr);
10649a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(4) = icntl;
10659a2535b5SHong Zhang   if (mumps->id.ICNTL(4) || PetscLogPrintInfo) mumps->id.ICNTL(3) = 6; /* resume MUMPS default id.ICNTL(3) = 6 */
10669a2535b5SHong Zhang 
1067d341cd04SHong 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);
10689a2535b5SHong Zhang   if (flg) mumps->id.ICNTL(6) = icntl;
10699a2535b5SHong Zhang 
1070d341cd04SHong 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);
1071dcd589f8SShri Abhyankar   if (flg) {
10722205254eSKarl 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");
10732205254eSKarl Rupp     else mumps->id.ICNTL(7) = icntl;
1074dcd589f8SShri Abhyankar   }
1075e0b74bf9SHong Zhang 
10760298fd71SBarry 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);
1077d341cd04SHong 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() */
10780298fd71SBarry 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);
1079d341cd04SHong 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);
1080d341cd04SHong 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);
1081d341cd04SHong 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);
1082d341cd04SHong 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);
1083d341cd04SHong 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);
10844e34a73bSHong 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 */
1085d341cd04SHong 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 */
10869a2535b5SHong Zhang 
1087d341cd04SHong 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);
10880298fd71SBarry 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);
10890298fd71SBarry 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);
10909a2535b5SHong Zhang   if (mumps->id.ICNTL(24)) {
10919a2535b5SHong Zhang     mumps->id.ICNTL(13) = 1; /* turn-off ScaLAPACK to help with the correct detection of null pivots */
1092d7ebd59bSHong Zhang   }
1093d7ebd59bSHong Zhang 
1094d341cd04SHong 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);
1095d341cd04SHong 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);
10962cd7d884SHong 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);
10970298fd71SBarry 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);
1098d341cd04SHong 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);
10990298fd71SBarry 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);
1100d341cd04SHong 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);
11014e34a73bSHong 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 */
11020298fd71SBarry Smith   ierr = PetscOptionsInt("-mat_mumps_icntl_33","ICNTL(33): compute determinant","None",mumps->id.ICNTL(33),&mumps->id.ICNTL(33),NULL);CHKERRQ(ierr);
1103dcd589f8SShri Abhyankar 
11040298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_1","CNTL(1): relative pivoting threshold","None",mumps->id.CNTL(1),&mumps->id.CNTL(1),NULL);CHKERRQ(ierr);
11050298fd71SBarry 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);
11060298fd71SBarry Smith   ierr = PetscOptionsReal("-mat_mumps_cntl_3","CNTL(3): absolute pivoting threshold","None",mumps->id.CNTL(3),&mumps->id.CNTL(3),NULL);CHKERRQ(ierr);
11070298fd71SBarry 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);
11080298fd71SBarry 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);
1109e5bb22a1SHong Zhang 
11100298fd71SBarry Smith   ierr = PetscOptionsString("-mat_mumps_ooc_tmpdir", "out of core directory", "None", mumps->id.ooc_tmpdir, mumps->id.ooc_tmpdir, 256, NULL);
1111b34f08ffSHong Zhang 
111216d797efSHong Zhang   ierr = PetscOptionsIntArray("-mat_mumps_view_info","request INFO local to each processor","",info,&ninfo,NULL);CHKERRQ(ierr);
1113b34f08ffSHong Zhang   if (ninfo) {
1114b34f08ffSHong Zhang     if (ninfo > 40) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"number of INFO %d must <= 40\n",ninfo);
1115b34f08ffSHong Zhang     ierr = PetscMalloc1(ninfo,&mumps->info);CHKERRQ(ierr);
1116b34f08ffSHong Zhang     mumps->ninfo = ninfo;
1117b34f08ffSHong Zhang     for (i=0; i<ninfo; i++) {
1118b34f08ffSHong Zhang       if (info[i] < 0 || info[i]>40) {
1119b34f08ffSHong Zhang         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"index of INFO %d must between 1 and 40\n",ninfo);
1120b34f08ffSHong Zhang       } else {
1121b34f08ffSHong Zhang         mumps->info[i] = info[i];
1122b34f08ffSHong Zhang       }
1123b34f08ffSHong Zhang     }
1124b34f08ffSHong Zhang   }
1125b34f08ffSHong Zhang 
1126dcd589f8SShri Abhyankar   PetscOptionsEnd();
1127dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
1128dcd589f8SShri Abhyankar }
1129dcd589f8SShri Abhyankar 
1130dcd589f8SShri Abhyankar #undef __FUNCT__
1131dcd589f8SShri Abhyankar #define __FUNCT__ "PetscInitializeMUMPS"
1132f697e70eSHong Zhang PetscErrorCode PetscInitializeMUMPS(Mat A,Mat_MUMPS *mumps)
1133dcd589f8SShri Abhyankar {
1134dcd589f8SShri Abhyankar   PetscErrorCode ierr;
1135dcd589f8SShri Abhyankar 
1136dcd589f8SShri Abhyankar   PetscFunctionBegin;
1137ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &mumps->myid);
1138ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&mumps->size);CHKERRQ(ierr);
1139ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)A),&(mumps->comm_mumps));CHKERRQ(ierr);
11402205254eSKarl Rupp 
1141f697e70eSHong Zhang   mumps->id.comm_fortran = MPI_Comm_c2f(mumps->comm_mumps);
1142f697e70eSHong Zhang 
1143f697e70eSHong Zhang   mumps->id.job = JOB_INIT;
1144f697e70eSHong Zhang   mumps->id.par = 1;  /* host participates factorizaton and solve */
1145f697e70eSHong Zhang   mumps->id.sym = mumps->sym;
11462907cef9SHong Zhang   PetscMUMPS_c(&mumps->id);
1147f697e70eSHong Zhang 
1148f697e70eSHong Zhang   mumps->CleanUpMUMPS = PETSC_FALSE;
11490298fd71SBarry Smith   mumps->scat_rhs     = NULL;
11500298fd71SBarry Smith   mumps->scat_sol     = NULL;
11519a2535b5SHong Zhang 
115270544d5fSHong Zhang   /* set PETSc-MUMPS default options - override MUMPS default */
11539a2535b5SHong Zhang   mumps->id.ICNTL(3) = 0;
11549a2535b5SHong Zhang   mumps->id.ICNTL(4) = 0;
11559a2535b5SHong Zhang   if (mumps->size == 1) {
11569a2535b5SHong Zhang     mumps->id.ICNTL(18) = 0;   /* centralized assembled matrix input */
11579a2535b5SHong Zhang   } else {
11589a2535b5SHong Zhang     mumps->id.ICNTL(18) = 3;   /* distributed assembled matrix input */
11594e34a73bSHong Zhang     mumps->id.ICNTL(20) = 0;   /* rhs is in dense format */
116070544d5fSHong Zhang     mumps->id.ICNTL(21) = 1;   /* distributed solution */
11619a2535b5SHong Zhang   }
11626444a565SStefano Zampini 
11636444a565SStefano Zampini   /* schur */
11646444a565SStefano Zampini   mumps->id.size_schur = 0;
11656444a565SStefano Zampini   mumps->id.listvar_schur = NULL;
11666444a565SStefano Zampini   mumps->id.schur = NULL;
1167*b5fa320bSStefano Zampini   mumps->schur_second_solve = PETSC_FALSE;
1168*b5fa320bSStefano Zampini   mumps->sizeredrhs = 0;
1169*b5fa320bSStefano Zampini   mumps->schur_pivots = NULL;
1170*b5fa320bSStefano Zampini   mumps->schur_work = NULL;
1171dcd589f8SShri Abhyankar   PetscFunctionReturn(0);
1172dcd589f8SShri Abhyankar }
1173dcd589f8SShri Abhyankar 
1174a5e57a09SHong 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 */
1175397b6df1SKris Buschelman #undef __FUNCT__
1176f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS"
11770481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1178b24902e0SBarry Smith {
1179a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1180dcd589f8SShri Abhyankar   PetscErrorCode ierr;
118167877ebaSShri Abhyankar   Vec            b;
118267877ebaSShri Abhyankar   IS             is_iden;
118367877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1184397b6df1SKris Buschelman 
1185397b6df1SKris Buschelman   PetscFunctionBegin;
1186a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1187dcd589f8SShri Abhyankar 
11889a2535b5SHong Zhang   /* Set MUMPS options from the options database */
11899a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1190dcd589f8SShri Abhyankar 
1191a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1192dcd589f8SShri Abhyankar 
119367877ebaSShri Abhyankar   /* analysis phase */
119467877ebaSShri Abhyankar   /*----------------*/
1195a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1196a5e57a09SHong Zhang   mumps->id.n   = M;
1197a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
119867877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1199a5e57a09SHong Zhang     if (!mumps->myid) {
1200a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1201a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1202940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
120367877ebaSShri Abhyankar       }
1204a5e57a09SHong Zhang       if (mumps->id.ICNTL(7) == 1) { /* use user-provide matrix ordering - assuming r = c ordering */
12055248a706SHong Zhang         /*
12065248a706SHong Zhang         PetscBool      flag;
12075248a706SHong Zhang         ierr = ISEqual(r,c,&flag);CHKERRQ(ierr);
12085248a706SHong Zhang         if (!flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"row_perm != col_perm");
12095248a706SHong Zhang         ierr = ISView(r,PETSC_VIEWER_STDOUT_SELF);
12105248a706SHong Zhang          */
1211a5e57a09SHong Zhang         if (!mumps->myid) {
1212e0b74bf9SHong Zhang           const PetscInt *idx;
1213e0b74bf9SHong Zhang           PetscInt       i,*perm_in;
12142205254eSKarl Rupp 
1215785e854fSJed Brown           ierr = PetscMalloc1(M,&perm_in);CHKERRQ(ierr);
1216e0b74bf9SHong Zhang           ierr = ISGetIndices(r,&idx);CHKERRQ(ierr);
12172205254eSKarl Rupp 
1218a5e57a09SHong Zhang           mumps->id.perm_in = perm_in;
1219e0b74bf9SHong Zhang           for (i=0; i<M; i++) perm_in[i] = idx[i]+1; /* perm_in[]: start from 1, not 0! */
1220e0b74bf9SHong Zhang           ierr = ISRestoreIndices(r,&idx);CHKERRQ(ierr);
1221e0b74bf9SHong Zhang         }
1222e0b74bf9SHong Zhang       }
122367877ebaSShri Abhyankar     }
122467877ebaSShri Abhyankar     break;
122567877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1226a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1227a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1228a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1229940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
123067877ebaSShri Abhyankar     }
123167877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1232a5e57a09SHong Zhang     if (!mumps->myid) {
12332cd7d884SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->rmap->N,&mumps->b_seq);CHKERRQ(ierr);
12342cd7d884SHong Zhang       ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->N,0,1,&is_iden);CHKERRQ(ierr);
123567877ebaSShri Abhyankar     } else {
1236a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
123767877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
123867877ebaSShri Abhyankar     }
12392a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1240a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
12416bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
12426bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
124367877ebaSShri Abhyankar     break;
124467877ebaSShri Abhyankar   }
1245a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1246a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
124767877ebaSShri Abhyankar 
1248719d5645SBarry Smith   F->ops->lufactornumeric = MatFactorNumeric_MUMPS;
1249dcd589f8SShri Abhyankar   F->ops->solve           = MatSolve_MUMPS;
125051d5961aSHong Zhang   F->ops->solvetranspose  = MatSolveTranspose_MUMPS;
12514e34a73bSHong Zhang   F->ops->matsolve        = MatMatSolve_MUMPS;
1252b24902e0SBarry Smith   PetscFunctionReturn(0);
1253b24902e0SBarry Smith }
1254b24902e0SBarry Smith 
1255450b117fSShri Abhyankar /* Note the Petsc r and c permutations are ignored */
1256450b117fSShri Abhyankar #undef __FUNCT__
1257450b117fSShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_BAIJMUMPS"
1258450b117fSShri Abhyankar PetscErrorCode MatLUFactorSymbolic_BAIJMUMPS(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1259450b117fSShri Abhyankar {
1260a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1261dcd589f8SShri Abhyankar   PetscErrorCode ierr;
126267877ebaSShri Abhyankar   Vec            b;
126367877ebaSShri Abhyankar   IS             is_iden;
126467877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1265450b117fSShri Abhyankar 
1266450b117fSShri Abhyankar   PetscFunctionBegin;
1267a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1268dcd589f8SShri Abhyankar 
12699a2535b5SHong Zhang   /* Set MUMPS options from the options database */
12709a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1271dcd589f8SShri Abhyankar 
1272a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
127367877ebaSShri Abhyankar 
127467877ebaSShri Abhyankar   /* analysis phase */
127567877ebaSShri Abhyankar   /*----------------*/
1276a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1277a5e57a09SHong Zhang   mumps->id.n   = M;
1278a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
127967877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1280a5e57a09SHong Zhang     if (!mumps->myid) {
1281a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1282a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1283940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
128467877ebaSShri Abhyankar       }
128567877ebaSShri Abhyankar     }
128667877ebaSShri Abhyankar     break;
128767877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1288a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1289a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1290a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1291940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
129267877ebaSShri Abhyankar     }
129367877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1294a5e57a09SHong Zhang     if (!mumps->myid) {
1295a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
129667877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
129767877ebaSShri Abhyankar     } else {
1298a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
129967877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
130067877ebaSShri Abhyankar     }
13012a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1302a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
13036bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
13046bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
130567877ebaSShri Abhyankar     break;
130667877ebaSShri Abhyankar   }
1307a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1308a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
130967877ebaSShri Abhyankar 
1310450b117fSShri Abhyankar   F->ops->lufactornumeric = MatFactorNumeric_MUMPS;
1311dcd589f8SShri Abhyankar   F->ops->solve           = MatSolve_MUMPS;
131251d5961aSHong Zhang   F->ops->solvetranspose  = MatSolveTranspose_MUMPS;
1313450b117fSShri Abhyankar   PetscFunctionReturn(0);
1314450b117fSShri Abhyankar }
1315b24902e0SBarry Smith 
1316141f4205SHong Zhang /* Note the Petsc r permutation and factor info are ignored */
1317397b6df1SKris Buschelman #undef __FUNCT__
131867877ebaSShri Abhyankar #define __FUNCT__ "MatCholeskyFactorSymbolic_MUMPS"
131967877ebaSShri Abhyankar PetscErrorCode MatCholeskyFactorSymbolic_MUMPS(Mat F,Mat A,IS r,const MatFactorInfo *info)
1320b24902e0SBarry Smith {
1321a5e57a09SHong Zhang   Mat_MUMPS      *mumps = (Mat_MUMPS*)F->spptr;
1322dcd589f8SShri Abhyankar   PetscErrorCode ierr;
132367877ebaSShri Abhyankar   Vec            b;
132467877ebaSShri Abhyankar   IS             is_iden;
132567877ebaSShri Abhyankar   const PetscInt M = A->rmap->N;
1326397b6df1SKris Buschelman 
1327397b6df1SKris Buschelman   PetscFunctionBegin;
1328a5e57a09SHong Zhang   mumps->matstruc = DIFFERENT_NONZERO_PATTERN;
1329dcd589f8SShri Abhyankar 
13309a2535b5SHong Zhang   /* Set MUMPS options from the options database */
13319a2535b5SHong Zhang   ierr = PetscSetMUMPSFromOptions(F,A);CHKERRQ(ierr);
1332dcd589f8SShri Abhyankar 
1333a5e57a09SHong Zhang   ierr = (*mumps->ConvertToTriples)(A, 1, MAT_INITIAL_MATRIX, &mumps->nz, &mumps->irn, &mumps->jcn, &mumps->val);CHKERRQ(ierr);
1334dcd589f8SShri Abhyankar 
133567877ebaSShri Abhyankar   /* analysis phase */
133667877ebaSShri Abhyankar   /*----------------*/
1337a5e57a09SHong Zhang   mumps->id.job = JOB_FACTSYMBOLIC;
1338a5e57a09SHong Zhang   mumps->id.n   = M;
1339a5e57a09SHong Zhang   switch (mumps->id.ICNTL(18)) {
134067877ebaSShri Abhyankar   case 0:  /* centralized assembled matrix input */
1341a5e57a09SHong Zhang     if (!mumps->myid) {
1342a5e57a09SHong Zhang       mumps->id.nz =mumps->nz; mumps->id.irn=mumps->irn; mumps->id.jcn=mumps->jcn;
1343a5e57a09SHong Zhang       if (mumps->id.ICNTL(6)>1) {
1344940cd9d6SSatish Balay         mumps->id.a = (MumpsScalar*)mumps->val;
134567877ebaSShri Abhyankar       }
134667877ebaSShri Abhyankar     }
134767877ebaSShri Abhyankar     break;
134867877ebaSShri Abhyankar   case 3:  /* distributed assembled matrix input (size>1) */
1349a5e57a09SHong Zhang     mumps->id.nz_loc = mumps->nz;
1350a5e57a09SHong Zhang     mumps->id.irn_loc=mumps->irn; mumps->id.jcn_loc=mumps->jcn;
1351a5e57a09SHong Zhang     if (mumps->id.ICNTL(6)>1) {
1352940cd9d6SSatish Balay       mumps->id.a_loc = (MumpsScalar*)mumps->val;
135367877ebaSShri Abhyankar     }
135467877ebaSShri Abhyankar     /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
1355a5e57a09SHong Zhang     if (!mumps->myid) {
1356a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&mumps->b_seq);CHKERRQ(ierr);
135767877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr);
135867877ebaSShri Abhyankar     } else {
1359a5e57a09SHong Zhang       ierr = VecCreateSeq(PETSC_COMM_SELF,0,&mumps->b_seq);CHKERRQ(ierr);
136067877ebaSShri Abhyankar       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr);
136167877ebaSShri Abhyankar     }
13622a7a6963SBarry Smith     ierr = MatCreateVecs(A,NULL,&b);CHKERRQ(ierr);
1363a5e57a09SHong Zhang     ierr = VecScatterCreate(b,is_iden,mumps->b_seq,is_iden,&mumps->scat_rhs);CHKERRQ(ierr);
13646bf464f9SBarry Smith     ierr = ISDestroy(&is_iden);CHKERRQ(ierr);
13656bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
136667877ebaSShri Abhyankar     break;
136767877ebaSShri Abhyankar   }
1368a5e57a09SHong Zhang   PetscMUMPS_c(&mumps->id);
1369a5e57a09SHong Zhang   if (mumps->id.INFOG(1) < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",mumps->id.INFOG(1));
137067877ebaSShri Abhyankar 
13712792810eSHong Zhang   F->ops->choleskyfactornumeric = MatFactorNumeric_MUMPS;
1372dcd589f8SShri Abhyankar   F->ops->solve                 = MatSolve_MUMPS;
137351d5961aSHong Zhang   F->ops->solvetranspose        = MatSolve_MUMPS;
13744e34a73bSHong Zhang   F->ops->matsolve              = MatMatSolve_MUMPS;
13754e34a73bSHong Zhang #if defined(PETSC_USE_COMPLEX)
13760298fd71SBarry Smith   F->ops->getinertia = NULL;
13774e34a73bSHong Zhang #else
13784e34a73bSHong Zhang   F->ops->getinertia = MatGetInertia_SBAIJMUMPS;
1379db4efbfdSBarry Smith #endif
1380b24902e0SBarry Smith   PetscFunctionReturn(0);
1381b24902e0SBarry Smith }
1382b24902e0SBarry Smith 
1383397b6df1SKris Buschelman #undef __FUNCT__
138464e6c443SBarry Smith #define __FUNCT__ "MatView_MUMPS"
138564e6c443SBarry Smith PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer)
138674ed9c26SBarry Smith {
1387f6c57405SHong Zhang   PetscErrorCode    ierr;
138864e6c443SBarry Smith   PetscBool         iascii;
138964e6c443SBarry Smith   PetscViewerFormat format;
1390a5e57a09SHong Zhang   Mat_MUMPS         *mumps=(Mat_MUMPS*)A->spptr;
1391f6c57405SHong Zhang 
1392f6c57405SHong Zhang   PetscFunctionBegin;
139364e6c443SBarry Smith   /* check if matrix is mumps type */
139464e6c443SBarry Smith   if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0);
139564e6c443SBarry Smith 
1396251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
139764e6c443SBarry Smith   if (iascii) {
139864e6c443SBarry Smith     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
139964e6c443SBarry Smith     if (format == PETSC_VIEWER_ASCII_INFO) {
140064e6c443SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr);
1401a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  SYM (matrix type):                   %d \n",mumps->id.sym);CHKERRQ(ierr);
1402a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  PAR (host participation):            %d \n",mumps->id.par);CHKERRQ(ierr);
1403a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(1) (output for error):         %d \n",mumps->id.ICNTL(1));CHKERRQ(ierr);
1404a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(2) (output of diagnostic msg): %d \n",mumps->id.ICNTL(2));CHKERRQ(ierr);
1405a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(3) (output for global info):   %d \n",mumps->id.ICNTL(3));CHKERRQ(ierr);
1406a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(4) (level of printing):        %d \n",mumps->id.ICNTL(4));CHKERRQ(ierr);
1407a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(5) (input mat struct):         %d \n",mumps->id.ICNTL(5));CHKERRQ(ierr);
1408a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(6) (matrix prescaling):        %d \n",mumps->id.ICNTL(6));CHKERRQ(ierr);
1409a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(7) (sequentia matrix ordering):%d \n",mumps->id.ICNTL(7));CHKERRQ(ierr);
1410a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(8) (scalling strategy):        %d \n",mumps->id.ICNTL(8));CHKERRQ(ierr);
1411a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(10) (max num of refinements):  %d \n",mumps->id.ICNTL(10));CHKERRQ(ierr);
1412a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(11) (error analysis):          %d \n",mumps->id.ICNTL(11));CHKERRQ(ierr);
1413a5e57a09SHong Zhang       if (mumps->id.ICNTL(11)>0) {
1414a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(4) (inf norm of input mat):        %g\n",mumps->id.RINFOG(4));CHKERRQ(ierr);
1415a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(5) (inf norm of solution):         %g\n",mumps->id.RINFOG(5));CHKERRQ(ierr);
1416a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(6) (inf norm of residual):         %g\n",mumps->id.RINFOG(6));CHKERRQ(ierr);
1417a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(7),RINFOG(8) (backward error est): %g, %g\n",mumps->id.RINFOG(7),mumps->id.RINFOG(8));CHKERRQ(ierr);
1418a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(9) (error estimate):               %g \n",mumps->id.RINFOG(9));CHKERRQ(ierr);
1419a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"    RINFOG(10),RINFOG(11)(condition numbers): %g, %g\n",mumps->id.RINFOG(10),mumps->id.RINFOG(11));CHKERRQ(ierr);
1420f6c57405SHong Zhang       }
1421a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(12) (efficiency control):                         %d \n",mumps->id.ICNTL(12));CHKERRQ(ierr);
1422a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(13) (efficiency control):                         %d \n",mumps->id.ICNTL(13));CHKERRQ(ierr);
1423a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(14) (percentage of estimated workspace increase): %d \n",mumps->id.ICNTL(14));CHKERRQ(ierr);
1424f6c57405SHong Zhang       /* ICNTL(15-17) not used */
1425a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(18) (input mat struct):                           %d \n",mumps->id.ICNTL(18));CHKERRQ(ierr);
1426a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(19) (Shur complement info):                       %d \n",mumps->id.ICNTL(19));CHKERRQ(ierr);
1427a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(20) (rhs sparse pattern):                         %d \n",mumps->id.ICNTL(20));CHKERRQ(ierr);
1428ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(21) (solution struct):                            %d \n",mumps->id.ICNTL(21));CHKERRQ(ierr);
1429a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(22) (in-core/out-of-core facility):               %d \n",mumps->id.ICNTL(22));CHKERRQ(ierr);
1430a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(23) (max size of memory can be allocated locally):%d \n",mumps->id.ICNTL(23));CHKERRQ(ierr);
1431c0165424SHong Zhang 
1432a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(24) (detection of null pivot rows):               %d \n",mumps->id.ICNTL(24));CHKERRQ(ierr);
1433a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(25) (computation of a null space basis):          %d \n",mumps->id.ICNTL(25));CHKERRQ(ierr);
1434a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(26) (Schur options for rhs or solution):          %d \n",mumps->id.ICNTL(26));CHKERRQ(ierr);
1435a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(27) (experimental parameter):                     %d \n",mumps->id.ICNTL(27));CHKERRQ(ierr);
1436a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(28) (use parallel or sequential ordering):        %d \n",mumps->id.ICNTL(28));CHKERRQ(ierr);
1437a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(29) (parallel ordering):                          %d \n",mumps->id.ICNTL(29));CHKERRQ(ierr);
143842179a6aSHong Zhang 
1439a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(30) (user-specified set of entries in inv(A)):    %d \n",mumps->id.ICNTL(30));CHKERRQ(ierr);
1440a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(31) (factors is discarded in the solve phase):    %d \n",mumps->id.ICNTL(31));CHKERRQ(ierr);
1441a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ICNTL(33) (compute determinant):                        %d \n",mumps->id.ICNTL(33));CHKERRQ(ierr);
1442f6c57405SHong Zhang 
1443a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(1) (relative pivoting threshold):      %g \n",mumps->id.CNTL(1));CHKERRQ(ierr);
1444a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(2) (stopping criterion of refinement): %g \n",mumps->id.CNTL(2));CHKERRQ(ierr);
1445ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(3) (absolute pivoting threshold):      %g \n",mumps->id.CNTL(3));CHKERRQ(ierr);
1446ca3dc52bSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(4) (value of static pivoting):         %g \n",mumps->id.CNTL(4));CHKERRQ(ierr);
1447a5e57a09SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  CNTL(5) (fixation for null pivots):         %g \n",mumps->id.CNTL(5));CHKERRQ(ierr);
1448f6c57405SHong Zhang 
1449f6c57405SHong Zhang       /* infomation local to each processor */
145034ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);
14517b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
1452a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %g \n",mumps->myid,mumps->id.RINFO(1));CHKERRQ(ierr);
145334ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
145434ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);
1455a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(2));CHKERRQ(ierr);
145634ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
145734ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);
1458a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d]  %g \n",mumps->myid,mumps->id.RINFO(3));CHKERRQ(ierr);
145934ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1460f6c57405SHong Zhang 
146134ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(15) (estimated size of (in MB) MUMPS internal data for running numerical factorization): \n");CHKERRQ(ierr);
1462a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"  [%d] %d \n",mumps->myid,mumps->id.INFO(15));CHKERRQ(ierr);
146334ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1464f6c57405SHong Zhang 
146534ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(16) (size of (in MB) MUMPS internal data used during numerical factorization): \n");CHKERRQ(ierr);
1466a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(16));CHKERRQ(ierr);
146734ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1468f6c57405SHong Zhang 
146934ed7027SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer, "  INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);
1470a5e57a09SHong Zhang       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(23));CHKERRQ(ierr);
147134ed7027SBarry Smith       ierr = PetscViewerFlush(viewer);
1472b34f08ffSHong Zhang 
1473b34f08ffSHong Zhang       if (mumps->ninfo && mumps->ninfo <= 40){
1474b34f08ffSHong Zhang         PetscInt i;
1475b34f08ffSHong Zhang         for (i=0; i<mumps->ninfo; i++){
1476b34f08ffSHong Zhang           ierr = PetscViewerASCIIPrintf(viewer, "  INFO(%d): \n",mumps->info[i]);CHKERRQ(ierr);
1477b34f08ffSHong Zhang           ierr = PetscViewerASCIISynchronizedPrintf(viewer,"    [%d] %d \n",mumps->myid,mumps->id.INFO(mumps->info[i]));CHKERRQ(ierr);
1478b34f08ffSHong Zhang           ierr = PetscViewerFlush(viewer);
1479b34f08ffSHong Zhang         }
1480b34f08ffSHong Zhang       }
1481b34f08ffSHong Zhang 
1482b34f08ffSHong Zhang 
14837b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
1484f6c57405SHong Zhang 
1485a5e57a09SHong Zhang       if (!mumps->myid) { /* information from the host */
1486a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",mumps->id.RINFOG(1));CHKERRQ(ierr);
1487a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",mumps->id.RINFOG(2));CHKERRQ(ierr);
1488a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",mumps->id.RINFOG(3));CHKERRQ(ierr);
1489a5e57a09SHong 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);
1490f6c57405SHong Zhang 
1491a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(3));CHKERRQ(ierr);
1492a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",mumps->id.INFOG(4));CHKERRQ(ierr);
1493a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(5) (estimated maximum front size in the complete tree): %d \n",mumps->id.INFOG(5));CHKERRQ(ierr);
1494a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(6) (number of nodes in the complete tree): %d \n",mumps->id.INFOG(6));CHKERRQ(ierr);
1495a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(7) (ordering option effectively use after analysis): %d \n",mumps->id.INFOG(7));CHKERRQ(ierr);
1496a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",mumps->id.INFOG(8));CHKERRQ(ierr);
1497a5e57a09SHong 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);
1498a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(10) (total integer space store the matrix factors after factorization): %d \n",mumps->id.INFOG(10));CHKERRQ(ierr);
1499a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(11) (order of largest frontal matrix after factorization): %d \n",mumps->id.INFOG(11));CHKERRQ(ierr);
1500a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(12) (number of off-diagonal pivots): %d \n",mumps->id.INFOG(12));CHKERRQ(ierr);
1501a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(13) (number of delayed pivots after factorization): %d \n",mumps->id.INFOG(13));CHKERRQ(ierr);
1502a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(14) (number of memory compress after factorization): %d \n",mumps->id.INFOG(14));CHKERRQ(ierr);
1503a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(15) (number of steps of iterative refinement after solution): %d \n",mumps->id.INFOG(15));CHKERRQ(ierr);
1504a5e57a09SHong 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);
1505a5e57a09SHong 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);
1506a5e57a09SHong 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);
1507a5e57a09SHong 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);
1508a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(20) (estimated number of entries in the factors): %d \n",mumps->id.INFOG(20));CHKERRQ(ierr);
1509a5e57a09SHong 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);
1510a5e57a09SHong 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);
1511a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",mumps->id.INFOG(23));CHKERRQ(ierr);
1512a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",mumps->id.INFOG(24));CHKERRQ(ierr);
1513a5e57a09SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",mumps->id.INFOG(25));CHKERRQ(ierr);
151440d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(28) (after factorization: number of null pivots encountered): %d\n",mumps->id.INFOG(28));CHKERRQ(ierr);
151540d435e3SHong 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);
151640d435e3SHong 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);
151740d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(32) (after analysis: type of analysis done): %d\n",mumps->id.INFOG(32));CHKERRQ(ierr);
151840d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(33) (value used for ICNTL(8)): %d\n",mumps->id.INFOG(33));CHKERRQ(ierr);
151940d435e3SHong Zhang         ierr = PetscViewerASCIIPrintf(viewer,"  INFOG(34) (exponent of the determinant if determinant is requested): %d\n",mumps->id.INFOG(34));CHKERRQ(ierr);
1520f6c57405SHong Zhang       }
1521f6c57405SHong Zhang     }
1522cb828f0fSHong Zhang   }
1523f6c57405SHong Zhang   PetscFunctionReturn(0);
1524f6c57405SHong Zhang }
1525f6c57405SHong Zhang 
152635bd34faSBarry Smith #undef __FUNCT__
152735bd34faSBarry Smith #define __FUNCT__ "MatGetInfo_MUMPS"
152835bd34faSBarry Smith PetscErrorCode MatGetInfo_MUMPS(Mat A,MatInfoType flag,MatInfo *info)
152935bd34faSBarry Smith {
1530cb828f0fSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)A->spptr;
153135bd34faSBarry Smith 
153235bd34faSBarry Smith   PetscFunctionBegin;
153335bd34faSBarry Smith   info->block_size        = 1.0;
1534cb828f0fSHong Zhang   info->nz_allocated      = mumps->id.INFOG(20);
1535cb828f0fSHong Zhang   info->nz_used           = mumps->id.INFOG(20);
153635bd34faSBarry Smith   info->nz_unneeded       = 0.0;
153735bd34faSBarry Smith   info->assemblies        = 0.0;
153835bd34faSBarry Smith   info->mallocs           = 0.0;
153935bd34faSBarry Smith   info->memory            = 0.0;
154035bd34faSBarry Smith   info->fill_ratio_given  = 0;
154135bd34faSBarry Smith   info->fill_ratio_needed = 0;
154235bd34faSBarry Smith   info->factor_mallocs    = 0;
154335bd34faSBarry Smith   PetscFunctionReturn(0);
154435bd34faSBarry Smith }
154535bd34faSBarry Smith 
15465ccb76cbSHong Zhang /* -------------------------------------------------------------------------------------------*/
15475ccb76cbSHong Zhang #undef __FUNCT__
15486444a565SStefano Zampini #define __FUNCT__ "MatMumpsSetSchurIndices_MUMPS"
15496444a565SStefano Zampini PetscErrorCode MatMumpsSetSchurIndices_MUMPS(Mat F,PetscInt size,PetscInt idxs[])
15506444a565SStefano Zampini {
15516444a565SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
15526444a565SStefano Zampini   PetscErrorCode ierr;
15536444a565SStefano Zampini 
15546444a565SStefano Zampini   PetscFunctionBegin;
15556444a565SStefano Zampini   if (mumps->size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MUMPS parallel computation of Schur complements not yet supported from PETSc\n");
15566444a565SStefano Zampini   if (mumps->id.size_schur != size) {
15576444a565SStefano Zampini     ierr = PetscFree2(mumps->id.listvar_schur,mumps->id.schur);CHKERRQ(ierr);
15586444a565SStefano Zampini     mumps->id.size_schur = size;
15596444a565SStefano Zampini     mumps->id.schur_lld = size;
15606444a565SStefano Zampini     ierr = PetscMalloc2(size,&mumps->id.listvar_schur,size*size,&mumps->id.schur);CHKERRQ(ierr);
15616444a565SStefano Zampini   }
15626444a565SStefano Zampini   ierr = PetscMemcpy(mumps->id.listvar_schur,idxs,size*sizeof(PetscInt));CHKERRQ(ierr);
15636444a565SStefano Zampini   if (F->factortype == MAT_FACTOR_LU) {
15646444a565SStefano Zampini     mumps->id.ICNTL(19) = 3; /* return full matrix */
15656444a565SStefano Zampini   } else {
15666444a565SStefano Zampini     mumps->id.ICNTL(19) = 2; /* return lower triangular part */
15676444a565SStefano Zampini   }
1568*b5fa320bSStefano Zampini   mumps->id.ICNTL(26) = -1;
15696444a565SStefano Zampini   PetscFunctionReturn(0);
15706444a565SStefano Zampini }
15716444a565SStefano Zampini 
15726444a565SStefano Zampini #undef __FUNCT__
15736444a565SStefano Zampini #define __FUNCT__ "MatMumpsSetSchurIndices"
15746444a565SStefano Zampini /*@
15756444a565SStefano Zampini   MatMumpsSetSchurIndices - Set indices defining the Schur complement that MUMPS will compute during the factorization steps
15766444a565SStefano Zampini 
15776444a565SStefano Zampini    Logically Collective on Mat
15786444a565SStefano Zampini 
15796444a565SStefano Zampini    Input Parameters:
15806444a565SStefano Zampini +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
15816444a565SStefano Zampini .  size - size of the Schur complement indices
15826444a565SStefano Zampini -  idxs[] - array of Schur complement indices
15836444a565SStefano Zampini 
15846444a565SStefano Zampini    Notes:
15856444a565SStefano Zampini    The user has to free the array idxs[] since it is copied by the routine.
15866444a565SStefano Zampini    Currently implemented for sequential matrices
15876444a565SStefano Zampini 
15886444a565SStefano Zampini    Level: advanced
15896444a565SStefano Zampini 
15906444a565SStefano Zampini    References: MUMPS Users' Guide
15916444a565SStefano Zampini 
15926444a565SStefano Zampini .seealso: MatGetFactor()
15936444a565SStefano Zampini @*/
15946444a565SStefano Zampini PetscErrorCode MatMumpsSetSchurIndices(Mat F,PetscInt size,PetscInt idxs[])
15956444a565SStefano Zampini {
15966444a565SStefano Zampini   PetscErrorCode ierr;
15976444a565SStefano Zampini 
15986444a565SStefano Zampini   PetscFunctionBegin;
15996444a565SStefano Zampini   PetscValidIntPointer(idxs,3);
16006444a565SStefano Zampini   ierr = PetscTryMethod(F,"MatMumpsSetSchurIndices_C",(Mat,PetscInt,PetscInt[]),(F,size,idxs));CHKERRQ(ierr);
16016444a565SStefano Zampini   PetscFunctionReturn(0);
16026444a565SStefano Zampini }
16036444a565SStefano Zampini /* -------------------------------------------------------------------------------------------*/
16046444a565SStefano Zampini #undef __FUNCT__
16056444a565SStefano Zampini #define __FUNCT__ "MatMumpsGetSchurComplement_MUMPS"
16066444a565SStefano Zampini PetscErrorCode MatMumpsGetSchurComplement_MUMPS(Mat F,Mat* S)
16076444a565SStefano Zampini {
16086444a565SStefano Zampini   Mat            St;
16096444a565SStefano Zampini   Mat_MUMPS      *mumps =(Mat_MUMPS*)F->spptr;
16106444a565SStefano Zampini   PetscScalar    *array;
16116444a565SStefano Zampini #if defined(PETSC_USE_COMPLEX)
16126444a565SStefano Zampini   PetscScalar    im = PetscSqrtScalar(-1.0);
16136444a565SStefano Zampini #endif
16146444a565SStefano Zampini   PetscErrorCode ierr;
16156444a565SStefano Zampini 
16166444a565SStefano Zampini   PetscFunctionBegin;
16176444a565SStefano Zampini   if (mumps->id.job != JOB_FACTNUMERIC) {
16186444a565SStefano Zampini     SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONG,"Numerical factorization phase not yet performed! You should call MatFactorSymbolic/Numeric before");
16196444a565SStefano Zampini   } else if (mumps->id.size_schur == 0) {
16206444a565SStefano Zampini     SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_ARG_WRONG,"Schur indices not set! You should call MatMumpsSetSchurIndices before");
16216444a565SStefano Zampini   }
16226444a565SStefano Zampini 
16236444a565SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)F),&St);CHKERRQ(ierr);
16246444a565SStefano Zampini   ierr = MatSetSizes(St,PETSC_DECIDE,PETSC_DECIDE,mumps->id.size_schur,mumps->id.size_schur);CHKERRQ(ierr);
16256444a565SStefano Zampini   ierr = MatSetType(St,MATDENSE);CHKERRQ(ierr);
16266444a565SStefano Zampini   ierr = MatSetUp(St);CHKERRQ(ierr);
16276444a565SStefano Zampini   ierr = MatDenseGetArray(St,&array);CHKERRQ(ierr);
16286444a565SStefano Zampini   if (mumps->sym == 0) { /* MUMPS always return a full matrix */
16296444a565SStefano Zampini     if (mumps->id.ICNTL(19) == 1) { /* stored by rows */
16306444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
16316444a565SStefano Zampini       for (i=0;i<N;i++) {
16326444a565SStefano Zampini         for (j=0;j<N;j++) {
16336444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
16346444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
16356444a565SStefano Zampini #else
16366444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
16376444a565SStefano Zampini #endif
16386444a565SStefano Zampini           array[j*N+i] = val;
16396444a565SStefano Zampini         }
16406444a565SStefano Zampini       }
16416444a565SStefano Zampini     } else { /* stored by columns */
16426444a565SStefano Zampini       ierr = PetscMemcpy(array,mumps->id.schur,mumps->id.size_schur*mumps->id.size_schur*sizeof(PetscScalar));CHKERRQ(ierr);
16436444a565SStefano Zampini     }
16446444a565SStefano Zampini   } else { /* either full or lower-triangular (not packed) */
16456444a565SStefano Zampini     if (mumps->id.ICNTL(19) == 2) { /* lower triangular stored by columns */
16466444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
16476444a565SStefano Zampini       for (i=0;i<N;i++) {
16486444a565SStefano Zampini         for (j=i;j<N;j++) {
16496444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
16506444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
16516444a565SStefano Zampini #else
16526444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
16536444a565SStefano Zampini #endif
16546444a565SStefano Zampini           array[i*N+j] = val;
16556444a565SStefano Zampini         }
16566444a565SStefano Zampini         for (j=i;j<N;j++) {
16576444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
16586444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
16596444a565SStefano Zampini #else
16606444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
16616444a565SStefano Zampini #endif
16626444a565SStefano Zampini           array[j*N+i] = val;
16636444a565SStefano Zampini         }
16646444a565SStefano Zampini       }
16656444a565SStefano Zampini     } else if (mumps->id.ICNTL(19) == 3) { /* full matrix */
16666444a565SStefano Zampini       ierr = PetscMemcpy(array,mumps->id.schur,mumps->id.size_schur*mumps->id.size_schur*sizeof(PetscScalar));CHKERRQ(ierr);
16676444a565SStefano Zampini     } else { /* ICNTL(19) == 1 lower triangular stored by rows */
16686444a565SStefano Zampini       PetscInt i,j,N=mumps->id.size_schur;
16696444a565SStefano Zampini       for (i=0;i<N;i++) {
16706444a565SStefano Zampini         for (j=0;j<i+1;j++) {
16716444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
16726444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
16736444a565SStefano Zampini #else
16746444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
16756444a565SStefano Zampini #endif
16766444a565SStefano Zampini           array[i*N+j] = val;
16776444a565SStefano Zampini         }
16786444a565SStefano Zampini         for (j=0;j<i+1;j++) {
16796444a565SStefano Zampini #if !defined(PETSC_USE_COMPLEX)
16806444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j];
16816444a565SStefano Zampini #else
16826444a565SStefano Zampini           PetscScalar val = mumps->id.schur[i*N+j].r + im*mumps->id.schur[i*N+j].i;
16836444a565SStefano Zampini #endif
16846444a565SStefano Zampini           array[j*N+i] = val;
16856444a565SStefano Zampini         }
16866444a565SStefano Zampini       }
16876444a565SStefano Zampini     }
16886444a565SStefano Zampini   }
16896444a565SStefano Zampini   ierr = MatDenseRestoreArray(St,&array);CHKERRQ(ierr);
16906444a565SStefano Zampini   *S = St;
16916444a565SStefano Zampini   PetscFunctionReturn(0);
16926444a565SStefano Zampini }
16936444a565SStefano Zampini 
16946444a565SStefano Zampini #undef __FUNCT__
16956444a565SStefano Zampini #define __FUNCT__ "MatMumpsGetSchurComplement"
16966444a565SStefano Zampini /*@
16976444a565SStefano Zampini   MatMumpsGetSchurComplement - Get Schur complement matrix computed by MUMPS during the factorization step
16986444a565SStefano Zampini 
16996444a565SStefano Zampini    Logically Collective on Mat
17006444a565SStefano Zampini 
17016444a565SStefano Zampini    Input Parameters:
17026444a565SStefano Zampini +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
17036444a565SStefano Zampini .  *S - location where to return the Schur complement (MATDENSE)
17046444a565SStefano Zampini 
17056444a565SStefano Zampini    Notes:
17066444a565SStefano Zampini    Currently implemented for sequential matrices
17076444a565SStefano Zampini 
17086444a565SStefano Zampini    Level: advanced
17096444a565SStefano Zampini 
17106444a565SStefano Zampini    References: MUMPS Users' Guide
17116444a565SStefano Zampini 
17126444a565SStefano Zampini .seealso: MatGetFactor()
17136444a565SStefano Zampini @*/
17146444a565SStefano Zampini PetscErrorCode MatMumpsGetSchurComplement(Mat F,Mat* S)
17156444a565SStefano Zampini {
17166444a565SStefano Zampini   PetscErrorCode ierr;
17176444a565SStefano Zampini 
17186444a565SStefano Zampini   PetscFunctionBegin;
17196444a565SStefano Zampini   ierr = PetscTryMethod(F,"MatMumpsGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
17206444a565SStefano Zampini   PetscFunctionReturn(0);
17216444a565SStefano Zampini }
17226444a565SStefano Zampini 
17236444a565SStefano Zampini /* -------------------------------------------------------------------------------------------*/
17246444a565SStefano Zampini #undef __FUNCT__
17255ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl_MUMPS"
17265ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl_MUMPS(Mat F,PetscInt icntl,PetscInt ival)
17275ccb76cbSHong Zhang {
1728a5e57a09SHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
17295ccb76cbSHong Zhang 
17305ccb76cbSHong Zhang   PetscFunctionBegin;
1731a5e57a09SHong Zhang   mumps->id.ICNTL(icntl) = ival;
17325ccb76cbSHong Zhang   PetscFunctionReturn(0);
17335ccb76cbSHong Zhang }
17345ccb76cbSHong Zhang 
17355ccb76cbSHong Zhang #undef __FUNCT__
1736bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetIcntl_MUMPS"
1737bc6112feSHong Zhang PetscErrorCode MatMumpsGetIcntl_MUMPS(Mat F,PetscInt icntl,PetscInt *ival)
1738bc6112feSHong Zhang {
1739bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1740bc6112feSHong Zhang 
1741bc6112feSHong Zhang   PetscFunctionBegin;
1742bc6112feSHong Zhang   *ival = mumps->id.ICNTL(icntl);
1743bc6112feSHong Zhang   PetscFunctionReturn(0);
1744bc6112feSHong Zhang }
1745bc6112feSHong Zhang 
1746bc6112feSHong Zhang #undef __FUNCT__
17475ccb76cbSHong Zhang #define __FUNCT__ "MatMumpsSetIcntl"
17485ccb76cbSHong Zhang /*@
17495ccb76cbSHong Zhang   MatMumpsSetIcntl - Set MUMPS parameter ICNTL()
17505ccb76cbSHong Zhang 
17515ccb76cbSHong Zhang    Logically Collective on Mat
17525ccb76cbSHong Zhang 
17535ccb76cbSHong Zhang    Input Parameters:
17545ccb76cbSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
17555ccb76cbSHong Zhang .  icntl - index of MUMPS parameter array ICNTL()
17565ccb76cbSHong Zhang -  ival - value of MUMPS ICNTL(icntl)
17575ccb76cbSHong Zhang 
17585ccb76cbSHong Zhang   Options Database:
17595ccb76cbSHong Zhang .   -mat_mumps_icntl_<icntl> <ival>
17605ccb76cbSHong Zhang 
17615ccb76cbSHong Zhang    Level: beginner
17625ccb76cbSHong Zhang 
17635ccb76cbSHong Zhang    References: MUMPS Users' Guide
17645ccb76cbSHong Zhang 
17655ccb76cbSHong Zhang .seealso: MatGetFactor()
17665ccb76cbSHong Zhang @*/
17675ccb76cbSHong Zhang PetscErrorCode MatMumpsSetIcntl(Mat F,PetscInt icntl,PetscInt ival)
17685ccb76cbSHong Zhang {
17695ccb76cbSHong Zhang   PetscErrorCode ierr;
17705ccb76cbSHong Zhang 
17715ccb76cbSHong Zhang   PetscFunctionBegin;
17725ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
17735ccb76cbSHong Zhang   PetscValidLogicalCollectiveInt(F,ival,3);
17745ccb76cbSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsSetIcntl_C",(Mat,PetscInt,PetscInt),(F,icntl,ival));CHKERRQ(ierr);
17755ccb76cbSHong Zhang   PetscFunctionReturn(0);
17765ccb76cbSHong Zhang }
17775ccb76cbSHong Zhang 
1778bc6112feSHong Zhang #undef __FUNCT__
1779bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetIcntl"
1780a21f80fcSHong Zhang /*@
1781a21f80fcSHong Zhang   MatMumpsGetIcntl - Get MUMPS parameter ICNTL()
1782a21f80fcSHong Zhang 
1783a21f80fcSHong Zhang    Logically Collective on Mat
1784a21f80fcSHong Zhang 
1785a21f80fcSHong Zhang    Input Parameters:
1786a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
1787a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array ICNTL()
1788a21f80fcSHong Zhang 
1789a21f80fcSHong Zhang   Output Parameter:
1790a21f80fcSHong Zhang .  ival - value of MUMPS ICNTL(icntl)
1791a21f80fcSHong Zhang 
1792a21f80fcSHong Zhang    Level: beginner
1793a21f80fcSHong Zhang 
1794a21f80fcSHong Zhang    References: MUMPS Users' Guide
1795a21f80fcSHong Zhang 
1796a21f80fcSHong Zhang .seealso: MatGetFactor()
1797a21f80fcSHong Zhang @*/
1798bc6112feSHong Zhang PetscErrorCode MatMumpsGetIcntl(Mat F,PetscInt icntl,PetscInt *ival)
1799bc6112feSHong Zhang {
1800bc6112feSHong Zhang   PetscErrorCode ierr;
1801bc6112feSHong Zhang 
1802bc6112feSHong Zhang   PetscFunctionBegin;
1803bc6112feSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
1804bc6112feSHong Zhang   PetscValidIntPointer(ival,3);
1805bc6112feSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetIcntl_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
1806bc6112feSHong Zhang   PetscFunctionReturn(0);
1807bc6112feSHong Zhang }
1808bc6112feSHong Zhang 
18098928b65cSHong Zhang /* -------------------------------------------------------------------------------------------*/
18108928b65cSHong Zhang #undef __FUNCT__
18118928b65cSHong Zhang #define __FUNCT__ "MatMumpsSetCntl_MUMPS"
18128928b65cSHong Zhang PetscErrorCode MatMumpsSetCntl_MUMPS(Mat F,PetscInt icntl,PetscReal val)
18138928b65cSHong Zhang {
18148928b65cSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
18158928b65cSHong Zhang 
18168928b65cSHong Zhang   PetscFunctionBegin;
18178928b65cSHong Zhang   mumps->id.CNTL(icntl) = val;
18188928b65cSHong Zhang   PetscFunctionReturn(0);
18198928b65cSHong Zhang }
18208928b65cSHong Zhang 
18218928b65cSHong Zhang #undef __FUNCT__
1822bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetCntl_MUMPS"
1823bc6112feSHong Zhang PetscErrorCode MatMumpsGetCntl_MUMPS(Mat F,PetscInt icntl,PetscReal *val)
1824bc6112feSHong Zhang {
1825bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1826bc6112feSHong Zhang 
1827bc6112feSHong Zhang   PetscFunctionBegin;
1828bc6112feSHong Zhang   *val = mumps->id.CNTL(icntl);
1829bc6112feSHong Zhang   PetscFunctionReturn(0);
1830bc6112feSHong Zhang }
1831bc6112feSHong Zhang 
1832bc6112feSHong Zhang #undef __FUNCT__
18338928b65cSHong Zhang #define __FUNCT__ "MatMumpsSetCntl"
18348928b65cSHong Zhang /*@
18358928b65cSHong Zhang   MatMumpsSetCntl - Set MUMPS parameter CNTL()
18368928b65cSHong Zhang 
18378928b65cSHong Zhang    Logically Collective on Mat
18388928b65cSHong Zhang 
18398928b65cSHong Zhang    Input Parameters:
18408928b65cSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
18418928b65cSHong Zhang .  icntl - index of MUMPS parameter array CNTL()
18428928b65cSHong Zhang -  val - value of MUMPS CNTL(icntl)
18438928b65cSHong Zhang 
18448928b65cSHong Zhang   Options Database:
18458928b65cSHong Zhang .   -mat_mumps_cntl_<icntl> <val>
18468928b65cSHong Zhang 
18478928b65cSHong Zhang    Level: beginner
18488928b65cSHong Zhang 
18498928b65cSHong Zhang    References: MUMPS Users' Guide
18508928b65cSHong Zhang 
18518928b65cSHong Zhang .seealso: MatGetFactor()
18528928b65cSHong Zhang @*/
18538928b65cSHong Zhang PetscErrorCode MatMumpsSetCntl(Mat F,PetscInt icntl,PetscReal val)
18548928b65cSHong Zhang {
18558928b65cSHong Zhang   PetscErrorCode ierr;
18568928b65cSHong Zhang 
18578928b65cSHong Zhang   PetscFunctionBegin;
18588928b65cSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
1859bc6112feSHong Zhang   PetscValidLogicalCollectiveReal(F,val,3);
18608928b65cSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsSetCntl_C",(Mat,PetscInt,PetscReal),(F,icntl,val));CHKERRQ(ierr);
18618928b65cSHong Zhang   PetscFunctionReturn(0);
18628928b65cSHong Zhang }
18638928b65cSHong Zhang 
1864bc6112feSHong Zhang #undef __FUNCT__
1865bc6112feSHong Zhang #define __FUNCT__ "MatMumpsGetCntl"
1866a21f80fcSHong Zhang /*@
1867a21f80fcSHong Zhang   MatMumpsGetCntl - Get MUMPS parameter CNTL()
1868a21f80fcSHong Zhang 
1869a21f80fcSHong Zhang    Logically Collective on Mat
1870a21f80fcSHong Zhang 
1871a21f80fcSHong Zhang    Input Parameters:
1872a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
1873a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array CNTL()
1874a21f80fcSHong Zhang 
1875a21f80fcSHong Zhang   Output Parameter:
1876a21f80fcSHong Zhang .  val - value of MUMPS CNTL(icntl)
1877a21f80fcSHong Zhang 
1878a21f80fcSHong Zhang    Level: beginner
1879a21f80fcSHong Zhang 
1880a21f80fcSHong Zhang    References: MUMPS Users' Guide
1881a21f80fcSHong Zhang 
1882a21f80fcSHong Zhang .seealso: MatGetFactor()
1883a21f80fcSHong Zhang @*/
1884bc6112feSHong Zhang PetscErrorCode MatMumpsGetCntl(Mat F,PetscInt icntl,PetscReal *val)
1885bc6112feSHong Zhang {
1886bc6112feSHong Zhang   PetscErrorCode ierr;
1887bc6112feSHong Zhang 
1888bc6112feSHong Zhang   PetscFunctionBegin;
1889bc6112feSHong Zhang   PetscValidLogicalCollectiveInt(F,icntl,2);
1890bc6112feSHong Zhang   PetscValidRealPointer(val,3);
1891bc6112feSHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetCntl_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
1892bc6112feSHong Zhang   PetscFunctionReturn(0);
1893bc6112feSHong Zhang }
1894bc6112feSHong Zhang 
1895bc6112feSHong Zhang #undef __FUNCT__
1896ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfo_MUMPS"
1897ca810319SHong Zhang PetscErrorCode MatMumpsGetInfo_MUMPS(Mat F,PetscInt icntl,PetscInt *info)
1898bc6112feSHong Zhang {
1899bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1900bc6112feSHong Zhang 
1901bc6112feSHong Zhang   PetscFunctionBegin;
1902bc6112feSHong Zhang   *info = mumps->id.INFO(icntl);
1903bc6112feSHong Zhang   PetscFunctionReturn(0);
1904bc6112feSHong Zhang }
1905bc6112feSHong Zhang 
1906bc6112feSHong Zhang #undef __FUNCT__
1907ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfog_MUMPS"
1908ca810319SHong Zhang PetscErrorCode MatMumpsGetInfog_MUMPS(Mat F,PetscInt icntl,PetscInt *infog)
1909bc6112feSHong Zhang {
1910bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1911bc6112feSHong Zhang 
1912bc6112feSHong Zhang   PetscFunctionBegin;
1913bc6112feSHong Zhang   *infog = mumps->id.INFOG(icntl);
1914bc6112feSHong Zhang   PetscFunctionReturn(0);
1915bc6112feSHong Zhang }
1916bc6112feSHong Zhang 
1917bc6112feSHong Zhang #undef __FUNCT__
1918ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfo_MUMPS"
1919ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfo_MUMPS(Mat F,PetscInt icntl,PetscReal *rinfo)
1920bc6112feSHong Zhang {
1921bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1922bc6112feSHong Zhang 
1923bc6112feSHong Zhang   PetscFunctionBegin;
1924bc6112feSHong Zhang   *rinfo = mumps->id.RINFO(icntl);
1925bc6112feSHong Zhang   PetscFunctionReturn(0);
1926bc6112feSHong Zhang }
1927bc6112feSHong Zhang 
1928bc6112feSHong Zhang #undef __FUNCT__
1929ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfog_MUMPS"
1930ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfog_MUMPS(Mat F,PetscInt icntl,PetscReal *rinfog)
1931bc6112feSHong Zhang {
1932bc6112feSHong Zhang   Mat_MUMPS *mumps =(Mat_MUMPS*)F->spptr;
1933bc6112feSHong Zhang 
1934bc6112feSHong Zhang   PetscFunctionBegin;
1935bc6112feSHong Zhang   *rinfog = mumps->id.RINFOG(icntl);
1936bc6112feSHong Zhang   PetscFunctionReturn(0);
1937bc6112feSHong Zhang }
1938bc6112feSHong Zhang 
1939bc6112feSHong Zhang #undef __FUNCT__
1940ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfo"
1941a21f80fcSHong Zhang /*@
1942a21f80fcSHong Zhang   MatMumpsGetInfo - Get MUMPS parameter INFO()
1943a21f80fcSHong Zhang 
1944a21f80fcSHong Zhang    Logically Collective on Mat
1945a21f80fcSHong Zhang 
1946a21f80fcSHong Zhang    Input Parameters:
1947a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
1948a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array INFO()
1949a21f80fcSHong Zhang 
1950a21f80fcSHong Zhang   Output Parameter:
1951a21f80fcSHong Zhang .  ival - value of MUMPS INFO(icntl)
1952a21f80fcSHong Zhang 
1953a21f80fcSHong Zhang    Level: beginner
1954a21f80fcSHong Zhang 
1955a21f80fcSHong Zhang    References: MUMPS Users' Guide
1956a21f80fcSHong Zhang 
1957a21f80fcSHong Zhang .seealso: MatGetFactor()
1958a21f80fcSHong Zhang @*/
1959ca810319SHong Zhang PetscErrorCode MatMumpsGetInfo(Mat F,PetscInt icntl,PetscInt *ival)
1960bc6112feSHong Zhang {
1961bc6112feSHong Zhang   PetscErrorCode ierr;
1962bc6112feSHong Zhang 
1963bc6112feSHong Zhang   PetscFunctionBegin;
1964ca810319SHong Zhang   PetscValidIntPointer(ival,3);
1965ca810319SHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetInfo_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
1966bc6112feSHong Zhang   PetscFunctionReturn(0);
1967bc6112feSHong Zhang }
1968bc6112feSHong Zhang 
1969bc6112feSHong Zhang #undef __FUNCT__
1970ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetInfog"
1971a21f80fcSHong Zhang /*@
1972a21f80fcSHong Zhang   MatMumpsGetInfog - Get MUMPS parameter INFOG()
1973a21f80fcSHong Zhang 
1974a21f80fcSHong Zhang    Logically Collective on Mat
1975a21f80fcSHong Zhang 
1976a21f80fcSHong Zhang    Input Parameters:
1977a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
1978a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array INFOG()
1979a21f80fcSHong Zhang 
1980a21f80fcSHong Zhang   Output Parameter:
1981a21f80fcSHong Zhang .  ival - value of MUMPS INFOG(icntl)
1982a21f80fcSHong Zhang 
1983a21f80fcSHong Zhang    Level: beginner
1984a21f80fcSHong Zhang 
1985a21f80fcSHong Zhang    References: MUMPS Users' Guide
1986a21f80fcSHong Zhang 
1987a21f80fcSHong Zhang .seealso: MatGetFactor()
1988a21f80fcSHong Zhang @*/
1989ca810319SHong Zhang PetscErrorCode MatMumpsGetInfog(Mat F,PetscInt icntl,PetscInt *ival)
1990bc6112feSHong Zhang {
1991bc6112feSHong Zhang   PetscErrorCode ierr;
1992bc6112feSHong Zhang 
1993bc6112feSHong Zhang   PetscFunctionBegin;
1994ca810319SHong Zhang   PetscValidIntPointer(ival,3);
1995ca810319SHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetInfog_C",(Mat,PetscInt,PetscInt*),(F,icntl,ival));CHKERRQ(ierr);
1996bc6112feSHong Zhang   PetscFunctionReturn(0);
1997bc6112feSHong Zhang }
1998bc6112feSHong Zhang 
1999bc6112feSHong Zhang #undef __FUNCT__
2000ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfo"
2001a21f80fcSHong Zhang /*@
2002a21f80fcSHong Zhang   MatMumpsGetRinfo - Get MUMPS parameter RINFO()
2003a21f80fcSHong Zhang 
2004a21f80fcSHong Zhang    Logically Collective on Mat
2005a21f80fcSHong Zhang 
2006a21f80fcSHong Zhang    Input Parameters:
2007a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2008a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array RINFO()
2009a21f80fcSHong Zhang 
2010a21f80fcSHong Zhang   Output Parameter:
2011a21f80fcSHong Zhang .  val - value of MUMPS RINFO(icntl)
2012a21f80fcSHong Zhang 
2013a21f80fcSHong Zhang    Level: beginner
2014a21f80fcSHong Zhang 
2015a21f80fcSHong Zhang    References: MUMPS Users' Guide
2016a21f80fcSHong Zhang 
2017a21f80fcSHong Zhang .seealso: MatGetFactor()
2018a21f80fcSHong Zhang @*/
2019ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfo(Mat F,PetscInt icntl,PetscReal *val)
2020bc6112feSHong Zhang {
2021bc6112feSHong Zhang   PetscErrorCode ierr;
2022bc6112feSHong Zhang 
2023bc6112feSHong Zhang   PetscFunctionBegin;
2024bc6112feSHong Zhang   PetscValidRealPointer(val,3);
2025ca810319SHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetRinfo_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
2026bc6112feSHong Zhang   PetscFunctionReturn(0);
2027bc6112feSHong Zhang }
2028bc6112feSHong Zhang 
2029bc6112feSHong Zhang #undef __FUNCT__
2030ca810319SHong Zhang #define __FUNCT__ "MatMumpsGetRinfog"
2031a21f80fcSHong Zhang /*@
2032a21f80fcSHong Zhang   MatMumpsGetRinfog - Get MUMPS parameter RINFOG()
2033a21f80fcSHong Zhang 
2034a21f80fcSHong Zhang    Logically Collective on Mat
2035a21f80fcSHong Zhang 
2036a21f80fcSHong Zhang    Input Parameters:
2037a21f80fcSHong Zhang +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
2038a21f80fcSHong Zhang -  icntl - index of MUMPS parameter array RINFOG()
2039a21f80fcSHong Zhang 
2040a21f80fcSHong Zhang   Output Parameter:
2041a21f80fcSHong Zhang .  val - value of MUMPS RINFOG(icntl)
2042a21f80fcSHong Zhang 
2043a21f80fcSHong Zhang    Level: beginner
2044a21f80fcSHong Zhang 
2045a21f80fcSHong Zhang    References: MUMPS Users' Guide
2046a21f80fcSHong Zhang 
2047a21f80fcSHong Zhang .seealso: MatGetFactor()
2048a21f80fcSHong Zhang @*/
2049ca810319SHong Zhang PetscErrorCode MatMumpsGetRinfog(Mat F,PetscInt icntl,PetscReal *val)
2050bc6112feSHong Zhang {
2051bc6112feSHong Zhang   PetscErrorCode ierr;
2052bc6112feSHong Zhang 
2053bc6112feSHong Zhang   PetscFunctionBegin;
2054bc6112feSHong Zhang   PetscValidRealPointer(val,3);
2055ca810319SHong Zhang   ierr = PetscTryMethod(F,"MatMumpsGetRinfog_C",(Mat,PetscInt,PetscReal*),(F,icntl,val));CHKERRQ(ierr);
2056bc6112feSHong Zhang   PetscFunctionReturn(0);
2057bc6112feSHong Zhang }
2058bc6112feSHong Zhang 
205924b6179bSKris Buschelman /*MC
20602692d6eeSBarry Smith   MATSOLVERMUMPS -  A matrix type providing direct solvers (LU and Cholesky) for
206124b6179bSKris Buschelman   distributed and sequential matrices via the external package MUMPS.
206224b6179bSKris Buschelman 
206341c8de11SBarry Smith   Works with MATAIJ and MATSBAIJ matrices
206424b6179bSKris Buschelman 
206524b6179bSKris Buschelman   Options Database Keys:
20664e34a73bSHong Zhang +  -mat_mumps_icntl_1 <6>: ICNTL(1): output stream for error messages (None)
20674e34a73bSHong Zhang .  -mat_mumps_icntl_2 <0>: ICNTL(2): output stream for diagnostic printing, statistics, and warning (None)
20684e34a73bSHong Zhang .  -mat_mumps_icntl_3 <0>: ICNTL(3): output stream for global information, collected on the host (None)
20694e34a73bSHong Zhang .  -mat_mumps_icntl_4 <0>: ICNTL(4): level of printing (0 to 4) (None)
20704e34a73bSHong Zhang .  -mat_mumps_icntl_6 <7>: ICNTL(6): permutes to a zero-free diagonal and/or scale the matrix (0 to 7) (None)
20714e34a73bSHong Zhang .  -mat_mumps_icntl_7 <7>: ICNTL(7): computes a symmetric permutation in sequential analysis (0 to 7). 3=Scotch, 4=PORD, 5=Metis (None)
20724e34a73bSHong Zhang .  -mat_mumps_icntl_8 <77>: ICNTL(8): scaling strategy (-2 to 8 or 77) (None)
20734e34a73bSHong Zhang .  -mat_mumps_icntl_10 <0>: ICNTL(10): max num of refinements (None)
20744e34a73bSHong Zhang .  -mat_mumps_icntl_11 <0>: ICNTL(11): statistics related to an error analysis (via -ksp_view) (None)
20754e34a73bSHong Zhang .  -mat_mumps_icntl_12 <1>: ICNTL(12): an ordering strategy for symmetric matrices (0 to 3) (None)
20764e34a73bSHong Zhang .  -mat_mumps_icntl_13 <0>: ICNTL(13): parallelism of the root node (enable ScaLAPACK) and its splitting (None)
20774e34a73bSHong Zhang .  -mat_mumps_icntl_14 <20>: ICNTL(14): percentage increase in the estimated working space (None)
20784e34a73bSHong Zhang .  -mat_mumps_icntl_19 <0>: ICNTL(19): computes the Schur complement (None)
20794e34a73bSHong Zhang .  -mat_mumps_icntl_22 <0>: ICNTL(22): in-core/out-of-core factorization and solve (0 or 1) (None)
20804e34a73bSHong Zhang .  -mat_mumps_icntl_23 <0>: ICNTL(23): max size of the working memory (MB) that can allocate per processor (None)
20814e34a73bSHong Zhang .  -mat_mumps_icntl_24 <0>: ICNTL(24): detection of null pivot rows (0 or 1) (None)
20824e34a73bSHong Zhang .  -mat_mumps_icntl_25 <0>: ICNTL(25): compute a solution of a deficient matrix and a null space basis (None)
20834e34a73bSHong Zhang .  -mat_mumps_icntl_26 <0>: ICNTL(26): drives the solution phase if a Schur complement matrix (None)
20844e34a73bSHong Zhang .  -mat_mumps_icntl_28 <1>: ICNTL(28): use 1 for sequential analysis and ictnl(7) ordering, or 2 for parallel analysis and ictnl(29) ordering (None)
20854e34a73bSHong Zhang .  -mat_mumps_icntl_29 <0>: ICNTL(29): parallel ordering 1 = ptscotch, 2 = parmetis (None)
20864e34a73bSHong Zhang .  -mat_mumps_icntl_30 <0>: ICNTL(30): compute user-specified set of entries in inv(A) (None)
20874e34a73bSHong Zhang .  -mat_mumps_icntl_31 <0>: ICNTL(31): indicates which factors may be discarded during factorization (None)
20884e34a73bSHong Zhang .  -mat_mumps_icntl_33 <0>: ICNTL(33): compute determinant (None)
20894e34a73bSHong Zhang .  -mat_mumps_cntl_1 <0.01>: CNTL(1): relative pivoting threshold (None)
20904e34a73bSHong Zhang .  -mat_mumps_cntl_2 <1.49012e-08>: CNTL(2): stopping criterion of refinement (None)
20914e34a73bSHong Zhang .  -mat_mumps_cntl_3 <0>: CNTL(3): absolute pivoting threshold (None)
20924e34a73bSHong Zhang .  -mat_mumps_cntl_4 <-1>: CNTL(4): value for static pivoting (None)
20934e34a73bSHong Zhang -  -mat_mumps_cntl_5 <0>: CNTL(5): fixation for null pivots (None)
209424b6179bSKris Buschelman 
209524b6179bSKris Buschelman   Level: beginner
209624b6179bSKris Buschelman 
209741c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
209841c8de11SBarry Smith 
209924b6179bSKris Buschelman M*/
210024b6179bSKris Buschelman 
210135bd34faSBarry Smith #undef __FUNCT__
210235bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_mumps"
2103f7a08781SBarry Smith static PetscErrorCode MatFactorGetSolverPackage_mumps(Mat A,const MatSolverPackage *type)
210435bd34faSBarry Smith {
210535bd34faSBarry Smith   PetscFunctionBegin;
21062692d6eeSBarry Smith   *type = MATSOLVERMUMPS;
210735bd34faSBarry Smith   PetscFunctionReturn(0);
210835bd34faSBarry Smith }
210935bd34faSBarry Smith 
2110bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI AIJ matrices */
21112877fffaSHong Zhang #undef __FUNCT__
2112bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_aij_mumps"
21138cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat A,MatFactorType ftype,Mat *F)
21142877fffaSHong Zhang {
21152877fffaSHong Zhang   Mat            B;
21162877fffaSHong Zhang   PetscErrorCode ierr;
21172877fffaSHong Zhang   Mat_MUMPS      *mumps;
2118ace3abfcSBarry Smith   PetscBool      isSeqAIJ;
21192877fffaSHong Zhang 
21202877fffaSHong Zhang   PetscFunctionBegin;
21212877fffaSHong Zhang   /* Create the factorization matrix */
2122251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr);
2123ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
21242877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
21252877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2126bccb9932SShri Abhyankar   if (isSeqAIJ) {
21270298fd71SBarry Smith     ierr = MatSeqAIJSetPreallocation(B,0,NULL);CHKERRQ(ierr);
2128bccb9932SShri Abhyankar   } else {
21290298fd71SBarry Smith     ierr = MatMPIAIJSetPreallocation(B,0,NULL,0,NULL);CHKERRQ(ierr);
2130bccb9932SShri Abhyankar   }
21312877fffaSHong Zhang 
2132b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
21332205254eSKarl Rupp 
21342877fffaSHong Zhang   B->ops->view        = MatView_MUMPS;
213535bd34faSBarry Smith   B->ops->getinfo     = MatGetInfo_MUMPS;
213620be8e61SHong Zhang   B->ops->getdiagonal = MatGetDiagonal_MUMPS;
21372205254eSKarl Rupp 
2138bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
2139bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2140bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2141bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2142bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2143bc6112feSHong Zhang 
2144ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2145ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2146ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2147ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
21486444a565SStefano Zampini 
21496444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetSchurIndices_C",MatMumpsSetSchurIndices_MUMPS);CHKERRQ(ierr);
21506444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetSchurComplement_C",MatMumpsGetSchurComplement_MUMPS);CHKERRQ(ierr);
2151450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
2152450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS;
2153d5f3da31SBarry Smith     B->factortype            = MAT_FACTOR_LU;
2154bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqaij;
2155bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpiaij;
2156746480a1SHong Zhang     mumps->sym = 0;
2157dcd589f8SShri Abhyankar   } else {
215867877ebaSShri Abhyankar     B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
2159450b117fSShri Abhyankar     B->factortype                  = MAT_FACTOR_CHOLESKY;
2160bccb9932SShri Abhyankar     if (isSeqAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqaij_seqsbaij;
2161bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpiaij_mpisbaij;
21626fdc2a6dSBarry Smith     if (A->spd_set && A->spd) mumps->sym = 1;
21636fdc2a6dSBarry Smith     else                      mumps->sym = 2;
2164450b117fSShri Abhyankar   }
21652877fffaSHong Zhang 
21662877fffaSHong Zhang   mumps->isAIJ    = PETSC_TRUE;
2167bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
21682877fffaSHong Zhang   B->ops->destroy = MatDestroy_MUMPS;
21692877fffaSHong Zhang   B->spptr        = (void*)mumps;
21702205254eSKarl Rupp 
2171f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2172746480a1SHong Zhang 
21732877fffaSHong Zhang   *F = B;
21742877fffaSHong Zhang   PetscFunctionReturn(0);
21752877fffaSHong Zhang }
21762877fffaSHong Zhang 
2177bccb9932SShri Abhyankar /* MatGetFactor for Seq and MPI SBAIJ matrices */
21782877fffaSHong Zhang #undef __FUNCT__
2179bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_sbaij_mumps"
21808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_sbaij_mumps(Mat A,MatFactorType ftype,Mat *F)
21812877fffaSHong Zhang {
21822877fffaSHong Zhang   Mat            B;
21832877fffaSHong Zhang   PetscErrorCode ierr;
21842877fffaSHong Zhang   Mat_MUMPS      *mumps;
2185ace3abfcSBarry Smith   PetscBool      isSeqSBAIJ;
21862877fffaSHong Zhang 
21872877fffaSHong Zhang   PetscFunctionBegin;
2188ce94432eSBarry Smith   if (ftype != MAT_FACTOR_CHOLESKY) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with MUMPS LU, use AIJ matrix");
2189ce94432eSBarry 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");
2190251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr);
21912877fffaSHong Zhang   /* Create the factorization matrix */
2192ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
21932877fffaSHong Zhang   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
21942877fffaSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2195b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
2196bccb9932SShri Abhyankar   if (isSeqSBAIJ) {
21970298fd71SBarry Smith     ierr = MatSeqSBAIJSetPreallocation(B,1,0,NULL);CHKERRQ(ierr);
21982205254eSKarl Rupp 
219916ebf90aSShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_seqsbaij_seqsbaij;
2200dcd589f8SShri Abhyankar   } else {
22010298fd71SBarry Smith     ierr = MatMPISBAIJSetPreallocation(B,1,0,NULL,0,NULL);CHKERRQ(ierr);
22022205254eSKarl Rupp 
2203bccb9932SShri Abhyankar     mumps->ConvertToTriples = MatConvertToTriples_mpisbaij_mpisbaij;
2204bccb9932SShri Abhyankar   }
2205bccb9932SShri Abhyankar 
220667877ebaSShri Abhyankar   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_MUMPS;
2207bccb9932SShri Abhyankar   B->ops->view                   = MatView_MUMPS;
220820be8e61SHong Zhang   B->ops->getdiagonal            = MatGetDiagonal_MUMPS;
22092205254eSKarl Rupp 
2210bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
2211b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2212b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2213b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2214b13644aeSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2215bc6112feSHong Zhang 
2216ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2217ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2218ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2219ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
22202205254eSKarl Rupp 
22216444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetSchurIndices_C",MatMumpsSetSchurIndices_MUMPS);CHKERRQ(ierr);
22226444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetSchurComplement_C",MatMumpsGetSchurComplement_MUMPS);CHKERRQ(ierr);
22236444a565SStefano Zampini 
2224f4762488SHong Zhang   B->factortype = MAT_FACTOR_CHOLESKY;
22256fdc2a6dSBarry Smith   if (A->spd_set && A->spd) mumps->sym = 1;
22266fdc2a6dSBarry Smith   else                      mumps->sym = 2;
2227a214ac2aSShri Abhyankar 
2228bccb9932SShri Abhyankar   mumps->isAIJ    = PETSC_FALSE;
2229bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
2230f3c0ef26SHong Zhang   B->ops->destroy = MatDestroy_MUMPS;
22312877fffaSHong Zhang   B->spptr        = (void*)mumps;
22322205254eSKarl Rupp 
2233f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2234746480a1SHong Zhang 
22352877fffaSHong Zhang   *F = B;
22362877fffaSHong Zhang   PetscFunctionReturn(0);
22372877fffaSHong Zhang }
223897969023SHong Zhang 
2239450b117fSShri Abhyankar #undef __FUNCT__
2240bccb9932SShri Abhyankar #define __FUNCT__ "MatGetFactor_baij_mumps"
22418cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_baij_mumps(Mat A,MatFactorType ftype,Mat *F)
224267877ebaSShri Abhyankar {
224367877ebaSShri Abhyankar   Mat            B;
224467877ebaSShri Abhyankar   PetscErrorCode ierr;
224567877ebaSShri Abhyankar   Mat_MUMPS      *mumps;
2246ace3abfcSBarry Smith   PetscBool      isSeqBAIJ;
224767877ebaSShri Abhyankar 
224867877ebaSShri Abhyankar   PetscFunctionBegin;
224967877ebaSShri Abhyankar   /* Create the factorization matrix */
2250251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&isSeqBAIJ);CHKERRQ(ierr);
2251ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
225267877ebaSShri Abhyankar   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
225367877ebaSShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2254bccb9932SShri Abhyankar   if (isSeqBAIJ) {
22550298fd71SBarry Smith     ierr = MatSeqBAIJSetPreallocation(B,A->rmap->bs,0,NULL);CHKERRQ(ierr);
2256bccb9932SShri Abhyankar   } else {
22570298fd71SBarry Smith     ierr = MatMPIBAIJSetPreallocation(B,A->rmap->bs,0,NULL,0,NULL);CHKERRQ(ierr);
2258bccb9932SShri Abhyankar   }
2259450b117fSShri Abhyankar 
2260b00a9115SJed Brown   ierr = PetscNewLog(B,&mumps);CHKERRQ(ierr);
2261450b117fSShri Abhyankar   if (ftype == MAT_FACTOR_LU) {
2262450b117fSShri Abhyankar     B->ops->lufactorsymbolic = MatLUFactorSymbolic_BAIJMUMPS;
2263450b117fSShri Abhyankar     B->factortype            = MAT_FACTOR_LU;
2264bccb9932SShri Abhyankar     if (isSeqBAIJ) mumps->ConvertToTriples = MatConvertToTriples_seqbaij_seqaij;
2265bccb9932SShri Abhyankar     else mumps->ConvertToTriples = MatConvertToTriples_mpibaij_mpiaij;
2266746480a1SHong Zhang     mumps->sym = 0;
2267f23aa3ddSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc BAIJ matrices with MUMPS Cholesky, use SBAIJ or AIJ matrix instead\n");
2268bccb9932SShri Abhyankar 
2269450b117fSShri Abhyankar   B->ops->view        = MatView_MUMPS;
227020be8e61SHong Zhang   B->ops->getdiagonal = MatGetDiagonal_MUMPS;
22712205254eSKarl Rupp 
2272bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_mumps);CHKERRQ(ierr);
2273bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetIcntl_C",MatMumpsSetIcntl_MUMPS);CHKERRQ(ierr);
2274bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetIcntl_C",MatMumpsGetIcntl_MUMPS);CHKERRQ(ierr);
2275bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetCntl_C",MatMumpsSetCntl_MUMPS);CHKERRQ(ierr);
2276bc6112feSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetCntl_C",MatMumpsGetCntl_MUMPS);CHKERRQ(ierr);
2277bc6112feSHong Zhang 
2278ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfo_C",MatMumpsGetInfo_MUMPS);CHKERRQ(ierr);
2279ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetInfog_C",MatMumpsGetInfog_MUMPS);CHKERRQ(ierr);
2280ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfo_C",MatMumpsGetRinfo_MUMPS);CHKERRQ(ierr);
2281ca810319SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetRinfog_C",MatMumpsGetRinfog_MUMPS);CHKERRQ(ierr);
2282450b117fSShri Abhyankar 
22836444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsSetSchurIndices_C",MatMumpsSetSchurIndices_MUMPS);CHKERRQ(ierr);
22846444a565SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMumpsGetSchurComplement_C",MatMumpsGetSchurComplement_MUMPS);CHKERRQ(ierr);
22856444a565SStefano Zampini 
2286450b117fSShri Abhyankar   mumps->isAIJ    = PETSC_TRUE;
2287bf0cc555SLisandro Dalcin   mumps->Destroy  = B->ops->destroy;
2288450b117fSShri Abhyankar   B->ops->destroy = MatDestroy_MUMPS;
2289450b117fSShri Abhyankar   B->spptr        = (void*)mumps;
22902205254eSKarl Rupp 
2291f697e70eSHong Zhang   ierr = PetscInitializeMUMPS(A,mumps);CHKERRQ(ierr);
2292746480a1SHong Zhang 
2293450b117fSShri Abhyankar   *F = B;
2294450b117fSShri Abhyankar   PetscFunctionReturn(0);
2295450b117fSShri Abhyankar }
229642c9c57cSBarry Smith 
229742c9c57cSBarry Smith PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*);
229842c9c57cSBarry Smith PETSC_EXTERN PetscErrorCode MatGetFactor_baij_mumps(Mat,MatFactorType,Mat*);
229942c9c57cSBarry Smith PETSC_EXTERN PetscErrorCode MatGetFactor_sbaij_mumps(Mat,MatFactorType,Mat*);
230042c9c57cSBarry Smith 
230142c9c57cSBarry Smith #undef __FUNCT__
230242c9c57cSBarry Smith #define __FUNCT__ "MatSolverPackageRegister_MUMPS"
230329b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverPackageRegister_MUMPS(void)
230442c9c57cSBarry Smith {
230542c9c57cSBarry Smith   PetscErrorCode ierr;
230642c9c57cSBarry Smith 
230742c9c57cSBarry Smith   PetscFunctionBegin;
230842c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIAIJ,         MAT_FACTOR_LU,MatGetFactor_aij_mumps);CHKERRQ(ierr);
230942c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_aij_mumps);CHKERRQ(ierr);
231042c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIBAIJ,         MAT_FACTOR_LU,MatGetFactor_baij_mumps);CHKERRQ(ierr);
231142c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPIBAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_baij_mumps);CHKERRQ(ierr);
231242c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATMPISBAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_sbaij_mumps);CHKERRQ(ierr);
231342c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQAIJ,         MAT_FACTOR_LU,MatGetFactor_aij_mumps);CHKERRQ(ierr);
231442c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_aij_mumps);CHKERRQ(ierr);
231542c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQBAIJ,         MAT_FACTOR_LU,MatGetFactor_baij_mumps);CHKERRQ(ierr);
231642c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQBAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_baij_mumps);CHKERRQ(ierr);
231742c9c57cSBarry Smith   ierr = MatSolverPackageRegister(MATSOLVERMUMPS,MATSEQSBAIJ,         MAT_FACTOR_CHOLESKY,MatGetFactor_sbaij_mumps);CHKERRQ(ierr);
231842c9c57cSBarry Smith   PetscFunctionReturn(0);
231942c9c57cSBarry Smith }
232042c9c57cSBarry Smith 
2321