114b396bbSKris Buschelman 25a46d3faSBarry Smith /* -------------------------------------------------------------------- 35a46d3faSBarry Smith 45a46d3faSBarry Smith This file implements a subclass of the SeqAIJ matrix class that uses 55d8b2efaSHong Zhang the SuperLU sparse solver. You can use this as a starting point for 65a46d3faSBarry Smith implementing your own subclass of a PETSc matrix class. 75a46d3faSBarry Smith 85a46d3faSBarry Smith This demonstrates a way to make an implementation inheritence of a PETSc 95a46d3faSBarry Smith matrix type. This means constructing a new matrix type (SuperLU) by changing some 105a46d3faSBarry Smith of the methods of the previous type (SeqAIJ), adding additional data, and possibly 115a46d3faSBarry Smith additional method. (See any book on object oriented programming). 1214b396bbSKris Buschelman */ 1314b396bbSKris Buschelman 145a46d3faSBarry Smith /* 155a46d3faSBarry Smith Defines the data structure for the base matrix type (SeqAIJ) 165a46d3faSBarry Smith */ 17c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 1814b396bbSKris Buschelman 195a46d3faSBarry Smith /* 205a46d3faSBarry Smith SuperLU include files 215a46d3faSBarry Smith */ 2214b396bbSKris Buschelman EXTERN_C_BEGIN 2314b396bbSKris Buschelman #if defined(PETSC_USE_COMPLEX) 24c6db04a5SJed Brown #include <slu_zdefs.h> 2514b396bbSKris Buschelman #else 26c6db04a5SJed Brown #include <slu_ddefs.h> 2714b396bbSKris Buschelman #endif 28c6db04a5SJed Brown #include <slu_util.h> 2914b396bbSKris Buschelman EXTERN_C_END 3014b396bbSKris Buschelman 315a46d3faSBarry Smith /* 325a46d3faSBarry Smith This is the data we are "ADDING" to the SeqAIJ matrix type to get the SuperLU matrix type 335a46d3faSBarry Smith */ 3414b396bbSKris Buschelman typedef struct { 3575af56d4SHong Zhang SuperMatrix A,L,U,B,X; 3675af56d4SHong Zhang superlu_options_t options; 37da7a1d00SHong Zhang PetscInt *perm_c; /* column permutation vector */ 38da7a1d00SHong Zhang PetscInt *perm_r; /* row permutations from partial pivoting */ 39da7a1d00SHong Zhang PetscInt *etree; 40da7a1d00SHong Zhang PetscReal *R, *C; 4175af56d4SHong Zhang char equed[1]; 42da7a1d00SHong Zhang PetscInt lwork; 4375af56d4SHong Zhang void *work; 44da7a1d00SHong Zhang PetscReal rpg, rcond; 4575af56d4SHong Zhang mem_usage_t mem_usage; 4675af56d4SHong Zhang MatStructure flg; 475d8b2efaSHong Zhang SuperLUStat_t stat; 48cae5a23dSHong Zhang Mat A_dup; 49cae5a23dSHong Zhang PetscScalar *rhs_dup; 5014b396bbSKris Buschelman 5114b396bbSKris Buschelman /* Flag to clean up (non-global) SuperLU objects during Destroy */ 52ace3abfcSBarry Smith PetscBool CleanUpSuperLU; 53f0c56d0fSKris Buschelman } Mat_SuperLU; 5414b396bbSKris Buschelman 55e0e586b9SHong Zhang extern PetscErrorCode MatFactorInfo_SuperLU(Mat,PetscViewer); 560481f469SBarry Smith extern PetscErrorCode MatLUFactorNumeric_SuperLU(Mat,Mat,const MatFactorInfo *); 57e0e586b9SHong Zhang extern PetscErrorCode MatDestroy_SuperLU(Mat); 58e0e586b9SHong Zhang extern PetscErrorCode MatView_SuperLU(Mat,PetscViewer); 59e0e586b9SHong Zhang extern PetscErrorCode MatAssemblyEnd_SuperLU(Mat,MatAssemblyType); 60e0e586b9SHong Zhang extern PetscErrorCode MatSolve_SuperLU(Mat,Vec,Vec); 61e0b74bf9SHong Zhang extern PetscErrorCode MatMatSolve_SuperLU(Mat,Mat,Mat); 62e0e586b9SHong Zhang extern PetscErrorCode MatSolveTranspose_SuperLU(Mat,Vec,Vec); 630481f469SBarry Smith extern PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat,Mat,IS,IS,const MatFactorInfo*); 64e0e586b9SHong Zhang extern PetscErrorCode MatDuplicate_SuperLU(Mat, MatDuplicateOption, Mat *); 65e0e586b9SHong Zhang 665a46d3faSBarry Smith /* 675a46d3faSBarry Smith Utility function 685a46d3faSBarry Smith */ 695a46d3faSBarry Smith #undef __FUNCT__ 705a46d3faSBarry Smith #define __FUNCT__ "MatFactorInfo_SuperLU" 715a46d3faSBarry Smith PetscErrorCode MatFactorInfo_SuperLU(Mat A,PetscViewer viewer) 725a46d3faSBarry Smith { 735a46d3faSBarry Smith Mat_SuperLU *lu= (Mat_SuperLU*)A->spptr; 745a46d3faSBarry Smith PetscErrorCode ierr; 755a46d3faSBarry Smith superlu_options_t options; 765a46d3faSBarry Smith 775a46d3faSBarry Smith PetscFunctionBegin; 785a46d3faSBarry Smith /* check if matrix is superlu_dist type */ 795a46d3faSBarry Smith if (A->ops->solve != MatSolve_SuperLU) PetscFunctionReturn(0); 805a46d3faSBarry Smith 815a46d3faSBarry Smith options = lu->options; 825a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"SuperLU run parameters:\n");CHKERRQ(ierr); 835a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Equil: %s\n",(options.Equil != NO) ? "YES": "NO");CHKERRQ(ierr); 845a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ColPerm: %D\n",options.ColPerm);CHKERRQ(ierr); 855a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," IterRefine: %D\n",options.IterRefine);CHKERRQ(ierr); 865a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," SymmetricMode: %s\n",(options.SymmetricMode != NO) ? "YES": "NO");CHKERRQ(ierr); 875a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," DiagPivotThresh: %g\n",options.DiagPivotThresh);CHKERRQ(ierr); 885a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," PivotGrowth: %s\n",(options.PivotGrowth != NO) ? "YES": "NO");CHKERRQ(ierr); 895a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ConditionNumber: %s\n",(options.ConditionNumber != NO) ? "YES": "NO");CHKERRQ(ierr); 905a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," RowPerm: %D\n",options.RowPerm);CHKERRQ(ierr); 915a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ReplaceTinyPivot: %s\n",(options.ReplaceTinyPivot != NO) ? "YES": "NO");CHKERRQ(ierr); 925a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," PrintStat: %s\n",(options.PrintStat != NO) ? "YES": "NO");CHKERRQ(ierr); 935a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," lwork: %D\n",lu->lwork);CHKERRQ(ierr); 94d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU){ 95cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_DropTol: %g\n",options.ILU_DropTol);CHKERRQ(ierr); 96cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_FillTol: %g\n",options.ILU_FillTol);CHKERRQ(ierr); 97cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_FillFactor: %g\n",options.ILU_FillFactor);CHKERRQ(ierr); 98cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_DropRule: %D\n",options.ILU_DropRule);CHKERRQ(ierr); 99cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_Norm: %D\n",options.ILU_Norm);CHKERRQ(ierr); 100cffbb591SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," ILU_MILU: %D\n",options.ILU_MILU);CHKERRQ(ierr); 101cffbb591SHong Zhang } 1025a46d3faSBarry Smith PetscFunctionReturn(0); 1035a46d3faSBarry Smith } 1045a46d3faSBarry Smith 1055a46d3faSBarry Smith /* 1065a46d3faSBarry Smith These are the methods provided to REPLACE the corresponding methods of the 1075a46d3faSBarry Smith SeqAIJ matrix class. Other methods of SeqAIJ are not replaced 1085a46d3faSBarry Smith */ 1095a46d3faSBarry Smith #undef __FUNCT__ 1105a46d3faSBarry Smith #define __FUNCT__ "MatLUFactorNumeric_SuperLU" 1110481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_SuperLU(Mat F,Mat A,const MatFactorInfo *info) 1125a46d3faSBarry Smith { 1131d5ca7f3SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)F->spptr; 114cae5a23dSHong Zhang Mat_SeqAIJ *aa; 1155a46d3faSBarry Smith PetscErrorCode ierr; 1165a46d3faSBarry Smith PetscInt sinfo; 1175a46d3faSBarry Smith PetscReal ferr, berr; 1185a46d3faSBarry Smith NCformat *Ustore; 1195a46d3faSBarry Smith SCformat *Lstore; 1205a46d3faSBarry Smith 1215a46d3faSBarry Smith PetscFunctionBegin; 1225a46d3faSBarry Smith if (lu->flg == SAME_NONZERO_PATTERN){ /* successing numerical factorization */ 1235a46d3faSBarry Smith lu->options.Fact = SamePattern; 1245a46d3faSBarry Smith /* Ref: ~SuperLU_3.0/EXAMPLE/dlinsolx2.c */ 1255a46d3faSBarry Smith Destroy_SuperMatrix_Store(&lu->A); 126cae5a23dSHong Zhang if (lu->options.Equil){ 127cae5a23dSHong Zhang ierr = MatCopy_SeqAIJ(A,lu->A_dup,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 128cae5a23dSHong Zhang } 1295a46d3faSBarry Smith if ( lu->lwork >= 0 ) { 1305a46d3faSBarry Smith Destroy_SuperNode_Matrix(&lu->L); 1315a46d3faSBarry Smith Destroy_CompCol_Matrix(&lu->U); 1325a46d3faSBarry Smith lu->options.Fact = SamePattern; 1335a46d3faSBarry Smith } 1345a46d3faSBarry Smith } 1355a46d3faSBarry Smith 1365a46d3faSBarry Smith /* Create the SuperMatrix for lu->A=A^T: 1375a46d3faSBarry Smith Since SuperLU likes column-oriented matrices,we pass it the transpose, 1385a46d3faSBarry Smith and then solve A^T X = B in MatSolve(). */ 139cae5a23dSHong Zhang if (lu->options.Equil){ 140cae5a23dSHong Zhang aa = (Mat_SeqAIJ*)(lu->A_dup)->data; 141cae5a23dSHong Zhang } else { 142cae5a23dSHong Zhang aa = (Mat_SeqAIJ*)(A)->data; 143cae5a23dSHong Zhang } 1445a46d3faSBarry Smith #if defined(PETSC_USE_COMPLEX) 145d0f46423SBarry Smith zCreate_CompCol_Matrix(&lu->A,A->cmap->n,A->rmap->n,aa->nz,(doublecomplex*)aa->a,aa->j,aa->i, 1465a46d3faSBarry Smith SLU_NC,SLU_Z,SLU_GE); 1475a46d3faSBarry Smith #else 148d0f46423SBarry Smith dCreate_CompCol_Matrix(&lu->A,A->cmap->n,A->rmap->n,aa->nz,aa->a,aa->j,aa->i, 1495a46d3faSBarry Smith SLU_NC,SLU_D,SLU_GE); 1505a46d3faSBarry Smith #endif 1515a46d3faSBarry Smith 1525a46d3faSBarry Smith /* Numerical factorization */ 1535a46d3faSBarry Smith lu->B.ncol = 0; /* Indicate not to solve the system */ 154d5f3da31SBarry Smith if (F->factortype == MAT_FACTOR_LU){ 1555a46d3faSBarry Smith #if defined(PETSC_USE_COMPLEX) 1565a46d3faSBarry Smith zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 1575a46d3faSBarry Smith &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 1585d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &sinfo); 1595a46d3faSBarry Smith #else 1605a46d3faSBarry Smith dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 1615a46d3faSBarry Smith &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 1625d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &sinfo); 1635a46d3faSBarry Smith #endif 164d5f3da31SBarry Smith } else if (F->factortype == MAT_FACTOR_ILU){ 165cffbb591SHong Zhang /* Compute the incomplete factorization, condition number and pivot growth */ 166cffbb591SHong Zhang #if defined(PETSC_USE_COMPLEX) 167cffbb591SHong Zhang zgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r,lu->etree, lu->equed, lu->R, lu->C, 168cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 1695d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &sinfo); 170cffbb591SHong Zhang #else 171cffbb591SHong Zhang dgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 172cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 1735d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &sinfo); 174cffbb591SHong Zhang #endif 175cffbb591SHong Zhang } else { 176e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 177cffbb591SHong Zhang } 1785a46d3faSBarry Smith if ( !sinfo || sinfo == lu->A.ncol+1 ) { 1795a46d3faSBarry Smith if ( lu->options.PivotGrowth ) 1805a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Recip. pivot growth = %e\n", lu->rpg); 1815a46d3faSBarry Smith if ( lu->options.ConditionNumber ) 1825a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Recip. condition number = %e\n", lu->rcond); 1835a46d3faSBarry Smith } else if ( sinfo > 0 ){ 1845a46d3faSBarry Smith if ( lu->lwork == -1 ) { 1855a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", sinfo - lu->A.ncol); 1869308c137SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot in row %D",sinfo); 1875a46d3faSBarry Smith } else { /* sinfo < 0 */ 188e32f2f54SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", sinfo,-sinfo); 1895a46d3faSBarry Smith } 1905a46d3faSBarry Smith 1915a46d3faSBarry Smith if ( lu->options.PrintStat ) { 1925a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF,"MatLUFactorNumeric_SuperLU():\n"); 1935d8b2efaSHong Zhang StatPrint(&lu->stat); 1945a46d3faSBarry Smith Lstore = (SCformat *) lu->L.Store; 1955a46d3faSBarry Smith Ustore = (NCformat *) lu->U.Store; 1965a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor L = %D\n", Lstore->nnz); 1975a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor U = %D\n", Ustore->nnz); 1985a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in L+U = %D\n", Lstore->nnz + Ustore->nnz - lu->A.ncol); 1996da386baSHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," L\\U MB %.3f\ttotal MB needed %.3f\n", 2006da386baSHong Zhang lu->mem_usage.for_lu/1e6, lu->mem_usage.total_needed/1e6); 2015a46d3faSBarry Smith } 2025a46d3faSBarry Smith 2035a46d3faSBarry Smith lu->flg = SAME_NONZERO_PATTERN; 2041d5ca7f3SHong Zhang F->ops->solve = MatSolve_SuperLU; 2051d5ca7f3SHong Zhang F->ops->solvetranspose = MatSolveTranspose_SuperLU; 206e0b74bf9SHong Zhang F->ops->matsolve = MatMatSolve_SuperLU; 2075a46d3faSBarry Smith PetscFunctionReturn(0); 2085a46d3faSBarry Smith } 2095a46d3faSBarry Smith 21014b396bbSKris Buschelman #undef __FUNCT__ 211f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_SuperLU" 212dfbe8321SBarry Smith PetscErrorCode MatDestroy_SuperLU(Mat A) 21314b396bbSKris Buschelman { 214dfbe8321SBarry Smith PetscErrorCode ierr; 215f0c56d0fSKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU*)A->spptr; 21614b396bbSKris Buschelman 21714b396bbSKris Buschelman PetscFunctionBegin; 218bf0cc555SLisandro Dalcin if (lu && lu->CleanUpSuperLU) { /* Free the SuperLU datastructures */ 21975af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->A); 22075af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->B); 22175af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->X); 2225d8b2efaSHong Zhang StatFree(&lu->stat); 2230e742b69SHong Zhang if (lu->lwork >= 0) { 2240e742b69SHong Zhang Destroy_SuperNode_Matrix(&lu->L); 2250e742b69SHong Zhang Destroy_CompCol_Matrix(&lu->U); 2260e742b69SHong Zhang } 2270e742b69SHong Zhang } 228bf0cc555SLisandro Dalcin if (lu) { 2299ce50919SHong Zhang ierr = PetscFree(lu->etree);CHKERRQ(ierr); 2309ce50919SHong Zhang ierr = PetscFree(lu->perm_r);CHKERRQ(ierr); 2319ce50919SHong Zhang ierr = PetscFree(lu->perm_c);CHKERRQ(ierr); 2329ce50919SHong Zhang ierr = PetscFree(lu->R);CHKERRQ(ierr); 2339ce50919SHong Zhang ierr = PetscFree(lu->C);CHKERRQ(ierr); 234bf0cc555SLisandro Dalcin ierr = PetscFree(lu->rhs_dup);CHKERRQ(ierr); 235bf0cc555SLisandro Dalcin ierr = MatDestroy(&lu->A_dup);CHKERRQ(ierr); 236bf0cc555SLisandro Dalcin } 237bf0cc555SLisandro Dalcin ierr = PetscFree(A->spptr);CHKERRQ(ierr); 2380e742b69SHong Zhang 239d954db57SHong Zhang /* clear composed functions */ 240d954db57SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatFactorGetSolverPackage_C","",PETSC_NULL);CHKERRQ(ierr); 241790a96dfSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSuperluSetILUDropTol_C","",PETSC_NULL);CHKERRQ(ierr); 242d954db57SHong Zhang 243b24902e0SBarry Smith ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr); 24414b396bbSKris Buschelman PetscFunctionReturn(0); 24514b396bbSKris Buschelman } 24614b396bbSKris Buschelman 24714b396bbSKris Buschelman #undef __FUNCT__ 248f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_SuperLU" 249dfbe8321SBarry Smith PetscErrorCode MatView_SuperLU(Mat A,PetscViewer viewer) 25014b396bbSKris Buschelman { 251dfbe8321SBarry Smith PetscErrorCode ierr; 252ace3abfcSBarry Smith PetscBool iascii; 25314b396bbSKris Buschelman PetscViewerFormat format; 25414b396bbSKris Buschelman 25514b396bbSKris Buschelman PetscFunctionBegin; 256251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 25732077d6dSBarry Smith if (iascii) { 25814b396bbSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2592f59403fSHong Zhang if (format == PETSC_VIEWER_ASCII_INFO) { 260f0c56d0fSKris Buschelman ierr = MatFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr); 26114b396bbSKris Buschelman } 26214b396bbSKris Buschelman } 26314b396bbSKris Buschelman PetscFunctionReturn(0); 26414b396bbSKris Buschelman } 26514b396bbSKris Buschelman 26614b396bbSKris Buschelman 26714b396bbSKris Buschelman #undef __FUNCT__ 268c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU_Private" 269c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU_Private(Mat A,Vec b,Vec x) 27014b396bbSKris Buschelman { 271f0c56d0fSKris Buschelman Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 27275af56d4SHong Zhang PetscScalar *barray,*xarray; 273dfbe8321SBarry Smith PetscErrorCode ierr; 274cae5a23dSHong Zhang PetscInt info,i,n=x->map->n; 275da7a1d00SHong Zhang PetscReal ferr,berr; 27614b396bbSKris Buschelman 27714b396bbSKris Buschelman PetscFunctionBegin; 278937a6b0eSHong Zhang if ( lu->lwork == -1 ) { 279937a6b0eSHong Zhang PetscFunctionReturn(0); 280937a6b0eSHong Zhang } 281cae5a23dSHong Zhang 28275af56d4SHong Zhang lu->B.ncol = 1; /* Set the number of right-hand side */ 283cae5a23dSHong Zhang if (lu->options.Equil && !lu->rhs_dup){ 284cae5a23dSHong Zhang /* superlu overwrites b when Equil is used, thus create rhs_dup to keep user's b unchanged */ 285cae5a23dSHong Zhang ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->rhs_dup);CHKERRQ(ierr); 286cae5a23dSHong Zhang } 287cae5a23dSHong Zhang if (lu->options.Equil){ 288cae5a23dSHong Zhang /* Copy b into rsh_dup */ 28975af56d4SHong Zhang ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 290cae5a23dSHong Zhang ierr = PetscMemcpy(lu->rhs_dup,barray,n*sizeof(PetscScalar));CHKERRQ(ierr); 291cae5a23dSHong Zhang ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 292cae5a23dSHong Zhang barray = lu->rhs_dup; 293cae5a23dSHong Zhang } else { 294cae5a23dSHong Zhang ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 295cae5a23dSHong Zhang } 29675af56d4SHong Zhang ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 2975fe6150dSHong Zhang 2985fe6150dSHong Zhang #if defined(PETSC_USE_COMPLEX) 2995fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = (doublecomplex*)barray; 3005fe6150dSHong Zhang ((DNformat*)lu->X.Store)->nzval = (doublecomplex*)xarray; 3015fe6150dSHong Zhang #else 3025fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = barray; 30375af56d4SHong Zhang ((DNformat*)lu->X.Store)->nzval = xarray; 3045fe6150dSHong Zhang #endif 30575af56d4SHong Zhang 30675af56d4SHong Zhang lu->options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ 307d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_LU){ 3088914a3f7SHong Zhang #if defined(PETSC_USE_COMPLEX) 3098914a3f7SHong Zhang zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 3108914a3f7SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 3115d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 3128914a3f7SHong Zhang #else 31375af56d4SHong Zhang dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 31475af56d4SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 3155d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 3168914a3f7SHong Zhang #endif 317d5f3da31SBarry Smith } else if (A->factortype == MAT_FACTOR_ILU){ 318cffbb591SHong Zhang #if defined(PETSC_USE_COMPLEX) 319cffbb591SHong Zhang zgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 320cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 3215d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 322cffbb591SHong Zhang #else 323cffbb591SHong Zhang dgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 324cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 3255d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 326cffbb591SHong Zhang #endif 327cffbb591SHong Zhang } else { 328e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 329cffbb591SHong Zhang } 330cae5a23dSHong Zhang if (!lu->options.Equil){ 33175af56d4SHong Zhang ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 332cae5a23dSHong Zhang } 33375af56d4SHong Zhang ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 33475af56d4SHong Zhang 335958c9bccSBarry Smith if ( !info || info == lu->A.ncol+1 ) { 33675af56d4SHong Zhang if ( lu->options.IterRefine ) { 3378914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Iterative Refinement:\n"); 3388914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); 33975af56d4SHong Zhang for (i = 0; i < 1; ++i) 3405d8b2efaSHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8d%8d%16e%16e\n", i+1, lu->stat.RefineSteps, ferr, berr); 34175af56d4SHong Zhang } 3428914a3f7SHong Zhang } else if ( info > 0 ){ 3438914a3f7SHong Zhang if ( lu->lwork == -1 ) { 34477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", info - lu->A.ncol); 3458914a3f7SHong Zhang } else { 34677431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",info); 3478914a3f7SHong Zhang } 3488914a3f7SHong Zhang } else if (info < 0){ 349e32f2f54SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", info,-info); 35014b396bbSKris Buschelman } 35114b396bbSKris Buschelman 3528914a3f7SHong Zhang if ( lu->options.PrintStat ) { 3538914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve__SuperLU():\n"); 3545d8b2efaSHong Zhang StatPrint(&lu->stat); 3558914a3f7SHong Zhang } 35675af56d4SHong Zhang PetscFunctionReturn(0); 35775af56d4SHong Zhang } 35814b396bbSKris Buschelman 35914b396bbSKris Buschelman #undef __FUNCT__ 360c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU" 361c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU(Mat A,Vec b,Vec x) 362c29e884eSHong Zhang { 363c29e884eSHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 364c29e884eSHong Zhang PetscErrorCode ierr; 365c29e884eSHong Zhang 366c29e884eSHong Zhang PetscFunctionBegin; 367c29e884eSHong Zhang lu->options.Trans = TRANS; 368c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 369c29e884eSHong Zhang PetscFunctionReturn(0); 370c29e884eSHong Zhang } 371c29e884eSHong Zhang 372c29e884eSHong Zhang #undef __FUNCT__ 373c7c1fe80SHong Zhang #define __FUNCT__ "MatSolveTranspose_SuperLU" 374c7c1fe80SHong Zhang PetscErrorCode MatSolveTranspose_SuperLU(Mat A,Vec b,Vec x) 375c7c1fe80SHong Zhang { 376c7c1fe80SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 377c7c1fe80SHong Zhang PetscErrorCode ierr; 378c7c1fe80SHong Zhang 379c7c1fe80SHong Zhang PetscFunctionBegin; 380c7c1fe80SHong Zhang lu->options.Trans = NOTRANS; 381c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 382c7c1fe80SHong Zhang PetscFunctionReturn(0); 383c7c1fe80SHong Zhang } 384c7c1fe80SHong Zhang 385e0b74bf9SHong Zhang #undef __FUNCT__ 386e0b74bf9SHong Zhang #define __FUNCT__ "MatMatSolve_SuperLU" 387e0b74bf9SHong Zhang PetscErrorCode MatMatSolve_SuperLU(Mat A,Mat B,Mat X) 388e0b74bf9SHong Zhang { 389e0b74bf9SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 390cd723cd1SBarry Smith PetscBool flg; 391cd723cd1SBarry Smith PetscErrorCode ierr; 392e0b74bf9SHong Zhang 393e0b74bf9SHong Zhang PetscFunctionBegin; 394251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); 395cd723cd1SBarry Smith if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 396251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); 397cd723cd1SBarry Smith if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); lu->options.Trans = TRANS; 398e0b74bf9SHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatMatSolve_SuperLU() is not implemented yet"); 399e0b74bf9SHong Zhang PetscFunctionReturn(0); 400e0b74bf9SHong Zhang } 401e0b74bf9SHong Zhang 40214b396bbSKris Buschelman /* 40314b396bbSKris Buschelman Note the r permutation is ignored 40414b396bbSKris Buschelman */ 40514b396bbSKris Buschelman #undef __FUNCT__ 406f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_SuperLU" 4070481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 40814b396bbSKris Buschelman { 4091d5ca7f3SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)(F->spptr); 410b24902e0SBarry Smith 411b24902e0SBarry Smith PetscFunctionBegin; 412b24902e0SBarry Smith lu->flg = DIFFERENT_NONZERO_PATTERN; 413b24902e0SBarry Smith lu->CleanUpSuperLU = PETSC_TRUE; 4141d5ca7f3SHong Zhang F->ops->lufactornumeric = MatLUFactorNumeric_SuperLU; 415b24902e0SBarry Smith PetscFunctionReturn(0); 416b24902e0SBarry Smith } 417b24902e0SBarry Smith 41835bd34faSBarry Smith EXTERN_C_BEGIN 41935bd34faSBarry Smith #undef __FUNCT__ 4205ccb76cbSHong Zhang #define __FUNCT__ "MatSuperluSetILUDropTol_SuperLU" 4215ccb76cbSHong Zhang PetscErrorCode MatSuperluSetILUDropTol_SuperLU(Mat F,PetscReal dtol) 4225ccb76cbSHong Zhang { 4235ccb76cbSHong Zhang Mat_SuperLU *lu= (Mat_SuperLU*)F->spptr; 4245ccb76cbSHong Zhang 4255ccb76cbSHong Zhang PetscFunctionBegin; 4265ccb76cbSHong Zhang lu->options.ILU_DropTol = dtol; 4275ccb76cbSHong Zhang PetscFunctionReturn(0); 4285ccb76cbSHong Zhang } 4295ccb76cbSHong Zhang EXTERN_C_END 4305ccb76cbSHong Zhang 4315ccb76cbSHong Zhang #undef __FUNCT__ 4325ccb76cbSHong Zhang #define __FUNCT__ "MatSuperluSetILUDropTol" 4335ccb76cbSHong Zhang /*@ 4345ccb76cbSHong Zhang MatSuperluSetILUDropTol - Set SuperLU ILU drop tolerance 4355ccb76cbSHong Zhang Logically Collective on Mat 4365ccb76cbSHong Zhang 4375ccb76cbSHong Zhang Input Parameters: 4385ccb76cbSHong Zhang + F - the factored matrix obtained by calling MatGetFactor() from PETSc-SuperLU interface 4395ccb76cbSHong Zhang - dtol - drop tolerance 4405ccb76cbSHong Zhang 4415ccb76cbSHong Zhang Options Database: 4425ccb76cbSHong Zhang . -mat_superlu_ilu_droptol <dtol> 4435ccb76cbSHong Zhang 4445ccb76cbSHong Zhang Level: beginner 4455ccb76cbSHong Zhang 4465ccb76cbSHong Zhang References: SuperLU Users' Guide 4475ccb76cbSHong Zhang 4485ccb76cbSHong Zhang .seealso: MatGetFactor() 4495ccb76cbSHong Zhang @*/ 4505ccb76cbSHong Zhang PetscErrorCode MatSuperluSetILUDropTol(Mat F,PetscReal dtol) 4515ccb76cbSHong Zhang { 4525ccb76cbSHong Zhang PetscErrorCode ierr; 4535ccb76cbSHong Zhang 4545ccb76cbSHong Zhang PetscFunctionBegin; 4555ccb76cbSHong Zhang PetscValidHeaderSpecific(F,MAT_CLASSID,1); 4565ccb76cbSHong Zhang PetscValidLogicalCollectiveInt(F,dtol,2); 4575ccb76cbSHong Zhang ierr = PetscTryMethod(F,"MatSuperluSetILUDropTol_C",(Mat,PetscReal),(F,dtol));CHKERRQ(ierr); 4585ccb76cbSHong Zhang PetscFunctionReturn(0); 4595ccb76cbSHong Zhang } 4605ccb76cbSHong Zhang 4615ccb76cbSHong Zhang EXTERN_C_BEGIN 4625ccb76cbSHong Zhang #undef __FUNCT__ 46335bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_superlu" 46435bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_superlu(Mat A,const MatSolverPackage *type) 46535bd34faSBarry Smith { 46635bd34faSBarry Smith PetscFunctionBegin; 4672692d6eeSBarry Smith *type = MATSOLVERSUPERLU; 46835bd34faSBarry Smith PetscFunctionReturn(0); 46935bd34faSBarry Smith } 47035bd34faSBarry Smith EXTERN_C_END 47135bd34faSBarry Smith 472b24902e0SBarry Smith 473b24902e0SBarry Smith /*MC 474ba992d64SSatish Balay MATSOLVERSUPERLU = "superlu" - A solver package providing solvers LU and ILU for sequential matrices 475b24902e0SBarry Smith via the external package SuperLU. 476b24902e0SBarry Smith 477e2e64c6bSBarry Smith Use ./configure --download-superlu to have PETSc installed with SuperLU 478b24902e0SBarry Smith 479b24902e0SBarry Smith Options Database Keys: 480e08999f5SMatthew G Knepley + -mat_superlu_equil <FALSE> - Equil (None) 481e08999f5SMatthew G Knepley . -mat_superlu_colperm <COLAMD> - (choose one of) NATURAL MMD_ATA MMD_AT_PLUS_A COLAMD 482e08999f5SMatthew G Knepley . -mat_superlu_iterrefine <NOREFINE> - (choose one of) NOREFINE SINGLE DOUBLE EXTRA 483e08999f5SMatthew G Knepley . -mat_superlu_symmetricmode: <FALSE> - SymmetricMode (None) 484e08999f5SMatthew G Knepley . -mat_superlu_diagpivotthresh <1> - DiagPivotThresh (None) 485e08999f5SMatthew G Knepley . -mat_superlu_pivotgrowth <FALSE> - PivotGrowth (None) 486e08999f5SMatthew G Knepley . -mat_superlu_conditionnumber <FALSE> - ConditionNumber (None) 487e08999f5SMatthew G Knepley . -mat_superlu_rowperm <NOROWPERM> - (choose one of) NOROWPERM LargeDiag 488e08999f5SMatthew G Knepley . -mat_superlu_replacetinypivot <FALSE> - ReplaceTinyPivot (None) 489e08999f5SMatthew G Knepley . -mat_superlu_printstat <FALSE> - PrintStat (None) 490e08999f5SMatthew G Knepley . -mat_superlu_lwork <0> - size of work array in bytes used by factorization (None) 491e08999f5SMatthew G Knepley . -mat_superlu_ilu_droptol <0> - ILU_DropTol (None) 492e08999f5SMatthew G Knepley . -mat_superlu_ilu_filltol <0> - ILU_FillTol (None) 493e08999f5SMatthew G Knepley . -mat_superlu_ilu_fillfactor <0> - ILU_FillFactor (None) 494e08999f5SMatthew G Knepley . -mat_superlu_ilu_droprull <0> - ILU_DropRule (None) 495e08999f5SMatthew G Knepley . -mat_superlu_ilu_norm <0> - ILU_Norm (None) 496e08999f5SMatthew G Knepley - -mat_superlu_ilu_milu <0> - ILU_MILU (None) 497b24902e0SBarry Smith 4982692d6eeSBarry Smith Notes: Do not confuse this with MATSOLVERSUPERLU_DIST which is for parallel sparse solves 4995c9eb25fSBarry Smith 500b24902e0SBarry Smith Level: beginner 501b24902e0SBarry Smith 502*d45987f3SHong Zhang .seealso: PCLU, PCILU, MATSOLVERSUPERLU_DIST, MATSOLVERMUMPS, PCFactorSetMatSolverPackage(), MatSolverPackage 503b24902e0SBarry Smith M*/ 504b24902e0SBarry Smith 5055c9eb25fSBarry Smith EXTERN_C_BEGIN 506b24902e0SBarry Smith #undef __FUNCT__ 507b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_superlu" 5085c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_superlu(Mat A,MatFactorType ftype,Mat *F) 509b24902e0SBarry Smith { 51014b396bbSKris Buschelman Mat B; 511f0c56d0fSKris Buschelman Mat_SuperLU *lu; 5126849ba73SBarry Smith PetscErrorCode ierr; 5135d8b2efaSHong Zhang PetscInt indx,m=A->rmap->n,n=A->cmap->n; 514ace3abfcSBarry Smith PetscBool flg; 5155ca28756SHong Zhang const char *colperm[]={"NATURAL","MMD_ATA","MMD_AT_PLUS_A","COLAMD"}; /* MY_PERMC - not supported by the petsc interface yet */ 5165ca28756SHong Zhang const char *iterrefine[]={"NOREFINE", "SINGLE", "DOUBLE", "EXTRA"}; 5175ca28756SHong Zhang const char *rowperm[]={"NOROWPERM", "LargeDiag"}; /* MY_PERMC - not supported by the petsc interface yet */ 51814b396bbSKris Buschelman 51914b396bbSKris Buschelman PetscFunctionBegin; 5207adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 521d0f46423SBarry Smith ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 5227adad957SLisandro Dalcin ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 523899d7b4fSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 524f0c56d0fSKris Buschelman 525cffbb591SHong Zhang if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU){ 526b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_SuperLU; 527cffbb591SHong Zhang B->ops->ilufactorsymbolic = MatLUFactorSymbolic_SuperLU; 528b3a44c85SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 529cffbb591SHong Zhang 530b24902e0SBarry Smith B->ops->destroy = MatDestroy_SuperLU; 5313519fcdcSHong Zhang B->ops->view = MatView_SuperLU; 532d5f3da31SBarry Smith B->factortype = ftype; 53394b7f48cSBarry Smith B->assembled = PETSC_TRUE; /* required by -ksp_view */ 5345c9eb25fSBarry Smith B->preallocated = PETSC_TRUE; 53514b396bbSKris Buschelman 536b24902e0SBarry Smith ierr = PetscNewLog(B,Mat_SuperLU,&lu);CHKERRQ(ierr); 537cae5a23dSHong Zhang 538cffbb591SHong Zhang if (ftype == MAT_FACTOR_LU){ 5399ce50919SHong Zhang set_default_options(&lu->options); 5403d6581fbSHong Zhang /* Comments from SuperLU_4.0/SRC/dgssvx.c: 5413d6581fbSHong Zhang "Whether or not the system will be equilibrated depends on the 5423d6581fbSHong Zhang scaling of the matrix A, but if equilibration is used, A is 5433d6581fbSHong Zhang overwritten by diag(R)*A*diag(C) and B by diag(R)*B 5443d6581fbSHong Zhang (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans = TRANS or CONJ)." 5453d6581fbSHong Zhang We set 'options.Equil = NO' as default because additional space is needed for it. 5463d6581fbSHong Zhang */ 5473d6581fbSHong Zhang lu->options.Equil = NO; 548cffbb591SHong Zhang } else if (ftype == MAT_FACTOR_ILU){ 5490c74a584SJed Brown /* Set the default input options of ilu: */ 550cffbb591SHong Zhang ilu_set_default_options(&lu->options); 551cffbb591SHong Zhang } 5529ce50919SHong Zhang lu->options.PrintStat = NO; 5531a2e2f44SHong Zhang 5545d8b2efaSHong Zhang /* Initialize the statistics variables. */ 5555d8b2efaSHong Zhang StatInit(&lu->stat); 5568914a3f7SHong Zhang lu->lwork = 0; /* allocate space internally by system malloc */ 5579ce50919SHong Zhang 5587adad957SLisandro Dalcin ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"SuperLU Options","Mat");CHKERRQ(ierr); 559acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_equil","Equil","None",(PetscBool)lu->options.Equil,(PetscBool*)&lu->options.Equil,0);CHKERRQ(ierr); 5608914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_colperm","ColPerm","None",colperm,4,colperm[3],&indx,&flg);CHKERRQ(ierr); 5619ce50919SHong Zhang if (flg) {lu->options.ColPerm = (colperm_t)indx;} 5628914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_iterrefine","IterRefine","None",iterrefine,4,iterrefine[0],&indx,&flg);CHKERRQ(ierr); 5639ce50919SHong Zhang if (flg) { lu->options.IterRefine = (IterRefine_t)indx;} 564acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_symmetricmode","SymmetricMode","None",(PetscBool)lu->options.SymmetricMode,&flg,0);CHKERRQ(ierr); 5659ce50919SHong Zhang if (flg) lu->options.SymmetricMode = YES; 5668914a3f7SHong Zhang ierr = PetscOptionsReal("-mat_superlu_diagpivotthresh","DiagPivotThresh","None",lu->options.DiagPivotThresh,&lu->options.DiagPivotThresh,PETSC_NULL);CHKERRQ(ierr); 567acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_pivotgrowth","PivotGrowth","None",(PetscBool)lu->options.PivotGrowth,&flg,0);CHKERRQ(ierr); 5689ce50919SHong Zhang if (flg) lu->options.PivotGrowth = YES; 569acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_conditionnumber","ConditionNumber","None",(PetscBool)lu->options.ConditionNumber,&flg,0);CHKERRQ(ierr); 5709ce50919SHong Zhang if (flg) lu->options.ConditionNumber = YES; 571d7ebd59bSHong Zhang ierr = PetscOptionsEList("-mat_superlu_rowperm","rowperm","None",rowperm,2,rowperm[lu->options.RowPerm],&indx,&flg);CHKERRQ(ierr); 5729ce50919SHong Zhang if (flg) {lu->options.RowPerm = (rowperm_t)indx;} 573acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_replacetinypivot","ReplaceTinyPivot","None",(PetscBool)lu->options.ReplaceTinyPivot,&flg,0);CHKERRQ(ierr); 5749ce50919SHong Zhang if (flg) lu->options.ReplaceTinyPivot = YES; 575acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_printstat","PrintStat","None",(PetscBool)lu->options.PrintStat,&flg,0);CHKERRQ(ierr); 5769ce50919SHong Zhang if (flg) lu->options.PrintStat = YES; 5778914a3f7SHong Zhang ierr = PetscOptionsInt("-mat_superlu_lwork","size of work array in bytes used by factorization","None",lu->lwork,&lu->lwork,PETSC_NULL);CHKERRQ(ierr); 5785fe6150dSHong Zhang if (lu->lwork > 0 ){ 5795fe6150dSHong Zhang ierr = PetscMalloc(lu->lwork,&lu->work);CHKERRQ(ierr); 5805fe6150dSHong Zhang } else if (lu->lwork != 0 && lu->lwork != -1){ 58177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: lwork %D is not supported by SUPERLU. The default lwork=0 is used.\n",lu->lwork); 5828914a3f7SHong Zhang lu->lwork = 0; 5838914a3f7SHong Zhang } 584cffbb591SHong Zhang /* ilu options */ 585cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_droptol","ILU_DropTol","None",lu->options.ILU_DropTol,&lu->options.ILU_DropTol,PETSC_NULL);CHKERRQ(ierr); 586cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_filltol","ILU_FillTol","None",lu->options.ILU_FillTol,&lu->options.ILU_FillTol,PETSC_NULL);CHKERRQ(ierr); 587cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_fillfactor","ILU_FillFactor","None",lu->options.ILU_FillFactor,&lu->options.ILU_FillFactor,PETSC_NULL);CHKERRQ(ierr); 588cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_droprull","ILU_DropRule","None",lu->options.ILU_DropRule,&lu->options.ILU_DropRule,PETSC_NULL);CHKERRQ(ierr); 589cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_norm","ILU_Norm","None",lu->options.ILU_Norm,&indx,&flg);CHKERRQ(ierr); 590cffbb591SHong Zhang if (flg){ 591cffbb591SHong Zhang lu->options.ILU_Norm = (norm_t)indx; 592cffbb591SHong Zhang } 593cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_milu","ILU_MILU","None",lu->options.ILU_MILU,&indx,&flg);CHKERRQ(ierr); 594cffbb591SHong Zhang if (flg){ 595cffbb591SHong Zhang lu->options.ILU_MILU = (milu_t)indx; 596cffbb591SHong Zhang } 5979ce50919SHong Zhang PetscOptionsEnd(); 59838abfdaeSHong Zhang if (lu->options.Equil == YES) { 59938abfdaeSHong Zhang /* superlu overwrites input matrix and rhs when Equil is used, thus create A_dup to keep user's A unchanged */ 60038abfdaeSHong Zhang ierr = MatDuplicate_SeqAIJ(A,MAT_COPY_VALUES,&lu->A_dup);CHKERRQ(ierr); 60138abfdaeSHong Zhang } 6029ce50919SHong Zhang 6035d8b2efaSHong Zhang /* Allocate spaces (notice sizes are for the transpose) */ 6045d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->etree);CHKERRQ(ierr); 6055d8b2efaSHong Zhang ierr = PetscMalloc(n*sizeof(PetscInt),&lu->perm_r);CHKERRQ(ierr); 6065d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->perm_c);CHKERRQ(ierr); 6075d8b2efaSHong Zhang ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->R);CHKERRQ(ierr); 6085d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscScalar),&lu->C);CHKERRQ(ierr); 6095d8b2efaSHong Zhang 6105d8b2efaSHong Zhang /* create rhs and solution x without allocate space for .Store */ 6115d8b2efaSHong Zhang #if defined(PETSC_USE_COMPLEX) 6125d8b2efaSHong Zhang zCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 6135d8b2efaSHong Zhang zCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 6145d8b2efaSHong Zhang #else 6155d8b2efaSHong Zhang dCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 6165d8b2efaSHong Zhang dCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 6175d8b2efaSHong Zhang #endif 6185d8b2efaSHong Zhang 61975af56d4SHong Zhang #ifdef SUPERLU2 6205c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatCreateNull","MatCreateNull_SuperLU",(void(*)(void))MatCreateNull_SuperLU);CHKERRQ(ierr); 62175af56d4SHong Zhang #endif 62235bd34faSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_superlu",MatFactorGetSolverPackage_seqaij_superlu);CHKERRQ(ierr); 6235ccb76cbSHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSuperluSetILUDropTol_C","MatSuperluSetILUDropTol_SuperLU",MatSuperluSetILUDropTol_SuperLU);CHKERRQ(ierr); 6245c9eb25fSBarry Smith B->spptr = lu; 625899d7b4fSKris Buschelman *F = B; 62614b396bbSKris Buschelman PetscFunctionReturn(0); 62714b396bbSKris Buschelman } 6285c9eb25fSBarry Smith EXTERN_C_END 629d954db57SHong Zhang 630