11677d0b8SKris Buschelman 21677d0b8SKris Buschelman /* 359698cb0SHong Zhang Provides an interface to the UMFPACKv4.3 sparse solver 41677d0b8SKris Buschelman */ 51677d0b8SKris Buschelman 61677d0b8SKris Buschelman #include "src/mat/impls/aij/seq/aij.h" 71677d0b8SKris Buschelman 81677d0b8SKris Buschelman EXTERN_C_BEGIN 91677d0b8SKris Buschelman #include "umfpack.h" 101677d0b8SKris Buschelman EXTERN_C_END 111677d0b8SKris Buschelman 121677d0b8SKris Buschelman typedef struct { 131677d0b8SKris Buschelman void *Symbolic, *Numeric; 141677d0b8SKris Buschelman double Info[UMFPACK_INFO], Control[UMFPACK_CONTROL],*W; 151677d0b8SKris Buschelman int *Wi,*ai,*aj,*perm_c; 161677d0b8SKris Buschelman PetscScalar *av; 171677d0b8SKris Buschelman MatStructure flg; 181677d0b8SKris Buschelman PetscTruth PetscMatOdering; 191677d0b8SKris Buschelman 201677d0b8SKris Buschelman /* A few function pointers for inheritance */ 216849ba73SBarry Smith PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 226849ba73SBarry Smith PetscErrorCode (*MatView)(Mat,PetscViewer); 236849ba73SBarry Smith PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 246849ba73SBarry Smith PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 256849ba73SBarry Smith PetscErrorCode (*MatDestroy)(Mat); 261677d0b8SKris Buschelman 271677d0b8SKris Buschelman /* Flag to clean up UMFPACK objects during Destroy */ 281677d0b8SKris Buschelman PetscTruth CleanUpUMFPACK; 29f0c56d0fSKris Buschelman } Mat_UMFPACK; 30f0c56d0fSKris Buschelman 31dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_UMFPACK(Mat,MatDuplicateOption,Mat*); 32d844382dSKris Buschelman 33d844382dSKris Buschelman EXTERN_C_BEGIN 34d844382dSKris Buschelman #undef __FUNCT__ 35d844382dSKris Buschelman #define __FUNCT__ "MatConvert_UMFPACK_SeqAIJ" 366849ba73SBarry Smith PetscErrorCode MatConvert_UMFPACK_SeqAIJ(Mat A,const MatType type,Mat *newmat) 376849ba73SBarry Smith { 38d844382dSKris Buschelman /* This routine is only called to convert an unfactored PETSc-UMFPACK matrix */ 39d844382dSKris Buschelman /* to its base PETSc type, so we will ignore 'MatType type'. */ 40dfbe8321SBarry Smith PetscErrorCode ierr; 41d844382dSKris Buschelman Mat B=*newmat; 42f0c56d0fSKris Buschelman Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr; 43d844382dSKris Buschelman 44d844382dSKris Buschelman PetscFunctionBegin; 45d844382dSKris Buschelman if (B != A) { 46d844382dSKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 47f0c56d0fSKris Buschelman } 48d844382dSKris Buschelman /* Reset the original function pointers */ 49901853e0SKris Buschelman B->ops->duplicate = lu->MatDuplicate; 50901853e0SKris Buschelman B->ops->view = lu->MatView; 51901853e0SKris Buschelman B->ops->assemblyend = lu->MatAssemblyEnd; 52901853e0SKris Buschelman B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic; 53901853e0SKris Buschelman B->ops->destroy = lu->MatDestroy; 54d844382dSKris Buschelman 55d844382dSKris Buschelman ierr = PetscFree(lu);CHKERRQ(ierr); 56901853e0SKris Buschelman 57901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_umfpack_C","",PETSC_NULL);CHKERRQ(ierr); 58901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_umfpack_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 59901853e0SKris Buschelman 60d844382dSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 61d844382dSKris Buschelman *newmat = B; 62d844382dSKris Buschelman PetscFunctionReturn(0); 63d844382dSKris Buschelman } 64d844382dSKris Buschelman EXTERN_C_END 651677d0b8SKris Buschelman 661677d0b8SKris Buschelman #undef __FUNCT__ 67f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_UMFPACK" 68dfbe8321SBarry Smith PetscErrorCode MatDestroy_UMFPACK(Mat A) 69dfbe8321SBarry Smith { 70dfbe8321SBarry Smith PetscErrorCode ierr; 71f0c56d0fSKris Buschelman Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr; 721677d0b8SKris Buschelman 731677d0b8SKris Buschelman PetscFunctionBegin; 74fb731535SKris Buschelman if (lu->CleanUpUMFPACK) { 751677d0b8SKris Buschelman umfpack_di_free_symbolic(&lu->Symbolic); 761677d0b8SKris Buschelman umfpack_di_free_numeric(&lu->Numeric); 771677d0b8SKris Buschelman ierr = PetscFree(lu->Wi);CHKERRQ(ierr); 781677d0b8SKris Buschelman ierr = PetscFree(lu->W);CHKERRQ(ierr); 791677d0b8SKris Buschelman if (lu->PetscMatOdering) { 801677d0b8SKris Buschelman ierr = PetscFree(lu->perm_c);CHKERRQ(ierr); 811677d0b8SKris Buschelman } 821677d0b8SKris Buschelman } 83d844382dSKris Buschelman ierr = MatConvert_UMFPACK_SeqAIJ(A,MATSEQAIJ,&A);CHKERRQ(ierr); 84d844382dSKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 851677d0b8SKris Buschelman PetscFunctionReturn(0); 861677d0b8SKris Buschelman } 871677d0b8SKris Buschelman 881677d0b8SKris Buschelman #undef __FUNCT__ 89f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_UMFPACK" 906849ba73SBarry Smith PetscErrorCode MatSolve_UMFPACK(Mat A,Vec b,Vec x) 916849ba73SBarry Smith { 92f0c56d0fSKris Buschelman Mat_UMFPACK *lu = (Mat_UMFPACK*)A->spptr; 931677d0b8SKris Buschelman PetscScalar *av=lu->av,*ba,*xa; 94dfbe8321SBarry Smith PetscErrorCode ierr; 95dfbe8321SBarry Smith int *ai=lu->ai,*aj=lu->aj,status; 961677d0b8SKris Buschelman 971677d0b8SKris Buschelman PetscFunctionBegin; 981677d0b8SKris Buschelman /* solve Ax = b by umfpack_di_wsolve */ 991677d0b8SKris Buschelman /* ----------------------------------*/ 1001677d0b8SKris Buschelman ierr = VecGetArray(b,&ba); 1011677d0b8SKris Buschelman ierr = VecGetArray(x,&xa); 1021677d0b8SKris Buschelman 1031677d0b8SKris Buschelman status = umfpack_di_wsolve(UMFPACK_At,ai,aj,av,xa,ba,lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W); 1041677d0b8SKris Buschelman umfpack_di_report_info(lu->Control, lu->Info); 1051677d0b8SKris Buschelman if (status < 0){ 1061677d0b8SKris Buschelman umfpack_di_report_status(lu->Control, status); 107*e005ede5SBarry Smith SETERRQ(PETSC_ERR_LIB,"umfpack_di_wsolve failed"); 1081677d0b8SKris Buschelman } 1091677d0b8SKris Buschelman 1101677d0b8SKris Buschelman ierr = VecRestoreArray(b,&ba); 1111677d0b8SKris Buschelman ierr = VecRestoreArray(x,&xa); 1122a325a84SHong Zhang 1131677d0b8SKris Buschelman PetscFunctionReturn(0); 1141677d0b8SKris Buschelman } 1151677d0b8SKris Buschelman 1161677d0b8SKris Buschelman #undef __FUNCT__ 117f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_UMFPACK" 1186849ba73SBarry Smith PetscErrorCode MatLUFactorNumeric_UMFPACK(Mat A,Mat *F) 1196849ba73SBarry Smith { 120f0c56d0fSKris Buschelman Mat_UMFPACK *lu=(Mat_UMFPACK*)(*F)->spptr; 1216849ba73SBarry Smith PetscErrorCode ierr; 1226849ba73SBarry Smith int *ai=lu->ai,*aj=lu->aj,m=A->m,status; 1231677d0b8SKris Buschelman PetscScalar *av=lu->av; 1241677d0b8SKris Buschelman 1251677d0b8SKris Buschelman PetscFunctionBegin; 1261677d0b8SKris Buschelman /* numeric factorization of A' */ 1271677d0b8SKris Buschelman /* ----------------------------*/ 1282a325a84SHong Zhang if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric){ 1292a325a84SHong Zhang umfpack_di_free_numeric(&lu->Numeric); 1302a325a84SHong Zhang } 1311677d0b8SKris Buschelman status = umfpack_di_numeric (ai,aj,av,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info); 132*e005ede5SBarry Smith if (status < 0) SETERRQ(PETSC_ERR_LIB,"umfpack_di_numeric failed"); 1331677d0b8SKris Buschelman /* report numeric factorization of A' when Control[PRL] > 3 */ 1341677d0b8SKris Buschelman (void) umfpack_di_report_numeric (lu->Numeric, lu->Control); 1351677d0b8SKris Buschelman 1361677d0b8SKris Buschelman if (lu->flg == DIFFERENT_NONZERO_PATTERN){ /* first numeric factorization */ 1371677d0b8SKris Buschelman /* allocate working space to be used by Solve */ 1381677d0b8SKris Buschelman ierr = PetscMalloc(m * sizeof(int), &lu->Wi);CHKERRQ(ierr); 1391677d0b8SKris Buschelman ierr = PetscMalloc(5*m * sizeof(double), &lu->W);CHKERRQ(ierr); 1401677d0b8SKris Buschelman } 1412a325a84SHong Zhang lu->flg = SAME_NONZERO_PATTERN; 1422a325a84SHong Zhang lu->CleanUpUMFPACK = PETSC_TRUE; 1431677d0b8SKris Buschelman PetscFunctionReturn(0); 1441677d0b8SKris Buschelman } 1451677d0b8SKris Buschelman 1461677d0b8SKris Buschelman /* 1471677d0b8SKris Buschelman Note the r permutation is ignored 1481677d0b8SKris Buschelman */ 1491677d0b8SKris Buschelman #undef __FUNCT__ 150f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_UMFPACK" 1516849ba73SBarry Smith PetscErrorCode MatLUFactorSymbolic_UMFPACK(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 1526849ba73SBarry Smith { 153e1b4c3a1SKris Buschelman Mat B; 1541677d0b8SKris Buschelman Mat_SeqAIJ *mat=(Mat_SeqAIJ*)A->data; 155f0c56d0fSKris Buschelman Mat_UMFPACK *lu; 156dfbe8321SBarry Smith PetscErrorCode ierr; 157dfbe8321SBarry Smith int m=A->m,n=A->n,*ai=mat->i,*aj=mat->j,status,*ra,idx; 1581677d0b8SKris Buschelman PetscScalar *av=mat->a; 1590f6efc10SHong Zhang const char *strategy[]={"AUTO","UNSYMMETRIC","SYMMETRIC","2BY2"}, 1600f6efc10SHong Zhang *scale[]={"NONE","SUM","MAX"}; 1610f6efc10SHong Zhang PetscTruth flg; 1621677d0b8SKris Buschelman 1631677d0b8SKris Buschelman PetscFunctionBegin; 1641677d0b8SKris Buschelman /* Create the factorization matrix F */ 165e1b4c3a1SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,m,n,&B);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) */ 2241677d0b8SKris Buschelman ierr = PetscOptionsHasName(PETSC_NULL,"-pc_lu_mat_ordering_type",&lu->PetscMatOdering);CHKERRQ(ierr); 2251677d0b8SKris Buschelman if (lu->PetscMatOdering) { 2260f6efc10SHong Zhang ierr = ISGetIndices(r,&ra);CHKERRQ(ierr); 2271677d0b8SKris Buschelman ierr = PetscMalloc(A->m*sizeof(int),&lu->perm_c);CHKERRQ(ierr); 2280f6efc10SHong Zhang ierr = PetscMemcpy(lu->perm_c,ra,A->m*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); 246*e005ede5SBarry 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); 331d844382dSKris Buschelman if (format == PETSC_VIEWER_ASCII_FACTOR_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" 3416849ba73SBarry Smith PetscErrorCode MatConvert_SeqAIJ_UMFPACK(Mat A,const MatType type,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; 350d844382dSKris Buschelman if (B != A) { 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); 373d844382dSKris Buschelman PetscLogInfo(0,"Using UMFPACK for SeqAIJ LU factorization and solves."); 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" 427dfbe8321SBarry Smith PetscErrorCode 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); 435d844382dSKris Buschelman ierr = MatConvert_SeqAIJ_UMFPACK(A,MATUMFPACK,&A);CHKERRQ(ierr); 4361677d0b8SKris Buschelman PetscFunctionReturn(0); 4371677d0b8SKris Buschelman } 4381677d0b8SKris Buschelman EXTERN_C_END 439