xref: /petsc/src/mat/impls/aij/seq/umfpack/umfpack.c (revision 2f59403fd2df48e396e6efa2e07d12d9da4cd99d)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
21677d0b8SKris Buschelman 
31677d0b8SKris Buschelman /*
459698cb0SHong Zhang         Provides an interface to the UMFPACKv4.3 sparse solver
51677d0b8SKris Buschelman */
61677d0b8SKris Buschelman 
71677d0b8SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
81677d0b8SKris Buschelman 
91677d0b8SKris Buschelman EXTERN_C_BEGIN
101677d0b8SKris Buschelman #include "umfpack.h"
111677d0b8SKris Buschelman EXTERN_C_END
121677d0b8SKris Buschelman 
131677d0b8SKris Buschelman typedef struct {
141677d0b8SKris Buschelman   void         *Symbolic, *Numeric;
151677d0b8SKris Buschelman   double       Info[UMFPACK_INFO], Control[UMFPACK_CONTROL],*W;
161677d0b8SKris Buschelman   int          *Wi,*ai,*aj,*perm_c;
171677d0b8SKris Buschelman   PetscScalar  *av;
181677d0b8SKris Buschelman   MatStructure flg;
191677d0b8SKris Buschelman   PetscTruth   PetscMatOdering;
201677d0b8SKris Buschelman 
211677d0b8SKris Buschelman   /* A few function pointers for inheritance */
226849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
236849ba73SBarry Smith   PetscErrorCode (*MatView)(Mat,PetscViewer);
246849ba73SBarry Smith   PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType);
256849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
266849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
271677d0b8SKris Buschelman 
281677d0b8SKris Buschelman   /* Flag to clean up UMFPACK objects during Destroy */
291677d0b8SKris Buschelman   PetscTruth CleanUpUMFPACK;
30f0c56d0fSKris Buschelman } Mat_UMFPACK;
31f0c56d0fSKris Buschelman 
32dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_UMFPACK(Mat,MatDuplicateOption,Mat*);
33d844382dSKris Buschelman 
34d844382dSKris Buschelman EXTERN_C_BEGIN
35d844382dSKris Buschelman #undef __FUNCT__
36d844382dSKris Buschelman #define __FUNCT__ "MatConvert_UMFPACK_SeqAIJ"
3775179d2cSHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_UMFPACK_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat)
386849ba73SBarry Smith {
39d844382dSKris Buschelman   /* This routine is only called to convert an unfactored PETSc-UMFPACK matrix */
40d844382dSKris Buschelman   /* to its base PETSc type, so we will ignore 'MatType type'. */
41dfbe8321SBarry Smith   PetscErrorCode ierr;
42d844382dSKris Buschelman   Mat         B=*newmat;
43f0c56d0fSKris Buschelman   Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr;
44d844382dSKris Buschelman 
45d844382dSKris Buschelman   PetscFunctionBegin;
46ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
47d844382dSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
48f0c56d0fSKris Buschelman   }
49d844382dSKris Buschelman   /* Reset the original function pointers */
50901853e0SKris Buschelman   B->ops->duplicate        = lu->MatDuplicate;
51901853e0SKris Buschelman   B->ops->view             = lu->MatView;
52901853e0SKris Buschelman   B->ops->assemblyend      = lu->MatAssemblyEnd;
53901853e0SKris Buschelman   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
54901853e0SKris Buschelman   B->ops->destroy          = lu->MatDestroy;
55901853e0SKris Buschelman 
56901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_umfpack_C","",PETSC_NULL);CHKERRQ(ierr);
57901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_umfpack_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
58901853e0SKris Buschelman 
59d844382dSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
60d844382dSKris Buschelman   *newmat = B;
61d844382dSKris Buschelman   PetscFunctionReturn(0);
62d844382dSKris Buschelman }
63d844382dSKris Buschelman EXTERN_C_END
641677d0b8SKris Buschelman 
651677d0b8SKris Buschelman #undef __FUNCT__
66f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_UMFPACK"
67dfbe8321SBarry Smith PetscErrorCode MatDestroy_UMFPACK(Mat A)
68dfbe8321SBarry Smith {
69dfbe8321SBarry Smith   PetscErrorCode ierr;
70f0c56d0fSKris Buschelman   Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr;
711677d0b8SKris Buschelman 
721677d0b8SKris Buschelman   PetscFunctionBegin;
73fb731535SKris Buschelman   if (lu->CleanUpUMFPACK) {
741677d0b8SKris Buschelman     umfpack_di_free_symbolic(&lu->Symbolic);
751677d0b8SKris Buschelman     umfpack_di_free_numeric(&lu->Numeric);
761677d0b8SKris Buschelman     ierr = PetscFree(lu->Wi);CHKERRQ(ierr);
771677d0b8SKris Buschelman     ierr = PetscFree(lu->W);CHKERRQ(ierr);
781677d0b8SKris Buschelman     if (lu->PetscMatOdering) {
791677d0b8SKris Buschelman       ierr = PetscFree(lu->perm_c);CHKERRQ(ierr);
801677d0b8SKris Buschelman     }
811677d0b8SKris Buschelman   }
82ceb03754SKris Buschelman   ierr = MatConvert_UMFPACK_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
83d844382dSKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
841677d0b8SKris Buschelman   PetscFunctionReturn(0);
851677d0b8SKris Buschelman }
861677d0b8SKris Buschelman 
871677d0b8SKris Buschelman #undef __FUNCT__
88f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_UMFPACK"
896849ba73SBarry Smith PetscErrorCode MatSolve_UMFPACK(Mat A,Vec b,Vec x)
906849ba73SBarry Smith {
91f0c56d0fSKris Buschelman   Mat_UMFPACK *lu = (Mat_UMFPACK*)A->spptr;
921677d0b8SKris Buschelman   PetscScalar *av=lu->av,*ba,*xa;
93dfbe8321SBarry Smith   PetscErrorCode ierr;
94dfbe8321SBarry Smith   int          *ai=lu->ai,*aj=lu->aj,status;
951677d0b8SKris Buschelman 
961677d0b8SKris Buschelman   PetscFunctionBegin;
971677d0b8SKris Buschelman   /* solve Ax = b by umfpack_di_wsolve */
981677d0b8SKris Buschelman   /* ----------------------------------*/
991677d0b8SKris Buschelman   ierr = VecGetArray(b,&ba);
1001677d0b8SKris Buschelman   ierr = VecGetArray(x,&xa);
1011677d0b8SKris Buschelman 
1021677d0b8SKris Buschelman   status = umfpack_di_wsolve(UMFPACK_At,ai,aj,av,xa,ba,lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W);
1031677d0b8SKris Buschelman   umfpack_di_report_info(lu->Control, lu->Info);
1041677d0b8SKris Buschelman   if (status < 0){
1051677d0b8SKris Buschelman     umfpack_di_report_status(lu->Control, status);
106e005ede5SBarry Smith     SETERRQ(PETSC_ERR_LIB,"umfpack_di_wsolve failed");
1071677d0b8SKris Buschelman   }
1081677d0b8SKris Buschelman 
1091677d0b8SKris Buschelman   ierr = VecRestoreArray(b,&ba);
1101677d0b8SKris Buschelman   ierr = VecRestoreArray(x,&xa);
1112a325a84SHong Zhang 
1121677d0b8SKris Buschelman   PetscFunctionReturn(0);
1131677d0b8SKris Buschelman }
1141677d0b8SKris Buschelman 
1151677d0b8SKris Buschelman #undef __FUNCT__
116f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_UMFPACK"
117af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_UMFPACK(Mat A,MatFactorInfo *info,Mat *F)
1186849ba73SBarry Smith {
119f0c56d0fSKris Buschelman   Mat_UMFPACK *lu=(Mat_UMFPACK*)(*F)->spptr;
1206849ba73SBarry Smith   PetscErrorCode ierr;
1212a4c71feSBarry Smith   int         *ai=lu->ai,*aj=lu->aj,m=A->rmap.n,status;
1221677d0b8SKris Buschelman   PetscScalar *av=lu->av;
1231677d0b8SKris Buschelman 
1241677d0b8SKris Buschelman   PetscFunctionBegin;
1251677d0b8SKris Buschelman   /* numeric factorization of A' */
1261677d0b8SKris Buschelman   /* ----------------------------*/
1272a325a84SHong Zhang   if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric){
1282a325a84SHong Zhang       umfpack_di_free_numeric(&lu->Numeric);
1292a325a84SHong Zhang   }
1301677d0b8SKris Buschelman   status = umfpack_di_numeric (ai,aj,av,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info);
131e005ede5SBarry Smith   if (status < 0) SETERRQ(PETSC_ERR_LIB,"umfpack_di_numeric failed");
1321677d0b8SKris Buschelman   /* report numeric factorization of A' when Control[PRL] > 3 */
1331677d0b8SKris Buschelman   (void) umfpack_di_report_numeric (lu->Numeric, lu->Control);
1341677d0b8SKris Buschelman 
1351677d0b8SKris Buschelman   if (lu->flg == DIFFERENT_NONZERO_PATTERN){  /* first numeric factorization */
1361677d0b8SKris Buschelman     /* allocate working space to be used by Solve */
1371677d0b8SKris Buschelman     ierr = PetscMalloc(m * sizeof(int), &lu->Wi);CHKERRQ(ierr);
1381677d0b8SKris Buschelman     ierr = PetscMalloc(5*m * sizeof(double), &lu->W);CHKERRQ(ierr);
1391677d0b8SKris Buschelman   }
1402a325a84SHong Zhang   lu->flg = SAME_NONZERO_PATTERN;
1412a325a84SHong Zhang   lu->CleanUpUMFPACK = PETSC_TRUE;
1421677d0b8SKris Buschelman   PetscFunctionReturn(0);
1431677d0b8SKris Buschelman }
1441677d0b8SKris Buschelman 
1451677d0b8SKris Buschelman /*
1461677d0b8SKris Buschelman    Note the r permutation is ignored
1471677d0b8SKris Buschelman */
1481677d0b8SKris Buschelman #undef __FUNCT__
149f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_UMFPACK"
1506849ba73SBarry Smith PetscErrorCode MatLUFactorSymbolic_UMFPACK(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1516849ba73SBarry Smith {
152e1b4c3a1SKris Buschelman   Mat         B;
1531677d0b8SKris Buschelman   Mat_SeqAIJ  *mat=(Mat_SeqAIJ*)A->data;
154f0c56d0fSKris Buschelman   Mat_UMFPACK *lu;
155dfbe8321SBarry Smith   PetscErrorCode ierr;
1562a4c71feSBarry Smith   int          m=A->rmap.n,n=A->cmap.n,*ai=mat->i,*aj=mat->j,status,*ra,idx;
1571677d0b8SKris Buschelman   PetscScalar *av=mat->a;
1580f6efc10SHong Zhang   const char  *strategy[]={"AUTO","UNSYMMETRIC","SYMMETRIC","2BY2"},
1590f6efc10SHong Zhang               *scale[]={"NONE","SUM","MAX"};
1600f6efc10SHong Zhang   PetscTruth  flg;
1611677d0b8SKris Buschelman 
1621677d0b8SKris Buschelman   PetscFunctionBegin;
1631677d0b8SKris Buschelman   /* Create the factorization matrix F */
164f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&B);CHKERRQ(ierr);
165f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
166be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);CHKERRQ(ierr);
167e1b4c3a1SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
1681677d0b8SKris Buschelman 
169f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_UMFPACK;
170f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_UMFPACK;
171e1b4c3a1SKris Buschelman   B->factor               = FACTOR_LU;
17294b7f48cSBarry Smith   B->assembled            = PETSC_TRUE;  /* required by -ksp_view */
1731677d0b8SKris Buschelman 
174f0c56d0fSKris Buschelman   lu = (Mat_UMFPACK*)(B->spptr);
1751677d0b8SKris Buschelman 
1761677d0b8SKris Buschelman   /* initializations */
1771677d0b8SKris Buschelman   /* ------------------------------------------------*/
1781677d0b8SKris Buschelman   /* get the default control parameters */
1791677d0b8SKris Buschelman   umfpack_di_defaults (lu->Control);
1801677d0b8SKris Buschelman   lu->perm_c = PETSC_NULL;  /* use defaul UMFPACK col permutation */
1810f6efc10SHong Zhang   lu->Control[UMFPACK_IRSTEP] = 0; /* max num of iterative refinement steps to attempt */
1821677d0b8SKris Buschelman 
1831677d0b8SKris Buschelman   ierr = PetscOptionsBegin(A->comm,A->prefix,"UMFPACK Options","Mat");CHKERRQ(ierr);
1841677d0b8SKris Buschelman   /* Control parameters used by reporting routiones */
1851677d0b8SKris Buschelman   ierr = PetscOptionsReal("-mat_umfpack_prl","Control[UMFPACK_PRL]","None",lu->Control[UMFPACK_PRL],&lu->Control[UMFPACK_PRL],PETSC_NULL);CHKERRQ(ierr);
1861677d0b8SKris Buschelman 
1871677d0b8SKris Buschelman   /* Control parameters for symbolic factorization */
1880f6efc10SHong Zhang   ierr = PetscOptionsEList("-mat_umfpack_strategy","ordering and pivoting strategy","None",strategy,4,strategy[0],&idx,&flg);CHKERRQ(ierr);
1890f6efc10SHong Zhang   if (flg) {
1900f6efc10SHong Zhang     switch (idx){
1910f6efc10SHong Zhang     case 0: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO; break;
1920f6efc10SHong Zhang     case 1: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC; break;
1930f6efc10SHong Zhang     case 2: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC; break;
1940f6efc10SHong Zhang     case 3: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_2BY2; break;
1950f6efc10SHong Zhang     }
1960f6efc10SHong Zhang   }
1971677d0b8SKris Buschelman   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);
1981677d0b8SKris Buschelman   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);
1990f6efc10SHong 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);
2001677d0b8SKris Buschelman   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);
2010f6efc10SHong 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);
2020f6efc10SHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_fixq","Control[UMFPACK_FIXQ]","None",lu->Control[UMFPACK_FIXQ],&lu->Control[UMFPACK_FIXQ],PETSC_NULL);CHKERRQ(ierr);
2030f6efc10SHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_aggressive","Control[UMFPACK_AGGRESSIVE]","None",lu->Control[UMFPACK_AGGRESSIVE],&lu->Control[UMFPACK_AGGRESSIVE],PETSC_NULL);CHKERRQ(ierr);
2041677d0b8SKris Buschelman 
2051677d0b8SKris Buschelman   /* Control parameters used by numeric factorization */
2061677d0b8SKris Buschelman   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);
2070f6efc10SHong 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);
2080f6efc10SHong Zhang   ierr = PetscOptionsEList("-mat_umfpack_scale","Control[UMFPACK_SCALE]","None",scale,3,scale[0],&idx,&flg);CHKERRQ(ierr);
2090f6efc10SHong Zhang   if (flg) {
2100f6efc10SHong Zhang     switch (idx){
2110f6efc10SHong Zhang     case 0: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_NONE; break;
2120f6efc10SHong Zhang     case 1: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_SUM; break;
2130f6efc10SHong Zhang     case 2: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_MAX; break;
2140f6efc10SHong Zhang     }
2150f6efc10SHong Zhang   }
2161677d0b8SKris Buschelman   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);
2170f6efc10SHong 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);
2180f6efc10SHong Zhang   ierr = PetscOptionsReal("-mat_umfpack_droptol","Control[UMFPACK_DROPTOL]","None",lu->Control[UMFPACK_DROPTOL],&lu->Control[UMFPACK_DROPTOL],PETSC_NULL);CHKERRQ(ierr);
2191677d0b8SKris Buschelman 
2201677d0b8SKris Buschelman   /* Control parameters used by solve */
2211677d0b8SKris Buschelman   ierr = PetscOptionsReal("-mat_umfpack_irstep","Control[UMFPACK_IRSTEP]","None",lu->Control[UMFPACK_IRSTEP],&lu->Control[UMFPACK_IRSTEP],PETSC_NULL);CHKERRQ(ierr);
2221677d0b8SKris Buschelman 
2230f6efc10SHong Zhang   /* use Petsc mat ordering (note: size is for the transpose, and PETSc r = Umfpack perm_c) */
2242401956bSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-pc_factor_mat_ordering_type",&lu->PetscMatOdering);CHKERRQ(ierr);
2251677d0b8SKris Buschelman   if (lu->PetscMatOdering) {
2260f6efc10SHong Zhang     ierr = ISGetIndices(r,&ra);CHKERRQ(ierr);
2272a4c71feSBarry Smith     ierr = PetscMalloc(A->rmap.n*sizeof(int),&lu->perm_c);CHKERRQ(ierr);
2282a4c71feSBarry Smith     ierr = PetscMemcpy(lu->perm_c,ra,A->rmap.n*sizeof(int));CHKERRQ(ierr);
2290f6efc10SHong Zhang     ierr = ISRestoreIndices(r,&ra);CHKERRQ(ierr);
2301677d0b8SKris Buschelman   }
2311677d0b8SKris Buschelman   PetscOptionsEnd();
2321677d0b8SKris Buschelman 
2331677d0b8SKris Buschelman   /* print the control parameters */
2341677d0b8SKris Buschelman   if( lu->Control[UMFPACK_PRL] > 1 ) umfpack_di_report_control (lu->Control);
2351677d0b8SKris Buschelman 
2361677d0b8SKris Buschelman   /* symbolic factorization of A' */
2371677d0b8SKris Buschelman   /* ---------------------------------------------------------------------- */
2380f6efc10SHong Zhang   if (lu->PetscMatOdering) { /* use Petsc row ordering */
2390f6efc10SHong Zhang     status = umfpack_di_qsymbolic(n,m,ai,aj,av,lu->perm_c,&lu->Symbolic,lu->Control,lu->Info);
2400f6efc10SHong Zhang   } else { /* use Umfpack col ordering */
2410f6efc10SHong Zhang     status = umfpack_di_symbolic(n,m,ai,aj,av,&lu->Symbolic,lu->Control,lu->Info);
2420f6efc10SHong Zhang   }
2431677d0b8SKris Buschelman   if (status < 0){
2441677d0b8SKris Buschelman     umfpack_di_report_info(lu->Control, lu->Info);
2451677d0b8SKris Buschelman     umfpack_di_report_status(lu->Control, status);
246e005ede5SBarry Smith     SETERRQ(PETSC_ERR_LIB,"umfpack_di_symbolic failed");
2471677d0b8SKris Buschelman   }
2481677d0b8SKris Buschelman   /* report sumbolic factorization of A' when Control[PRL] > 3 */
2491677d0b8SKris Buschelman   (void) umfpack_di_report_symbolic(lu->Symbolic, lu->Control);
2501677d0b8SKris Buschelman 
2511677d0b8SKris Buschelman   lu->flg = DIFFERENT_NONZERO_PATTERN;
2521677d0b8SKris Buschelman   lu->ai  = ai;
2531677d0b8SKris Buschelman   lu->aj  = aj;
2541677d0b8SKris Buschelman   lu->av  = av;
255e1b4c3a1SKris Buschelman   lu->CleanUpUMFPACK = PETSC_TRUE;
256e1b4c3a1SKris Buschelman   *F = B;
2571677d0b8SKris Buschelman   PetscFunctionReturn(0);
2581677d0b8SKris Buschelman }
2591677d0b8SKris Buschelman 
2601677d0b8SKris Buschelman #undef __FUNCT__
261f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_UMFPACK"
2626849ba73SBarry Smith PetscErrorCode MatAssemblyEnd_UMFPACK(Mat A,MatAssemblyType mode)
2636849ba73SBarry Smith {
264dfbe8321SBarry Smith   PetscErrorCode ierr;
265f0c56d0fSKris Buschelman   Mat_UMFPACK *lu=(Mat_UMFPACK*)(A->spptr);
266d844382dSKris Buschelman 
2671677d0b8SKris Buschelman   PetscFunctionBegin;
268d844382dSKris Buschelman   ierr = (*lu->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
269d844382dSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
270f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic = MatLUFactorSymbolic_UMFPACK;
2711677d0b8SKris Buschelman   PetscFunctionReturn(0);
2721677d0b8SKris Buschelman }
2731677d0b8SKris Buschelman 
27494b7f48cSBarry Smith /* used by -ksp_view */
2751677d0b8SKris Buschelman #undef __FUNCT__
276f0c56d0fSKris Buschelman #define __FUNCT__ "MatFactorInfo_UMFPACK"
2776849ba73SBarry Smith PetscErrorCode MatFactorInfo_UMFPACK(Mat A,PetscViewer viewer)
2786849ba73SBarry Smith {
279f0c56d0fSKris Buschelman   Mat_UMFPACK *lu= (Mat_UMFPACK*)A->spptr;
280dfbe8321SBarry Smith   PetscErrorCode ierr;
281f0c56d0fSKris Buschelman 
2821677d0b8SKris Buschelman   PetscFunctionBegin;
2831677d0b8SKris Buschelman   /* check if matrix is UMFPACK type */
284f0c56d0fSKris Buschelman   if (A->ops->solve != MatSolve_UMFPACK) PetscFunctionReturn(0);
2851677d0b8SKris Buschelman 
2861677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"UMFPACK run parameters:\n");CHKERRQ(ierr);
2871677d0b8SKris Buschelman   /* Control parameters used by reporting routiones */
2881677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PRL]: %g\n",lu->Control[UMFPACK_PRL]);CHKERRQ(ierr);
2891677d0b8SKris Buschelman 
2901677d0b8SKris Buschelman   /* Control parameters used by symbolic factorization */
2910f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_STRATEGY]: %g\n",lu->Control[UMFPACK_STRATEGY]);CHKERRQ(ierr);
2921677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_COL]: %g\n",lu->Control[UMFPACK_DENSE_COL]);CHKERRQ(ierr);
2931677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DENSE_ROW]: %g\n",lu->Control[UMFPACK_DENSE_ROW]);CHKERRQ(ierr);
2940f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_AMD_DENSE]: %g\n",lu->Control[UMFPACK_AMD_DENSE]);CHKERRQ(ierr);
2951677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_BLOCK_SIZE]: %g\n",lu->Control[UMFPACK_BLOCK_SIZE]);CHKERRQ(ierr);
2960f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_2BY2_TOLERANCE]: %g\n",lu->Control[UMFPACK_2BY2_TOLERANCE]);CHKERRQ(ierr);
2970f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_FIXQ]: %g\n",lu->Control[UMFPACK_FIXQ]);CHKERRQ(ierr);
2980f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_AGGRESSIVE]: %g\n",lu->Control[UMFPACK_AGGRESSIVE]);CHKERRQ(ierr);
2991677d0b8SKris Buschelman 
3001677d0b8SKris Buschelman   /* Control parameters used by numeric factorization */
3011677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_PIVOT_TOLERANCE]);CHKERRQ(ierr);
3020f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_SYM_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE]);CHKERRQ(ierr);
3030f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_SCALE]: %g\n",lu->Control[UMFPACK_SCALE]);CHKERRQ(ierr);
3041677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_ALLOC_INIT]: %g\n",lu->Control[UMFPACK_ALLOC_INIT]);CHKERRQ(ierr);
3050f6efc10SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_DROPTOL]: %g\n",lu->Control[UMFPACK_DROPTOL]);CHKERRQ(ierr);
3061677d0b8SKris Buschelman 
3071677d0b8SKris Buschelman   /* Control parameters used by solve */
3081677d0b8SKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"  Control[UMFPACK_IRSTEP]: %g\n",lu->Control[UMFPACK_IRSTEP]);CHKERRQ(ierr);
3091677d0b8SKris Buschelman 
3101677d0b8SKris Buschelman   /* mat ordering */
3111677d0b8SKris Buschelman   if(!lu->PetscMatOdering) ierr = PetscViewerASCIIPrintf(viewer,"  UMFPACK default matrix ordering is used (not the PETSc matrix ordering) \n");CHKERRQ(ierr);
3121677d0b8SKris Buschelman 
3131677d0b8SKris Buschelman   PetscFunctionReturn(0);
3141677d0b8SKris Buschelman }
3151677d0b8SKris Buschelman 
316d844382dSKris Buschelman #undef __FUNCT__
317f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_UMFPACK"
3186849ba73SBarry Smith PetscErrorCode MatView_UMFPACK(Mat A,PetscViewer viewer)
3196849ba73SBarry Smith {
320dfbe8321SBarry Smith   PetscErrorCode ierr;
32132077d6dSBarry Smith   PetscTruth        iascii;
322d844382dSKris Buschelman   PetscViewerFormat format;
323f0c56d0fSKris Buschelman   Mat_UMFPACK       *lu=(Mat_UMFPACK*)(A->spptr);
324d844382dSKris Buschelman 
325d844382dSKris Buschelman   PetscFunctionBegin;
326d844382dSKris Buschelman   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
327d844382dSKris Buschelman 
32832077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
32932077d6dSBarry Smith   if (iascii) {
330d844382dSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
331*2f59403fSHong Zhang     if (format == PETSC_VIEWER_ASCII_INFO) {
332f0c56d0fSKris Buschelman       ierr = MatFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr);
333d844382dSKris Buschelman     }
334d844382dSKris Buschelman   }
335d844382dSKris Buschelman   PetscFunctionReturn(0);
336d844382dSKris Buschelman }
337d844382dSKris Buschelman 
338d844382dSKris Buschelman EXTERN_C_BEGIN
339d844382dSKris Buschelman #undef __FUNCT__
340d844382dSKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_UMFPACK"
34175179d2cSHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_UMFPACK(Mat A,MatType type,MatReuse reuse,Mat *newmat)
3426849ba73SBarry Smith {
343d844382dSKris Buschelman   /* This routine is only called to convert to MATUMFPACK */
344d844382dSKris Buschelman   /* from MATSEQAIJ, so we will ignore 'MatType type'. */
345dfbe8321SBarry Smith   PetscErrorCode ierr;
346d844382dSKris Buschelman   Mat         B=*newmat;
347f0c56d0fSKris Buschelman   Mat_UMFPACK *lu;
348d844382dSKris Buschelman 
349d844382dSKris Buschelman   PetscFunctionBegin;
350ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
351d844382dSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
352d844382dSKris Buschelman   }
353d844382dSKris Buschelman 
354f0c56d0fSKris Buschelman   ierr = PetscNew(Mat_UMFPACK,&lu);CHKERRQ(ierr);
355f0c56d0fSKris Buschelman   lu->MatDuplicate         = A->ops->duplicate;
356d844382dSKris Buschelman   lu->MatView              = A->ops->view;
357d844382dSKris Buschelman   lu->MatAssemblyEnd       = A->ops->assemblyend;
358d844382dSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
359d844382dSKris Buschelman   lu->MatDestroy           = A->ops->destroy;
360d844382dSKris Buschelman   lu->CleanUpUMFPACK       = PETSC_FALSE;
361d844382dSKris Buschelman 
362d844382dSKris Buschelman   B->spptr                 = (void*)lu;
363f0c56d0fSKris Buschelman   B->ops->duplicate        = MatDuplicate_UMFPACK;
364f0c56d0fSKris Buschelman   B->ops->view             = MatView_UMFPACK;
365f0c56d0fSKris Buschelman   B->ops->assemblyend      = MatAssemblyEnd_UMFPACK;
366f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic = MatLUFactorSymbolic_UMFPACK;
367f0c56d0fSKris Buschelman   B->ops->destroy          = MatDestroy_UMFPACK;
368d844382dSKris Buschelman 
369d844382dSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_umfpack_C",
370d844382dSKris Buschelman                                            "MatConvert_SeqAIJ_UMFPACK",MatConvert_SeqAIJ_UMFPACK);CHKERRQ(ierr);
371d844382dSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_umfpack_seqaij_C",
372d844382dSKris Buschelman                                            "MatConvert_UMFPACK_SeqAIJ",MatConvert_UMFPACK_SeqAIJ);CHKERRQ(ierr);
373ae15b995SBarry Smith   ierr = PetscInfo(0,"Using UMFPACK for SeqAIJ LU factorization and solves.\n");CHKERRQ(ierr);
374d844382dSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATUMFPACK);CHKERRQ(ierr);
375d844382dSKris Buschelman   *newmat = B;
376d844382dSKris Buschelman   PetscFunctionReturn(0);
377d844382dSKris Buschelman }
378d844382dSKris Buschelman EXTERN_C_END
379d844382dSKris Buschelman 
380f0c56d0fSKris Buschelman #undef __FUNCT__
381f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_UMFPACK"
3826849ba73SBarry Smith PetscErrorCode MatDuplicate_UMFPACK(Mat A, MatDuplicateOption op, Mat *M)
3836849ba73SBarry Smith {
384dfbe8321SBarry Smith   PetscErrorCode ierr;
3858f340917SKris Buschelman   Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr;
3868f340917SKris Buschelman 
387f0c56d0fSKris Buschelman   PetscFunctionBegin;
3888f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
3893f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_UMFPACK));CHKERRQ(ierr);
390f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
391f0c56d0fSKris Buschelman }
392f0c56d0fSKris Buschelman 
3932f71e704SKris Buschelman /*MC
394fafad747SKris Buschelman   MATUMFPACK - MATUMFPACK = "umfpack" - A matrix type providing direct solvers (LU) for sequential matrices
3952f71e704SKris Buschelman   via the external package UMFPACK.
3962f71e704SKris Buschelman 
3972f71e704SKris Buschelman   If UMFPACK is installed (see the manual for
3982f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
3992f71e704SKris Buschelman   a matrix type can be constructed which invokes UMFPACK solvers.
4002f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,UMFPACK).
4012f71e704SKris Buschelman   This matrix type is only supported for double precision real.
4022f71e704SKris Buschelman 
4032f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
40428b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
40528b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
4062f71e704SKris Buschelman 
4072f71e704SKris Buschelman   Consult UMFPACK documentation for more information about the Control parameters
4082f71e704SKris Buschelman   which correspond to the options database keys below.
4092f71e704SKris Buschelman 
4102f71e704SKris Buschelman   Options Database Keys:
4110bad9183SKris Buschelman + -mat_type umfpack - sets the matrix type to "umfpack" during a call to MatSetFromOptions()
4122f71e704SKris Buschelman . -mat_umfpack_prl - UMFPACK print level: Control[UMFPACK_PRL]
4132f71e704SKris Buschelman . -mat_umfpack_dense_col <alpha_c> - UMFPACK dense column threshold: Control[UMFPACK_DENSE_COL]
4142f71e704SKris Buschelman . -mat_umfpack_block_size <bs> - UMFPACK block size for BLAS-Level 3 calls: Control[UMFPACK_BLOCK_SIZE]
4152f71e704SKris Buschelman . -mat_umfpack_pivot_tolerance <delta> - UMFPACK partial pivot tolerance: Control[UMFPACK_PIVOT_TOLERANCE]
4162f71e704SKris Buschelman . -mat_umfpack_alloc_init <delta> - UMFPACK factorized matrix allocation modifier: Control[UMFPACK_ALLOC_INIT]
4172f71e704SKris Buschelman - -mat_umfpack_irstep <maxit> - UMFPACK maximum number of iterative refinement steps: Control[UMFPACK_IRSTEP]
4182f71e704SKris Buschelman 
4192f71e704SKris Buschelman    Level: beginner
4202f71e704SKris Buschelman 
4212f71e704SKris Buschelman .seealso: PCLU
4222f71e704SKris Buschelman M*/
4232f71e704SKris Buschelman 
4241677d0b8SKris Buschelman EXTERN_C_BEGIN
4251677d0b8SKris Buschelman #undef __FUNCT__
426f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_UMFPACK"
427be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_UMFPACK(Mat A)
428dfbe8321SBarry Smith {
429dfbe8321SBarry Smith   PetscErrorCode ierr;
4301677d0b8SKris Buschelman 
4311677d0b8SKris Buschelman   PetscFunctionBegin;
4325441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and UMFPACK types */
4335441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATUMFPACK);CHKERRQ(ierr);
4341677d0b8SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
435ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_UMFPACK(A,MATUMFPACK,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
4361677d0b8SKris Buschelman   PetscFunctionReturn(0);
4371677d0b8SKris Buschelman }
4381677d0b8SKris Buschelman EXTERN_C_END
439