xref: /petsc/src/mat/impls/aij/seq/klu/klu.c (revision a364b7d26afe6a9fe4d3c9eeadc618609f0680cd)
169e15a41SShri Abhyankar 
269e15a41SShri Abhyankar /*
369e15a41SShri Abhyankar    Provides an interface to the KLUv1.2 sparse solver
469e15a41SShri Abhyankar 
569e15a41SShri Abhyankar    When build with PETSC_USE_64BIT_INDICES this will use SuiteSparse_long as the
669e15a41SShri Abhyankar    integer type in KLU, otherwise it will use int. This means
769e15a41SShri Abhyankar    all integers in this file are simply declared as PetscInt. Also it means
869e15a41SShri Abhyankar    that KLU SuiteSparse_long version MUST be built with 64 bit integers when used.
969e15a41SShri Abhyankar 
1069e15a41SShri Abhyankar */
1169e15a41SShri Abhyankar #include <../src/mat/impls/aij/seq/aij.h>
1269e15a41SShri Abhyankar 
1369e15a41SShri Abhyankar #if defined(PETSC_USE_64BIT_INDICES)
1469e15a41SShri Abhyankar #define klu_K_defaults                klu_l_defaults
1569e15a41SShri Abhyankar #define klu_K_analyze                 klu_l_analyze
1669e15a41SShri Abhyankar #define klu_K_analyze_given           klu_l_analyze_given
1769e15a41SShri Abhyankar #define klu_K_free_symbolic           klu_l_free_symbolic
1869e15a41SShri Abhyankar #define klu_K_free_numeric            klu_l_free_numeric
1969e15a41SShri Abhyankar #define klu_K_common                  klu_l_common
2069e15a41SShri Abhyankar #define klu_K_symbolic                klu_l_symbolic
2169e15a41SShri Abhyankar #define klu_K_numeric                 klu_l_numeric
2269e15a41SShri Abhyankar #if defined(PETSC_USE_COMPLEX)
2369e15a41SShri Abhyankar #define klu_K_factor                  klu_zl_factor
2469e15a41SShri Abhyankar #define klu_K_solve                   klu_zl_solve
2569e15a41SShri Abhyankar #define klu_K_tsolve                  klu_zl_tsolve
2669e15a41SShri Abhyankar #define klu_K_refactor                klu_zl_refactor
2769e15a41SShri Abhyankar #define klu_K_sort                    klu_zl_sort
2869e15a41SShri Abhyankar #define klu_K_flops                   klu_zl_flops
2969e15a41SShri Abhyankar #define klu_K_rgrowth                 klu_zl_rgrowth
3069e15a41SShri Abhyankar #define klu_K_condest                 klu_zl_condest
3169e15a41SShri Abhyankar #define klu_K_rcond                   klu_zl_rcond
3269e15a41SShri Abhyankar #define klu_K_scale                   klu_zl_scale
3369e15a41SShri Abhyankar #else
3469e15a41SShri Abhyankar #define klu_K_factor                  klu_l_factor
3569e15a41SShri Abhyankar #define klu_K_solve                   klu_l_solve
3669e15a41SShri Abhyankar #define klu_K_tsolve                  klu_l_tsolve
3769e15a41SShri Abhyankar #define klu_K_refactor                klu_l_refactor
3869e15a41SShri Abhyankar #define klu_K_sort                    klu_l_sort
3969e15a41SShri Abhyankar #define klu_K_flops                   klu_l_flops
4069e15a41SShri Abhyankar #define klu_K_rgrowth                 klu_l_rgrowth
4169e15a41SShri Abhyankar #define klu_K_condest                 klu_l_condest
4269e15a41SShri Abhyankar #define klu_K_rcond                   klu_l_rcond
4369e15a41SShri Abhyankar #define klu_K_scale                   klu_l_scale
4469e15a41SShri Abhyankar #endif
4569e15a41SShri Abhyankar #else
4669e15a41SShri Abhyankar #define klu_K_defaults                klu_defaults
4769e15a41SShri Abhyankar #define klu_K_analyze                 klu_analyze
4869e15a41SShri Abhyankar #define klu_K_analyze_given           klu_analyze_given
4969e15a41SShri Abhyankar #define klu_K_free_symbolic           klu_free_symbolic
5069e15a41SShri Abhyankar #define klu_K_free_numeric            klu_free_numeric
5169e15a41SShri Abhyankar #define klu_K_common                  klu_common
5269e15a41SShri Abhyankar #define klu_K_symbolic                klu_symbolic
5369e15a41SShri Abhyankar #define klu_K_numeric                 klu_numeric
5469e15a41SShri Abhyankar #if defined(PETSC_USE_COMPLEX)
5569e15a41SShri Abhyankar #define klu_K_factor                  klu_z_factor
5669e15a41SShri Abhyankar #define klu_K_solve                   klu_z_solve
5769e15a41SShri Abhyankar #define klu_K_tsolve                  klu_z_tsolve
5869e15a41SShri Abhyankar #define klu_K_refactor                klu_z_refactor
5969e15a41SShri Abhyankar #define klu_K_sort                    klu_z_sort
6069e15a41SShri Abhyankar #define klu_K_flops                   klu_z_flops
6169e15a41SShri Abhyankar #define klu_K_rgrowth                 klu_z_rgrowth
6269e15a41SShri Abhyankar #define klu_K_condest                 klu_z_condest
6369e15a41SShri Abhyankar #define klu_K_rcond                   klu_z_rcond
6469e15a41SShri Abhyankar #define klu_K_scale                   klu_z_scale
6569e15a41SShri Abhyankar #else
6669e15a41SShri Abhyankar #define klu_K_factor                  klu_factor
6769e15a41SShri Abhyankar #define klu_K_solve                   klu_solve
6869e15a41SShri Abhyankar #define klu_K_tsolve                  klu_tsolve
6969e15a41SShri Abhyankar #define klu_K_refactor                klu_refactor
7069e15a41SShri Abhyankar #define klu_K_sort                    klu_sort
7169e15a41SShri Abhyankar #define klu_K_flops                   klu_flops
7269e15a41SShri Abhyankar #define klu_K_rgrowth                 klu_rgrowth
7369e15a41SShri Abhyankar #define klu_K_condest                 klu_condest
7469e15a41SShri Abhyankar #define klu_K_rcond                   klu_rcond
7569e15a41SShri Abhyankar #define klu_K_scale                   klu_scale
7669e15a41SShri Abhyankar #endif
7769e15a41SShri Abhyankar #endif
7869e15a41SShri Abhyankar 
7969e15a41SShri Abhyankar 
8069e15a41SShri Abhyankar #define SuiteSparse_long long long
8169e15a41SShri Abhyankar #define SuiteSparse_long_max LONG_LONG_MAX
8269e15a41SShri Abhyankar #define SuiteSparse_long_id "%lld"
8369e15a41SShri Abhyankar 
8469e15a41SShri Abhyankar EXTERN_C_BEGIN
8569e15a41SShri Abhyankar #include <klu.h>
8669e15a41SShri Abhyankar EXTERN_C_END
8769e15a41SShri Abhyankar 
8869e15a41SShri Abhyankar static const char *KluOrderingTypes[] = {"AMD","COLAMD","PETSC"};
8969e15a41SShri Abhyankar static const char *scale[] ={"NONE","SUM","MAX"};
9069e15a41SShri Abhyankar 
9169e15a41SShri Abhyankar typedef struct {
9269e15a41SShri Abhyankar   klu_K_common   Common;
9369e15a41SShri Abhyankar   klu_K_symbolic *Symbolic;
9469e15a41SShri Abhyankar   klu_K_numeric  *Numeric;
9569e15a41SShri Abhyankar   PetscInt     *perm_c,*perm_r;
9669e15a41SShri Abhyankar   MatStructure flg;
9769e15a41SShri Abhyankar   PetscBool    PetscMatOrdering;
9869e15a41SShri Abhyankar 
9969e15a41SShri Abhyankar   /* Flag to clean up KLU objects during Destroy */
10069e15a41SShri Abhyankar   PetscBool CleanUpKLU;
10169e15a41SShri Abhyankar } Mat_KLU;
10269e15a41SShri Abhyankar 
10369e15a41SShri Abhyankar #undef __FUNCT__
10469e15a41SShri Abhyankar #define __FUNCT__ "MatDestroy_KLU"
10569e15a41SShri Abhyankar static PetscErrorCode MatDestroy_KLU(Mat A)
10669e15a41SShri Abhyankar {
10769e15a41SShri Abhyankar   PetscErrorCode ierr;
10869e15a41SShri Abhyankar   Mat_KLU    *lu=(Mat_KLU*)A->spptr;
10969e15a41SShri Abhyankar 
11069e15a41SShri Abhyankar   PetscFunctionBegin;
11169e15a41SShri Abhyankar   if (lu && lu->CleanUpKLU) {
11269e15a41SShri Abhyankar     klu_K_free_symbolic(&lu->Symbolic,&lu->Common);
11369e15a41SShri Abhyankar     klu_K_free_numeric(&lu->Numeric,&lu->Common);
114828fd075SShri Abhyankar     ierr = PetscFree2(lu->perm_r,lu->perm_c);CHKERRQ(ierr);
11569e15a41SShri Abhyankar   }
11669e15a41SShri Abhyankar   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
11769e15a41SShri Abhyankar   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
11869e15a41SShri Abhyankar   PetscFunctionReturn(0);
11969e15a41SShri Abhyankar }
12069e15a41SShri Abhyankar 
12169e15a41SShri Abhyankar #undef __FUNCT__
12269e15a41SShri Abhyankar #define __FUNCT__ "MatSolveTranspose_KLU"
12369e15a41SShri Abhyankar static PetscErrorCode MatSolveTranspose_KLU(Mat A,Vec b,Vec x)
12469e15a41SShri Abhyankar {
12569e15a41SShri Abhyankar   Mat_KLU       *lu = (Mat_KLU*)A->spptr;
12669e15a41SShri Abhyankar   PetscScalar    *xa;
12769e15a41SShri Abhyankar   PetscErrorCode ierr;
12869e15a41SShri Abhyankar   PetscInt       status;
12969e15a41SShri Abhyankar 
13069e15a41SShri Abhyankar   PetscFunctionBegin;
13169e15a41SShri Abhyankar   /* KLU uses a column major format, solve Ax = b by klu_*_solve */
13269e15a41SShri Abhyankar   /* ----------------------------------*/
13369e15a41SShri Abhyankar   ierr = VecCopy(b,x); /* klu_solve stores the solution in rhs */
13469e15a41SShri Abhyankar   ierr = VecGetArray(x,&xa);
13569e15a41SShri Abhyankar   status = klu_K_solve(lu->Symbolic,lu->Numeric,A->rmap->n,1,(PetscReal*)xa,&lu->Common);
13669e15a41SShri Abhyankar   if (status != 1) {
13769e15a41SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"KLU Solve failed");
13869e15a41SShri Abhyankar   }
13969e15a41SShri Abhyankar   ierr = VecRestoreArray(x,&xa);CHKERRQ(ierr);
14069e15a41SShri Abhyankar   PetscFunctionReturn(0);
14169e15a41SShri Abhyankar }
14269e15a41SShri Abhyankar 
14369e15a41SShri Abhyankar #undef __FUNCT__
14469e15a41SShri Abhyankar #define __FUNCT__ "MatSolve_KLU"
14569e15a41SShri Abhyankar static PetscErrorCode MatSolve_KLU(Mat A,Vec b,Vec x)
14669e15a41SShri Abhyankar {
14769e15a41SShri Abhyankar   Mat_KLU       *lu = (Mat_KLU*)A->spptr;
14869e15a41SShri Abhyankar   PetscScalar    *xa;
14969e15a41SShri Abhyankar   PetscErrorCode ierr;
15069e15a41SShri Abhyankar   PetscInt       status;
15169e15a41SShri Abhyankar 
15269e15a41SShri Abhyankar   PetscFunctionBegin;
15369e15a41SShri Abhyankar   /* KLU uses a column major format, solve A^Tx = b by klu_*_tsolve */
15469e15a41SShri Abhyankar   /* ----------------------------------*/
15569e15a41SShri Abhyankar   ierr = VecCopy(b,x); /* klu_solve stores the solution in rhs */
15669e15a41SShri Abhyankar   ierr = VecGetArray(x,&xa);
15769e15a41SShri Abhyankar #if defined(PETSC_USE_COMPLEX)
15869e15a41SShri Abhyankar   PetscInt conj_solve=1;
15969e15a41SShri Abhyankar   status = klu_K_tsolve(lu->Symbolic,lu->Numeric,A->rmap->n,1,(PetscReal*)xa,conj_solve,&lu->Common); /* conjugate solve */
16069e15a41SShri Abhyankar #else
16169e15a41SShri Abhyankar   status = klu_K_tsolve(lu->Symbolic,lu->Numeric,A->rmap->n,1,xa,&lu->Common);
16269e15a41SShri Abhyankar #endif
16369e15a41SShri Abhyankar   if (status != 1) {
16469e15a41SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"KLU Solve failed");
16569e15a41SShri Abhyankar   }
16669e15a41SShri Abhyankar   ierr = VecRestoreArray(x,&xa);CHKERRQ(ierr);
16769e15a41SShri Abhyankar   PetscFunctionReturn(0);
16869e15a41SShri Abhyankar }
16969e15a41SShri Abhyankar 
17069e15a41SShri Abhyankar #undef __FUNCT__
17169e15a41SShri Abhyankar #define __FUNCT__ "MatLUFactorNumeric_KLU"
17269e15a41SShri Abhyankar static PetscErrorCode MatLUFactorNumeric_KLU(Mat F,Mat A,const MatFactorInfo *info)
17369e15a41SShri Abhyankar {
17469e15a41SShri Abhyankar   Mat_KLU        *lu = (Mat_KLU*)(F)->spptr;
17569e15a41SShri Abhyankar   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
17669e15a41SShri Abhyankar   PetscInt       *ai = a->i,*aj=a->j;
17769e15a41SShri Abhyankar   PetscScalar    *av = a->a;
17869e15a41SShri Abhyankar 
17969e15a41SShri Abhyankar   PetscFunctionBegin;
18069e15a41SShri Abhyankar   /* numeric factorization of A' */
18169e15a41SShri Abhyankar   /* ----------------------------*/
18269e15a41SShri Abhyankar 
18369e15a41SShri Abhyankar   if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric) {
18469e15a41SShri Abhyankar     klu_K_free_numeric(&lu->Numeric,&lu->Common);
18569e15a41SShri Abhyankar   }
18669e15a41SShri Abhyankar   lu->Numeric = klu_K_factor(ai,aj,(PetscReal*)av,lu->Symbolic,&lu->Common);
18769e15a41SShri Abhyankar   if(!lu->Numeric) {
18869e15a41SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"KLU Numeric factorization failed");
18969e15a41SShri Abhyankar   }
19069e15a41SShri Abhyankar 
19169e15a41SShri Abhyankar   lu->flg                = SAME_NONZERO_PATTERN;
19269e15a41SShri Abhyankar   lu->CleanUpKLU         = PETSC_TRUE;
19369e15a41SShri Abhyankar   F->ops->solve          = MatSolve_KLU;
19469e15a41SShri Abhyankar   F->ops->solvetranspose = MatSolveTranspose_KLU;
19569e15a41SShri Abhyankar   PetscFunctionReturn(0);
19669e15a41SShri Abhyankar }
19769e15a41SShri Abhyankar 
19869e15a41SShri Abhyankar #undef __FUNCT__
19969e15a41SShri Abhyankar #define __FUNCT__ "MatLUFactorSymbolic_KLU"
20069e15a41SShri Abhyankar static PetscErrorCode MatLUFactorSymbolic_KLU(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
20169e15a41SShri Abhyankar {
20269e15a41SShri Abhyankar   Mat_SeqAIJ     *a  = (Mat_SeqAIJ*)A->data;
20369e15a41SShri Abhyankar   Mat_KLU       *lu = (Mat_KLU*)(F->spptr);
20469e15a41SShri Abhyankar   PetscErrorCode ierr;
20569e15a41SShri Abhyankar   PetscInt       i,*ai = a->i,*aj = a->j,m=A->rmap->n,n=A->cmap->n;
20669e15a41SShri Abhyankar   const PetscInt *ra,*ca;
20769e15a41SShri Abhyankar 
20869e15a41SShri Abhyankar   PetscFunctionBegin;
20969e15a41SShri Abhyankar   if (lu->PetscMatOrdering) {
21069e15a41SShri Abhyankar     ierr = ISGetIndices(r,&ra);CHKERRQ(ierr);
21169e15a41SShri Abhyankar     ierr = ISGetIndices(c,&ca);CHKERRQ(ierr);
21234c5654cSShri Abhyankar     ierr = PetscMalloc2(m,&lu->perm_r,n,&lu->perm_c);CHKERRQ(ierr);
21369e15a41SShri Abhyankar     /* we cannot simply memcpy on 64 bit archs */
21469e15a41SShri Abhyankar     for (i = 0; i < m; i++) lu->perm_r[i] = ra[i];
21569e15a41SShri Abhyankar     for (i = 0; i < n; i++) lu->perm_c[i] = ca[i];
21669e15a41SShri Abhyankar     ierr = ISRestoreIndices(r,&ra);CHKERRQ(ierr);
21769e15a41SShri Abhyankar     ierr = ISRestoreIndices(c,&ca);CHKERRQ(ierr);
21869e15a41SShri Abhyankar   }
21969e15a41SShri Abhyankar 
22069e15a41SShri Abhyankar   /* symbolic factorization of A' */
22169e15a41SShri Abhyankar   /* ---------------------------------------------------------------------- */
22269e15a41SShri Abhyankar   if (lu->PetscMatOrdering) { /* use Petsc ordering */
22369e15a41SShri Abhyankar     lu->Symbolic = klu_K_analyze_given(n,ai,aj,lu->perm_c,lu->perm_r,&lu->Common);
22469e15a41SShri Abhyankar   } else { /* use klu internal ordering */
22569e15a41SShri Abhyankar     lu->Symbolic = klu_K_analyze(n,ai,aj,&lu->Common);
22669e15a41SShri Abhyankar   }
22769e15a41SShri Abhyankar   if (!lu->Symbolic) {
22869e15a41SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"KLU Symbolic Factorization failed");
22969e15a41SShri Abhyankar   }
23069e15a41SShri Abhyankar 
23169e15a41SShri Abhyankar   lu->flg                   = DIFFERENT_NONZERO_PATTERN;
23269e15a41SShri Abhyankar   lu->CleanUpKLU            = PETSC_TRUE;
23369e15a41SShri Abhyankar   (F)->ops->lufactornumeric = MatLUFactorNumeric_KLU;
23469e15a41SShri Abhyankar   PetscFunctionReturn(0);
23569e15a41SShri Abhyankar }
23669e15a41SShri Abhyankar 
23769e15a41SShri Abhyankar #undef __FUNCT__
23869e15a41SShri Abhyankar #define __FUNCT__ "MatFactorInfo_KLU"
23969e15a41SShri Abhyankar static PetscErrorCode MatFactorInfo_KLU(Mat A,PetscViewer viewer)
24069e15a41SShri Abhyankar {
24169e15a41SShri Abhyankar   Mat_KLU       *lu= (Mat_KLU*)A->spptr;
24269e15a41SShri Abhyankar   klu_K_numeric *Numeric=(klu_K_numeric*)lu->Numeric;
24369e15a41SShri Abhyankar   PetscErrorCode ierr;
24469e15a41SShri Abhyankar 
24569e15a41SShri Abhyankar   PetscFunctionBegin;
24669e15a41SShri Abhyankar   /* check if matrix is KLU type */
24769e15a41SShri Abhyankar   if (A->ops->solve != MatSolve_KLU) PetscFunctionReturn(0);
24869e15a41SShri Abhyankar 
24969e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"KLU stats:\n");CHKERRQ(ierr);
25069e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"  Number of diagonal blocks: %d\n",Numeric->nblocks);
25169e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"  Total nonzeros=%d\n",Numeric->lnz+Numeric->unz);CHKERRQ(ierr);
25269e15a41SShri Abhyankar 
25369e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"KLU runtime parameters:\n");CHKERRQ(ierr);
25469e15a41SShri Abhyankar 
25569e15a41SShri Abhyankar   /* Control parameters used by numeric factorization */
25669e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"  Partial pivoting tolerance: %g\n",lu->Common.tol);CHKERRQ(ierr);
25769e15a41SShri Abhyankar   /* BTF preordering */
25869e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer,"  BTF preordering enabled: %d\n",lu->Common.btf);CHKERRQ(ierr);
25969e15a41SShri Abhyankar   /* mat ordering */
26069e15a41SShri Abhyankar   if (!lu->PetscMatOrdering) {
26169e15a41SShri Abhyankar     ierr = PetscViewerASCIIPrintf(viewer,"  Ordering: %s (not using the PETSc ordering)\n",KluOrderingTypes[(int)lu->Common.ordering]);CHKERRQ(ierr);
26269e15a41SShri Abhyankar   } else {
26369e15a41SShri Abhyankar     ierr = PetscViewerASCIIPrintf(viewer,"  Using PETSc ordering\n");CHKERRQ(ierr);
26469e15a41SShri Abhyankar   }
26569e15a41SShri Abhyankar   /* matrix row scaling */
26669e15a41SShri Abhyankar   ierr = PetscViewerASCIIPrintf(viewer, "  Matrix row scaling: %s\n",scale[(int)lu->Common.scale]);CHKERRQ(ierr);
26769e15a41SShri Abhyankar   PetscFunctionReturn(0);
26869e15a41SShri Abhyankar }
26969e15a41SShri Abhyankar 
27069e15a41SShri Abhyankar #undef __FUNCT__
27169e15a41SShri Abhyankar #define __FUNCT__ "MatView_KLU"
27269e15a41SShri Abhyankar static PetscErrorCode MatView_KLU(Mat A,PetscViewer viewer)
27369e15a41SShri Abhyankar {
27469e15a41SShri Abhyankar   PetscErrorCode    ierr;
27569e15a41SShri Abhyankar   PetscBool         iascii;
27669e15a41SShri Abhyankar   PetscViewerFormat format;
27769e15a41SShri Abhyankar 
27869e15a41SShri Abhyankar   PetscFunctionBegin;
27969e15a41SShri Abhyankar   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
28069e15a41SShri Abhyankar 
28169e15a41SShri Abhyankar   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
28269e15a41SShri Abhyankar   if (iascii) {
28369e15a41SShri Abhyankar     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
28469e15a41SShri Abhyankar     if (format == PETSC_VIEWER_ASCII_INFO) {
28569e15a41SShri Abhyankar       ierr = MatFactorInfo_KLU(A,viewer);CHKERRQ(ierr);
28669e15a41SShri Abhyankar     }
28769e15a41SShri Abhyankar   }
28869e15a41SShri Abhyankar   PetscFunctionReturn(0);
28969e15a41SShri Abhyankar }
29069e15a41SShri Abhyankar 
29169e15a41SShri Abhyankar #undef __FUNCT__
29269e15a41SShri Abhyankar #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_klu"
29369e15a41SShri Abhyankar PetscErrorCode MatFactorGetSolverPackage_seqaij_klu(Mat A,const MatSolverPackage *type)
29469e15a41SShri Abhyankar {
29569e15a41SShri Abhyankar   PetscFunctionBegin;
29669e15a41SShri Abhyankar   *type = MATSOLVERKLU;
29769e15a41SShri Abhyankar   PetscFunctionReturn(0);
29869e15a41SShri Abhyankar }
29969e15a41SShri Abhyankar 
30069e15a41SShri Abhyankar 
30169e15a41SShri Abhyankar /*MC
30269e15a41SShri Abhyankar   MATSOLVERKLU = "klu" - A matrix type providing direct solvers (LU) for sequential matrices
30369e15a41SShri Abhyankar   via the external package KLU.
30469e15a41SShri Abhyankar 
305057b0833SShri Abhyankar   ./configure --download-suitesparse to install PETSc to use KLU
30669e15a41SShri Abhyankar 
30769e15a41SShri Abhyankar   Consult KLU documentation for more information on the options database keys below.
30869e15a41SShri Abhyankar 
30969e15a41SShri Abhyankar   Options Database Keys:
31069e15a41SShri Abhyankar + -mat_klu_pivot_tol <0.001>                  - Partial pivoting tolerance
31169e15a41SShri Abhyankar . -mat_klu_use_btf <1>                        - Use BTF preordering
31269e15a41SShri Abhyankar . -mat_klu_ordering <AMD>                     - KLU reordering scheme to reduce fill-in (choose one of) AMD COLAMD PETSC
31369e15a41SShri Abhyankar - -mat_klu_row_scale <NONE>                   - Matrix row scaling (choose one of) NONE SUM MAX
31469e15a41SShri Abhyankar 
315*a364b7d2SBarry Smith    Note: KLU is part of SuiteSparse http://faculty.cse.tamu.edu/davis/suitesparse.html
316*a364b7d2SBarry Smith 
31769e15a41SShri Abhyankar    Level: beginner
31869e15a41SShri Abhyankar 
31969e15a41SShri Abhyankar .seealso: PCLU, MATSOLVERUMFPACK, MATSOLVERCHOLMOD, PCFactorSetMatSolverPackage(), MatSolverPackage
32069e15a41SShri Abhyankar M*/
32169e15a41SShri Abhyankar 
32269e15a41SShri Abhyankar #undef __FUNCT__
32369e15a41SShri Abhyankar #define __FUNCT__ "MatGetFactor_seqaij_klu"
32469e15a41SShri Abhyankar PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_klu(Mat A,MatFactorType ftype,Mat *F)
32569e15a41SShri Abhyankar {
32669e15a41SShri Abhyankar   Mat            B;
32769e15a41SShri Abhyankar   Mat_KLU       *lu;
32869e15a41SShri Abhyankar   PetscErrorCode ierr;
32969e15a41SShri Abhyankar   PetscInt       m=A->rmap->n,n=A->cmap->n,idx,status;
33069e15a41SShri Abhyankar   PetscBool      flg;
33169e15a41SShri Abhyankar 
33269e15a41SShri Abhyankar   PetscFunctionBegin;
33369e15a41SShri Abhyankar   /* Create the factorization matrix F */
33469e15a41SShri Abhyankar   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
33569e15a41SShri Abhyankar   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
33669e15a41SShri Abhyankar   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
33769e15a41SShri Abhyankar   ierr = MatSeqAIJSetPreallocation(B,0,NULL);CHKERRQ(ierr);
33869e15a41SShri Abhyankar   ierr = PetscNewLog(B,&lu);CHKERRQ(ierr);
33969e15a41SShri Abhyankar 
34069e15a41SShri Abhyankar   B->spptr                 = lu;
34169e15a41SShri Abhyankar   B->ops->lufactorsymbolic = MatLUFactorSymbolic_KLU;
34269e15a41SShri Abhyankar   B->ops->destroy          = MatDestroy_KLU;
34369e15a41SShri Abhyankar   B->ops->view             = MatView_KLU;
34469e15a41SShri Abhyankar 
34569e15a41SShri Abhyankar   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_seqaij_klu);CHKERRQ(ierr);
34669e15a41SShri Abhyankar 
34769e15a41SShri Abhyankar   B->factortype   = MAT_FACTOR_LU;
34869e15a41SShri Abhyankar   B->assembled    = PETSC_TRUE;           /* required by -ksp_view */
34969e15a41SShri Abhyankar   B->preallocated = PETSC_TRUE;
35069e15a41SShri Abhyankar 
35169e15a41SShri Abhyankar   /* initializations */
35269e15a41SShri Abhyankar   /* ------------------------------------------------*/
35369e15a41SShri Abhyankar   /* get the default control parameters */
35469e15a41SShri Abhyankar   status = klu_K_defaults(&lu->Common);
35569e15a41SShri Abhyankar   if(status <= 0) {
35669e15a41SShri Abhyankar     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"KLU Initialization failed");
35769e15a41SShri Abhyankar   }
35869e15a41SShri Abhyankar   lu->Common.scale = 0; /* No row scaling */
35969e15a41SShri Abhyankar 
36069e15a41SShri Abhyankar   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"KLU Options","Mat");CHKERRQ(ierr);
36169e15a41SShri Abhyankar   /* Partial pivoting tolerance */
36269e15a41SShri Abhyankar   ierr = PetscOptionsReal("-mat_klu_pivot_tol","Partial pivoting tolerance","None",lu->Common.tol,&lu->Common.tol,NULL);CHKERRQ(ierr);
36369e15a41SShri Abhyankar   /* BTF pre-ordering */
36469e15a41SShri Abhyankar   ierr = PetscOptionsInt("-mat_klu_use_btf","Enable BTF preordering","None",lu->Common.btf,&lu->Common.btf,NULL);CHKERRQ(ierr);
36569e15a41SShri Abhyankar   /* Matrix reordering */
36669e15a41SShri Abhyankar   ierr = PetscOptionsEList("-mat_klu_ordering","Internal ordering method","None",KluOrderingTypes,sizeof(KluOrderingTypes)/sizeof(KluOrderingTypes[0]),KluOrderingTypes[0],&idx,&flg);CHKERRQ(ierr);
36769e15a41SShri Abhyankar   if (flg) {
36869e15a41SShri Abhyankar     if ((int)idx == 2) lu->PetscMatOrdering = PETSC_TRUE;   /* use Petsc mat ordering (note: size is for the transpose, and PETSc r = Klu perm_c) */
36969e15a41SShri Abhyankar     else lu->Common.ordering = (int)idx;
37069e15a41SShri Abhyankar   }
37169e15a41SShri Abhyankar   /* Matrix row scaling */
37269e15a41SShri Abhyankar   ierr = PetscOptionsEList("-mat_klu_row_scale","Matrix row scaling","None",scale,3,scale[0],&idx,&flg);CHKERRQ(ierr);
37369e15a41SShri Abhyankar   PetscOptionsEnd();
37469e15a41SShri Abhyankar   *F = B;
37569e15a41SShri Abhyankar   PetscFunctionReturn(0);
37669e15a41SShri Abhyankar }
377