1be1d678aSKris Buschelman #define PETSCMAT_DLL 214b396bbSKris Buschelman 35a46d3faSBarry Smith /* -------------------------------------------------------------------- 45a46d3faSBarry Smith 55a46d3faSBarry Smith This file implements a subclass of the SeqAIJ matrix class that uses 65d8b2efaSHong Zhang the SuperLU sparse solver. You can use this as a starting point for 75a46d3faSBarry Smith implementing your own subclass of a PETSc matrix class. 85a46d3faSBarry Smith 95a46d3faSBarry Smith This demonstrates a way to make an implementation inheritence of a PETSc 105a46d3faSBarry Smith matrix type. This means constructing a new matrix type (SuperLU) by changing some 115a46d3faSBarry Smith of the methods of the previous type (SeqAIJ), adding additional data, and possibly 125a46d3faSBarry Smith additional method. (See any book on object oriented programming). 1314b396bbSKris Buschelman */ 1414b396bbSKris Buschelman 155a46d3faSBarry Smith /* 165a46d3faSBarry Smith Defines the data structure for the base matrix type (SeqAIJ) 175a46d3faSBarry Smith */ 188ece9e9aSSatish Balay #include "../src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 1914b396bbSKris Buschelman 205a46d3faSBarry Smith /* 215a46d3faSBarry Smith SuperLU include files 225a46d3faSBarry Smith */ 2314b396bbSKris Buschelman EXTERN_C_BEGIN 2414b396bbSKris Buschelman #if defined(PETSC_USE_COMPLEX) 2566f57492SHong Zhang #include "slu_zdefs.h" 2614b396bbSKris Buschelman #else 2766f57492SHong Zhang #include "slu_ddefs.h" 2814b396bbSKris Buschelman #endif 2966f57492SHong Zhang #include "slu_util.h" 3014b396bbSKris Buschelman EXTERN_C_END 3114b396bbSKris Buschelman 325a46d3faSBarry Smith /* 335a46d3faSBarry Smith This is the data we are "ADDING" to the SeqAIJ matrix type to get the SuperLU matrix type 345a46d3faSBarry Smith */ 3514b396bbSKris Buschelman typedef struct { 3675af56d4SHong Zhang SuperMatrix A,L,U,B,X; 3775af56d4SHong Zhang superlu_options_t options; 38da7a1d00SHong Zhang PetscInt *perm_c; /* column permutation vector */ 39da7a1d00SHong Zhang PetscInt *perm_r; /* row permutations from partial pivoting */ 40da7a1d00SHong Zhang PetscInt *etree; 41da7a1d00SHong Zhang PetscReal *R, *C; 4275af56d4SHong Zhang char equed[1]; 43da7a1d00SHong Zhang PetscInt lwork; 4475af56d4SHong Zhang void *work; 45da7a1d00SHong Zhang PetscReal rpg, rcond; 4675af56d4SHong Zhang mem_usage_t mem_usage; 4775af56d4SHong Zhang MatStructure flg; 485d8b2efaSHong Zhang SuperLUStat_t stat; 49cae5a23dSHong Zhang Mat A_dup; 50cae5a23dSHong Zhang PetscScalar *rhs_dup; 5114b396bbSKris Buschelman 5214b396bbSKris Buschelman /* Flag to clean up (non-global) SuperLU objects during Destroy */ 53ace3abfcSBarry Smith PetscBool CleanUpSuperLU; 54f0c56d0fSKris Buschelman } Mat_SuperLU; 5514b396bbSKris Buschelman 56e0e586b9SHong Zhang extern PetscErrorCode MatFactorInfo_SuperLU(Mat,PetscViewer); 570481f469SBarry Smith extern PetscErrorCode MatLUFactorNumeric_SuperLU(Mat,Mat,const MatFactorInfo *); 58e0e586b9SHong Zhang extern PetscErrorCode MatDestroy_SuperLU(Mat); 59e0e586b9SHong Zhang extern PetscErrorCode MatView_SuperLU(Mat,PetscViewer); 60e0e586b9SHong Zhang extern PetscErrorCode MatAssemblyEnd_SuperLU(Mat,MatAssemblyType); 61e0e586b9SHong Zhang extern PetscErrorCode MatSolve_SuperLU(Mat,Vec,Vec); 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 { 113719d5645SBarry Smith 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; 204719d5645SBarry Smith (F)->ops->solve = MatSolve_SuperLU; 205719d5645SBarry Smith (F)->ops->solvetranspose = MatSolveTranspose_SuperLU; 2065a46d3faSBarry Smith PetscFunctionReturn(0); 2075a46d3faSBarry Smith } 2085a46d3faSBarry Smith 20914b396bbSKris Buschelman #undef __FUNCT__ 210f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_SuperLU" 211dfbe8321SBarry Smith PetscErrorCode MatDestroy_SuperLU(Mat A) 21214b396bbSKris Buschelman { 213dfbe8321SBarry Smith PetscErrorCode ierr; 214f0c56d0fSKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU*)A->spptr; 21514b396bbSKris Buschelman 21614b396bbSKris Buschelman PetscFunctionBegin; 21775af56d4SHong Zhang if (lu->CleanUpSuperLU) { /* Free the SuperLU datastructures */ 21875af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->A); 21975af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->B); 22075af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->X); 2215d8b2efaSHong Zhang StatFree(&lu->stat); 2220e742b69SHong Zhang if ( lu->lwork >= 0 ) { 2230e742b69SHong Zhang Destroy_SuperNode_Matrix(&lu->L); 2240e742b69SHong Zhang Destroy_CompCol_Matrix(&lu->U); 2250e742b69SHong Zhang } 2260e742b69SHong Zhang 2270e742b69SHong Zhang } 2289ce50919SHong Zhang 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); 2340e742b69SHong Zhang 235d954db57SHong Zhang /* clear composed functions */ 236d954db57SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatFactorGetSolverPackage_C","",PETSC_NULL);CHKERRQ(ierr); 237790a96dfSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSuperluSetILUDropTol_C","",PETSC_NULL);CHKERRQ(ierr); 238d954db57SHong Zhang 239b24902e0SBarry Smith ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr); 240cae5a23dSHong Zhang if (lu->A_dup){ierr = MatDestroy(lu->A_dup);CHKERRQ(ierr);} 241cae5a23dSHong Zhang if (lu->rhs_dup){ierr = PetscFree(lu->rhs_dup);CHKERRQ(ierr);} 24214b396bbSKris Buschelman PetscFunctionReturn(0); 24314b396bbSKris Buschelman } 24414b396bbSKris Buschelman 24514b396bbSKris Buschelman #undef __FUNCT__ 246f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_SuperLU" 247dfbe8321SBarry Smith PetscErrorCode MatView_SuperLU(Mat A,PetscViewer viewer) 24814b396bbSKris Buschelman { 249dfbe8321SBarry Smith PetscErrorCode ierr; 250ace3abfcSBarry Smith PetscBool iascii; 25114b396bbSKris Buschelman PetscViewerFormat format; 25214b396bbSKris Buschelman 25314b396bbSKris Buschelman PetscFunctionBegin; 2542692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 25532077d6dSBarry Smith if (iascii) { 25614b396bbSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 2572f59403fSHong Zhang if (format == PETSC_VIEWER_ASCII_INFO) { 258f0c56d0fSKris Buschelman ierr = MatFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr); 25914b396bbSKris Buschelman } 26014b396bbSKris Buschelman } 26114b396bbSKris Buschelman PetscFunctionReturn(0); 26214b396bbSKris Buschelman } 26314b396bbSKris Buschelman 26414b396bbSKris Buschelman 26514b396bbSKris Buschelman #undef __FUNCT__ 266c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU_Private" 267c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU_Private(Mat A,Vec b,Vec x) 26814b396bbSKris Buschelman { 269f0c56d0fSKris Buschelman Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 27075af56d4SHong Zhang PetscScalar *barray,*xarray; 271dfbe8321SBarry Smith PetscErrorCode ierr; 272cae5a23dSHong Zhang PetscInt info,i,n=x->map->n; 273da7a1d00SHong Zhang PetscReal ferr,berr; 27414b396bbSKris Buschelman 27514b396bbSKris Buschelman PetscFunctionBegin; 276937a6b0eSHong Zhang if ( lu->lwork == -1 ) { 277937a6b0eSHong Zhang PetscFunctionReturn(0); 278937a6b0eSHong Zhang } 279cae5a23dSHong Zhang 28075af56d4SHong Zhang lu->B.ncol = 1; /* Set the number of right-hand side */ 281cae5a23dSHong Zhang if (lu->options.Equil && !lu->rhs_dup){ 282cae5a23dSHong Zhang /* superlu overwrites b when Equil is used, thus create rhs_dup to keep user's b unchanged */ 283cae5a23dSHong Zhang ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->rhs_dup);CHKERRQ(ierr); 284cae5a23dSHong Zhang } 285cae5a23dSHong Zhang if (lu->options.Equil){ 286cae5a23dSHong Zhang /* Copy b into rsh_dup */ 28775af56d4SHong Zhang ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 288cae5a23dSHong Zhang ierr = PetscMemcpy(lu->rhs_dup,barray,n*sizeof(PetscScalar));CHKERRQ(ierr); 289cae5a23dSHong Zhang ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 290cae5a23dSHong Zhang barray = lu->rhs_dup; 291cae5a23dSHong Zhang } else { 292cae5a23dSHong Zhang ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 293cae5a23dSHong Zhang } 29475af56d4SHong Zhang ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 2955fe6150dSHong Zhang 2965fe6150dSHong Zhang #if defined(PETSC_USE_COMPLEX) 2975fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = (doublecomplex*)barray; 2985fe6150dSHong Zhang ((DNformat*)lu->X.Store)->nzval = (doublecomplex*)xarray; 2995fe6150dSHong Zhang #else 3005fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = barray; 30175af56d4SHong Zhang ((DNformat*)lu->X.Store)->nzval = xarray; 3025fe6150dSHong Zhang #endif 30375af56d4SHong Zhang 30475af56d4SHong Zhang lu->options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ 305d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_LU){ 3068914a3f7SHong Zhang #if defined(PETSC_USE_COMPLEX) 3078914a3f7SHong Zhang zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 3088914a3f7SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 3095d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 3108914a3f7SHong Zhang #else 31175af56d4SHong Zhang dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 31275af56d4SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 3135d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 3148914a3f7SHong Zhang #endif 315d5f3da31SBarry Smith } else if (A->factortype == MAT_FACTOR_ILU){ 316cffbb591SHong Zhang #if defined(PETSC_USE_COMPLEX) 317cffbb591SHong Zhang zgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 318cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 3195d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 320cffbb591SHong Zhang #else 321cffbb591SHong Zhang dgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 322cffbb591SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, 3235d8b2efaSHong Zhang &lu->mem_usage, &lu->stat, &info); 324cffbb591SHong Zhang #endif 325cffbb591SHong Zhang } else { 326e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 327cffbb591SHong Zhang } 328cae5a23dSHong Zhang if (!lu->options.Equil){ 32975af56d4SHong Zhang ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 330cae5a23dSHong Zhang } 33175af56d4SHong Zhang ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 33275af56d4SHong Zhang 333958c9bccSBarry Smith if ( !info || info == lu->A.ncol+1 ) { 33475af56d4SHong Zhang if ( lu->options.IterRefine ) { 3358914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Iterative Refinement:\n"); 3368914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); 33775af56d4SHong Zhang for (i = 0; i < 1; ++i) 3385d8b2efaSHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8d%8d%16e%16e\n", i+1, lu->stat.RefineSteps, ferr, berr); 33975af56d4SHong Zhang } 3408914a3f7SHong Zhang } else if ( info > 0 ){ 3418914a3f7SHong Zhang if ( lu->lwork == -1 ) { 34277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", info - lu->A.ncol); 3438914a3f7SHong Zhang } else { 34477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",info); 3458914a3f7SHong Zhang } 3468914a3f7SHong Zhang } else if (info < 0){ 347e32f2f54SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", info,-info); 34814b396bbSKris Buschelman } 34914b396bbSKris Buschelman 3508914a3f7SHong Zhang if ( lu->options.PrintStat ) { 3518914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve__SuperLU():\n"); 3525d8b2efaSHong Zhang StatPrint(&lu->stat); 3538914a3f7SHong Zhang } 35475af56d4SHong Zhang PetscFunctionReturn(0); 35575af56d4SHong Zhang } 35614b396bbSKris Buschelman 35714b396bbSKris Buschelman #undef __FUNCT__ 358c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU" 359c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU(Mat A,Vec b,Vec x) 360c29e884eSHong Zhang { 361c29e884eSHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 362c29e884eSHong Zhang PetscErrorCode ierr; 363c29e884eSHong Zhang 364c29e884eSHong Zhang PetscFunctionBegin; 365c29e884eSHong Zhang lu->options.Trans = TRANS; 366c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 367c29e884eSHong Zhang PetscFunctionReturn(0); 368c29e884eSHong Zhang } 369c29e884eSHong Zhang 370c29e884eSHong Zhang #undef __FUNCT__ 371c7c1fe80SHong Zhang #define __FUNCT__ "MatSolveTranspose_SuperLU" 372c7c1fe80SHong Zhang PetscErrorCode MatSolveTranspose_SuperLU(Mat A,Vec b,Vec x) 373c7c1fe80SHong Zhang { 374c7c1fe80SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 375c7c1fe80SHong Zhang PetscErrorCode ierr; 376c7c1fe80SHong Zhang 377c7c1fe80SHong Zhang PetscFunctionBegin; 378c7c1fe80SHong Zhang lu->options.Trans = NOTRANS; 379c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 380c7c1fe80SHong Zhang PetscFunctionReturn(0); 381c7c1fe80SHong Zhang } 382c7c1fe80SHong Zhang 38314b396bbSKris Buschelman /* 38414b396bbSKris Buschelman Note the r permutation is ignored 38514b396bbSKris Buschelman */ 38614b396bbSKris Buschelman #undef __FUNCT__ 387f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_SuperLU" 3880481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 38914b396bbSKris Buschelman { 390719d5645SBarry Smith Mat_SuperLU *lu = (Mat_SuperLU*)((F)->spptr); 391b24902e0SBarry Smith 392b24902e0SBarry Smith PetscFunctionBegin; 393b24902e0SBarry Smith lu->flg = DIFFERENT_NONZERO_PATTERN; 394b24902e0SBarry Smith lu->CleanUpSuperLU = PETSC_TRUE; 395719d5645SBarry Smith (F)->ops->lufactornumeric = MatLUFactorNumeric_SuperLU; 396b24902e0SBarry Smith PetscFunctionReturn(0); 397b24902e0SBarry Smith } 398b24902e0SBarry Smith 39935bd34faSBarry Smith EXTERN_C_BEGIN 40035bd34faSBarry Smith #undef __FUNCT__ 401*5ccb76cbSHong Zhang #define __FUNCT__ "MatSuperluSetILUDropTol_SuperLU" 402*5ccb76cbSHong Zhang PetscErrorCode MatSuperluSetILUDropTol_SuperLU(Mat F,PetscReal dtol) 403*5ccb76cbSHong Zhang { 404*5ccb76cbSHong Zhang Mat_SuperLU *lu= (Mat_SuperLU*)F->spptr; 405*5ccb76cbSHong Zhang 406*5ccb76cbSHong Zhang PetscFunctionBegin; 407*5ccb76cbSHong Zhang lu->options.ILU_DropTol = dtol; 408*5ccb76cbSHong Zhang PetscFunctionReturn(0); 409*5ccb76cbSHong Zhang } 410*5ccb76cbSHong Zhang EXTERN_C_END 411*5ccb76cbSHong Zhang 412*5ccb76cbSHong Zhang #undef __FUNCT__ 413*5ccb76cbSHong Zhang #define __FUNCT__ "MatSuperluSetILUDropTol" 414*5ccb76cbSHong Zhang /*@ 415*5ccb76cbSHong Zhang MatSuperluSetILUDropTol - Set SuperLU ILU drop tolerance 416*5ccb76cbSHong Zhang Logically Collective on Mat 417*5ccb76cbSHong Zhang 418*5ccb76cbSHong Zhang Input Parameters: 419*5ccb76cbSHong Zhang + F - the factored matrix obtained by calling MatGetFactor() from PETSc-SuperLU interface 420*5ccb76cbSHong Zhang - dtol - drop tolerance 421*5ccb76cbSHong Zhang 422*5ccb76cbSHong Zhang Options Database: 423*5ccb76cbSHong Zhang . -mat_superlu_ilu_droptol <dtol> 424*5ccb76cbSHong Zhang 425*5ccb76cbSHong Zhang Level: beginner 426*5ccb76cbSHong Zhang 427*5ccb76cbSHong Zhang References: SuperLU Users' Guide 428*5ccb76cbSHong Zhang 429*5ccb76cbSHong Zhang .seealso: MatGetFactor() 430*5ccb76cbSHong Zhang @*/ 431*5ccb76cbSHong Zhang PetscErrorCode MatSuperluSetILUDropTol(Mat F,PetscReal dtol) 432*5ccb76cbSHong Zhang { 433*5ccb76cbSHong Zhang PetscErrorCode ierr; 434*5ccb76cbSHong Zhang 435*5ccb76cbSHong Zhang PetscFunctionBegin; 436*5ccb76cbSHong Zhang PetscValidHeaderSpecific(F,MAT_CLASSID,1); 437*5ccb76cbSHong Zhang PetscValidLogicalCollectiveInt(F,dtol,2); 438*5ccb76cbSHong Zhang ierr = PetscTryMethod(F,"MatSuperluSetILUDropTol_C",(Mat,PetscReal),(F,dtol));CHKERRQ(ierr); 439*5ccb76cbSHong Zhang PetscFunctionReturn(0); 440*5ccb76cbSHong Zhang } 441*5ccb76cbSHong Zhang 442*5ccb76cbSHong Zhang EXTERN_C_BEGIN 443*5ccb76cbSHong Zhang #undef __FUNCT__ 44435bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_superlu" 44535bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_superlu(Mat A,const MatSolverPackage *type) 44635bd34faSBarry Smith { 44735bd34faSBarry Smith PetscFunctionBegin; 4482692d6eeSBarry Smith *type = MATSOLVERSUPERLU; 44935bd34faSBarry Smith PetscFunctionReturn(0); 45035bd34faSBarry Smith } 45135bd34faSBarry Smith EXTERN_C_END 45235bd34faSBarry Smith 453b24902e0SBarry Smith 454b24902e0SBarry Smith /*MC 455ba992d64SSatish Balay MATSOLVERSUPERLU = "superlu" - A solver package providing solvers LU and ILU for sequential matrices 456b24902e0SBarry Smith via the external package SuperLU. 457b24902e0SBarry Smith 458e2e64c6bSBarry Smith Use ./configure --download-superlu to have PETSc installed with SuperLU 459b24902e0SBarry Smith 460b24902e0SBarry Smith Options Database Keys: 4612de22e2eSHong Zhang + -mat_superlu_equil: <FALSE> Equil (None) 4622de22e2eSHong Zhang . -mat_superlu_colperm <COLAMD> (choose one of) NATURAL MMD_ATA MMD_AT_PLUS_A COLAMD 4632de22e2eSHong Zhang . -mat_superlu_iterrefine <NOREFINE> (choose one of) NOREFINE SINGLE DOUBLE EXTRA 4642de22e2eSHong Zhang . -mat_superlu_symmetricmode: <FALSE> SymmetricMode (None) 4652de22e2eSHong Zhang . -mat_superlu_diagpivotthresh <1>: DiagPivotThresh (None) 4662de22e2eSHong Zhang . -mat_superlu_pivotgrowth: <FALSE> PivotGrowth (None) 4672de22e2eSHong Zhang . -mat_superlu_conditionnumber: <FALSE> ConditionNumber (None) 4682de22e2eSHong Zhang . -mat_superlu_rowperm <NOROWPERM> (choose one of) NOROWPERM LargeDiag 4692de22e2eSHong Zhang . -mat_superlu_replacetinypivot: <FALSE> ReplaceTinyPivot (None) 4702de22e2eSHong Zhang . -mat_superlu_printstat: <FALSE> PrintStat (None) 4712de22e2eSHong Zhang . -mat_superlu_lwork <0>: size of work array in bytes used by factorization (None) 4722de22e2eSHong Zhang . -mat_superlu_ilu_droptol <0>: ILU_DropTol (None) 4732de22e2eSHong Zhang . -mat_superlu_ilu_filltol <0>: ILU_FillTol (None) 4742de22e2eSHong Zhang . -mat_superlu_ilu_fillfactor <0>: ILU_FillFactor (None) 4752de22e2eSHong Zhang . -mat_superlu_ilu_droprull <0>: ILU_DropRule (None) 4762de22e2eSHong Zhang . -mat_superlu_ilu_norm <0>: ILU_Norm (None) 4772de22e2eSHong Zhang - -mat_superlu_ilu_milu <0>: ILU_MILU (None) 478b24902e0SBarry Smith 4792692d6eeSBarry Smith Notes: Do not confuse this with MATSOLVERSUPERLU_DIST which is for parallel sparse solves 4805c9eb25fSBarry Smith 481b24902e0SBarry Smith Level: beginner 482b24902e0SBarry Smith 483ba992d64SSatish Balay .seealso: PCLU, PCILU, MATSOLVERSUPERLU_DIST, MATSOLVERMUMPS, MATSOLVERSPOOLES, PCFactorSetMatSolverPackage(), MatSolverPackage 484b24902e0SBarry Smith M*/ 485b24902e0SBarry Smith 4865c9eb25fSBarry Smith EXTERN_C_BEGIN 487b24902e0SBarry Smith #undef __FUNCT__ 488b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_superlu" 4895c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_superlu(Mat A,MatFactorType ftype,Mat *F) 490b24902e0SBarry Smith { 49114b396bbSKris Buschelman Mat B; 492f0c56d0fSKris Buschelman Mat_SuperLU *lu; 4936849ba73SBarry Smith PetscErrorCode ierr; 4945d8b2efaSHong Zhang PetscInt indx,m=A->rmap->n,n=A->cmap->n; 495ace3abfcSBarry Smith PetscBool flg; 4965ca28756SHong Zhang const char *colperm[]={"NATURAL","MMD_ATA","MMD_AT_PLUS_A","COLAMD"}; /* MY_PERMC - not supported by the petsc interface yet */ 4975ca28756SHong Zhang const char *iterrefine[]={"NOREFINE", "SINGLE", "DOUBLE", "EXTRA"}; 4985ca28756SHong Zhang const char *rowperm[]={"NOROWPERM", "LargeDiag"}; /* MY_PERMC - not supported by the petsc interface yet */ 49914b396bbSKris Buschelman 50014b396bbSKris Buschelman PetscFunctionBegin; 5017adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 502d0f46423SBarry Smith ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 5037adad957SLisandro Dalcin ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 504899d7b4fSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 505f0c56d0fSKris Buschelman 506cffbb591SHong Zhang if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU){ 507b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_SuperLU; 508cffbb591SHong Zhang B->ops->ilufactorsymbolic = MatLUFactorSymbolic_SuperLU; 509cffbb591SHong Zhang } else { 510e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 511cffbb591SHong Zhang } 512cffbb591SHong Zhang 513b24902e0SBarry Smith B->ops->destroy = MatDestroy_SuperLU; 5143519fcdcSHong Zhang B->ops->view = MatView_SuperLU; 515d5f3da31SBarry Smith B->factortype = ftype; 51694b7f48cSBarry Smith B->assembled = PETSC_TRUE; /* required by -ksp_view */ 5175c9eb25fSBarry Smith B->preallocated = PETSC_TRUE; 51814b396bbSKris Buschelman 519b24902e0SBarry Smith ierr = PetscNewLog(B,Mat_SuperLU,&lu);CHKERRQ(ierr); 520cae5a23dSHong Zhang 521cffbb591SHong Zhang if (ftype == MAT_FACTOR_LU){ 5229ce50919SHong Zhang set_default_options(&lu->options); 5233d6581fbSHong Zhang /* Comments from SuperLU_4.0/SRC/dgssvx.c: 5243d6581fbSHong Zhang "Whether or not the system will be equilibrated depends on the 5253d6581fbSHong Zhang scaling of the matrix A, but if equilibration is used, A is 5263d6581fbSHong Zhang overwritten by diag(R)*A*diag(C) and B by diag(R)*B 5273d6581fbSHong Zhang (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans = TRANS or CONJ)." 5283d6581fbSHong Zhang We set 'options.Equil = NO' as default because additional space is needed for it. 5293d6581fbSHong Zhang */ 5303d6581fbSHong Zhang lu->options.Equil = NO; 531cffbb591SHong Zhang } else if (ftype == MAT_FACTOR_ILU){ 532cffbb591SHong Zhang /* Set the default input options of ilu: 533cffbb591SHong Zhang options.Fact = DOFACT; 5343d6581fbSHong Zhang options.Equil = YES; // must be YES for ilu - don't know why 535cffbb591SHong Zhang options.ColPerm = COLAMD; 536cffbb591SHong Zhang options.DiagPivotThresh = 0.1; //different from complete LU 537cffbb591SHong Zhang options.Trans = NOTRANS; 538cffbb591SHong Zhang options.IterRefine = NOREFINE; 539cffbb591SHong Zhang options.SymmetricMode = NO; 540cffbb591SHong Zhang options.PivotGrowth = NO; 541cffbb591SHong Zhang options.ConditionNumber = NO; 542cffbb591SHong Zhang options.PrintStat = YES; 543cffbb591SHong Zhang options.RowPerm = LargeDiag; 544cffbb591SHong Zhang options.ILU_DropTol = 1e-4; 545cffbb591SHong Zhang options.ILU_FillTol = 1e-2; 546cffbb591SHong Zhang options.ILU_FillFactor = 10.0; 547cffbb591SHong Zhang options.ILU_DropRule = DROP_BASIC | DROP_AREA; 548cffbb591SHong Zhang options.ILU_Norm = INF_NORM; 549cffbb591SHong Zhang options.ILU_MILU = SMILU_2; 550cffbb591SHong Zhang */ 551cffbb591SHong Zhang ilu_set_default_options(&lu->options); 552cffbb591SHong Zhang } 5539ce50919SHong Zhang lu->options.PrintStat = NO; 5541a2e2f44SHong Zhang 5555d8b2efaSHong Zhang /* Initialize the statistics variables. */ 5565d8b2efaSHong Zhang StatInit(&lu->stat); 5578914a3f7SHong Zhang lu->lwork = 0; /* allocate space internally by system malloc */ 5589ce50919SHong Zhang 5597adad957SLisandro Dalcin ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"SuperLU Options","Mat");CHKERRQ(ierr); 560acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_equil","Equil","None",(PetscBool)lu->options.Equil,(PetscBool*)&lu->options.Equil,0);CHKERRQ(ierr); 5618914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_colperm","ColPerm","None",colperm,4,colperm[3],&indx,&flg);CHKERRQ(ierr); 5629ce50919SHong Zhang if (flg) {lu->options.ColPerm = (colperm_t)indx;} 5638914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_iterrefine","IterRefine","None",iterrefine,4,iterrefine[0],&indx,&flg);CHKERRQ(ierr); 5649ce50919SHong Zhang if (flg) { lu->options.IterRefine = (IterRefine_t)indx;} 565acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_symmetricmode","SymmetricMode","None",(PetscBool)lu->options.SymmetricMode,&flg,0);CHKERRQ(ierr); 5669ce50919SHong Zhang if (flg) lu->options.SymmetricMode = YES; 5678914a3f7SHong Zhang ierr = PetscOptionsReal("-mat_superlu_diagpivotthresh","DiagPivotThresh","None",lu->options.DiagPivotThresh,&lu->options.DiagPivotThresh,PETSC_NULL);CHKERRQ(ierr); 568acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_pivotgrowth","PivotGrowth","None",(PetscBool)lu->options.PivotGrowth,&flg,0);CHKERRQ(ierr); 5699ce50919SHong Zhang if (flg) lu->options.PivotGrowth = YES; 570acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_conditionnumber","ConditionNumber","None",(PetscBool)lu->options.ConditionNumber,&flg,0);CHKERRQ(ierr); 5719ce50919SHong Zhang if (flg) lu->options.ConditionNumber = YES; 5728914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_rowperm","rowperm","None",rowperm,2,rowperm[0],&indx,&flg);CHKERRQ(ierr); 5739ce50919SHong Zhang if (flg) {lu->options.RowPerm = (rowperm_t)indx;} 574acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_replacetinypivot","ReplaceTinyPivot","None",(PetscBool)lu->options.ReplaceTinyPivot,&flg,0);CHKERRQ(ierr); 5759ce50919SHong Zhang if (flg) lu->options.ReplaceTinyPivot = YES; 576acfcf0e5SJed Brown ierr = PetscOptionsBool("-mat_superlu_printstat","PrintStat","None",(PetscBool)lu->options.PrintStat,&flg,0);CHKERRQ(ierr); 5779ce50919SHong Zhang if (flg) lu->options.PrintStat = YES; 5788914a3f7SHong Zhang ierr = PetscOptionsInt("-mat_superlu_lwork","size of work array in bytes used by factorization","None",lu->lwork,&lu->lwork,PETSC_NULL);CHKERRQ(ierr); 5795fe6150dSHong Zhang if (lu->lwork > 0 ){ 5805fe6150dSHong Zhang ierr = PetscMalloc(lu->lwork,&lu->work);CHKERRQ(ierr); 5815fe6150dSHong Zhang } else if (lu->lwork != 0 && lu->lwork != -1){ 58277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: lwork %D is not supported by SUPERLU. The default lwork=0 is used.\n",lu->lwork); 5838914a3f7SHong Zhang lu->lwork = 0; 5848914a3f7SHong Zhang } 585cffbb591SHong Zhang /* ilu options */ 586cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_droptol","ILU_DropTol","None",lu->options.ILU_DropTol,&lu->options.ILU_DropTol,PETSC_NULL);CHKERRQ(ierr); 587cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_filltol","ILU_FillTol","None",lu->options.ILU_FillTol,&lu->options.ILU_FillTol,PETSC_NULL);CHKERRQ(ierr); 588cffbb591SHong Zhang ierr = PetscOptionsReal("-mat_superlu_ilu_fillfactor","ILU_FillFactor","None",lu->options.ILU_FillFactor,&lu->options.ILU_FillFactor,PETSC_NULL);CHKERRQ(ierr); 589cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_droprull","ILU_DropRule","None",lu->options.ILU_DropRule,&lu->options.ILU_DropRule,PETSC_NULL);CHKERRQ(ierr); 590cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_norm","ILU_Norm","None",lu->options.ILU_Norm,&indx,&flg);CHKERRQ(ierr); 591cffbb591SHong Zhang if (flg){ 592cffbb591SHong Zhang lu->options.ILU_Norm = (norm_t)indx; 593cffbb591SHong Zhang } 594cffbb591SHong Zhang ierr = PetscOptionsInt("-mat_superlu_ilu_milu","ILU_MILU","None",lu->options.ILU_MILU,&indx,&flg);CHKERRQ(ierr); 595cffbb591SHong Zhang if (flg){ 596cffbb591SHong Zhang lu->options.ILU_MILU = (milu_t)indx; 597cffbb591SHong Zhang } 5989ce50919SHong Zhang PetscOptionsEnd(); 59938abfdaeSHong Zhang if (lu->options.Equil == YES) { 60038abfdaeSHong Zhang /* superlu overwrites input matrix and rhs when Equil is used, thus create A_dup to keep user's A unchanged */ 60138abfdaeSHong Zhang ierr = MatDuplicate_SeqAIJ(A,MAT_COPY_VALUES,&lu->A_dup);CHKERRQ(ierr); 60238abfdaeSHong Zhang } 6039ce50919SHong Zhang 6045d8b2efaSHong Zhang /* Allocate spaces (notice sizes are for the transpose) */ 6055d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->etree);CHKERRQ(ierr); 6065d8b2efaSHong Zhang ierr = PetscMalloc(n*sizeof(PetscInt),&lu->perm_r);CHKERRQ(ierr); 6075d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->perm_c);CHKERRQ(ierr); 6085d8b2efaSHong Zhang ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->R);CHKERRQ(ierr); 6095d8b2efaSHong Zhang ierr = PetscMalloc(m*sizeof(PetscScalar),&lu->C);CHKERRQ(ierr); 6105d8b2efaSHong Zhang 6115d8b2efaSHong Zhang /* create rhs and solution x without allocate space for .Store */ 6125d8b2efaSHong Zhang #if defined(PETSC_USE_COMPLEX) 6135d8b2efaSHong Zhang zCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 6145d8b2efaSHong Zhang zCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 6155d8b2efaSHong Zhang #else 6165d8b2efaSHong Zhang dCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 6175d8b2efaSHong Zhang dCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 6185d8b2efaSHong Zhang #endif 6195d8b2efaSHong Zhang 62075af56d4SHong Zhang #ifdef SUPERLU2 6215c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatCreateNull","MatCreateNull_SuperLU",(void(*)(void))MatCreateNull_SuperLU);CHKERRQ(ierr); 62275af56d4SHong Zhang #endif 62335bd34faSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_superlu",MatFactorGetSolverPackage_seqaij_superlu);CHKERRQ(ierr); 624*5ccb76cbSHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSuperluSetILUDropTol_C","MatSuperluSetILUDropTol_SuperLU",MatSuperluSetILUDropTol_SuperLU);CHKERRQ(ierr); 6255c9eb25fSBarry Smith B->spptr = lu; 626899d7b4fSKris Buschelman *F = B; 62714b396bbSKris Buschelman PetscFunctionReturn(0); 62814b396bbSKris Buschelman } 6295c9eb25fSBarry Smith EXTERN_C_END 630d954db57SHong Zhang 631