xref: /petsc/src/mat/impls/aij/mpi/strumpack/strumpack.c (revision 24a4cbef429a7ba006a614594317320191121b8e)
17d6ea485SPieter Ghysels #include <../src/mat/impls/aij/seq/aij.h>
27d6ea485SPieter Ghysels #include <../src/mat/impls/aij/mpi/mpiaij.h>
37d6ea485SPieter Ghysels #include <StrumpackSparseSolver.h>
47d6ea485SPieter Ghysels 
57d6ea485SPieter Ghysels /*
67d6ea485SPieter Ghysels   These are only relevant for MATMPIAIJ, not for MATSEQAIJ.
77d6ea485SPieter Ghysels     REPLICATED  - STRUMPACK expects the entire sparse matrix and right-hand side on every process.
87d6ea485SPieter Ghysels     DISTRIBUTED - STRUMPACK expects the sparse matrix and right-hand side to be distributed across the entire MPI communicator.
97d6ea485SPieter Ghysels */
107d6ea485SPieter Ghysels typedef enum {REPLICATED, DISTRIBUTED} STRUMPACK_MatInputMode;
117d6ea485SPieter Ghysels const char *STRUMPACK_MatInputModes[] = {"REPLICATED","DISTRIBUTED","STRUMPACK_MatInputMode","PETSC_",0};
127d6ea485SPieter Ghysels 
137d6ea485SPieter Ghysels typedef struct {
147d6ea485SPieter Ghysels   STRUMPACK_SparseSolver S;
157d6ea485SPieter Ghysels   STRUMPACK_MatInputMode MatInputMode;
167d6ea485SPieter Ghysels } STRUMPACK_data;
177d6ea485SPieter Ghysels 
187d6ea485SPieter Ghysels extern PetscErrorCode MatFactorInfo_STRUMPACK(Mat,PetscViewer);
197d6ea485SPieter Ghysels extern PetscErrorCode MatLUFactorNumeric_STRUMPACK(Mat,Mat,const MatFactorInfo*);
207d6ea485SPieter Ghysels extern PetscErrorCode MatDestroy_STRUMPACK(Mat);
217d6ea485SPieter Ghysels extern PetscErrorCode MatView_STRUMPACK(Mat,PetscViewer);
227d6ea485SPieter Ghysels extern PetscErrorCode MatSolve_STRUMPACK(Mat,Vec,Vec);
237d6ea485SPieter Ghysels extern PetscErrorCode MatLUFactorSymbolic_STRUMPACK(Mat,Mat,IS,IS,const MatFactorInfo*);
247d6ea485SPieter Ghysels extern PetscErrorCode MatDestroy_MPIAIJ(Mat);
257d6ea485SPieter Ghysels 
267d6ea485SPieter Ghysels #undef __FUNCT__
277d6ea485SPieter Ghysels #define __FUNCT__ "MatGetDiagonal_STRUMPACK"
287d6ea485SPieter Ghysels PetscErrorCode MatGetDiagonal_STRUMPACK(Mat A,Vec v)
297d6ea485SPieter Ghysels {
307d6ea485SPieter Ghysels   PetscFunctionBegin;
317d6ea485SPieter Ghysels   SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type: STRUMPACK factor");
327d6ea485SPieter Ghysels   PetscFunctionReturn(0);
337d6ea485SPieter Ghysels }
347d6ea485SPieter Ghysels 
357d6ea485SPieter Ghysels #undef __FUNCT__
367d6ea485SPieter Ghysels #define __FUNCT__ "MatDestroy_STRUMPACK"
377d6ea485SPieter Ghysels PetscErrorCode MatDestroy_STRUMPACK(Mat A)
387d6ea485SPieter Ghysels {
397d6ea485SPieter Ghysels   STRUMPACK_data *sp = (STRUMPACK_data*)A->spptr;
407d6ea485SPieter Ghysels   PetscErrorCode ierr;
417d6ea485SPieter Ghysels   PetscBool      flg;
427d6ea485SPieter Ghysels 
437d6ea485SPieter Ghysels   PetscFunctionBegin;
447d6ea485SPieter Ghysels   /* Deallocate STRUMPACK storage */
457d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_destroy",STRUMPACK_destroy(&(sp->S)));
467d6ea485SPieter Ghysels   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
477d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
487d6ea485SPieter Ghysels   if (flg) {
497d6ea485SPieter Ghysels     ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
507d6ea485SPieter Ghysels   } else {
517d6ea485SPieter Ghysels     ierr = MatDestroy_MPIAIJ(A);CHKERRQ(ierr);
527d6ea485SPieter Ghysels   }
537d6ea485SPieter Ghysels   PetscFunctionReturn(0);
547d6ea485SPieter Ghysels }
557d6ea485SPieter Ghysels 
567d6ea485SPieter Ghysels #undef __FUNCT__
577d6ea485SPieter Ghysels #define __FUNCT__ "MatSolve_STRUMPACK"
587d6ea485SPieter Ghysels PetscErrorCode MatSolve_STRUMPACK(Mat A,Vec b_mpi,Vec x)
597d6ea485SPieter Ghysels {
607d6ea485SPieter Ghysels   STRUMPACK_data        *sp = (STRUMPACK_data*)A->spptr;
617d6ea485SPieter Ghysels   STRUMPACK_RETURN_CODE sp_err;
627d6ea485SPieter Ghysels   PetscErrorCode        ierr;
637d6ea485SPieter Ghysels   PetscMPIInt           size;
647d6ea485SPieter Ghysels   PetscInt              N=A->cmap->N;
657d6ea485SPieter Ghysels   const PetscScalar     *bptr;
667d6ea485SPieter Ghysels   PetscScalar           *xptr;
677d6ea485SPieter Ghysels   Vec                   x_seq,b_seq;
687d6ea485SPieter Ghysels   IS                    iden;
697d6ea485SPieter Ghysels   VecScatter            scat;
707d6ea485SPieter Ghysels 
717d6ea485SPieter Ghysels   PetscFunctionBegin;
727d6ea485SPieter Ghysels   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
737d6ea485SPieter Ghysels   if (size > 1 && sp->MatInputMode == REPLICATED) {
747d6ea485SPieter Ghysels     ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x_seq);CHKERRQ(ierr);
757d6ea485SPieter Ghysels     ierr = VecGetArray(x_seq,&xptr);CHKERRQ(ierr);
76*24a4cbefSPieter Ghysels     /* replicated mat input, convert b to b_seq */
777d6ea485SPieter Ghysels     ierr = VecCreateSeq(PETSC_COMM_SELF,N,&b_seq);CHKERRQ(ierr);
787d6ea485SPieter Ghysels     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iden);CHKERRQ(ierr);
797d6ea485SPieter Ghysels     ierr = VecScatterCreate(b_mpi,iden,b_seq,iden,&scat);CHKERRQ(ierr);
807d6ea485SPieter Ghysels     ierr = ISDestroy(&iden);CHKERRQ(ierr);
817d6ea485SPieter Ghysels     ierr = VecScatterBegin(scat,b_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
827d6ea485SPieter Ghysels     ierr = VecScatterEnd(scat,b_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
837d6ea485SPieter Ghysels     ierr = VecGetArrayRead(b_seq,&bptr);CHKERRQ(ierr);
847d6ea485SPieter Ghysels   } else { /* size==1 || distributed mat input */
857d6ea485SPieter Ghysels     ierr = VecGetArray(x,&xptr);CHKERRQ(ierr);
867d6ea485SPieter Ghysels     ierr = VecGetArrayRead(b_mpi,&bptr);CHKERRQ(ierr);
877d6ea485SPieter Ghysels   }
887d6ea485SPieter Ghysels 
897d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_solve",sp_err = STRUMPACK_solve(sp->S,(PetscScalar*)bptr,xptr,0));
907d6ea485SPieter Ghysels 
917d6ea485SPieter Ghysels   if (sp_err != STRUMPACK_SUCCESS) {
927d6ea485SPieter Ghysels     if (sp_err == STRUMPACK_MATRIX_NOT_SET)        SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix was not set");
937d6ea485SPieter Ghysels     else if (sp_err == STRUMPACK_REORDERING_ERROR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix reordering failed");
947d6ea485SPieter Ghysels     else                                           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: solve failed");
957d6ea485SPieter Ghysels   }
967d6ea485SPieter Ghysels 
977d6ea485SPieter Ghysels   if (size > 1 && sp->MatInputMode == REPLICATED) {
987d6ea485SPieter Ghysels     ierr = VecRestoreArrayRead(b_seq,&bptr);CHKERRQ(ierr);
997d6ea485SPieter Ghysels     ierr = VecDestroy(&b_seq);CHKERRQ(ierr);
1007d6ea485SPieter Ghysels     /* convert seq x to mpi x */
1017d6ea485SPieter Ghysels     ierr = VecRestoreArray(x_seq,&xptr);CHKERRQ(ierr);
1027d6ea485SPieter Ghysels     ierr = VecScatterBegin(scat,x_seq,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1037d6ea485SPieter Ghysels     ierr = VecScatterEnd(scat,x_seq,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1047d6ea485SPieter Ghysels     ierr = VecScatterDestroy(&scat);CHKERRQ(ierr);
1057d6ea485SPieter Ghysels     ierr = VecDestroy(&x_seq);CHKERRQ(ierr);
1067d6ea485SPieter Ghysels   } else {
1077d6ea485SPieter Ghysels     ierr = VecRestoreArray(x,&xptr);CHKERRQ(ierr);
1087d6ea485SPieter Ghysels     ierr = VecRestoreArrayRead(b_mpi,&bptr);CHKERRQ(ierr);
1097d6ea485SPieter Ghysels   }
1107d6ea485SPieter Ghysels 
1117d6ea485SPieter Ghysels   PetscFunctionReturn(0);
1127d6ea485SPieter Ghysels }
1137d6ea485SPieter Ghysels 
1147d6ea485SPieter Ghysels #undef __FUNCT__
1157d6ea485SPieter Ghysels #define __FUNCT__ "MatMatSolve_STRUMPACK"
1167d6ea485SPieter Ghysels PetscErrorCode MatMatSolve_STRUMPACK(Mat A,Mat B_mpi,Mat X)
1177d6ea485SPieter Ghysels {
1187d6ea485SPieter Ghysels   PetscErrorCode   ierr;
1197d6ea485SPieter Ghysels   PetscBool        flg;
1207d6ea485SPieter Ghysels 
1217d6ea485SPieter Ghysels   PetscFunctionBegin;
1227d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompareAny((PetscObject)B_mpi,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
1237d6ea485SPieter Ghysels   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
1247d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
1257d6ea485SPieter Ghysels   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
1267d6ea485SPieter Ghysels   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatMatSolve_STRUMPACK() is not implemented yet");
1277d6ea485SPieter Ghysels   PetscFunctionReturn(0);
1287d6ea485SPieter Ghysels }
1297d6ea485SPieter Ghysels 
1307d6ea485SPieter Ghysels 
1317d6ea485SPieter Ghysels #undef __FUNCT__
1327d6ea485SPieter Ghysels #define __FUNCT__ "MatLUFactorNumeric_STRUMPACK"
1337d6ea485SPieter Ghysels PetscErrorCode MatLUFactorNumeric_STRUMPACK(Mat F,Mat A,const MatFactorInfo *info)
1347d6ea485SPieter Ghysels {
1357d6ea485SPieter Ghysels   STRUMPACK_data        *sp = (STRUMPACK_data*)F->spptr;
1367d6ea485SPieter Ghysels   STRUMPACK_RETURN_CODE sp_err;
1377d6ea485SPieter Ghysels   Mat                   *tseq,A_seq = NULL;
1387d6ea485SPieter Ghysels   Mat_SeqAIJ            *A_d,*A_o;
1397d6ea485SPieter Ghysels   Mat_MPIAIJ            *mat;
1407d6ea485SPieter Ghysels   PetscErrorCode        ierr;
1417d6ea485SPieter Ghysels   PetscInt              M=A->rmap->N,m=A->rmap->n,N=A->cmap->N;
1427d6ea485SPieter Ghysels   PetscMPIInt           size;
1437d6ea485SPieter Ghysels   IS                    isrow;
1447d6ea485SPieter Ghysels   PetscBool             flg;
1457d6ea485SPieter Ghysels 
1467d6ea485SPieter Ghysels   PetscFunctionBegin;
1477d6ea485SPieter Ghysels   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
1487d6ea485SPieter Ghysels 
1497d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr);
1507d6ea485SPieter Ghysels   if (flg) { /* A is MATMPIAIJ */
1517d6ea485SPieter Ghysels     if (sp->MatInputMode == REPLICATED) {
1527d6ea485SPieter Ghysels       if (size > 1) { /* convert mpi A to seq mat A */
1537d6ea485SPieter Ghysels         ierr = ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);CHKERRQ(ierr);
1547d6ea485SPieter Ghysels         ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq);CHKERRQ(ierr);
1557d6ea485SPieter Ghysels         ierr = ISDestroy(&isrow);CHKERRQ(ierr);
1567d6ea485SPieter Ghysels         A_seq = *tseq;
1577d6ea485SPieter Ghysels         ierr  = PetscFree(tseq);CHKERRQ(ierr);
1587d6ea485SPieter Ghysels         A_d   = (Mat_SeqAIJ*)A_seq->data;
1597d6ea485SPieter Ghysels       } else { /* size == 1 */
1607d6ea485SPieter Ghysels         mat = (Mat_MPIAIJ*)A->data;
1617d6ea485SPieter Ghysels         A_d = (Mat_SeqAIJ*)(mat->A)->data;
1627d6ea485SPieter Ghysels       }
1637d6ea485SPieter Ghysels       PetscStackCall("STRUMPACK_set_csr_matrix",STRUMPACK_set_csr_matrix(sp->S,&N,A_d->i,A_d->j,A_d->a,0));
1647d6ea485SPieter Ghysels     } else { /* sp->MatInputMode == DISTRIBUTED */
1657d6ea485SPieter Ghysels       mat = (Mat_MPIAIJ*)A->data;
1667d6ea485SPieter Ghysels       A_d = (Mat_SeqAIJ*)(mat->A)->data;
1677d6ea485SPieter Ghysels       A_o = (Mat_SeqAIJ*)(mat->B)->data;
1687d6ea485SPieter Ghysels       PetscStackCall("STRUMPACK_set_MPIAIJ_matrix",STRUMPACK_set_MPIAIJ_matrix(sp->S,&m,A_d->i,A_d->j,A_d->a,A_o->i,A_o->j,A_o->a,mat->garray));
1697d6ea485SPieter Ghysels     }
1707d6ea485SPieter Ghysels   } else { /* A is MATSEQAIJ */
1717d6ea485SPieter Ghysels     A_d = (Mat_SeqAIJ*)A->data;
1727d6ea485SPieter Ghysels     PetscStackCall("STRUMPACK_set_csr_matrix",STRUMPACK_set_csr_matrix(sp->S,&N,A_d->i,A_d->j,A_d->a,0));
1737d6ea485SPieter Ghysels   }
1747d6ea485SPieter Ghysels 
1757d6ea485SPieter Ghysels   /* Reorder and Factor the matrix. */
1767d6ea485SPieter Ghysels   /* TODO figure out how to avoid reorder if the matrix values changed, but the pattern remains the same. */
1777d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_reorder",sp_err = STRUMPACK_reorder(sp->S));
1787d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_factor",sp_err = STRUMPACK_factor(sp->S));
1797d6ea485SPieter Ghysels   if (sp_err != STRUMPACK_SUCCESS) {
1807d6ea485SPieter Ghysels     if (sp_err == STRUMPACK_MATRIX_NOT_SET)        SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix was not set");
1817d6ea485SPieter Ghysels     else if (sp_err == STRUMPACK_REORDERING_ERROR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix reordering failed");
1827d6ea485SPieter Ghysels     else                                           SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: factorization failed");
1837d6ea485SPieter Ghysels   }
1847d6ea485SPieter Ghysels   if (flg && sp->MatInputMode == REPLICATED && size > 1) {
1857d6ea485SPieter Ghysels     ierr = MatDestroy(&A_seq);CHKERRQ(ierr);
1867d6ea485SPieter Ghysels   }
1877d6ea485SPieter Ghysels   PetscFunctionReturn(0);
1887d6ea485SPieter Ghysels }
1897d6ea485SPieter Ghysels 
1907d6ea485SPieter Ghysels #undef __FUNCT__
1917d6ea485SPieter Ghysels #define __FUNCT__ "MatLUFactorSymbolic_STRUMPACK"
1927d6ea485SPieter Ghysels PetscErrorCode MatLUFactorSymbolic_STRUMPACK(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1937d6ea485SPieter Ghysels {
1947d6ea485SPieter Ghysels   PetscFunctionBegin;
1957d6ea485SPieter Ghysels   F->ops->lufactornumeric = MatLUFactorNumeric_STRUMPACK;
1967d6ea485SPieter Ghysels   F->ops->solve           = MatSolve_STRUMPACK;
1977d6ea485SPieter Ghysels   F->ops->matsolve        = MatMatSolve_STRUMPACK;
1987d6ea485SPieter Ghysels   PetscFunctionReturn(0);
1997d6ea485SPieter Ghysels }
2007d6ea485SPieter Ghysels 
2017d6ea485SPieter Ghysels #undef __FUNCT__
2027d6ea485SPieter Ghysels #define __FUNCT__ "MatFactorGetSolverPackage_aij_strumpack"
2037d6ea485SPieter Ghysels PetscErrorCode MatFactorGetSolverPackage_aij_strumpack(Mat A,const MatSolverPackage *type)
2047d6ea485SPieter Ghysels {
2057d6ea485SPieter Ghysels   PetscFunctionBegin;
2067d6ea485SPieter Ghysels   *type = MATSOLVERSTRUMPACK;
2077d6ea485SPieter Ghysels   PetscFunctionReturn(0);
2087d6ea485SPieter Ghysels }
2097d6ea485SPieter Ghysels 
2107d6ea485SPieter Ghysels #undef __FUNCT__
2117d6ea485SPieter Ghysels #define __FUNCT__ "MatGetFactor_aij_strumpack"
2127d6ea485SPieter Ghysels PETSC_EXTERN PetscErrorCode MatGetFactor_aij_strumpack(Mat A,MatFactorType ftype,Mat *F)
2137d6ea485SPieter Ghysels {
2147d6ea485SPieter Ghysels   Mat                 B;
2157d6ea485SPieter Ghysels   STRUMPACK_data      *sp;
2167d6ea485SPieter Ghysels   PetscErrorCode      ierr;
2177d6ea485SPieter Ghysels   PetscInt            M=A->rmap->N,N=A->cmap->N;
2187d6ea485SPieter Ghysels   PetscMPIInt         size;
2197d6ea485SPieter Ghysels   STRUMPACK_INTERFACE iface;
2207d6ea485SPieter Ghysels   PetscBool           verb,flg;
2217d6ea485SPieter Ghysels   int                 argc;
2227d6ea485SPieter Ghysels   char                **args;
2237d6ea485SPieter Ghysels   const STRUMPACK_PRECISION table[2][2][2] = {{{STRUMPACK_FLOATCOMPLEX_64,STRUMPACK_DOUBLECOMPLEX_64},
2247d6ea485SPieter Ghysels                                                {STRUMPACK_FLOAT_64,STRUMPACK_DOUBLE_64}},
2257d6ea485SPieter Ghysels                                               {{STRUMPACK_FLOATCOMPLEX,STRUMPACK_DOUBLECOMPLEX},
2267d6ea485SPieter Ghysels                                                {STRUMPACK_FLOAT,STRUMPACK_DOUBLE}}};
2277d6ea485SPieter Ghysels   const STRUMPACK_PRECISION prec = table[(sizeof(PetscInt)==8)?0:1][(PETSC_SCALAR==PETSC_COMPLEX)?0:1][(PETSC_REAL==PETSC_FLOAT)?0:1];
2287d6ea485SPieter Ghysels 
2297d6ea485SPieter Ghysels   PetscFunctionBegin;
2307d6ea485SPieter Ghysels   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
2317d6ea485SPieter Ghysels   /* Create the factorization matrix */
2327d6ea485SPieter Ghysels   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2337d6ea485SPieter Ghysels   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,M,N);CHKERRQ(ierr);
2347d6ea485SPieter Ghysels   ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2357d6ea485SPieter Ghysels   ierr = MatSeqAIJSetPreallocation(B,0,NULL);
2367d6ea485SPieter Ghysels   ierr = MatMPIAIJSetPreallocation(B,0,NULL,0,NULL);CHKERRQ(ierr);
2377d6ea485SPieter Ghysels   B->ops->lufactorsymbolic = MatLUFactorSymbolic_STRUMPACK;
2387d6ea485SPieter Ghysels   B->ops->view             = MatView_STRUMPACK;
2397d6ea485SPieter Ghysels   B->ops->destroy          = MatDestroy_STRUMPACK;
2407d6ea485SPieter Ghysels   B->ops->getdiagonal      = MatGetDiagonal_STRUMPACK;
2417d6ea485SPieter Ghysels   ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_aij_strumpack);CHKERRQ(ierr);
2427d6ea485SPieter Ghysels   B->factortype = MAT_FACTOR_LU;
2437d6ea485SPieter Ghysels   ierr     = PetscNewLog(B,&sp);CHKERRQ(ierr);
2447d6ea485SPieter Ghysels   B->spptr = sp;
2457d6ea485SPieter Ghysels 
2467d6ea485SPieter Ghysels   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"STRUMPACK Options","Mat");CHKERRQ(ierr);
2477d6ea485SPieter Ghysels   sp->MatInputMode = DISTRIBUTED;
2487d6ea485SPieter Ghysels   iface = STRUMPACK_MPI_DIST;
249*24a4cbefSPieter Ghysels   ierr = PetscOptionsEnum("-mat_strumpack_matinput","Matrix input mode (replicated or distributed)","None",STRUMPACK_MatInputModes,
2507d6ea485SPieter Ghysels                           (PetscEnum)sp->MatInputMode,(PetscEnum*)&sp->MatInputMode,NULL);CHKERRQ(ierr);
2517d6ea485SPieter Ghysels   if (sp->MatInputMode == DISTRIBUTED && size == 1) sp->MatInputMode = REPLICATED;
2527d6ea485SPieter Ghysels   if (sp->MatInputMode == DISTRIBUTED)     iface = STRUMPACK_MPI_DIST;
2537d6ea485SPieter Ghysels   else if (sp->MatInputMode == REPLICATED) iface = STRUMPACK_MPI;
2547d6ea485SPieter Ghysels 
2557d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);
2567d6ea485SPieter Ghysels   if (flg) iface = STRUMPACK_MT;
2577d6ea485SPieter Ghysels 
2587d6ea485SPieter Ghysels   if (PetscLogPrintInfo) verb = PETSC_TRUE;
2597d6ea485SPieter Ghysels   else verb = PETSC_FALSE;
2607d6ea485SPieter Ghysels   ierr = PetscOptionsBool("-mat_strumpack_verbose","Print STRUMPACK information","None",verb,&verb,NULL);CHKERRQ(ierr);
2617d6ea485SPieter Ghysels   PetscOptionsEnd();
2627d6ea485SPieter Ghysels 
2637d6ea485SPieter Ghysels   ierr = PetscGetArgs(&argc,&args);CHKERRQ(ierr);
2647d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_init",STRUMPACK_init(&(sp->S),PetscObjectComm((PetscObject)A),prec,iface,argc,args,verb));
2657d6ea485SPieter Ghysels   PetscStackCall("STRUMPACK_set_from_options",STRUMPACK_set_from_options(sp->S));
2667d6ea485SPieter Ghysels 
2677d6ea485SPieter Ghysels   *F = B;
2687d6ea485SPieter Ghysels   PetscFunctionReturn(0);
2697d6ea485SPieter Ghysels }
2707d6ea485SPieter Ghysels 
2717d6ea485SPieter Ghysels #undef __FUNCT__
2727d6ea485SPieter Ghysels #define __FUNCT__ "MatSolverPackageRegister_STRUMPACK"
2737d6ea485SPieter Ghysels PETSC_EXTERN PetscErrorCode MatSolverPackageRegister_STRUMPACK(void)
2747d6ea485SPieter Ghysels {
2757d6ea485SPieter Ghysels   PetscErrorCode ierr;
2767d6ea485SPieter Ghysels 
2777d6ea485SPieter Ghysels   PetscFunctionBegin;
2787d6ea485SPieter Ghysels   ierr = MatSolverPackageRegister(MATSOLVERSTRUMPACK,MATMPIAIJ,MAT_FACTOR_LU,MatGetFactor_aij_strumpack);CHKERRQ(ierr);
2797d6ea485SPieter Ghysels   ierr = MatSolverPackageRegister(MATSOLVERSTRUMPACK,MATSEQAIJ,MAT_FACTOR_LU,MatGetFactor_aij_strumpack);CHKERRQ(ierr);
2807d6ea485SPieter Ghysels   PetscFunctionReturn(0);
2817d6ea485SPieter Ghysels }
2827d6ea485SPieter Ghysels 
2837d6ea485SPieter Ghysels #undef __FUNCT__
2847d6ea485SPieter Ghysels #define __FUNCT__ "MatFactorInfo_STRUMPACK"
2857d6ea485SPieter Ghysels PetscErrorCode MatFactorInfo_STRUMPACK(Mat A,PetscViewer viewer)
2867d6ea485SPieter Ghysels {
2877d6ea485SPieter Ghysels   PetscErrorCode  ierr;
2887d6ea485SPieter Ghysels 
2897d6ea485SPieter Ghysels   PetscFunctionBegin;
2907d6ea485SPieter Ghysels   /* check if matrix is strumpack type */
2917d6ea485SPieter Ghysels   if (A->ops->solve != MatSolve_STRUMPACK) PetscFunctionReturn(0);
2927d6ea485SPieter Ghysels   ierr = PetscViewerASCIIPrintf(viewer,"STRUMPACK sparse solver!\n");CHKERRQ(ierr);
2937d6ea485SPieter Ghysels   PetscFunctionReturn(0);
2947d6ea485SPieter Ghysels }
2957d6ea485SPieter Ghysels 
2967d6ea485SPieter Ghysels #undef __FUNCT__
2977d6ea485SPieter Ghysels #define __FUNCT__ "MatView_STRUMPACK"
2987d6ea485SPieter Ghysels PetscErrorCode MatView_STRUMPACK(Mat A,PetscViewer viewer)
2997d6ea485SPieter Ghysels {
3007d6ea485SPieter Ghysels   PetscErrorCode    ierr;
3017d6ea485SPieter Ghysels   PetscBool         iascii;
3027d6ea485SPieter Ghysels   PetscViewerFormat format;
3037d6ea485SPieter Ghysels 
3047d6ea485SPieter Ghysels   PetscFunctionBegin;
3057d6ea485SPieter Ghysels   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3067d6ea485SPieter Ghysels   if (iascii) {
3077d6ea485SPieter Ghysels     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
3087d6ea485SPieter Ghysels     if (format == PETSC_VIEWER_ASCII_INFO) {
3097d6ea485SPieter Ghysels       ierr = MatFactorInfo_STRUMPACK(A,viewer);CHKERRQ(ierr);
3107d6ea485SPieter Ghysels     }
3117d6ea485SPieter Ghysels   }
3127d6ea485SPieter Ghysels   PetscFunctionReturn(0);
3137d6ea485SPieter Ghysels }
3147d6ea485SPieter Ghysels 
3157d6ea485SPieter Ghysels 
3167d6ea485SPieter Ghysels /*MC
3177d6ea485SPieter Ghysels   MATSOLVERSSTRUMPACK - Parallel direct solver package for LU factorization
3187d6ea485SPieter Ghysels 
3197d6ea485SPieter Ghysels   Use ./configure --download-strumpack to have PETSc installed with STRUMPACK
3207d6ea485SPieter Ghysels 
3217d6ea485SPieter Ghysels   Use -pc_type lu -pc_factor_mat_solver_package strumpack to us this direct solver
3227d6ea485SPieter Ghysels 
3237d6ea485SPieter Ghysels    Works with AIJ matrices
3247d6ea485SPieter Ghysels 
3257d6ea485SPieter Ghysels .seealso: PCLU
3267d6ea485SPieter Ghysels 
3277d6ea485SPieter Ghysels .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
3287d6ea485SPieter Ghysels 
3297d6ea485SPieter Ghysels M*/
3307d6ea485SPieter Ghysels 
331