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