xref: /petsc/src/mat/impls/aij/seq/superlu/superlu.c (revision e32f2f54e699d0aa6e733466c00da7e34666fe5e)
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 */
187c4f633dSBarry Smith #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;
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 */
5314b396bbSKris Buschelman   PetscTruth 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 {
176*e32f2f54SBarry 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);
1865a46d3faSBarry Smith     } else {
1875a46d3faSBarry Smith       ierr = PetscPrintf(PETSC_COMM_SELF,"  Warning: gssvx() returns info %D\n",sinfo);
1885a46d3faSBarry Smith     }
1895a46d3faSBarry Smith   } else { /* sinfo < 0 */
190*e32f2f54SBarry Smith     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", sinfo,-sinfo);
1915a46d3faSBarry Smith   }
1925a46d3faSBarry Smith 
1935a46d3faSBarry Smith   if ( lu->options.PrintStat ) {
1945a46d3faSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF,"MatLUFactorNumeric_SuperLU():\n");
1955d8b2efaSHong Zhang     StatPrint(&lu->stat);
1965a46d3faSBarry Smith     Lstore = (SCformat *) lu->L.Store;
1975a46d3faSBarry Smith     Ustore = (NCformat *) lu->U.Store;
1985a46d3faSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF,"  No of nonzeros in factor L = %D\n", Lstore->nnz);
1995a46d3faSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF,"  No of nonzeros in factor U = %D\n", Ustore->nnz);
2005a46d3faSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF,"  No of nonzeros in L+U = %D\n", Lstore->nnz + Ustore->nnz - lu->A.ncol);
2016da386baSHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"  L\\U MB %.3f\ttotal MB needed %.3f\n",
2026da386baSHong Zhang 	       lu->mem_usage.for_lu/1e6, lu->mem_usage.total_needed/1e6);
2035a46d3faSBarry Smith   }
2045a46d3faSBarry Smith 
2055a46d3faSBarry Smith   lu->flg = SAME_NONZERO_PATTERN;
206719d5645SBarry Smith   (F)->ops->solve          = MatSolve_SuperLU;
207719d5645SBarry Smith   (F)->ops->solvetranspose = MatSolveTranspose_SuperLU;
2085a46d3faSBarry Smith   PetscFunctionReturn(0);
2095a46d3faSBarry Smith }
2105a46d3faSBarry Smith 
21114b396bbSKris Buschelman #undef __FUNCT__
212f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_SuperLU"
213dfbe8321SBarry Smith PetscErrorCode MatDestroy_SuperLU(Mat A)
21414b396bbSKris Buschelman {
215dfbe8321SBarry Smith   PetscErrorCode ierr;
216f0c56d0fSKris Buschelman   Mat_SuperLU    *lu=(Mat_SuperLU*)A->spptr;
21714b396bbSKris Buschelman 
21814b396bbSKris Buschelman   PetscFunctionBegin;
21975af56d4SHong Zhang   if (lu->CleanUpSuperLU) { /* Free the SuperLU datastructures */
22075af56d4SHong Zhang     Destroy_SuperMatrix_Store(&lu->A);
22175af56d4SHong Zhang     Destroy_SuperMatrix_Store(&lu->B);
22275af56d4SHong Zhang     Destroy_SuperMatrix_Store(&lu->X);
2235d8b2efaSHong Zhang     StatFree(&lu->stat);
2249ce50919SHong Zhang 
2259ce50919SHong Zhang     ierr = PetscFree(lu->etree);CHKERRQ(ierr);
2269ce50919SHong Zhang     ierr = PetscFree(lu->perm_r);CHKERRQ(ierr);
2279ce50919SHong Zhang     ierr = PetscFree(lu->perm_c);CHKERRQ(ierr);
2289ce50919SHong Zhang     ierr = PetscFree(lu->R);CHKERRQ(ierr);
2299ce50919SHong Zhang     ierr = PetscFree(lu->C);CHKERRQ(ierr);
23075af56d4SHong Zhang     if ( lu->lwork >= 0 ) {
231fb3e25aaSKris Buschelman       Destroy_SuperNode_Matrix(&lu->L);
232fb3e25aaSKris Buschelman       Destroy_CompCol_Matrix(&lu->U);
23375af56d4SHong Zhang     }
234fb3e25aaSKris Buschelman   }
235b24902e0SBarry Smith   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
236cae5a23dSHong Zhang   if (lu->A_dup){ierr = MatDestroy(lu->A_dup);CHKERRQ(ierr);}
237cae5a23dSHong Zhang   if (lu->rhs_dup){ierr = PetscFree(lu->rhs_dup);CHKERRQ(ierr);}
23814b396bbSKris Buschelman   PetscFunctionReturn(0);
23914b396bbSKris Buschelman }
24014b396bbSKris Buschelman 
24114b396bbSKris Buschelman #undef __FUNCT__
242f0c56d0fSKris Buschelman #define __FUNCT__ "MatView_SuperLU"
243dfbe8321SBarry Smith PetscErrorCode MatView_SuperLU(Mat A,PetscViewer viewer)
24414b396bbSKris Buschelman {
245dfbe8321SBarry Smith   PetscErrorCode    ierr;
24632077d6dSBarry Smith   PetscTruth        iascii;
24714b396bbSKris Buschelman   PetscViewerFormat format;
24814b396bbSKris Buschelman 
24914b396bbSKris Buschelman   PetscFunctionBegin;
250b24902e0SBarry Smith   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
25114b396bbSKris Buschelman 
25232077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
25332077d6dSBarry Smith   if (iascii) {
25414b396bbSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
2552f59403fSHong Zhang     if (format == PETSC_VIEWER_ASCII_INFO) {
256f0c56d0fSKris Buschelman       ierr = MatFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr);
25714b396bbSKris Buschelman     }
25814b396bbSKris Buschelman   }
25914b396bbSKris Buschelman   PetscFunctionReturn(0);
26014b396bbSKris Buschelman }
26114b396bbSKris Buschelman 
26214b396bbSKris Buschelman 
26314b396bbSKris Buschelman #undef __FUNCT__
264c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU_Private"
265c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU_Private(Mat A,Vec b,Vec x)
26614b396bbSKris Buschelman {
267f0c56d0fSKris Buschelman   Mat_SuperLU    *lu = (Mat_SuperLU*)A->spptr;
26875af56d4SHong Zhang   PetscScalar    *barray,*xarray;
269dfbe8321SBarry Smith   PetscErrorCode ierr;
270cae5a23dSHong Zhang   PetscInt       info,i,n=x->map->n;
271da7a1d00SHong Zhang   PetscReal      ferr,berr;
27214b396bbSKris Buschelman 
27314b396bbSKris Buschelman   PetscFunctionBegin;
274937a6b0eSHong Zhang   if ( lu->lwork == -1 ) {
275937a6b0eSHong Zhang     PetscFunctionReturn(0);
276937a6b0eSHong Zhang   }
277cae5a23dSHong Zhang 
27875af56d4SHong Zhang   lu->B.ncol = 1;   /* Set the number of right-hand side */
279cae5a23dSHong Zhang   if (lu->options.Equil && !lu->rhs_dup){
280cae5a23dSHong Zhang     /* superlu overwrites b when Equil is used, thus create rhs_dup to keep user's b unchanged */
281cae5a23dSHong Zhang     ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->rhs_dup);CHKERRQ(ierr);
282cae5a23dSHong Zhang   }
283cae5a23dSHong Zhang   if (lu->options.Equil){
284cae5a23dSHong Zhang     /* Copy b into rsh_dup */
28575af56d4SHong Zhang     ierr = VecGetArray(b,&barray);CHKERRQ(ierr);
286cae5a23dSHong Zhang     ierr = PetscMemcpy(lu->rhs_dup,barray,n*sizeof(PetscScalar));CHKERRQ(ierr);
287cae5a23dSHong Zhang     ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr);
288cae5a23dSHong Zhang     barray = lu->rhs_dup;
289cae5a23dSHong Zhang   } else {
290cae5a23dSHong Zhang     ierr = VecGetArray(b,&barray);CHKERRQ(ierr);
291cae5a23dSHong Zhang   }
29275af56d4SHong Zhang   ierr = VecGetArray(x,&xarray);CHKERRQ(ierr);
2935fe6150dSHong Zhang 
2945fe6150dSHong Zhang #if defined(PETSC_USE_COMPLEX)
2955fe6150dSHong Zhang   ((DNformat*)lu->B.Store)->nzval = (doublecomplex*)barray;
2965fe6150dSHong Zhang   ((DNformat*)lu->X.Store)->nzval = (doublecomplex*)xarray;
2975fe6150dSHong Zhang #else
2985fe6150dSHong Zhang   ((DNformat*)lu->B.Store)->nzval = barray;
29975af56d4SHong Zhang   ((DNformat*)lu->X.Store)->nzval = xarray;
3005fe6150dSHong Zhang #endif
30175af56d4SHong Zhang 
30275af56d4SHong Zhang   lu->options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */
303d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU){
3048914a3f7SHong Zhang #if defined(PETSC_USE_COMPLEX)
3058914a3f7SHong Zhang     zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C,
3068914a3f7SHong Zhang            &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr,
3075d8b2efaSHong Zhang            &lu->mem_usage, &lu->stat, &info);
3088914a3f7SHong Zhang #else
30975af56d4SHong Zhang     dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C,
31075af56d4SHong 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 #endif
313d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_ILU){
314cffbb591SHong Zhang #if defined(PETSC_USE_COMPLEX)
315cffbb591SHong Zhang     zgsisx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C,
316cffbb591SHong Zhang            &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond,
3175d8b2efaSHong Zhang            &lu->mem_usage, &lu->stat, &info);
318cffbb591SHong Zhang #else
319cffbb591SHong Zhang     dgsisx(&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 #endif
323cffbb591SHong Zhang   } else {
324*e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported");
325cffbb591SHong Zhang   }
326cae5a23dSHong Zhang   if (!lu->options.Equil){
32775af56d4SHong Zhang     ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr);
328cae5a23dSHong Zhang   }
32975af56d4SHong Zhang   ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr);
33075af56d4SHong Zhang 
331958c9bccSBarry Smith   if ( !info || info == lu->A.ncol+1 ) {
33275af56d4SHong Zhang     if ( lu->options.IterRefine ) {
3338914a3f7SHong Zhang       ierr = PetscPrintf(PETSC_COMM_SELF,"Iterative Refinement:\n");
3348914a3f7SHong Zhang       ierr = PetscPrintf(PETSC_COMM_SELF,"  %8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR");
33575af56d4SHong Zhang       for (i = 0; i < 1; ++i)
3365d8b2efaSHong Zhang         ierr = PetscPrintf(PETSC_COMM_SELF,"  %8d%8d%16e%16e\n", i+1, lu->stat.RefineSteps, ferr, berr);
33775af56d4SHong Zhang     }
3388914a3f7SHong Zhang   } else if ( info > 0 ){
3398914a3f7SHong Zhang     if ( lu->lwork == -1 ) {
34077431f27SBarry Smith       ierr = PetscPrintf(PETSC_COMM_SELF,"  ** Estimated memory: %D bytes\n", info - lu->A.ncol);
3418914a3f7SHong Zhang     } else {
34277431f27SBarry Smith       ierr = PetscPrintf(PETSC_COMM_SELF,"  Warning: gssvx() returns info %D\n",info);
3438914a3f7SHong Zhang     }
3448914a3f7SHong Zhang   } else if (info < 0){
345*e32f2f54SBarry Smith     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", info,-info);
34614b396bbSKris Buschelman   }
34714b396bbSKris Buschelman 
3488914a3f7SHong Zhang   if ( lu->options.PrintStat ) {
3498914a3f7SHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve__SuperLU():\n");
3505d8b2efaSHong Zhang     StatPrint(&lu->stat);
3518914a3f7SHong Zhang   }
35275af56d4SHong Zhang   PetscFunctionReturn(0);
35375af56d4SHong Zhang }
35414b396bbSKris Buschelman 
35514b396bbSKris Buschelman #undef __FUNCT__
356c29e884eSHong Zhang #define __FUNCT__ "MatSolve_SuperLU"
357c29e884eSHong Zhang PetscErrorCode MatSolve_SuperLU(Mat A,Vec b,Vec x)
358c29e884eSHong Zhang {
359c29e884eSHong Zhang   Mat_SuperLU    *lu = (Mat_SuperLU*)A->spptr;
360c29e884eSHong Zhang   PetscErrorCode ierr;
361c29e884eSHong Zhang 
362c29e884eSHong Zhang   PetscFunctionBegin;
363c29e884eSHong Zhang   lu->options.Trans = TRANS;
364c29e884eSHong Zhang   ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr);
365c29e884eSHong Zhang   PetscFunctionReturn(0);
366c29e884eSHong Zhang }
367c29e884eSHong Zhang 
368c29e884eSHong Zhang #undef __FUNCT__
369c7c1fe80SHong Zhang #define __FUNCT__ "MatSolveTranspose_SuperLU"
370c7c1fe80SHong Zhang PetscErrorCode MatSolveTranspose_SuperLU(Mat A,Vec b,Vec x)
371c7c1fe80SHong Zhang {
372c7c1fe80SHong Zhang   Mat_SuperLU    *lu = (Mat_SuperLU*)A->spptr;
373c7c1fe80SHong Zhang   PetscErrorCode ierr;
374c7c1fe80SHong Zhang 
375c7c1fe80SHong Zhang   PetscFunctionBegin;
376c7c1fe80SHong Zhang   lu->options.Trans = NOTRANS;
377c29e884eSHong Zhang   ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr);
378c7c1fe80SHong Zhang   PetscFunctionReturn(0);
379c7c1fe80SHong Zhang }
380c7c1fe80SHong Zhang 
38114b396bbSKris Buschelman /*
38214b396bbSKris Buschelman    Note the r permutation is ignored
38314b396bbSKris Buschelman */
38414b396bbSKris Buschelman #undef __FUNCT__
385f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_SuperLU"
3860481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
38714b396bbSKris Buschelman {
388719d5645SBarry Smith   Mat_SuperLU    *lu = (Mat_SuperLU*)((F)->spptr);
389b24902e0SBarry Smith 
390b24902e0SBarry Smith   PetscFunctionBegin;
391b24902e0SBarry Smith   lu->flg                   = DIFFERENT_NONZERO_PATTERN;
392b24902e0SBarry Smith   lu->CleanUpSuperLU        = PETSC_TRUE;
393719d5645SBarry Smith   (F)->ops->lufactornumeric = MatLUFactorNumeric_SuperLU;
394b24902e0SBarry Smith   PetscFunctionReturn(0);
395b24902e0SBarry Smith }
396b24902e0SBarry Smith 
39735bd34faSBarry Smith EXTERN_C_BEGIN
39835bd34faSBarry Smith #undef __FUNCT__
39935bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_superlu"
40035bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_superlu(Mat A,const MatSolverPackage *type)
40135bd34faSBarry Smith {
40235bd34faSBarry Smith   PetscFunctionBegin;
40335bd34faSBarry Smith   *type = MAT_SOLVER_SUPERLU;
40435bd34faSBarry Smith   PetscFunctionReturn(0);
40535bd34faSBarry Smith }
40635bd34faSBarry Smith EXTERN_C_END
40735bd34faSBarry Smith 
408b24902e0SBarry Smith 
409b24902e0SBarry Smith /*MC
410b5e56a35SBarry Smith   MAT_SOLVER_SUPERLU = "superlu" - A solver package roviding direct solvers (LU) for sequential matrices
411b24902e0SBarry Smith   via the external package SuperLU.
412b24902e0SBarry Smith 
413e2e64c6bSBarry Smith   Use ./configure --download-superlu to have PETSc installed with SuperLU
414b24902e0SBarry Smith 
415b24902e0SBarry Smith   Options Database Keys:
4165c9eb25fSBarry Smith + -mat_superlu_ordering <0,1,2,3> - 0: natural ordering,
417b24902e0SBarry Smith                                     1: MMD applied to A'*A,
418b24902e0SBarry Smith                                     2: MMD applied to A'+A,
419b24902e0SBarry Smith                                     3: COLAMD, approximate minimum degree column ordering
420b24902e0SBarry Smith . -mat_superlu_iterrefine - have SuperLU do iterative refinement after the triangular solve
421b24902e0SBarry Smith                           choices: NOREFINE, SINGLE, DOUBLE, EXTRA; default is NOREFINE
422b24902e0SBarry Smith - -mat_superlu_printstat - print SuperLU statistics about the factorization
423b24902e0SBarry Smith 
4245c9eb25fSBarry Smith    Notes: Do not confuse this with MAT_SOLVER_SUPERLU_DIST which is for parallel sparse solves
4255c9eb25fSBarry Smith 
426b24902e0SBarry Smith    Level: beginner
427b24902e0SBarry Smith 
42841c8de11SBarry Smith .seealso: PCLU, MAT_SOLVER_SUPERLU_DIST, MAT_SOLVER_MUMPS, MAT_SOLVER_SPOOLES, PCFactorSetMatSolverPackage(), MatSolverPackage
429b24902e0SBarry Smith M*/
430b24902e0SBarry Smith 
4315c9eb25fSBarry Smith EXTERN_C_BEGIN
432b24902e0SBarry Smith #undef __FUNCT__
433b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_superlu"
4345c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_superlu(Mat A,MatFactorType ftype,Mat *F)
435b24902e0SBarry Smith {
43614b396bbSKris Buschelman   Mat            B;
437f0c56d0fSKris Buschelman   Mat_SuperLU    *lu;
4386849ba73SBarry Smith   PetscErrorCode ierr;
4395d8b2efaSHong Zhang   PetscInt       indx,m=A->rmap->n,n=A->cmap->n;
4409ce50919SHong Zhang   PetscTruth     flg;
4415ca28756SHong Zhang   const char     *colperm[]={"NATURAL","MMD_ATA","MMD_AT_PLUS_A","COLAMD"}; /* MY_PERMC - not supported by the petsc interface yet */
4425ca28756SHong Zhang   const char     *iterrefine[]={"NOREFINE", "SINGLE", "DOUBLE", "EXTRA"};
4435ca28756SHong Zhang   const char     *rowperm[]={"NOROWPERM", "LargeDiag"}; /* MY_PERMC - not supported by the petsc interface yet */
44414b396bbSKris Buschelman 
44514b396bbSKris Buschelman   PetscFunctionBegin;
4467adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
447d0f46423SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
4487adad957SLisandro Dalcin   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
449899d7b4fSKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
450f0c56d0fSKris Buschelman 
451cffbb591SHong Zhang   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU){
452b24902e0SBarry Smith     B->ops->lufactorsymbolic  = MatLUFactorSymbolic_SuperLU;
453cffbb591SHong Zhang     B->ops->ilufactorsymbolic = MatLUFactorSymbolic_SuperLU;
454cffbb591SHong Zhang   } else {
455*e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported");
456cffbb591SHong Zhang   }
457cffbb591SHong Zhang 
458b24902e0SBarry Smith   B->ops->destroy          = MatDestroy_SuperLU;
4593519fcdcSHong Zhang   B->ops->view             = MatView_SuperLU;
460d5f3da31SBarry Smith   B->factortype            = ftype;
46194b7f48cSBarry Smith   B->assembled             = PETSC_TRUE;  /* required by -ksp_view */
4625c9eb25fSBarry Smith   B->preallocated          = PETSC_TRUE;
46314b396bbSKris Buschelman 
464b24902e0SBarry Smith   ierr = PetscNewLog(B,Mat_SuperLU,&lu);CHKERRQ(ierr);
465cae5a23dSHong Zhang 
466cffbb591SHong Zhang   if (ftype == MAT_FACTOR_LU){
4679ce50919SHong Zhang     set_default_options(&lu->options);
468cffbb591SHong Zhang   } else if (ftype == MAT_FACTOR_ILU){
469cffbb591SHong Zhang     /* Set the default input options of ilu:
470cffbb591SHong Zhang 	options.Fact = DOFACT;
471cffbb591SHong Zhang 	options.Equil = YES;
472cffbb591SHong Zhang 	options.ColPerm = COLAMD;
473cffbb591SHong Zhang 	options.DiagPivotThresh = 0.1; //different from complete LU
474cffbb591SHong Zhang 	options.Trans = NOTRANS;
475cffbb591SHong Zhang 	options.IterRefine = NOREFINE;
476cffbb591SHong Zhang 	options.SymmetricMode = NO;
477cffbb591SHong Zhang 	options.PivotGrowth = NO;
478cffbb591SHong Zhang 	options.ConditionNumber = NO;
479cffbb591SHong Zhang 	options.PrintStat = YES;
480cffbb591SHong Zhang 	options.RowPerm = LargeDiag;
481cffbb591SHong Zhang 	options.ILU_DropTol = 1e-4;
482cffbb591SHong Zhang 	options.ILU_FillTol = 1e-2;
483cffbb591SHong Zhang 	options.ILU_FillFactor = 10.0;
484cffbb591SHong Zhang 	options.ILU_DropRule = DROP_BASIC | DROP_AREA;
485cffbb591SHong Zhang 	options.ILU_Norm = INF_NORM;
486cffbb591SHong Zhang 	options.ILU_MILU = SMILU_2;
487cffbb591SHong Zhang     */
4881a2e2f44SHong Zhang 
489cffbb591SHong Zhang     ilu_set_default_options(&lu->options);
490cffbb591SHong Zhang   }
491cae5a23dSHong Zhang   /* Comments from SuperLU_4.0/SRC/dgssvx.c:
492cae5a23dSHong Zhang       "Whether or not the system will be equilibrated depends on the
493cae5a23dSHong Zhang        scaling of the matrix A, but if equilibration is used, A is
494cae5a23dSHong Zhang        overwritten by diag(R)*A*diag(C) and B by diag(R)*B
495cae5a23dSHong Zhang        (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans = TRANS or CONJ)."
496cae5a23dSHong Zhang      We set 'options.Equil = NO' as default because additional space is needed for it.
497cae5a23dSHong Zhang   */
4981a2e2f44SHong Zhang   lu->options.Equil     = NO;
4999ce50919SHong Zhang   lu->options.PrintStat = NO;
5001a2e2f44SHong Zhang 
5015d8b2efaSHong Zhang   /* Initialize the statistics variables. */
5025d8b2efaSHong Zhang   StatInit(&lu->stat);
5038914a3f7SHong Zhang   lu->lwork = 0;   /* allocate space internally by system malloc */
5049ce50919SHong Zhang 
5057adad957SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"SuperLU Options","Mat");CHKERRQ(ierr);
506cffbb591SHong Zhang     ierr = PetscOptionsTruth("-mat_superlu_equil","Equil","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
507cae5a23dSHong Zhang     if (flg) { /* superlu overwrites input matrix and rhs when Equil is used, thus create A_dup to keep user's A unchanged */
508cae5a23dSHong Zhang       lu->options.Equil = YES;
509cae5a23dSHong Zhang       ierr = MatDuplicate_SeqAIJ(A,MAT_COPY_VALUES,&lu->A_dup);CHKERRQ(ierr);
510cae5a23dSHong Zhang     }
5118914a3f7SHong Zhang     ierr = PetscOptionsEList("-mat_superlu_colperm","ColPerm","None",colperm,4,colperm[3],&indx,&flg);CHKERRQ(ierr);
5129ce50919SHong Zhang     if (flg) {lu->options.ColPerm = (colperm_t)indx;}
5138914a3f7SHong Zhang     ierr = PetscOptionsEList("-mat_superlu_iterrefine","IterRefine","None",iterrefine,4,iterrefine[0],&indx,&flg);CHKERRQ(ierr);
5149ce50919SHong Zhang     if (flg) { lu->options.IterRefine = (IterRefine_t)indx;}
5154dc4c822SBarry Smith     ierr = PetscOptionsTruth("-mat_superlu_symmetricmode","SymmetricMode","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
5169ce50919SHong Zhang     if (flg) lu->options.SymmetricMode = YES;
5178914a3f7SHong Zhang     ierr = PetscOptionsReal("-mat_superlu_diagpivotthresh","DiagPivotThresh","None",lu->options.DiagPivotThresh,&lu->options.DiagPivotThresh,PETSC_NULL);CHKERRQ(ierr);
5184dc4c822SBarry Smith     ierr = PetscOptionsTruth("-mat_superlu_pivotgrowth","PivotGrowth","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
5199ce50919SHong Zhang     if (flg) lu->options.PivotGrowth = YES;
5204dc4c822SBarry Smith     ierr = PetscOptionsTruth("-mat_superlu_conditionnumber","ConditionNumber","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
5219ce50919SHong Zhang     if (flg) lu->options.ConditionNumber = YES;
5228914a3f7SHong Zhang     ierr = PetscOptionsEList("-mat_superlu_rowperm","rowperm","None",rowperm,2,rowperm[0],&indx,&flg);CHKERRQ(ierr);
5239ce50919SHong Zhang     if (flg) {lu->options.RowPerm = (rowperm_t)indx;}
5244dc4c822SBarry Smith     ierr = PetscOptionsTruth("-mat_superlu_replacetinypivot","ReplaceTinyPivot","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
5259ce50919SHong Zhang     if (flg) lu->options.ReplaceTinyPivot = YES;
5264dc4c822SBarry Smith     ierr = PetscOptionsTruth("-mat_superlu_printstat","PrintStat","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr);
5279ce50919SHong Zhang     if (flg) lu->options.PrintStat = YES;
5288914a3f7SHong Zhang     ierr = PetscOptionsInt("-mat_superlu_lwork","size of work array in bytes used by factorization","None",lu->lwork,&lu->lwork,PETSC_NULL);CHKERRQ(ierr);
5295fe6150dSHong Zhang     if (lu->lwork > 0 ){
5305fe6150dSHong Zhang       ierr = PetscMalloc(lu->lwork,&lu->work);CHKERRQ(ierr);
5315fe6150dSHong Zhang     } else if (lu->lwork != 0 && lu->lwork != -1){
53277431f27SBarry Smith       ierr = PetscPrintf(PETSC_COMM_SELF,"   Warning: lwork %D is not supported by SUPERLU. The default lwork=0 is used.\n",lu->lwork);
5338914a3f7SHong Zhang       lu->lwork = 0;
5348914a3f7SHong Zhang     }
535cffbb591SHong Zhang     /* ilu options */
536cffbb591SHong Zhang     ierr = PetscOptionsReal("-mat_superlu_ilu_droptol","ILU_DropTol","None",lu->options.ILU_DropTol,&lu->options.ILU_DropTol,PETSC_NULL);CHKERRQ(ierr);
537cffbb591SHong Zhang     ierr = PetscOptionsReal("-mat_superlu_ilu_filltol","ILU_FillTol","None",lu->options.ILU_FillTol,&lu->options.ILU_FillTol,PETSC_NULL);CHKERRQ(ierr);
538cffbb591SHong Zhang     ierr = PetscOptionsReal("-mat_superlu_ilu_fillfactor","ILU_FillFactor","None",lu->options.ILU_FillFactor,&lu->options.ILU_FillFactor,PETSC_NULL);CHKERRQ(ierr);
539cffbb591SHong Zhang     ierr = PetscOptionsInt("-mat_superlu_ilu_droprull","ILU_DropRule","None",lu->options.ILU_DropRule,&lu->options.ILU_DropRule,PETSC_NULL);CHKERRQ(ierr);
540cffbb591SHong Zhang     ierr = PetscOptionsInt("-mat_superlu_ilu_norm","ILU_Norm","None",lu->options.ILU_Norm,&indx,&flg);CHKERRQ(ierr);
541cffbb591SHong Zhang     if (flg){
542cffbb591SHong Zhang       lu->options.ILU_Norm = (norm_t)indx;
543cffbb591SHong Zhang     }
544cffbb591SHong Zhang     ierr = PetscOptionsInt("-mat_superlu_ilu_milu","ILU_MILU","None",lu->options.ILU_MILU,&indx,&flg);CHKERRQ(ierr);
545cffbb591SHong Zhang     if (flg){
546cffbb591SHong Zhang       lu->options.ILU_MILU = (milu_t)indx;
547cffbb591SHong Zhang     }
5489ce50919SHong Zhang   PetscOptionsEnd();
5499ce50919SHong Zhang 
5505d8b2efaSHong Zhang   /* Allocate spaces (notice sizes are for the transpose) */
5515d8b2efaSHong Zhang   ierr = PetscMalloc(m*sizeof(PetscInt),&lu->etree);CHKERRQ(ierr);
5525d8b2efaSHong Zhang   ierr = PetscMalloc(n*sizeof(PetscInt),&lu->perm_r);CHKERRQ(ierr);
5535d8b2efaSHong Zhang   ierr = PetscMalloc(m*sizeof(PetscInt),&lu->perm_c);CHKERRQ(ierr);
5545d8b2efaSHong Zhang   ierr = PetscMalloc(n*sizeof(PetscScalar),&lu->R);CHKERRQ(ierr);
5555d8b2efaSHong Zhang   ierr = PetscMalloc(m*sizeof(PetscScalar),&lu->C);CHKERRQ(ierr);
5565d8b2efaSHong Zhang 
5575d8b2efaSHong Zhang   /* create rhs and solution x without allocate space for .Store */
5585d8b2efaSHong Zhang #if defined(PETSC_USE_COMPLEX)
5595d8b2efaSHong Zhang   zCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE);
5605d8b2efaSHong Zhang   zCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE);
5615d8b2efaSHong Zhang #else
5625d8b2efaSHong Zhang   dCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE);
5635d8b2efaSHong Zhang   dCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE);
5645d8b2efaSHong Zhang #endif
5655d8b2efaSHong Zhang 
56675af56d4SHong Zhang #ifdef SUPERLU2
5675c9eb25fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatCreateNull","MatCreateNull_SuperLU",(void(*)(void))MatCreateNull_SuperLU);CHKERRQ(ierr);
56875af56d4SHong Zhang #endif
56935bd34faSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_superlu",MatFactorGetSolverPackage_seqaij_superlu);CHKERRQ(ierr);
5705c9eb25fSBarry Smith   B->spptr = lu;
571899d7b4fSKris Buschelman   *F = B;
57214b396bbSKris Buschelman   PetscFunctionReturn(0);
57314b396bbSKris Buschelman }
5745c9eb25fSBarry Smith EXTERN_C_END
575