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 65a46d3faSBarry Smith the SuperLU 3.0 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 */ 1814b396bbSKris Buschelman #include "src/mat/impls/aij/seq/aij.h" 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; 4814b396bbSKris Buschelman 495a46d3faSBarry Smith /* 505a46d3faSBarry Smith This is where the methods for the superclass (SeqAIJ) are kept while we 515a46d3faSBarry Smith reset the pointers in the function table to the new (SuperLU) versions 525a46d3faSBarry Smith */ 536849ba73SBarry Smith PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 546849ba73SBarry Smith PetscErrorCode (*MatView)(Mat,PetscViewer); 556849ba73SBarry Smith PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 566849ba73SBarry Smith PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 576849ba73SBarry Smith PetscErrorCode (*MatDestroy)(Mat); 5814b396bbSKris Buschelman 5914b396bbSKris Buschelman /* Flag to clean up (non-global) SuperLU objects during Destroy */ 6014b396bbSKris Buschelman PetscTruth CleanUpSuperLU; 61f0c56d0fSKris Buschelman } Mat_SuperLU; 6214b396bbSKris Buschelman 63*e0e586b9SHong Zhang extern PetscErrorCode MatFactorInfo_SuperLU(Mat,PetscViewer); 64*e0e586b9SHong Zhang extern PetscErrorCode MatLUFactorNumeric_SuperLU(Mat,MatFactorInfo *,Mat *); 65*e0e586b9SHong Zhang extern PetscErrorCode MatDestroy_SuperLU(Mat); 66*e0e586b9SHong Zhang extern PetscErrorCode MatView_SuperLU(Mat,PetscViewer); 67*e0e586b9SHong Zhang extern PetscErrorCode MatAssemblyEnd_SuperLU(Mat,MatAssemblyType); 68*e0e586b9SHong Zhang extern PetscErrorCode MatSolve_SuperLU(Mat,Vec,Vec); 69*e0e586b9SHong Zhang extern PetscErrorCode MatSolveTranspose_SuperLU(Mat,Vec,Vec); 70*e0e586b9SHong Zhang extern PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat,IS,IS,MatFactorInfo *,Mat *); 71*e0e586b9SHong Zhang extern PetscErrorCode MatDuplicate_SuperLU(Mat, MatDuplicateOption, Mat *); 72*e0e586b9SHong Zhang 735a46d3faSBarry Smith /* 745a46d3faSBarry Smith Takes a SuperLU matrix (that is a SeqAIJ matrix with the additional SuperLU data-structures 755a46d3faSBarry Smith and methods) and converts it back to a regular SeqAIJ matrix. 765a46d3faSBarry Smith */ 775a46d3faSBarry Smith EXTERN_C_BEGIN 785a46d3faSBarry Smith #undef __FUNCT__ 795a46d3faSBarry Smith #define __FUNCT__ "MatConvert_SuperLU_SeqAIJ" 805a46d3faSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SuperLU_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat) 815a46d3faSBarry Smith { 825a46d3faSBarry Smith PetscErrorCode ierr; 835a46d3faSBarry Smith Mat B=*newmat; 845a46d3faSBarry Smith Mat_SuperLU *lu=(Mat_SuperLU *)A->spptr; 8514b396bbSKris Buschelman 865a46d3faSBarry Smith PetscFunctionBegin; 875a46d3faSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 885a46d3faSBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 895a46d3faSBarry Smith } 905a46d3faSBarry Smith /* Reset the original SeqAIJ function pointers */ 915a46d3faSBarry Smith B->ops->duplicate = lu->MatDuplicate; 925a46d3faSBarry Smith B->ops->view = lu->MatView; 935a46d3faSBarry Smith B->ops->assemblyend = lu->MatAssemblyEnd; 945a46d3faSBarry Smith B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic; 955a46d3faSBarry Smith B->ops->destroy = lu->MatDestroy; 965a46d3faSBarry Smith 975a46d3faSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_superlu_C","",PETSC_NULL);CHKERRQ(ierr); 985a46d3faSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_superlu_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 995a46d3faSBarry Smith 1005a46d3faSBarry Smith /* change the type name back to its original value */ 1015a46d3faSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 1025a46d3faSBarry Smith *newmat = B; 1035a46d3faSBarry Smith PetscFunctionReturn(0); 1045a46d3faSBarry Smith } 1055a46d3faSBarry Smith EXTERN_C_END 106b0592601SKris Buschelman 107b0592601SKris Buschelman EXTERN_C_BEGIN 1085a46d3faSBarry Smith #undef __FUNCT__ 1095a46d3faSBarry Smith #define __FUNCT__ "MatConvert_SeqAIJ_SuperLU" 1105a46d3faSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_SuperLU(Mat A,MatType type,MatReuse reuse,Mat *newmat) 1115a46d3faSBarry Smith { 1125a46d3faSBarry Smith PetscErrorCode ierr; 1135a46d3faSBarry Smith Mat B=*newmat; 1145a46d3faSBarry Smith Mat_SuperLU *lu; 1155a46d3faSBarry Smith 1165a46d3faSBarry Smith PetscFunctionBegin; 1175a46d3faSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 1185a46d3faSBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 1195a46d3faSBarry Smith } 1205a46d3faSBarry Smith 1215a46d3faSBarry Smith ierr = PetscNew(Mat_SuperLU,&lu);CHKERRQ(ierr); 1225a46d3faSBarry Smith /* save the original SeqAIJ methods that we are changing */ 1235a46d3faSBarry Smith lu->MatDuplicate = A->ops->duplicate; 1245a46d3faSBarry Smith lu->MatView = A->ops->view; 1255a46d3faSBarry Smith lu->MatAssemblyEnd = A->ops->assemblyend; 1265a46d3faSBarry Smith lu->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 1275a46d3faSBarry Smith lu->MatDestroy = A->ops->destroy; 1285a46d3faSBarry Smith lu->CleanUpSuperLU = PETSC_FALSE; 1295a46d3faSBarry Smith 1305a46d3faSBarry Smith /* add to the matrix the location for all the SuperLU data is to be stored */ 1315a46d3faSBarry Smith B->spptr = (void*)lu; 1325a46d3faSBarry Smith 1335a46d3faSBarry Smith /* set the methods in the function table to the SuperLU versions */ 1345a46d3faSBarry Smith B->ops->duplicate = MatDuplicate_SuperLU; 1355a46d3faSBarry Smith B->ops->view = MatView_SuperLU; 1365a46d3faSBarry Smith B->ops->assemblyend = MatAssemblyEnd_SuperLU; 1375a46d3faSBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_SuperLU; 1385a46d3faSBarry Smith B->ops->choleskyfactorsymbolic = 0; 1395a46d3faSBarry Smith B->ops->destroy = MatDestroy_SuperLU; 1405a46d3faSBarry Smith 1415a46d3faSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_superlu_C", 1425a46d3faSBarry Smith "MatConvert_SeqAIJ_SuperLU",MatConvert_SeqAIJ_SuperLU);CHKERRQ(ierr); 1435a46d3faSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_superlu_seqaij_C", 1445a46d3faSBarry Smith "MatConvert_SuperLU_SeqAIJ",MatConvert_SuperLU_SeqAIJ);CHKERRQ(ierr); 1455a46d3faSBarry Smith ierr = PetscInfo(0,"Using SuperLU for SeqAIJ LU factorization and solves.\n");CHKERRQ(ierr); 1465a46d3faSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSUPERLU);CHKERRQ(ierr); 1475a46d3faSBarry Smith *newmat = B; 1485a46d3faSBarry Smith PetscFunctionReturn(0); 1495a46d3faSBarry Smith } 150b0592601SKris Buschelman EXTERN_C_END 15114b396bbSKris Buschelman 1525a46d3faSBarry Smith /* 1535a46d3faSBarry Smith Utility function 1545a46d3faSBarry Smith */ 1555a46d3faSBarry Smith #undef __FUNCT__ 1565a46d3faSBarry Smith #define __FUNCT__ "MatFactorInfo_SuperLU" 1575a46d3faSBarry Smith PetscErrorCode MatFactorInfo_SuperLU(Mat A,PetscViewer viewer) 1585a46d3faSBarry Smith { 1595a46d3faSBarry Smith Mat_SuperLU *lu= (Mat_SuperLU*)A->spptr; 1605a46d3faSBarry Smith PetscErrorCode ierr; 1615a46d3faSBarry Smith superlu_options_t options; 1625a46d3faSBarry Smith 1635a46d3faSBarry Smith PetscFunctionBegin; 1645a46d3faSBarry Smith /* check if matrix is superlu_dist type */ 1655a46d3faSBarry Smith if (A->ops->solve != MatSolve_SuperLU) PetscFunctionReturn(0); 1665a46d3faSBarry Smith 1675a46d3faSBarry Smith options = lu->options; 1685a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"SuperLU run parameters:\n");CHKERRQ(ierr); 1695a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Equil: %s\n",(options.Equil != NO) ? "YES": "NO");CHKERRQ(ierr); 1705a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ColPerm: %D\n",options.ColPerm);CHKERRQ(ierr); 1715a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," IterRefine: %D\n",options.IterRefine);CHKERRQ(ierr); 1725a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," SymmetricMode: %s\n",(options.SymmetricMode != NO) ? "YES": "NO");CHKERRQ(ierr); 1735a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," DiagPivotThresh: %g\n",options.DiagPivotThresh);CHKERRQ(ierr); 1745a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," PivotGrowth: %s\n",(options.PivotGrowth != NO) ? "YES": "NO");CHKERRQ(ierr); 1755a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ConditionNumber: %s\n",(options.ConditionNumber != NO) ? "YES": "NO");CHKERRQ(ierr); 1765a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," RowPerm: %D\n",options.RowPerm);CHKERRQ(ierr); 1775a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ReplaceTinyPivot: %s\n",(options.ReplaceTinyPivot != NO) ? "YES": "NO");CHKERRQ(ierr); 1785a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," PrintStat: %s\n",(options.PrintStat != NO) ? "YES": "NO");CHKERRQ(ierr); 1795a46d3faSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," lwork: %D\n",lu->lwork);CHKERRQ(ierr); 1805a46d3faSBarry Smith 1815a46d3faSBarry Smith PetscFunctionReturn(0); 1825a46d3faSBarry Smith } 1835a46d3faSBarry Smith 1845a46d3faSBarry Smith /* 1855a46d3faSBarry Smith These are the methods provided to REPLACE the corresponding methods of the 1865a46d3faSBarry Smith SeqAIJ matrix class. Other methods of SeqAIJ are not replaced 1875a46d3faSBarry Smith */ 1885a46d3faSBarry Smith #undef __FUNCT__ 1895a46d3faSBarry Smith #define __FUNCT__ "MatLUFactorNumeric_SuperLU" 1905a46d3faSBarry Smith PetscErrorCode MatLUFactorNumeric_SuperLU(Mat A,MatFactorInfo *info,Mat *F) 1915a46d3faSBarry Smith { 1925a46d3faSBarry Smith Mat_SeqAIJ *aa = (Mat_SeqAIJ*)(A)->data; 1935a46d3faSBarry Smith Mat_SuperLU *lu = (Mat_SuperLU*)(*F)->spptr; 1945a46d3faSBarry Smith PetscErrorCode ierr; 1955a46d3faSBarry Smith PetscInt sinfo; 1965a46d3faSBarry Smith SuperLUStat_t stat; 1975a46d3faSBarry Smith PetscReal ferr, berr; 1985a46d3faSBarry Smith NCformat *Ustore; 1995a46d3faSBarry Smith SCformat *Lstore; 2005a46d3faSBarry Smith 2015a46d3faSBarry Smith PetscFunctionBegin; 2025a46d3faSBarry Smith if (lu->flg == SAME_NONZERO_PATTERN){ /* successing numerical factorization */ 2035a46d3faSBarry Smith lu->options.Fact = SamePattern; 2045a46d3faSBarry Smith /* Ref: ~SuperLU_3.0/EXAMPLE/dlinsolx2.c */ 2055a46d3faSBarry Smith Destroy_SuperMatrix_Store(&lu->A); 2065a46d3faSBarry Smith if ( lu->lwork >= 0 ) { 2075a46d3faSBarry Smith Destroy_SuperNode_Matrix(&lu->L); 2085a46d3faSBarry Smith Destroy_CompCol_Matrix(&lu->U); 2095a46d3faSBarry Smith lu->options.Fact = SamePattern; 2105a46d3faSBarry Smith } 2115a46d3faSBarry Smith } 2125a46d3faSBarry Smith 2135a46d3faSBarry Smith /* Create the SuperMatrix for lu->A=A^T: 2145a46d3faSBarry Smith Since SuperLU likes column-oriented matrices,we pass it the transpose, 2155a46d3faSBarry Smith and then solve A^T X = B in MatSolve(). */ 2165a46d3faSBarry Smith #if defined(PETSC_USE_COMPLEX) 2175a46d3faSBarry Smith zCreate_CompCol_Matrix(&lu->A,A->cmap.n,A->rmap.n,aa->nz,(doublecomplex*)aa->a,aa->j,aa->i, 2185a46d3faSBarry Smith SLU_NC,SLU_Z,SLU_GE); 2195a46d3faSBarry Smith #else 2205a46d3faSBarry Smith dCreate_CompCol_Matrix(&lu->A,A->cmap.n,A->rmap.n,aa->nz,aa->a,aa->j,aa->i, 2215a46d3faSBarry Smith SLU_NC,SLU_D,SLU_GE); 2225a46d3faSBarry Smith #endif 2235a46d3faSBarry Smith 2245a46d3faSBarry Smith /* Initialize the statistics variables. */ 2255a46d3faSBarry Smith StatInit(&stat); 2265a46d3faSBarry Smith 2275a46d3faSBarry Smith /* Numerical factorization */ 2285a46d3faSBarry Smith lu->B.ncol = 0; /* Indicate not to solve the system */ 2295a46d3faSBarry Smith #if defined(PETSC_USE_COMPLEX) 2305a46d3faSBarry Smith zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 2315a46d3faSBarry Smith &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 2325a46d3faSBarry Smith &lu->mem_usage, &stat, &sinfo); 2335a46d3faSBarry Smith #else 2345a46d3faSBarry Smith dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 2355a46d3faSBarry Smith &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 2365a46d3faSBarry Smith &lu->mem_usage, &stat, &sinfo); 2375a46d3faSBarry Smith #endif 2385a46d3faSBarry Smith if ( !sinfo || sinfo == lu->A.ncol+1 ) { 2395a46d3faSBarry Smith if ( lu->options.PivotGrowth ) 2405a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Recip. pivot growth = %e\n", lu->rpg); 2415a46d3faSBarry Smith if ( lu->options.ConditionNumber ) 2425a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Recip. condition number = %e\n", lu->rcond); 2435a46d3faSBarry Smith } else if ( sinfo > 0 ){ 2445a46d3faSBarry Smith if ( lu->lwork == -1 ) { 2455a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", sinfo - lu->A.ncol); 2465a46d3faSBarry Smith } else { 2475a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",sinfo); 2485a46d3faSBarry Smith } 2495a46d3faSBarry Smith } else { /* sinfo < 0 */ 2505a46d3faSBarry Smith SETERRQ2(PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", sinfo,-sinfo); 2515a46d3faSBarry Smith } 2525a46d3faSBarry Smith 2535a46d3faSBarry Smith if ( lu->options.PrintStat ) { 2545a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF,"MatLUFactorNumeric_SuperLU():\n"); 2555a46d3faSBarry Smith StatPrint(&stat); 2565a46d3faSBarry Smith Lstore = (SCformat *) lu->L.Store; 2575a46d3faSBarry Smith Ustore = (NCformat *) lu->U.Store; 2585a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor L = %D\n", Lstore->nnz); 2595a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor U = %D\n", Ustore->nnz); 2605a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in L+U = %D\n", Lstore->nnz + Ustore->nnz - lu->A.ncol); 2615a46d3faSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," L\\U MB %.3f\ttotal MB needed %.3f\texpansions %D\n", 2625a46d3faSBarry Smith lu->mem_usage.for_lu/1e6, lu->mem_usage.total_needed/1e6, 2635a46d3faSBarry Smith lu->mem_usage.expansions); 2645a46d3faSBarry Smith } 2655a46d3faSBarry Smith StatFree(&stat); 2665a46d3faSBarry Smith 2675a46d3faSBarry Smith lu->flg = SAME_NONZERO_PATTERN; 2685a46d3faSBarry Smith PetscFunctionReturn(0); 2695a46d3faSBarry Smith } 2705a46d3faSBarry Smith 27114b396bbSKris Buschelman #undef __FUNCT__ 272f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_SuperLU" 273dfbe8321SBarry Smith PetscErrorCode MatDestroy_SuperLU(Mat A) 27414b396bbSKris Buschelman { 275dfbe8321SBarry Smith PetscErrorCode ierr; 276f0c56d0fSKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU*)A->spptr; 27714b396bbSKris Buschelman 27814b396bbSKris Buschelman PetscFunctionBegin; 27975af56d4SHong Zhang if (lu->CleanUpSuperLU) { /* Free the SuperLU datastructures */ 28075af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->A); 28175af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->B); 28275af56d4SHong Zhang Destroy_SuperMatrix_Store(&lu->X); 2839ce50919SHong Zhang 2849ce50919SHong Zhang ierr = PetscFree(lu->etree);CHKERRQ(ierr); 2859ce50919SHong Zhang ierr = PetscFree(lu->perm_r);CHKERRQ(ierr); 2869ce50919SHong Zhang ierr = PetscFree(lu->perm_c);CHKERRQ(ierr); 2879ce50919SHong Zhang ierr = PetscFree(lu->R);CHKERRQ(ierr); 2889ce50919SHong Zhang ierr = PetscFree(lu->C);CHKERRQ(ierr); 28975af56d4SHong Zhang if ( lu->lwork >= 0 ) { 290fb3e25aaSKris Buschelman Destroy_SuperNode_Matrix(&lu->L); 291fb3e25aaSKris Buschelman Destroy_CompCol_Matrix(&lu->U); 29275af56d4SHong Zhang } 293fb3e25aaSKris Buschelman } 294ceb03754SKris Buschelman ierr = MatConvert_SuperLU_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 295fb3e25aaSKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 29614b396bbSKris Buschelman PetscFunctionReturn(0); 29714b396bbSKris Buschelman } 29814b396bbSKris Buschelman 29914b396bbSKris Buschelman #undef __FUNCT__ 300f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_SuperLU" 301dfbe8321SBarry Smith PetscErrorCode MatView_SuperLU(Mat A,PetscViewer viewer) 30214b396bbSKris Buschelman { 303dfbe8321SBarry Smith PetscErrorCode ierr; 30432077d6dSBarry Smith PetscTruth iascii; 30514b396bbSKris Buschelman PetscViewerFormat format; 306f0c56d0fSKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU*)(A->spptr); 30714b396bbSKris Buschelman 30814b396bbSKris Buschelman PetscFunctionBegin; 30914b396bbSKris Buschelman ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr); 31014b396bbSKris Buschelman 31132077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 31232077d6dSBarry Smith if (iascii) { 31314b396bbSKris Buschelman ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 3142f59403fSHong Zhang if (format == PETSC_VIEWER_ASCII_INFO) { 315f0c56d0fSKris Buschelman ierr = MatFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr); 31614b396bbSKris Buschelman } 31714b396bbSKris Buschelman } 31814b396bbSKris Buschelman PetscFunctionReturn(0); 31914b396bbSKris Buschelman } 32014b396bbSKris Buschelman 32114b396bbSKris Buschelman #undef __FUNCT__ 322f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_SuperLU" 323dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SuperLU(Mat A,MatAssemblyType mode) { 324dfbe8321SBarry Smith PetscErrorCode ierr; 325f0c56d0fSKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU*)(A->spptr); 32614b396bbSKris Buschelman 32714b396bbSKris Buschelman PetscFunctionBegin; 32814b396bbSKris Buschelman ierr = (*lu->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 329b0592601SKris Buschelman lu->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 330f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_SuperLU; 33114b396bbSKris Buschelman PetscFunctionReturn(0); 33214b396bbSKris Buschelman } 33314b396bbSKris Buschelman 33414b396bbSKris Buschelman 33514b396bbSKris Buschelman #undef __FUNCT__ 336c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU_Private" 337c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU_Private(Mat A,Vec b,Vec x) 33814b396bbSKris Buschelman { 339f0c56d0fSKris Buschelman Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 34075af56d4SHong Zhang PetscScalar *barray,*xarray; 341dfbe8321SBarry Smith PetscErrorCode ierr; 342da7a1d00SHong Zhang PetscInt info,i; 34375af56d4SHong Zhang SuperLUStat_t stat; 344da7a1d00SHong Zhang PetscReal ferr,berr; 34514b396bbSKris Buschelman 34614b396bbSKris Buschelman PetscFunctionBegin; 347937a6b0eSHong Zhang if ( lu->lwork == -1 ) { 348937a6b0eSHong Zhang PetscFunctionReturn(0); 349937a6b0eSHong Zhang } 35075af56d4SHong Zhang lu->B.ncol = 1; /* Set the number of right-hand side */ 35175af56d4SHong Zhang ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 35275af56d4SHong Zhang ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 3535fe6150dSHong Zhang 3545fe6150dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3555fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = (doublecomplex*)barray; 3565fe6150dSHong Zhang ((DNformat*)lu->X.Store)->nzval = (doublecomplex*)xarray; 3575fe6150dSHong Zhang #else 3585fe6150dSHong Zhang ((DNformat*)lu->B.Store)->nzval = barray; 35975af56d4SHong Zhang ((DNformat*)lu->X.Store)->nzval = xarray; 3605fe6150dSHong Zhang #endif 36175af56d4SHong Zhang 36275af56d4SHong Zhang /* Initialize the statistics variables. */ 36375af56d4SHong Zhang StatInit(&stat); 36475af56d4SHong Zhang 36575af56d4SHong Zhang lu->options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ 3668914a3f7SHong Zhang #if defined(PETSC_USE_COMPLEX) 3678914a3f7SHong Zhang zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 3688914a3f7SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 3698914a3f7SHong Zhang &lu->mem_usage, &stat, &info); 3708914a3f7SHong Zhang #else 37175af56d4SHong Zhang dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 37275af56d4SHong Zhang &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 37375af56d4SHong Zhang &lu->mem_usage, &stat, &info); 3748914a3f7SHong Zhang #endif 37575af56d4SHong Zhang ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 37675af56d4SHong Zhang ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 37775af56d4SHong Zhang 378958c9bccSBarry Smith if ( !info || info == lu->A.ncol+1 ) { 37975af56d4SHong Zhang if ( lu->options.IterRefine ) { 3808914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Iterative Refinement:\n"); 3818914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); 38275af56d4SHong Zhang for (i = 0; i < 1; ++i) 3838914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF," %8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr, berr); 38475af56d4SHong Zhang } 3858914a3f7SHong Zhang } else if ( info > 0 ){ 3868914a3f7SHong Zhang if ( lu->lwork == -1 ) { 38777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", info - lu->A.ncol); 3888914a3f7SHong Zhang } else { 38977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",info); 3908914a3f7SHong Zhang } 3918914a3f7SHong Zhang } else if (info < 0){ 39277431f27SBarry Smith SETERRQ2(PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", info,-info); 39314b396bbSKris Buschelman } 39414b396bbSKris Buschelman 3958914a3f7SHong Zhang if ( lu->options.PrintStat ) { 3968914a3f7SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve__SuperLU():\n"); 3978914a3f7SHong Zhang StatPrint(&stat); 3988914a3f7SHong Zhang } 39975af56d4SHong Zhang StatFree(&stat); 40075af56d4SHong Zhang PetscFunctionReturn(0); 40175af56d4SHong Zhang } 40214b396bbSKris Buschelman 40314b396bbSKris Buschelman #undef __FUNCT__ 404c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU" 405c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU(Mat A,Vec b,Vec x) 406c29e884eSHong Zhang { 407c29e884eSHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 408c29e884eSHong Zhang PetscErrorCode ierr; 409c29e884eSHong Zhang 410c29e884eSHong Zhang PetscFunctionBegin; 411c29e884eSHong Zhang lu->options.Trans = TRANS; 412c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 413c29e884eSHong Zhang PetscFunctionReturn(0); 414c29e884eSHong Zhang } 415c29e884eSHong Zhang 416c29e884eSHong Zhang #undef __FUNCT__ 417c7c1fe80SHong Zhang #define __FUNCT__ "MatSolveTranspose_SuperLU" 418c7c1fe80SHong Zhang PetscErrorCode MatSolveTranspose_SuperLU(Mat A,Vec b,Vec x) 419c7c1fe80SHong Zhang { 420c7c1fe80SHong Zhang Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 421c7c1fe80SHong Zhang PetscErrorCode ierr; 422c7c1fe80SHong Zhang 423c7c1fe80SHong Zhang PetscFunctionBegin; 424c7c1fe80SHong Zhang lu->options.Trans = NOTRANS; 425c29e884eSHong Zhang ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 426c7c1fe80SHong Zhang PetscFunctionReturn(0); 427c7c1fe80SHong Zhang } 428c7c1fe80SHong Zhang 42914b396bbSKris Buschelman 43014b396bbSKris Buschelman /* 43114b396bbSKris Buschelman Note the r permutation is ignored 43214b396bbSKris Buschelman */ 43314b396bbSKris Buschelman #undef __FUNCT__ 434f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_SuperLU" 435dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 43614b396bbSKris Buschelman { 43714b396bbSKris Buschelman Mat B; 438f0c56d0fSKris Buschelman Mat_SuperLU *lu; 4396849ba73SBarry Smith PetscErrorCode ierr; 4402a4c71feSBarry Smith PetscInt m=A->rmap.n,n=A->cmap.n,indx; 4419ce50919SHong Zhang PetscTruth flg; 4425ca28756SHong Zhang const char *colperm[]={"NATURAL","MMD_ATA","MMD_AT_PLUS_A","COLAMD"}; /* MY_PERMC - not supported by the petsc interface yet */ 4435ca28756SHong Zhang const char *iterrefine[]={"NOREFINE", "SINGLE", "DOUBLE", "EXTRA"}; 4445ca28756SHong Zhang const char *rowperm[]={"NOROWPERM", "LargeDiag"}; /* MY_PERMC - not supported by the petsc interface yet */ 44514b396bbSKris Buschelman 44614b396bbSKris Buschelman PetscFunctionBegin; 447f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&B);CHKERRQ(ierr); 4482a4c71feSBarry Smith ierr = MatSetSizes(B,A->rmap.n,A->cmap.n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 449be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 450899d7b4fSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 451f0c56d0fSKris Buschelman 452f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SuperLU; 453f0c56d0fSKris Buschelman B->ops->solve = MatSolve_SuperLU; 454c7c1fe80SHong Zhang B->ops->solvetranspose = MatSolveTranspose_SuperLU; 45514b396bbSKris Buschelman B->factor = FACTOR_LU; 45694b7f48cSBarry Smith B->assembled = PETSC_TRUE; /* required by -ksp_view */ 45714b396bbSKris Buschelman 458f0c56d0fSKris Buschelman lu = (Mat_SuperLU*)(B->spptr); 4599ce50919SHong Zhang 4609ce50919SHong Zhang /* Set SuperLU options */ 4619ce50919SHong Zhang /* the default values for options argument: 4629ce50919SHong Zhang options.Fact = DOFACT; 4639ce50919SHong Zhang options.Equil = YES; 4649ce50919SHong Zhang options.ColPerm = COLAMD; 4659ce50919SHong Zhang options.DiagPivotThresh = 1.0; 4669ce50919SHong Zhang options.Trans = NOTRANS; 4679ce50919SHong Zhang options.IterRefine = NOREFINE; 4689ce50919SHong Zhang options.SymmetricMode = NO; 4699ce50919SHong Zhang options.PivotGrowth = NO; 4709ce50919SHong Zhang options.ConditionNumber = NO; 4719ce50919SHong Zhang options.PrintStat = YES; 4729ce50919SHong Zhang */ 4739ce50919SHong Zhang set_default_options(&lu->options); 4748914a3f7SHong Zhang /* equilibration causes error in solve(), thus not supported here. See dgssvx.c for possible reason. */ 4758914a3f7SHong Zhang lu->options.Equil = NO; 4769ce50919SHong Zhang lu->options.PrintStat = NO; 4778914a3f7SHong Zhang lu->lwork = 0; /* allocate space internally by system malloc */ 4789ce50919SHong Zhang 4799ce50919SHong Zhang ierr = PetscOptionsBegin(A->comm,A->prefix,"SuperLU Options","Mat");CHKERRQ(ierr); 4808914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_colperm","ColPerm","None",colperm,4,colperm[3],&indx,&flg);CHKERRQ(ierr); 4819ce50919SHong Zhang if (flg) {lu->options.ColPerm = (colperm_t)indx;} 4828914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_iterrefine","IterRefine","None",iterrefine,4,iterrefine[0],&indx,&flg);CHKERRQ(ierr); 4839ce50919SHong Zhang if (flg) { lu->options.IterRefine = (IterRefine_t)indx;} 4844dc4c822SBarry Smith ierr = PetscOptionsTruth("-mat_superlu_symmetricmode","SymmetricMode","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 4859ce50919SHong Zhang if (flg) lu->options.SymmetricMode = YES; 4868914a3f7SHong Zhang ierr = PetscOptionsReal("-mat_superlu_diagpivotthresh","DiagPivotThresh","None",lu->options.DiagPivotThresh,&lu->options.DiagPivotThresh,PETSC_NULL);CHKERRQ(ierr); 4874dc4c822SBarry Smith ierr = PetscOptionsTruth("-mat_superlu_pivotgrowth","PivotGrowth","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 4889ce50919SHong Zhang if (flg) lu->options.PivotGrowth = YES; 4894dc4c822SBarry Smith ierr = PetscOptionsTruth("-mat_superlu_conditionnumber","ConditionNumber","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 4909ce50919SHong Zhang if (flg) lu->options.ConditionNumber = YES; 4918914a3f7SHong Zhang ierr = PetscOptionsEList("-mat_superlu_rowperm","rowperm","None",rowperm,2,rowperm[0],&indx,&flg);CHKERRQ(ierr); 4929ce50919SHong Zhang if (flg) {lu->options.RowPerm = (rowperm_t)indx;} 4934dc4c822SBarry Smith ierr = PetscOptionsTruth("-mat_superlu_replacetinypivot","ReplaceTinyPivot","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 4949ce50919SHong Zhang if (flg) lu->options.ReplaceTinyPivot = YES; 4954dc4c822SBarry Smith ierr = PetscOptionsTruth("-mat_superlu_printstat","PrintStat","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 4969ce50919SHong Zhang if (flg) lu->options.PrintStat = YES; 4978914a3f7SHong Zhang ierr = PetscOptionsInt("-mat_superlu_lwork","size of work array in bytes used by factorization","None",lu->lwork,&lu->lwork,PETSC_NULL);CHKERRQ(ierr); 4985fe6150dSHong Zhang if (lu->lwork > 0 ){ 4995fe6150dSHong Zhang ierr = PetscMalloc(lu->lwork,&lu->work);CHKERRQ(ierr); 5005fe6150dSHong Zhang } else if (lu->lwork != 0 && lu->lwork != -1){ 50177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," Warning: lwork %D is not supported by SUPERLU. The default lwork=0 is used.\n",lu->lwork); 5028914a3f7SHong Zhang lu->lwork = 0; 5038914a3f7SHong Zhang } 5049ce50919SHong Zhang PetscOptionsEnd(); 5059ce50919SHong Zhang 50675af56d4SHong Zhang #ifdef SUPERLU2 5072ecb5974SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatCreateNull","MatCreateNull_SuperLU", 508f0c56d0fSKris Buschelman (void(*)(void))MatCreateNull_SuperLU);CHKERRQ(ierr); 50975af56d4SHong Zhang #endif 51014b396bbSKris Buschelman 51175af56d4SHong Zhang /* Allocate spaces (notice sizes are for the transpose) */ 512da7a1d00SHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->etree);CHKERRQ(ierr); 513da7a1d00SHong Zhang ierr = PetscMalloc(n*sizeof(PetscInt),&lu->perm_r);CHKERRQ(ierr); 514da7a1d00SHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->perm_c);CHKERRQ(ierr); 515da7a1d00SHong Zhang ierr = PetscMalloc(n*sizeof(PetscInt),&lu->R);CHKERRQ(ierr); 516da7a1d00SHong Zhang ierr = PetscMalloc(m*sizeof(PetscInt),&lu->C);CHKERRQ(ierr); 51775af56d4SHong Zhang 5189ce50919SHong Zhang /* create rhs and solution x without allocate space for .Store */ 5195fe6150dSHong Zhang #if defined(PETSC_USE_COMPLEX) 520937a6b0eSHong Zhang zCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 521937a6b0eSHong Zhang zCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 5225fe6150dSHong Zhang #else 52375af56d4SHong Zhang dCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 52475af56d4SHong Zhang dCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 5255fe6150dSHong Zhang #endif 52614b396bbSKris Buschelman 52714b396bbSKris Buschelman lu->flg = DIFFERENT_NONZERO_PATTERN; 528e740cb95SKris Buschelman lu->CleanUpSuperLU = PETSC_TRUE; 529899d7b4fSKris Buschelman 530899d7b4fSKris Buschelman *F = B; 5312a4c71feSBarry Smith ierr = PetscLogObjectMemory(B,(A->rmap.n+A->cmap.n)*sizeof(PetscInt)+sizeof(Mat_SuperLU));CHKERRQ(ierr); 53214b396bbSKris Buschelman PetscFunctionReturn(0); 53314b396bbSKris Buschelman } 53414b396bbSKris Buschelman 535f0c56d0fSKris Buschelman 536f0c56d0fSKris Buschelman #undef __FUNCT__ 537f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_SuperLU" 538dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SuperLU(Mat A, MatDuplicateOption op, Mat *M) { 539da7a1d00SHong Zhang PetscErrorCode ierr; 5408f340917SKris Buschelman Mat_SuperLU *lu=(Mat_SuperLU *)A->spptr; 5418f340917SKris Buschelman 54214b396bbSKris Buschelman PetscFunctionBegin; 5438f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 5443f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_SuperLU));CHKERRQ(ierr); 54514b396bbSKris Buschelman PetscFunctionReturn(0); 54614b396bbSKris Buschelman } 54714b396bbSKris Buschelman 548b0592601SKris Buschelman 54924b6179bSKris Buschelman /*MC 550fafad747SKris Buschelman MATSUPERLU - MATSUPERLU = "superlu" - A matrix type providing direct solvers (LU) for sequential matrices 55124b6179bSKris Buschelman via the external package SuperLU. 55224b6179bSKris Buschelman 55324b6179bSKris Buschelman If SuperLU is installed (see the manual for 55424b6179bSKris Buschelman instructions on how to declare the existence of external packages), 55524b6179bSKris Buschelman a matrix type can be constructed which invokes SuperLU solvers. 55624b6179bSKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATSUPERLU). 55724b6179bSKris Buschelman 55824b6179bSKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 55928b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 56028b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 56124b6179bSKris Buschelman 56224b6179bSKris Buschelman Options Database Keys: 5630bad9183SKris Buschelman + -mat_type superlu - sets the matrix type to "superlu" during a call to MatSetFromOptions() 56451678082SBarry Smith . -mat_superlu_ordering <0,1,2,3> - 0: natural ordering, 56524b6179bSKris Buschelman 1: MMD applied to A'*A, 56624b6179bSKris Buschelman 2: MMD applied to A'+A, 56724b6179bSKris Buschelman 3: COLAMD, approximate minimum degree column ordering 56851678082SBarry Smith . -mat_superlu_iterrefine - have SuperLU do iterative refinement after the triangular solve 56951678082SBarry Smith choices: NOREFINE, SINGLE, DOUBLE, EXTRA; default is NOREFINE 57051678082SBarry Smith - -mat_superlu_printstat - print SuperLU statistics about the factorization 57124b6179bSKris Buschelman 57224b6179bSKris Buschelman Level: beginner 57324b6179bSKris Buschelman 57424b6179bSKris Buschelman .seealso: PCLU 57524b6179bSKris Buschelman M*/ 57624b6179bSKris Buschelman 5775a46d3faSBarry Smith /* 5785a46d3faSBarry Smith Constructor for the new derived matrix class. It simply creates the base 5795a46d3faSBarry Smith matrix class and then adds the additional information/methods needed by SuperLU. 5805a46d3faSBarry Smith */ 581b0592601SKris Buschelman EXTERN_C_BEGIN 582b0592601SKris Buschelman #undef __FUNCT__ 583f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_SuperLU" 584be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SuperLU(Mat A) 585dfbe8321SBarry Smith { 586dfbe8321SBarry Smith PetscErrorCode ierr; 587b0592601SKris Buschelman 588b0592601SKris Buschelman PetscFunctionBegin; 589b0592601SKris Buschelman ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); 590ceb03754SKris Buschelman ierr = MatConvert_SeqAIJ_SuperLU(A,MATSUPERLU,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 59114b396bbSKris Buschelman PetscFunctionReturn(0); 59214b396bbSKris Buschelman } 59314b396bbSKris Buschelman EXTERN_C_END 594