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 197d6ea485SPieter Ghysels #undef __FUNCT__ 207d6ea485SPieter Ghysels #define __FUNCT__ "MatGetDiagonal_STRUMPACK" 21ad0c5e61SPieter Ghysels static PetscErrorCode MatGetDiagonal_STRUMPACK(Mat A,Vec v) 227d6ea485SPieter Ghysels { 237d6ea485SPieter Ghysels PetscFunctionBegin; 247d6ea485SPieter Ghysels SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type: STRUMPACK factor"); 257d6ea485SPieter Ghysels PetscFunctionReturn(0); 267d6ea485SPieter Ghysels } 277d6ea485SPieter Ghysels 287d6ea485SPieter Ghysels #undef __FUNCT__ 297d6ea485SPieter Ghysels #define __FUNCT__ "MatDestroy_STRUMPACK" 30ad0c5e61SPieter Ghysels static PetscErrorCode MatDestroy_STRUMPACK(Mat A) 317d6ea485SPieter Ghysels { 327d6ea485SPieter Ghysels STRUMPACK_data *sp = (STRUMPACK_data*)A->spptr; 337d6ea485SPieter Ghysels PetscErrorCode ierr; 347d6ea485SPieter Ghysels PetscBool flg; 357d6ea485SPieter Ghysels 367d6ea485SPieter Ghysels PetscFunctionBegin; 377d6ea485SPieter Ghysels /* Deallocate STRUMPACK storage */ 387d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_destroy",STRUMPACK_destroy(&(sp->S))); 397d6ea485SPieter Ghysels ierr = PetscFree(A->spptr);CHKERRQ(ierr); 407d6ea485SPieter Ghysels ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 417d6ea485SPieter Ghysels if (flg) { 427d6ea485SPieter Ghysels ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr); 437d6ea485SPieter Ghysels } else { 447d6ea485SPieter Ghysels ierr = MatDestroy_MPIAIJ(A);CHKERRQ(ierr); 457d6ea485SPieter Ghysels } 467d6ea485SPieter Ghysels PetscFunctionReturn(0); 477d6ea485SPieter Ghysels } 487d6ea485SPieter Ghysels 497d6ea485SPieter Ghysels #undef __FUNCT__ 507d6ea485SPieter Ghysels #define __FUNCT__ "MatSolve_STRUMPACK" 51ad0c5e61SPieter Ghysels static PetscErrorCode MatSolve_STRUMPACK(Mat A,Vec b_mpi,Vec x) 527d6ea485SPieter Ghysels { 537d6ea485SPieter Ghysels STRUMPACK_data *sp = (STRUMPACK_data*)A->spptr; 547d6ea485SPieter Ghysels STRUMPACK_RETURN_CODE sp_err; 557d6ea485SPieter Ghysels PetscErrorCode ierr; 567d6ea485SPieter Ghysels PetscMPIInt size; 577d6ea485SPieter Ghysels PetscInt N=A->cmap->N; 587d6ea485SPieter Ghysels const PetscScalar *bptr; 597d6ea485SPieter Ghysels PetscScalar *xptr; 607d6ea485SPieter Ghysels Vec x_seq,b_seq; 617d6ea485SPieter Ghysels IS iden; 627d6ea485SPieter Ghysels VecScatter scat; 637d6ea485SPieter Ghysels 647d6ea485SPieter Ghysels PetscFunctionBegin; 657d6ea485SPieter Ghysels ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 667d6ea485SPieter Ghysels if (size > 1 && sp->MatInputMode == REPLICATED) { 677d6ea485SPieter Ghysels ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x_seq);CHKERRQ(ierr); 687d6ea485SPieter Ghysels ierr = VecGetArray(x_seq,&xptr);CHKERRQ(ierr); 6924a4cbefSPieter Ghysels /* replicated mat input, convert b to b_seq */ 707d6ea485SPieter Ghysels ierr = VecCreateSeq(PETSC_COMM_SELF,N,&b_seq);CHKERRQ(ierr); 717d6ea485SPieter Ghysels ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iden);CHKERRQ(ierr); 727d6ea485SPieter Ghysels ierr = VecScatterCreate(b_mpi,iden,b_seq,iden,&scat);CHKERRQ(ierr); 737d6ea485SPieter Ghysels ierr = ISDestroy(&iden);CHKERRQ(ierr); 747d6ea485SPieter Ghysels ierr = VecScatterBegin(scat,b_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 757d6ea485SPieter Ghysels ierr = VecScatterEnd(scat,b_mpi,b_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 767d6ea485SPieter Ghysels ierr = VecGetArrayRead(b_seq,&bptr);CHKERRQ(ierr); 777d6ea485SPieter Ghysels } else { /* size==1 || distributed mat input */ 787d6ea485SPieter Ghysels ierr = VecGetArray(x,&xptr);CHKERRQ(ierr); 797d6ea485SPieter Ghysels ierr = VecGetArrayRead(b_mpi,&bptr);CHKERRQ(ierr); 807d6ea485SPieter Ghysels } 817d6ea485SPieter Ghysels 827d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_solve",sp_err = STRUMPACK_solve(sp->S,(PetscScalar*)bptr,xptr,0)); 837d6ea485SPieter Ghysels 847d6ea485SPieter Ghysels if (sp_err != STRUMPACK_SUCCESS) { 857d6ea485SPieter Ghysels if (sp_err == STRUMPACK_MATRIX_NOT_SET) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix was not set"); 867d6ea485SPieter Ghysels else if (sp_err == STRUMPACK_REORDERING_ERROR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix reordering failed"); 877d6ea485SPieter Ghysels else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: solve failed"); 887d6ea485SPieter Ghysels } 897d6ea485SPieter Ghysels 907d6ea485SPieter Ghysels if (size > 1 && sp->MatInputMode == REPLICATED) { 917d6ea485SPieter Ghysels ierr = VecRestoreArrayRead(b_seq,&bptr);CHKERRQ(ierr); 927d6ea485SPieter Ghysels ierr = VecDestroy(&b_seq);CHKERRQ(ierr); 937d6ea485SPieter Ghysels /* convert seq x to mpi x */ 947d6ea485SPieter Ghysels ierr = VecRestoreArray(x_seq,&xptr);CHKERRQ(ierr); 957d6ea485SPieter Ghysels ierr = VecScatterBegin(scat,x_seq,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 967d6ea485SPieter Ghysels ierr = VecScatterEnd(scat,x_seq,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 977d6ea485SPieter Ghysels ierr = VecScatterDestroy(&scat);CHKERRQ(ierr); 987d6ea485SPieter Ghysels ierr = VecDestroy(&x_seq);CHKERRQ(ierr); 997d6ea485SPieter Ghysels } else { 1007d6ea485SPieter Ghysels ierr = VecRestoreArray(x,&xptr);CHKERRQ(ierr); 1017d6ea485SPieter Ghysels ierr = VecRestoreArrayRead(b_mpi,&bptr);CHKERRQ(ierr); 1027d6ea485SPieter Ghysels } 1037d6ea485SPieter Ghysels 1047d6ea485SPieter Ghysels PetscFunctionReturn(0); 1057d6ea485SPieter Ghysels } 1067d6ea485SPieter Ghysels 1077d6ea485SPieter Ghysels #undef __FUNCT__ 1087d6ea485SPieter Ghysels #define __FUNCT__ "MatMatSolve_STRUMPACK" 109ad0c5e61SPieter Ghysels static PetscErrorCode MatMatSolve_STRUMPACK(Mat A,Mat B_mpi,Mat X) 1107d6ea485SPieter Ghysels { 1117d6ea485SPieter Ghysels PetscErrorCode ierr; 1127d6ea485SPieter Ghysels PetscBool flg; 1137d6ea485SPieter Ghysels 1147d6ea485SPieter Ghysels PetscFunctionBegin; 1157d6ea485SPieter Ghysels ierr = PetscObjectTypeCompareAny((PetscObject)B_mpi,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 1167d6ea485SPieter Ghysels if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 1177d6ea485SPieter Ghysels ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 1187d6ea485SPieter Ghysels if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 1197d6ea485SPieter Ghysels SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatMatSolve_STRUMPACK() is not implemented yet"); 1207d6ea485SPieter Ghysels PetscFunctionReturn(0); 1217d6ea485SPieter Ghysels } 1227d6ea485SPieter Ghysels 123ad0c5e61SPieter Ghysels #undef __FUNCT__ 124ad0c5e61SPieter Ghysels #define __FUNCT__ "MatFactorInfo_STRUMPACK" 125ad0c5e61SPieter Ghysels static PetscErrorCode MatFactorInfo_STRUMPACK(Mat A,PetscViewer viewer) 126ad0c5e61SPieter Ghysels { 127ad0c5e61SPieter Ghysels PetscErrorCode ierr; 128ad0c5e61SPieter Ghysels 129ad0c5e61SPieter Ghysels PetscFunctionBegin; 130ad0c5e61SPieter Ghysels /* check if matrix is strumpack type */ 131ad0c5e61SPieter Ghysels if (A->ops->solve != MatSolve_STRUMPACK) PetscFunctionReturn(0); 132ad0c5e61SPieter Ghysels ierr = PetscViewerASCIIPrintf(viewer,"STRUMPACK sparse solver!\n");CHKERRQ(ierr); 133ad0c5e61SPieter Ghysels PetscFunctionReturn(0); 134ad0c5e61SPieter Ghysels } 135ad0c5e61SPieter Ghysels 136ad0c5e61SPieter Ghysels #undef __FUNCT__ 137ad0c5e61SPieter Ghysels #define __FUNCT__ "MatView_STRUMPACK" 138ad0c5e61SPieter Ghysels static PetscErrorCode MatView_STRUMPACK(Mat A,PetscViewer viewer) 139ad0c5e61SPieter Ghysels { 140ad0c5e61SPieter Ghysels PetscErrorCode ierr; 141ad0c5e61SPieter Ghysels PetscBool iascii; 142ad0c5e61SPieter Ghysels PetscViewerFormat format; 143ad0c5e61SPieter Ghysels 144ad0c5e61SPieter Ghysels PetscFunctionBegin; 145ad0c5e61SPieter Ghysels ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 146ad0c5e61SPieter Ghysels if (iascii) { 147ad0c5e61SPieter Ghysels ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 148ad0c5e61SPieter Ghysels if (format == PETSC_VIEWER_ASCII_INFO) { 149ad0c5e61SPieter Ghysels ierr = MatFactorInfo_STRUMPACK(A,viewer);CHKERRQ(ierr); 150ad0c5e61SPieter Ghysels } 151ad0c5e61SPieter Ghysels } 152ad0c5e61SPieter Ghysels PetscFunctionReturn(0); 153ad0c5e61SPieter Ghysels } 1547d6ea485SPieter Ghysels 1557d6ea485SPieter Ghysels #undef __FUNCT__ 1567d6ea485SPieter Ghysels #define __FUNCT__ "MatLUFactorNumeric_STRUMPACK" 157ad0c5e61SPieter Ghysels static PetscErrorCode MatLUFactorNumeric_STRUMPACK(Mat F,Mat A,const MatFactorInfo *info) 1587d6ea485SPieter Ghysels { 1597d6ea485SPieter Ghysels STRUMPACK_data *sp = (STRUMPACK_data*)F->spptr; 1607d6ea485SPieter Ghysels STRUMPACK_RETURN_CODE sp_err; 1617d6ea485SPieter Ghysels Mat *tseq,A_seq = NULL; 1627d6ea485SPieter Ghysels Mat_SeqAIJ *A_d,*A_o; 1637d6ea485SPieter Ghysels Mat_MPIAIJ *mat; 1647d6ea485SPieter Ghysels PetscErrorCode ierr; 1657d6ea485SPieter Ghysels PetscInt M=A->rmap->N,m=A->rmap->n,N=A->cmap->N; 1667d6ea485SPieter Ghysels PetscMPIInt size; 1677d6ea485SPieter Ghysels IS isrow; 1687d6ea485SPieter Ghysels PetscBool flg; 1697d6ea485SPieter Ghysels 1707d6ea485SPieter Ghysels PetscFunctionBegin; 1717d6ea485SPieter Ghysels ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 1727d6ea485SPieter Ghysels 1737d6ea485SPieter Ghysels ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 1747d6ea485SPieter Ghysels if (flg) { /* A is MATMPIAIJ */ 1757d6ea485SPieter Ghysels if (sp->MatInputMode == REPLICATED) { 1767d6ea485SPieter Ghysels if (size > 1) { /* convert mpi A to seq mat A */ 1777d6ea485SPieter Ghysels ierr = ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);CHKERRQ(ierr); 1787d6ea485SPieter Ghysels ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq);CHKERRQ(ierr); 1797d6ea485SPieter Ghysels ierr = ISDestroy(&isrow);CHKERRQ(ierr); 1807d6ea485SPieter Ghysels A_seq = *tseq; 1817d6ea485SPieter Ghysels ierr = PetscFree(tseq);CHKERRQ(ierr); 1827d6ea485SPieter Ghysels A_d = (Mat_SeqAIJ*)A_seq->data; 1837d6ea485SPieter Ghysels } else { /* size == 1 */ 1847d6ea485SPieter Ghysels mat = (Mat_MPIAIJ*)A->data; 1857d6ea485SPieter Ghysels A_d = (Mat_SeqAIJ*)(mat->A)->data; 1867d6ea485SPieter Ghysels } 1877d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_set_csr_matrix",STRUMPACK_set_csr_matrix(sp->S,&N,A_d->i,A_d->j,A_d->a,0)); 1887d6ea485SPieter Ghysels } else { /* sp->MatInputMode == DISTRIBUTED */ 1897d6ea485SPieter Ghysels mat = (Mat_MPIAIJ*)A->data; 1907d6ea485SPieter Ghysels A_d = (Mat_SeqAIJ*)(mat->A)->data; 1917d6ea485SPieter Ghysels A_o = (Mat_SeqAIJ*)(mat->B)->data; 1927d6ea485SPieter 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)); 1937d6ea485SPieter Ghysels } 1947d6ea485SPieter Ghysels } else { /* A is MATSEQAIJ */ 1957d6ea485SPieter Ghysels A_d = (Mat_SeqAIJ*)A->data; 1967d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_set_csr_matrix",STRUMPACK_set_csr_matrix(sp->S,&N,A_d->i,A_d->j,A_d->a,0)); 1977d6ea485SPieter Ghysels } 1987d6ea485SPieter Ghysels 1997d6ea485SPieter Ghysels /* Reorder and Factor the matrix. */ 2007d6ea485SPieter Ghysels /* TODO figure out how to avoid reorder if the matrix values changed, but the pattern remains the same. */ 2017d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_reorder",sp_err = STRUMPACK_reorder(sp->S)); 2027d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_factor",sp_err = STRUMPACK_factor(sp->S)); 2037d6ea485SPieter Ghysels if (sp_err != STRUMPACK_SUCCESS) { 2047d6ea485SPieter Ghysels if (sp_err == STRUMPACK_MATRIX_NOT_SET) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix was not set"); 2057d6ea485SPieter Ghysels else if (sp_err == STRUMPACK_REORDERING_ERROR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: matrix reordering failed"); 2067d6ea485SPieter Ghysels else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"STRUMPACK error: factorization failed"); 2077d6ea485SPieter Ghysels } 2087d6ea485SPieter Ghysels if (flg && sp->MatInputMode == REPLICATED && size > 1) { 2097d6ea485SPieter Ghysels ierr = MatDestroy(&A_seq);CHKERRQ(ierr); 2107d6ea485SPieter Ghysels } 2117d6ea485SPieter Ghysels PetscFunctionReturn(0); 2127d6ea485SPieter Ghysels } 2137d6ea485SPieter Ghysels 2147d6ea485SPieter Ghysels #undef __FUNCT__ 2157d6ea485SPieter Ghysels #define __FUNCT__ "MatLUFactorSymbolic_STRUMPACK" 216ad0c5e61SPieter Ghysels static PetscErrorCode MatLUFactorSymbolic_STRUMPACK(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 2177d6ea485SPieter Ghysels { 2187d6ea485SPieter Ghysels PetscFunctionBegin; 2197d6ea485SPieter Ghysels F->ops->lufactornumeric = MatLUFactorNumeric_STRUMPACK; 2207d6ea485SPieter Ghysels F->ops->solve = MatSolve_STRUMPACK; 2217d6ea485SPieter Ghysels F->ops->matsolve = MatMatSolve_STRUMPACK; 2227d6ea485SPieter Ghysels PetscFunctionReturn(0); 2237d6ea485SPieter Ghysels } 2247d6ea485SPieter Ghysels 2257d6ea485SPieter Ghysels #undef __FUNCT__ 2267d6ea485SPieter Ghysels #define __FUNCT__ "MatFactorGetSolverPackage_aij_strumpack" 227ad0c5e61SPieter Ghysels static PetscErrorCode MatFactorGetSolverPackage_aij_strumpack(Mat A,const MatSolverPackage *type) 2287d6ea485SPieter Ghysels { 2297d6ea485SPieter Ghysels PetscFunctionBegin; 2307d6ea485SPieter Ghysels *type = MATSOLVERSTRUMPACK; 2317d6ea485SPieter Ghysels PetscFunctionReturn(0); 2327d6ea485SPieter Ghysels } 2337d6ea485SPieter Ghysels 2347d6ea485SPieter Ghysels #undef __FUNCT__ 2357d6ea485SPieter Ghysels #define __FUNCT__ "MatGetFactor_aij_strumpack" 236ad0c5e61SPieter Ghysels static PetscErrorCode MatGetFactor_aij_strumpack(Mat A,MatFactorType ftype,Mat *F) 2377d6ea485SPieter Ghysels { 2387d6ea485SPieter Ghysels Mat B; 2397d6ea485SPieter Ghysels STRUMPACK_data *sp; 2407d6ea485SPieter Ghysels PetscErrorCode ierr; 2417d6ea485SPieter Ghysels PetscInt M=A->rmap->N,N=A->cmap->N; 2427d6ea485SPieter Ghysels PetscMPIInt size; 2437d6ea485SPieter Ghysels STRUMPACK_INTERFACE iface; 2447d6ea485SPieter Ghysels PetscBool verb,flg; 2457d6ea485SPieter Ghysels int argc; 246*55c022e5SPieter Ghysels char **args,*copts,*pname; 247*55c022e5SPieter Ghysels size_t len; 2487d6ea485SPieter Ghysels const STRUMPACK_PRECISION table[2][2][2] = {{{STRUMPACK_FLOATCOMPLEX_64,STRUMPACK_DOUBLECOMPLEX_64}, 2497d6ea485SPieter Ghysels {STRUMPACK_FLOAT_64,STRUMPACK_DOUBLE_64}}, 2507d6ea485SPieter Ghysels {{STRUMPACK_FLOATCOMPLEX,STRUMPACK_DOUBLECOMPLEX}, 2517d6ea485SPieter Ghysels {STRUMPACK_FLOAT,STRUMPACK_DOUBLE}}}; 2527d6ea485SPieter Ghysels const STRUMPACK_PRECISION prec = table[(sizeof(PetscInt)==8)?0:1][(PETSC_SCALAR==PETSC_COMPLEX)?0:1][(PETSC_REAL==PETSC_FLOAT)?0:1]; 2537d6ea485SPieter Ghysels 2547d6ea485SPieter Ghysels PetscFunctionBegin; 2557d6ea485SPieter Ghysels ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 2567d6ea485SPieter Ghysels /* Create the factorization matrix */ 2577d6ea485SPieter Ghysels ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 2587d6ea485SPieter Ghysels ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,M,N);CHKERRQ(ierr); 2597d6ea485SPieter Ghysels ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2607d6ea485SPieter Ghysels ierr = MatSeqAIJSetPreallocation(B,0,NULL); 2617d6ea485SPieter Ghysels ierr = MatMPIAIJSetPreallocation(B,0,NULL,0,NULL);CHKERRQ(ierr); 2627d6ea485SPieter Ghysels B->ops->lufactorsymbolic = MatLUFactorSymbolic_STRUMPACK; 2637d6ea485SPieter Ghysels B->ops->view = MatView_STRUMPACK; 2647d6ea485SPieter Ghysels B->ops->destroy = MatDestroy_STRUMPACK; 2657d6ea485SPieter Ghysels B->ops->getdiagonal = MatGetDiagonal_STRUMPACK; 2667d6ea485SPieter Ghysels ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverPackage_C",MatFactorGetSolverPackage_aij_strumpack);CHKERRQ(ierr); 2677d6ea485SPieter Ghysels B->factortype = MAT_FACTOR_LU; 2687d6ea485SPieter Ghysels ierr = PetscNewLog(B,&sp);CHKERRQ(ierr); 2697d6ea485SPieter Ghysels B->spptr = sp; 2707d6ea485SPieter Ghysels 2717d6ea485SPieter Ghysels ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"STRUMPACK Options","Mat");CHKERRQ(ierr); 2727d6ea485SPieter Ghysels sp->MatInputMode = DISTRIBUTED; 27324a4cbefSPieter Ghysels ierr = PetscOptionsEnum("-mat_strumpack_matinput","Matrix input mode (replicated or distributed)","None",STRUMPACK_MatInputModes, 2747d6ea485SPieter Ghysels (PetscEnum)sp->MatInputMode,(PetscEnum*)&sp->MatInputMode,NULL);CHKERRQ(ierr); 2757d6ea485SPieter Ghysels if (sp->MatInputMode == DISTRIBUTED && size == 1) sp->MatInputMode = REPLICATED; 27687e1f858SPieter Ghysels switch (sp->MatInputMode) { 27787e1f858SPieter Ghysels case REPLICATED: 27887e1f858SPieter Ghysels iface = STRUMPACK_MPI; 27987e1f858SPieter Ghysels break; 28087e1f858SPieter Ghysels case DISTRIBUTED: 28187e1f858SPieter Ghysels default: 28287e1f858SPieter Ghysels iface = STRUMPACK_MPI_DIST; 28387e1f858SPieter Ghysels } 2847d6ea485SPieter Ghysels ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg); 2857d6ea485SPieter Ghysels if (flg) iface = STRUMPACK_MT; 2867d6ea485SPieter Ghysels 2877d6ea485SPieter Ghysels if (PetscLogPrintInfo) verb = PETSC_TRUE; 2887d6ea485SPieter Ghysels else verb = PETSC_FALSE; 2897d6ea485SPieter Ghysels ierr = PetscOptionsBool("-mat_strumpack_verbose","Print STRUMPACK information","None",verb,&verb,NULL);CHKERRQ(ierr); 2907d6ea485SPieter Ghysels PetscOptionsEnd(); 2917d6ea485SPieter Ghysels 292*55c022e5SPieter Ghysels ierr = PetscOptionsGetAll(NULL,&copts);CHKERRQ(ierr); 293*55c022e5SPieter Ghysels ierr = PetscStrlen(copts,&len);CHKERRQ(ierr); 294*55c022e5SPieter Ghysels len += PETSC_MAX_PATH_LEN+1; 295*55c022e5SPieter Ghysels ierr = PetscMalloc1(len,&pname);CHKERRQ(ierr); 296*55c022e5SPieter Ghysels /* first string is assumed to be the program name, so add program name to options string */ 297*55c022e5SPieter Ghysels ierr = PetscGetProgramName(pname,len);CHKERRQ(ierr); 298*55c022e5SPieter Ghysels ierr = PetscStrcat(pname," ");CHKERRQ(ierr); 299*55c022e5SPieter Ghysels ierr = PetscStrcat(pname,copts);CHKERRQ(ierr); 300*55c022e5SPieter Ghysels ierr = PetscStrToArray(copts,' ',&argc,&args);CHKERRQ(ierr); 301*55c022e5SPieter Ghysels ierr = PetscFree(copts);CHKERRQ(ierr); 302*55c022e5SPieter Ghysels ierr = PetscFree(pname);CHKERRQ(ierr); 303*55c022e5SPieter Ghysels 3047d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_init",STRUMPACK_init(&(sp->S),PetscObjectComm((PetscObject)A),prec,iface,argc,args,verb)); 3057d6ea485SPieter Ghysels PetscStackCall("STRUMPACK_set_from_options",STRUMPACK_set_from_options(sp->S)); 3067d6ea485SPieter Ghysels 307*55c022e5SPieter Ghysels ierr = PetscStrToArrayDestroy(argc,args);CHKERRQ(ierr); 308*55c022e5SPieter Ghysels 3097d6ea485SPieter Ghysels *F = B; 3107d6ea485SPieter Ghysels PetscFunctionReturn(0); 3117d6ea485SPieter Ghysels } 3127d6ea485SPieter Ghysels 3137d6ea485SPieter Ghysels #undef __FUNCT__ 3147d6ea485SPieter Ghysels #define __FUNCT__ "MatSolverPackageRegister_STRUMPACK" 3157d6ea485SPieter Ghysels PETSC_EXTERN PetscErrorCode MatSolverPackageRegister_STRUMPACK(void) 3167d6ea485SPieter Ghysels { 3177d6ea485SPieter Ghysels PetscErrorCode ierr; 3187d6ea485SPieter Ghysels 3197d6ea485SPieter Ghysels PetscFunctionBegin; 3207d6ea485SPieter Ghysels ierr = MatSolverPackageRegister(MATSOLVERSTRUMPACK,MATMPIAIJ,MAT_FACTOR_LU,MatGetFactor_aij_strumpack);CHKERRQ(ierr); 3217d6ea485SPieter Ghysels ierr = MatSolverPackageRegister(MATSOLVERSTRUMPACK,MATSEQAIJ,MAT_FACTOR_LU,MatGetFactor_aij_strumpack);CHKERRQ(ierr); 3227d6ea485SPieter Ghysels PetscFunctionReturn(0); 3237d6ea485SPieter Ghysels } 3247d6ea485SPieter Ghysels 3257d6ea485SPieter Ghysels /*MC 3267d6ea485SPieter Ghysels MATSOLVERSSTRUMPACK - Parallel direct solver package for LU factorization 3277d6ea485SPieter Ghysels 3287d6ea485SPieter Ghysels Use ./configure --download-strumpack to have PETSc installed with STRUMPACK 3297d6ea485SPieter Ghysels 3307d6ea485SPieter Ghysels Use -pc_type lu -pc_factor_mat_solver_package strumpack to us this direct solver 3317d6ea485SPieter Ghysels 3327d6ea485SPieter Ghysels Works with AIJ matrices 3337d6ea485SPieter Ghysels 3347d6ea485SPieter Ghysels .seealso: PCLU 3357d6ea485SPieter Ghysels 3367d6ea485SPieter Ghysels .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage 3377d6ea485SPieter Ghysels 3387d6ea485SPieter Ghysels M*/ 3397d6ea485SPieter Ghysels 340