xref: /petsc/src/mat/impls/aij/seq/umfpack/umfpack.c (revision 5d0c19d75c660d4fec594a5399ec8d8ba29c54a8)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
21677d0b8SKris Buschelman 
31677d0b8SKris Buschelman /*
42d4e2982SHong Zhang    Provides an interface to the UMFPACKv5.1 sparse solver
52d4e2982SHong Zhang 
62d4e2982SHong Zhang    This interface uses the "UF_long version" of the UMFPACK API
72d4e2982SHong Zhang    (*_dl_* and *_zl_* routines, instead of *_di_* and *_zi_* routines)
82d4e2982SHong Zhang    so that UMFPACK can address more than 2Gb of memory on 64 bit
92d4e2982SHong Zhang    machines.
102d4e2982SHong Zhang 
112d4e2982SHong Zhang    If sizeof(UF_long) == 32 the interface only allocates the memory
122d4e2982SHong Zhang    necessary for UMFPACK's working arrays (W, Wi and possibly
132d4e2982SHong Zhang    perm_c). If sizeof(UF_long) == 64, in addition to allocating the
142d4e2982SHong Zhang    working arrays, the interface also has to re-allocate the matrix
152d4e2982SHong Zhang    index arrays (ai and aj, which must be stored as UF_long).
162d4e2982SHong Zhang 
172d4e2982SHong Zhang    The interface is implemented for both real and complex
182d4e2982SHong Zhang    arithmetic. Complex numbers are assumed to be in packed format,
192d4e2982SHong Zhang    which requires UMFPACK >= 4.4.
202d4e2982SHong Zhang 
212d4e2982SHong Zhang    We thank Christophe Geuzaine <geuzaine@acm.caltech.edu> for upgrading this interface to the UMFPACKv5.1
221677d0b8SKris Buschelman */
231677d0b8SKris Buschelman 
241677d0b8SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
251677d0b8SKris Buschelman 
261677d0b8SKris Buschelman EXTERN_C_BEGIN
271677d0b8SKris Buschelman #include "umfpack.h"
281677d0b8SKris Buschelman EXTERN_C_END
291677d0b8SKris Buschelman 
301677d0b8SKris Buschelman typedef struct {
311677d0b8SKris Buschelman   void         *Symbolic, *Numeric;
321677d0b8SKris Buschelman   double       Info[UMFPACK_INFO], Control[UMFPACK_CONTROL],*W;
332d4e2982SHong Zhang   UF_long      *Wi,*ai,*aj,*perm_c;
341677d0b8SKris Buschelman   PetscScalar  *av;
351677d0b8SKris Buschelman   MatStructure flg;
361677d0b8SKris Buschelman   PetscTruth   PetscMatOdering;
371677d0b8SKris Buschelman 
381677d0b8SKris Buschelman   /* Flag to clean up UMFPACK objects during Destroy */
391677d0b8SKris Buschelman   PetscTruth CleanUpUMFPACK;
40f0c56d0fSKris Buschelman } Mat_UMFPACK;
41f0c56d0fSKris Buschelman 
421677d0b8SKris Buschelman #undef __FUNCT__
43f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_UMFPACK"
44dfbe8321SBarry Smith PetscErrorCode MatDestroy_UMFPACK(Mat A)
45dfbe8321SBarry Smith {
46dfbe8321SBarry Smith   PetscErrorCode ierr;
47f0c56d0fSKris Buschelman   Mat_UMFPACK    *lu=(Mat_UMFPACK*)A->spptr;
481677d0b8SKris Buschelman 
491677d0b8SKris Buschelman   PetscFunctionBegin;
50fb731535SKris Buschelman   if (lu->CleanUpUMFPACK) {
512d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
522d4e2982SHong Zhang     umfpack_zl_free_symbolic(&lu->Symbolic);
532d4e2982SHong Zhang     umfpack_zl_free_numeric(&lu->Numeric);
542d4e2982SHong Zhang #else
552d4e2982SHong Zhang     umfpack_dl_free_symbolic(&lu->Symbolic);
562d4e2982SHong Zhang     umfpack_dl_free_numeric(&lu->Numeric);
572d4e2982SHong Zhang #endif
581677d0b8SKris Buschelman     ierr = PetscFree(lu->Wi);CHKERRQ(ierr);
591677d0b8SKris Buschelman     ierr = PetscFree(lu->W);CHKERRQ(ierr);
602d4e2982SHong Zhang     if(sizeof(UF_long) != sizeof(int)){
612d4e2982SHong Zhang       ierr = PetscFree(lu->ai);CHKERRQ(ierr);
622d4e2982SHong Zhang       ierr = PetscFree(lu->aj);CHKERRQ(ierr);
632d4e2982SHong Zhang     }
641677d0b8SKris Buschelman     if (lu->PetscMatOdering) {
651677d0b8SKris Buschelman       ierr = PetscFree(lu->perm_c);CHKERRQ(ierr);
661677d0b8SKris Buschelman     }
671677d0b8SKris Buschelman   }
68b24902e0SBarry Smith   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
691677d0b8SKris Buschelman   PetscFunctionReturn(0);
701677d0b8SKris Buschelman }
711677d0b8SKris Buschelman 
721677d0b8SKris Buschelman #undef __FUNCT__
73f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_UMFPACK"
746849ba73SBarry Smith PetscErrorCode MatSolve_UMFPACK(Mat A,Vec b,Vec x)
756849ba73SBarry Smith {
76f0c56d0fSKris Buschelman   Mat_UMFPACK *lu = (Mat_UMFPACK*)A->spptr;
771677d0b8SKris Buschelman   PetscScalar *av=lu->av,*ba,*xa;
78dfbe8321SBarry Smith   PetscErrorCode ierr;
792d4e2982SHong Zhang   UF_long     *ai=lu->ai,*aj=lu->aj,status;
801677d0b8SKris Buschelman 
811677d0b8SKris Buschelman   PetscFunctionBegin;
822d4e2982SHong Zhang   /* solve Ax = b by umfpack_*_wsolve */
831677d0b8SKris Buschelman   /* ----------------------------------*/
842d4e2982SHong Zhang 
852d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
862d4e2982SHong Zhang   ierr = VecConjugate(b);
872d4e2982SHong Zhang #endif
882d4e2982SHong Zhang 
891677d0b8SKris Buschelman   ierr = VecGetArray(b,&ba);
901677d0b8SKris Buschelman   ierr = VecGetArray(x,&xa);
911677d0b8SKris Buschelman 
922d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
932d4e2982SHong Zhang   status = umfpack_zl_wsolve(UMFPACK_At,ai,aj,(double*)av,NULL,(double*)xa,NULL,(double*)ba,NULL,
942d4e2982SHong Zhang 			     lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W);
952d4e2982SHong Zhang   umfpack_zl_report_info(lu->Control, lu->Info);
961677d0b8SKris Buschelman   if (status < 0){
972d4e2982SHong Zhang     umfpack_zl_report_status(lu->Control, status);
982d4e2982SHong Zhang     SETERRQ(PETSC_ERR_LIB,"umfpack_zl_wsolve failed");
991677d0b8SKris Buschelman   }
1002d4e2982SHong Zhang #else
1012d4e2982SHong Zhang   status = umfpack_dl_wsolve(UMFPACK_At,ai,aj,av,xa,ba,
1022d4e2982SHong Zhang 			     lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W);
1032d4e2982SHong Zhang   umfpack_dl_report_info(lu->Control, lu->Info);
1042d4e2982SHong Zhang   if (status < 0){
1052d4e2982SHong Zhang     umfpack_dl_report_status(lu->Control, status);
1062d4e2982SHong Zhang     SETERRQ(PETSC_ERR_LIB,"umfpack_dl_wsolve failed");
1072d4e2982SHong Zhang   }
1082d4e2982SHong Zhang #endif
1091677d0b8SKris Buschelman 
1101677d0b8SKris Buschelman   ierr = VecRestoreArray(b,&ba);
1111677d0b8SKris Buschelman   ierr = VecRestoreArray(x,&xa);
1122a325a84SHong Zhang 
1132d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
1142d4e2982SHong Zhang   ierr = VecConjugate(b);
1155b2a9f60SHong Zhang   ierr = VecConjugate(x);
1162d4e2982SHong Zhang #endif
1172d4e2982SHong Zhang 
1181677d0b8SKris Buschelman   PetscFunctionReturn(0);
1191677d0b8SKris Buschelman }
1201677d0b8SKris Buschelman 
1211677d0b8SKris Buschelman #undef __FUNCT__
122f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_UMFPACK"
123719d5645SBarry Smith PetscErrorCode MatLUFactorNumeric_UMFPACK(Mat F,Mat A,MatFactorInfo *info)
1246849ba73SBarry Smith {
125719d5645SBarry Smith   Mat_UMFPACK *lu=(Mat_UMFPACK*)(F)->spptr;
1266849ba73SBarry Smith   PetscErrorCode ierr;
127d0f46423SBarry Smith   UF_long     *ai=lu->ai,*aj=lu->aj,m=A->rmap->n,status;
1281677d0b8SKris Buschelman   PetscScalar *av=lu->av;
1291677d0b8SKris Buschelman 
1301677d0b8SKris Buschelman   PetscFunctionBegin;
1311677d0b8SKris Buschelman   /* numeric factorization of A' */
1321677d0b8SKris Buschelman   /* ----------------------------*/
1332d4e2982SHong Zhang 
1342d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
1352a325a84SHong Zhang   if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric){
1362d4e2982SHong Zhang     umfpack_zl_free_numeric(&lu->Numeric);
1372a325a84SHong Zhang   }
1382d4e2982SHong Zhang   status = umfpack_zl_numeric(ai,aj,(double*)av,NULL,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info);
1399f42a82aSMatthew Knepley   if (status < 0) {
1409f42a82aSMatthew Knepley     umfpack_zl_report_status(lu->Control, status);
1419f42a82aSMatthew Knepley     SETERRQ(PETSC_ERR_LIB,"umfpack_zl_numeric failed");
1429f42a82aSMatthew Knepley   }
1431677d0b8SKris Buschelman   /* report numeric factorization of A' when Control[PRL] > 3 */
1442d4e2982SHong Zhang   (void) umfpack_zl_report_numeric(lu->Numeric, lu->Control);
1452d4e2982SHong Zhang #else
1462d4e2982SHong Zhang   if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric){
1472d4e2982SHong Zhang     umfpack_dl_free_numeric(&lu->Numeric);
1482d4e2982SHong Zhang   }
1492d4e2982SHong Zhang   status = umfpack_dl_numeric(ai,aj,av,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info);
1509f42a82aSMatthew Knepley   if (status < 0) {
1519f42a82aSMatthew Knepley     umfpack_zl_report_status(lu->Control, status);
1529f42a82aSMatthew Knepley     SETERRQ(PETSC_ERR_LIB,"umfpack_dl_numeric failed");
1539f42a82aSMatthew Knepley   }
1542d4e2982SHong Zhang   /* report numeric factorization of A' when Control[PRL] > 3 */
1552d4e2982SHong Zhang   (void) umfpack_dl_report_numeric(lu->Numeric, lu->Control);
1562d4e2982SHong Zhang #endif
1571677d0b8SKris Buschelman 
1581677d0b8SKris Buschelman   if (lu->flg == DIFFERENT_NONZERO_PATTERN){  /* first numeric factorization */
1591677d0b8SKris Buschelman     /* allocate working space to be used by Solve */
1602d4e2982SHong Zhang     ierr = PetscMalloc(m * sizeof(UF_long), &lu->Wi);CHKERRQ(ierr);
1612d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
1622d4e2982SHong Zhang     ierr = PetscMalloc(2*5*m * sizeof(double), &lu->W);CHKERRQ(ierr);
1632d4e2982SHong Zhang #else
1641677d0b8SKris Buschelman     ierr = PetscMalloc(5*m * sizeof(double), &lu->W);CHKERRQ(ierr);
1652d4e2982SHong Zhang #endif
1661677d0b8SKris Buschelman   }
1672d4e2982SHong Zhang 
1682a325a84SHong Zhang   lu->flg = SAME_NONZERO_PATTERN;
1692a325a84SHong Zhang   lu->CleanUpUMFPACK = PETSC_TRUE;
170719d5645SBarry Smith   (F)->ops->solve            = MatSolve_UMFPACK;
1711677d0b8SKris Buschelman   PetscFunctionReturn(0);
1721677d0b8SKris Buschelman }
1731677d0b8SKris Buschelman 
1741677d0b8SKris Buschelman /*
1751677d0b8SKris Buschelman    Note the r permutation is ignored
1761677d0b8SKris Buschelman */
1771677d0b8SKris Buschelman #undef __FUNCT__
178f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_UMFPACK"
179719d5645SBarry Smith PetscErrorCode MatLUFactorSymbolic_UMFPACK(Mat F,Mat A,IS r,IS c,MatFactorInfo *info)
1806849ba73SBarry Smith {
1811677d0b8SKris Buschelman   Mat_SeqAIJ     *mat=(Mat_SeqAIJ*)A->data;
182719d5645SBarry Smith   Mat_UMFPACK    *lu = (Mat_UMFPACK*)(F->spptr);
183dfbe8321SBarry Smith   PetscErrorCode ierr;
184*5d0c19d7SBarry Smith   int            i,m=A->rmap->n,n=A->cmap->n;
185*5d0c19d7SBarry Smith   const PetscInt *ra;
1862d4e2982SHong Zhang   UF_long        status;
1871677d0b8SKris Buschelman   PetscScalar    *av=mat->a;
1881677d0b8SKris Buschelman 
1891677d0b8SKris Buschelman   PetscFunctionBegin;
1901677d0b8SKris Buschelman   if (lu->PetscMatOdering) {
1910f6efc10SHong Zhang     ierr = ISGetIndices(r,&ra);CHKERRQ(ierr);
1922d4e2982SHong Zhang     ierr = PetscMalloc(m*sizeof(UF_long),&lu->perm_c);CHKERRQ(ierr);
1932d4e2982SHong Zhang     /* we cannot simply memcpy on 64 bit archs */
1942d4e2982SHong Zhang     for(i = 0; i < m; i++) lu->perm_c[i] = ra[i];
1950f6efc10SHong Zhang     ierr = ISRestoreIndices(r,&ra);CHKERRQ(ierr);
1961677d0b8SKris Buschelman   }
1971677d0b8SKris Buschelman 
1982d4e2982SHong Zhang   if(sizeof(UF_long) != sizeof(int)){
1992d4e2982SHong Zhang     /* we cannot directly use mat->i and mat->j on 64 bit archs */
2002d4e2982SHong Zhang     ierr = PetscMalloc((m+1)*sizeof(UF_long),&lu->ai);CHKERRQ(ierr);
2012d4e2982SHong Zhang     ierr = PetscMalloc(mat->nz*sizeof(UF_long),&lu->aj);CHKERRQ(ierr);
2022d4e2982SHong Zhang     for(i = 0; i < m + 1; i++) lu->ai[i] = mat->i[i];
2032d4e2982SHong Zhang     for(i = 0; i < mat->nz; i++) lu->aj[i] = mat->j[i];
2042d4e2982SHong Zhang   }
2052d4e2982SHong Zhang   else{
2062d4e2982SHong Zhang     lu->ai = (UF_long*)mat->i;
2072d4e2982SHong Zhang     lu->aj = (UF_long*)mat->j;
2082d4e2982SHong Zhang   }
2092d4e2982SHong Zhang 
2101677d0b8SKris Buschelman   /* print the control parameters */
2112d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
2122d4e2982SHong Zhang   if(lu->Control[UMFPACK_PRL] > 1) umfpack_zl_report_control(lu->Control);
2132d4e2982SHong Zhang #else
2142d4e2982SHong Zhang   if(lu->Control[UMFPACK_PRL] > 1) umfpack_dl_report_control(lu->Control);
2152d4e2982SHong Zhang #endif
2161677d0b8SKris Buschelman 
2171677d0b8SKris Buschelman   /* symbolic factorization of A' */
2181677d0b8SKris Buschelman   /* ---------------------------------------------------------------------- */
2192d4e2982SHong Zhang #if defined(PETSC_USE_COMPLEX)
2200f6efc10SHong Zhang   if (lu->PetscMatOdering) { /* use Petsc row ordering */
2212d4e2982SHong Zhang     status = umfpack_zl_qsymbolic(n,m,lu->ai,lu->aj,(double*)av,NULL,
2222d4e2982SHong Zhang 				  lu->perm_c,&lu->Symbolic,lu->Control,lu->Info);
2230f6efc10SHong Zhang   } else { /* use Umfpack col ordering */
2242d4e2982SHong Zhang     status = umfpack_zl_symbolic(n,m,lu->ai,lu->aj,(double*)av,NULL,
2252d4e2982SHong Zhang 				 &lu->Symbolic,lu->Control,lu->Info);
2260f6efc10SHong Zhang   }
2271677d0b8SKris Buschelman   if (status < 0){
2282d4e2982SHong Zhang     umfpack_zl_report_info(lu->Control, lu->Info);
2292d4e2982SHong Zhang     umfpack_zl_report_status(lu->Control, status);
2302d4e2982SHong Zhang     SETERRQ(PETSC_ERR_LIB,"umfpack_dl_symbolic failed");
2311677d0b8SKris Buschelman   }
2321677d0b8SKris Buschelman   /* report sumbolic factorization of A' when Control[PRL] > 3 */
2332d4e2982SHong Zhang   (void) umfpack_zl_report_symbolic(lu->Symbolic, lu->Control);
2342d4e2982SHong Zhang #else
2352d4e2982SHong Zhang   if (lu->PetscMatOdering) { /* use Petsc row ordering */
2362d4e2982SHong Zhang     status = umfpack_dl_qsymbolic(n,m,lu->ai,lu->aj,av,
2372d4e2982SHong Zhang 				  lu->perm_c,&lu->Symbolic,lu->Control,lu->Info);
2382d4e2982SHong Zhang   } else { /* use Umfpack col ordering */
2392d4e2982SHong Zhang     status = umfpack_dl_symbolic(n,m,lu->ai,lu->aj,av,
2402d4e2982SHong Zhang 				 &lu->Symbolic,lu->Control,lu->Info);
2412d4e2982SHong Zhang   }
2422d4e2982SHong Zhang   if (status < 0){
2432d4e2982SHong Zhang     umfpack_dl_report_info(lu->Control, lu->Info);
2442d4e2982SHong Zhang     umfpack_dl_report_status(lu->Control, status);
2452d4e2982SHong Zhang     SETERRQ(PETSC_ERR_LIB,"umfpack_dl_symbolic failed");
2462d4e2982SHong Zhang   }
2472d4e2982SHong Zhang   /* report sumbolic factorization of A' when Control[PRL] > 3 */
2482d4e2982SHong Zhang   (void) umfpack_dl_report_symbolic(lu->Symbolic, lu->Control);
2492d4e2982SHong Zhang #endif
2501677d0b8SKris Buschelman 
2511677d0b8SKris Buschelman   lu->flg = DIFFERENT_NONZERO_PATTERN;
2521677d0b8SKris Buschelman   lu->av  = av;
253e1b4c3a1SKris Buschelman   lu->CleanUpUMFPACK = PETSC_TRUE;
254719d5645SBarry Smith   (F)->ops->lufactornumeric  = MatLUFactorNumeric_UMFPACK;
2551677d0b8SKris Buschelman   PetscFunctionReturn(0);
2561677d0b8SKris Buschelman }
2571677d0b8SKris Buschelman 
2581677d0b8SKris Buschelman #undef __FUNCT__
259f0c56d0fSKris Buschelman #define __FUNCT__ "MatFactorInfo_UMFPACK"
2606849ba73SBarry Smith PetscErrorCode MatFactorInfo_UMFPACK(Mat A,PetscViewer viewer)
2616849ba73SBarry Smith {
262f0c56d0fSKris Buschelman   Mat_UMFPACK    *lu= (Mat_UMFPACK*)A->spptr;
263dfbe8321SBarry Smith   PetscErrorCode ierr;
264f0c56d0fSKris Buschelman 
2651677d0b8SKris Buschelman   PetscFunctionBegin;
2661677d0b8SKris Buschelman   /* check if matrix is UMFPACK type */
267f0c56d0fSKris Buschelman   if (A->ops->solve != MatSolve_UMFPACK) PetscFunctionReturn(0);
2681677d0b8SKris Buschelman 
2691677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"UMFPACK run parameters:\n");CHKERRQ(ierr);
2701677d0b8SKris Buschelman   /* Control parameters used by reporting routiones */
2711677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PRL]: %g\n",lu->Control[UMFPACK_PRL]);CHKERRQ(ierr);
2721677d0b8SKris Buschelman 
2731677d0b8SKris Buschelman   /* Control parameters used by symbolic factorization */
2740f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_STRATEGY]: %g\n",lu->Control[UMFPACK_STRATEGY]);CHKERRQ(ierr);
2751677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_COL]: %g\n",lu->Control[UMFPACK_DENSE_COL]);CHKERRQ(ierr);
2761677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_ROW]: %g\n",lu->Control[UMFPACK_DENSE_ROW]);CHKERRQ(ierr);
2770f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_AMD_DENSE]: %g\n",lu->Control[UMFPACK_AMD_DENSE]);CHKERRQ(ierr);
2781677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_BLOCK_SIZE]: %g\n",lu->Control[UMFPACK_BLOCK_SIZE]);CHKERRQ(ierr);
2790f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_2BY2_TOLERANCE]: %g\n",lu->Control[UMFPACK_2BY2_TOLERANCE]);CHKERRQ(ierr);
2800f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_FIXQ]: %g\n",lu->Control[UMFPACK_FIXQ]);CHKERRQ(ierr);
2810f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_AGGRESSIVE]: %g\n",lu->Control[UMFPACK_AGGRESSIVE]);CHKERRQ(ierr);
2821677d0b8SKris Buschelman 
2831677d0b8SKris Buschelman   /* Control parameters used by numeric factorization */
2841677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_PIVOT_TOLERANCE]);CHKERRQ(ierr);
2850f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_SYM_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE]);CHKERRQ(ierr);
2860f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_SCALE]: %g\n",lu->Control[UMFPACK_SCALE]);CHKERRQ(ierr);
2871677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_ALLOC_INIT]: %g\n",lu->Control[UMFPACK_ALLOC_INIT]);CHKERRQ(ierr);
2880f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DROPTOL]: %g\n",lu->Control[UMFPACK_DROPTOL]);CHKERRQ(ierr);
2891677d0b8SKris Buschelman 
2901677d0b8SKris Buschelman   /* Control parameters used by solve */
2911677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_IRSTEP]: %g\n",lu->Control[UMFPACK_IRSTEP]);CHKERRQ(ierr);
2921677d0b8SKris Buschelman 
2931677d0b8SKris Buschelman   /* mat ordering */
2941677d0b8SKris Buschelman   if(!lu->PetscMatOdering) ierr = PetscViewerASCIIPrintf(viewer,"  UMFPACK default matrix ordering is used (not the PETSc matrix ordering) \n");CHKERRQ(ierr);
2951677d0b8SKris Buschelman 
2961677d0b8SKris Buschelman   PetscFunctionReturn(0);
2971677d0b8SKris Buschelman }
2981677d0b8SKris Buschelman 
299d844382dSKris Buschelman #undef __FUNCT__
300f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_UMFPACK"
3016849ba73SBarry Smith PetscErrorCode MatView_UMFPACK(Mat A,PetscViewer viewer)
3026849ba73SBarry Smith {
303dfbe8321SBarry Smith   PetscErrorCode    ierr;
30432077d6dSBarry Smith   PetscTruth        iascii;
305d844382dSKris Buschelman   PetscViewerFormat format;
306d844382dSKris Buschelman 
307d844382dSKris Buschelman   PetscFunctionBegin;
308b24902e0SBarry Smith   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
309d844382dSKris Buschelman 
31032077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
31132077d6dSBarry Smith   if (iascii) {
312d844382dSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
3132f59403fSHong Zhang     if (format == PETSC_VIEWER_ASCII_INFO) {
314f0c56d0fSKris Buschelman       ierr = MatFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr);
315d844382dSKris Buschelman     }
316d844382dSKris Buschelman   }
317d844382dSKris Buschelman   PetscFunctionReturn(0);
318d844382dSKris Buschelman }
319d844382dSKris Buschelman 
3202f71e704SKris Buschelman /*MC
3215c9eb25fSBarry Smith   MAT_SOLVER_UMFPACK = "umfpack" - A matrix type providing direct solvers (LU) for sequential matrices
3222f71e704SKris Buschelman   via the external package UMFPACK.
3232f71e704SKris Buschelman 
3245c9eb25fSBarry Smith   config/configure.py --download-umfpack to install PETSc to use UMFPACK
3252f71e704SKris Buschelman 
3262f71e704SKris Buschelman   Consult UMFPACK documentation for more information about the Control parameters
3272f71e704SKris Buschelman   which correspond to the options database keys below.
3282f71e704SKris Buschelman 
3292f71e704SKris Buschelman   Options Database Keys:
3305c9eb25fSBarry Smith + -mat_umfpack_prl - UMFPACK print level: Control[UMFPACK_PRL]
3313519fcdcSHong Zhang . -mat_umfpack_strategy <AUTO> (choose one of) AUTO UNSYMMETRIC SYMMETRIC 2BY2
3322f71e704SKris Buschelman . -mat_umfpack_dense_col <alpha_c> - UMFPACK dense column threshold: Control[UMFPACK_DENSE_COL]
3333519fcdcSHong Zhang . -mat_umfpack_dense_row <0.2>: Control[UMFPACK_DENSE_ROW]
3343519fcdcSHong Zhang . -mat_umfpack_amd_dense <10>: Control[UMFPACK_AMD_DENSE]
3352f71e704SKris Buschelman . -mat_umfpack_block_size <bs> - UMFPACK block size for BLAS-Level 3 calls: Control[UMFPACK_BLOCK_SIZE]
3363519fcdcSHong Zhang . -mat_umfpack_2by2_tolerance <0.01>: Control[UMFPACK_2BY2_TOLERANCE]
3373519fcdcSHong Zhang . -mat_umfpack_fixq <0>: Control[UMFPACK_FIXQ]
3383519fcdcSHong Zhang . -mat_umfpack_aggressive <1>: Control[UMFPACK_AGGRESSIVE]
3392f71e704SKris Buschelman . -mat_umfpack_pivot_tolerance <delta> - UMFPACK partial pivot tolerance: Control[UMFPACK_PIVOT_TOLERANCE]
3403519fcdcSHong Zhang .  -mat_umfpack_sym_pivot_tolerance <0.001>: Control[UMFPACK_SYM_PIVOT_TOLERANCE]
3413519fcdcSHong Zhang .  -mat_umfpack_scale <NONE> (choose one of) NONE SUM MAX
3422f71e704SKris Buschelman . -mat_umfpack_alloc_init <delta> - UMFPACK factorized matrix allocation modifier: Control[UMFPACK_ALLOC_INIT]
3433519fcdcSHong Zhang .  -mat_umfpack_droptol <0>: Control[UMFPACK_DROPTOL]
3442f71e704SKris Buschelman - -mat_umfpack_irstep <maxit> - UMFPACK maximum number of iterative refinement steps: Control[UMFPACK_IRSTEP]
3452f71e704SKris Buschelman 
3462f71e704SKris Buschelman    Level: beginner
3472f71e704SKris Buschelman 
3483519fcdcSHong Zhang .seealso: PCLU, MAT_SOLVER_SUPERLU, MAT_SOLVER_MUMPS, MAT_SOLVER_SPOOLES
3492f71e704SKris Buschelman M*/
3503519fcdcSHong Zhang EXTERN_C_BEGIN
3513519fcdcSHong Zhang #undef __FUNCT__
3523519fcdcSHong Zhang #define __FUNCT__ "MatGetFactor_seqaij_umfpack"
3533519fcdcSHong Zhang PetscErrorCode MatGetFactor_seqaij_umfpack(Mat A,MatFactorType ftype,Mat *F)
3543519fcdcSHong Zhang {
3553519fcdcSHong Zhang   Mat            B;
3563519fcdcSHong Zhang   Mat_UMFPACK    *lu;
3573519fcdcSHong Zhang   PetscErrorCode ierr;
3583519fcdcSHong Zhang   int            m=A->rmap->n,n=A->cmap->n,idx;
3592f71e704SKris Buschelman 
3603519fcdcSHong Zhang   const char     *strategy[]={"AUTO","UNSYMMETRIC","SYMMETRIC","2BY2"},
3613519fcdcSHong Zhang                  *scale[]={"NONE","SUM","MAX"};
3623519fcdcSHong Zhang   PetscTruth     flg;
3632d4e2982SHong Zhang 
3643519fcdcSHong Zhang   PetscFunctionBegin;
3653519fcdcSHong Zhang   /* Create the factorization matrix F */
3663519fcdcSHong Zhang   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
3673519fcdcSHong Zhang   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
3683519fcdcSHong Zhang   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
3693519fcdcSHong Zhang   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
3703519fcdcSHong Zhang   ierr = PetscNewLog(B,Mat_UMFPACK,&lu);CHKERRQ(ierr);
3713519fcdcSHong Zhang   B->spptr                 = lu;
3723519fcdcSHong Zhang   B->ops->lufactorsymbolic = MatLUFactorSymbolic_UMFPACK;
3733519fcdcSHong Zhang   B->ops->destroy          = MatDestroy_UMFPACK;
3743519fcdcSHong Zhang   B->ops->view             = MatView_UMFPACK;
3753519fcdcSHong Zhang   B->factor                = MAT_FACTOR_LU;
3763519fcdcSHong Zhang   B->assembled             = PETSC_TRUE;  /* required by -ksp_view */
3773519fcdcSHong Zhang   B->preallocated          = PETSC_TRUE;
3783519fcdcSHong Zhang 
3793519fcdcSHong Zhang   /* initializations */
3803519fcdcSHong Zhang   /* ------------------------------------------------*/
3813519fcdcSHong Zhang   /* get the default control parameters */
3823519fcdcSHong Zhang #if defined(PETSC_USE_COMPLEX)
3833519fcdcSHong Zhang   umfpack_zl_defaults(lu->Control);
3843519fcdcSHong Zhang #else
3853519fcdcSHong Zhang   umfpack_dl_defaults(lu->Control);
3863519fcdcSHong Zhang #endif
3873519fcdcSHong Zhang   lu->perm_c = PETSC_NULL;  /* use defaul UMFPACK col permutation */
3883519fcdcSHong Zhang   lu->Control[UMFPACK_IRSTEP] = 0; /* max num of iterative refinement steps to attempt */
3893519fcdcSHong Zhang 
3903519fcdcSHong Zhang   ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"UMFPACK Options","Mat");CHKERRQ(ierr);
3913519fcdcSHong Zhang   /* Control parameters used by reporting routiones */
3923519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_prl","Control[UMFPACK_PRL]","None",lu->Control[UMFPACK_PRL],&lu->Control[UMFPACK_PRL],PETSC_NULL);CHKERRQ(ierr);
3933519fcdcSHong Zhang 
3943519fcdcSHong Zhang   /* Control parameters for symbolic factorization */
3953519fcdcSHong Zhang   ierr = PetscOptionsEList("-mat_umfpack_strategy","ordering and pivoting strategy","None",strategy,4,strategy[0],&idx,&flg);CHKERRQ(ierr);
3963519fcdcSHong Zhang   if (flg) {
3973519fcdcSHong Zhang     switch (idx){
3983519fcdcSHong Zhang     case 0: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO; break;
3993519fcdcSHong Zhang     case 1: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC; break;
4003519fcdcSHong Zhang     case 2: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC; break;
4013519fcdcSHong Zhang     case 3: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_2BY2; break;
4023519fcdcSHong Zhang     }
4033519fcdcSHong Zhang   }
4043519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_dense_col","Control[UMFPACK_DENSE_COL]","None",lu->Control[UMFPACK_DENSE_COL],&lu->Control[UMFPACK_DENSE_COL],PETSC_NULL);CHKERRQ(ierr);
4053519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_dense_row","Control[UMFPACK_DENSE_ROW]","None",lu->Control[UMFPACK_DENSE_ROW],&lu->Control[UMFPACK_DENSE_ROW],PETSC_NULL);CHKERRQ(ierr);
4063519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_amd_dense","Control[UMFPACK_AMD_DENSE]","None",lu->Control[UMFPACK_AMD_DENSE],&lu->Control[UMFPACK_AMD_DENSE],PETSC_NULL);CHKERRQ(ierr);
4073519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_block_size","Control[UMFPACK_BLOCK_SIZE]","None",lu->Control[UMFPACK_BLOCK_SIZE],&lu->Control[UMFPACK_BLOCK_SIZE],PETSC_NULL);CHKERRQ(ierr);
4083519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_2by2_tolerance","Control[UMFPACK_2BY2_TOLERANCE]","None",lu->Control[UMFPACK_2BY2_TOLERANCE],&lu->Control[UMFPACK_2BY2_TOLERANCE],PETSC_NULL);CHKERRQ(ierr);
4093519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_fixq","Control[UMFPACK_FIXQ]","None",lu->Control[UMFPACK_FIXQ],&lu->Control[UMFPACK_FIXQ],PETSC_NULL);CHKERRQ(ierr);
4103519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_aggressive","Control[UMFPACK_AGGRESSIVE]","None",lu->Control[UMFPACK_AGGRESSIVE],&lu->Control[UMFPACK_AGGRESSIVE],PETSC_NULL);CHKERRQ(ierr);
4113519fcdcSHong Zhang 
4123519fcdcSHong Zhang   /* Control parameters used by numeric factorization */
4133519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_pivot_tolerance","Control[UMFPACK_PIVOT_TOLERANCE]","None",lu->Control[UMFPACK_PIVOT_TOLERANCE],&lu->Control[UMFPACK_PIVOT_TOLERANCE],PETSC_NULL);CHKERRQ(ierr);
4143519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_sym_pivot_tolerance","Control[UMFPACK_SYM_PIVOT_TOLERANCE]","None",lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE],&lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE],PETSC_NULL);CHKERRQ(ierr);
4153519fcdcSHong Zhang   ierr = PetscOptionsEList("-mat_umfpack_scale","Control[UMFPACK_SCALE]","None",scale,3,scale[0],&idx,&flg);CHKERRQ(ierr);
4163519fcdcSHong Zhang   if (flg) {
4173519fcdcSHong Zhang     switch (idx){
4183519fcdcSHong Zhang     case 0: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_NONE; break;
4193519fcdcSHong Zhang     case 1: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_SUM; break;
4203519fcdcSHong Zhang     case 2: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_MAX; break;
4213519fcdcSHong Zhang     }
4223519fcdcSHong Zhang   }
4233519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_alloc_init","Control[UMFPACK_ALLOC_INIT]","None",lu->Control[UMFPACK_ALLOC_INIT],&lu->Control[UMFPACK_ALLOC_INIT],PETSC_NULL);CHKERRQ(ierr);
4243519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_front_alloc_init","Control[UMFPACK_FRONT_ALLOC_INIT]","None",lu->Control[UMFPACK_FRONT_ALLOC_INIT],&lu->Control[UMFPACK_ALLOC_INIT],PETSC_NULL);CHKERRQ(ierr);
4253519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_droptol","Control[UMFPACK_DROPTOL]","None",lu->Control[UMFPACK_DROPTOL],&lu->Control[UMFPACK_DROPTOL],PETSC_NULL);CHKERRQ(ierr);
4263519fcdcSHong Zhang 
4273519fcdcSHong Zhang   /* Control parameters used by solve */
4283519fcdcSHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_irstep","Control[UMFPACK_IRSTEP]","None",lu->Control[UMFPACK_IRSTEP],&lu->Control[UMFPACK_IRSTEP],PETSC_NULL);CHKERRQ(ierr);
4293519fcdcSHong Zhang 
4303519fcdcSHong Zhang   /* use Petsc mat ordering (note: size is for the transpose, and PETSc r = Umfpack perm_c) */
4313519fcdcSHong Zhang   ierr = PetscOptionsHasName(PETSC_NULL,"-pc_factor_mat_ordering_type",&lu->PetscMatOdering);CHKERRQ(ierr);
4323519fcdcSHong Zhang   PetscOptionsEnd();
4333519fcdcSHong Zhang   *F = B;
4343519fcdcSHong Zhang   PetscFunctionReturn(0);
4353519fcdcSHong Zhang }
4363519fcdcSHong Zhang EXTERN_C_END
4372d4e2982SHong Zhang 
438