xref: /petsc/src/mat/impls/aij/mpi/strumpack/strumpack.c (revision 35e8bcc9b13184a6215398dcbff985cf336427a0)
148f88336SPieter Ghysels #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/
27d6ea485SPieter Ghysels #include <../src/mat/impls/aij/mpi/mpiaij.h>
37d6ea485SPieter Ghysels #include <StrumpackSparseSolver.h>
47d6ea485SPieter Ghysels 
5d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_STRUMPACK(Mat A, Vec v)
6d71ae5a4SJacob Faibussowitsch {
77d6ea485SPieter Ghysels   PetscFunctionBegin;
87d6ea485SPieter Ghysels   SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type: STRUMPACK factor");
93ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
107d6ea485SPieter Ghysels }
117d6ea485SPieter Ghysels 
12d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDestroy_STRUMPACK(Mat A)
13d71ae5a4SJacob Faibussowitsch {
14*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)A->data;
157d6ea485SPieter Ghysels 
167d6ea485SPieter Ghysels   PetscFunctionBegin;
177d6ea485SPieter Ghysels   /* Deallocate STRUMPACK storage */
18e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_destroy", STRUMPACK_destroy(S));
19*35e8bcc9SJunchao Zhang   PetscCall(PetscFree(A->data));
20575704cbSPieter Ghysels 
21575704cbSPieter Ghysels   /* clear composed functions */
229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatFactorGetSolverType_C", NULL));
239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetReordering_C", NULL));
249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetColPerm_C", NULL));
259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetHSSRelTol_C", NULL));
269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetHSSAbsTol_C", NULL));
279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetHSSMaxRank_C", NULL));
289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetHSSLeafSize_C", NULL));
299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSTRUMPACKSetHSSMinSepSize_C", NULL));
30575704cbSPieter Ghysels 
313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32575704cbSPieter Ghysels }
33575704cbSPieter Ghysels 
34d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetReordering_STRUMPACK(Mat F, MatSTRUMPACKReordering reordering)
35d71ae5a4SJacob Faibussowitsch {
36*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
37575704cbSPieter Ghysels 
38575704cbSPieter Ghysels   PetscFunctionBegin;
39e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_reordering_method", STRUMPACK_set_reordering_method(*S, (STRUMPACK_REORDERING_STRATEGY)reordering));
403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4134f43fa5SPieter Ghysels }
42e5a36eccSStefano Zampini 
43542aee0fSPieter Ghysels /*@
4434f43fa5SPieter Ghysels   MatSTRUMPACKSetReordering - Set STRUMPACK fill-reducing reordering
4534f43fa5SPieter Ghysels 
4634f43fa5SPieter Ghysels    Input Parameters:
4711a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor(`) from PETSc-STRUMPACK interface
4834f43fa5SPieter Ghysels -  reordering - the code to be used to find the fill-reducing reordering
4934f43fa5SPieter Ghysels       Possible values: NATURAL=0 METIS=1 PARMETIS=2 SCOTCH=3 PTSCOTCH=4 RCM=5
5034f43fa5SPieter Ghysels 
5111a5261eSBarry Smith   Options Database Key:
5234f43fa5SPieter Ghysels .   -mat_strumpack_reordering <METIS>  - Sparsity reducing matrix reordering (choose one of) NATURAL METIS PARMETIS SCOTCH PTSCOTCH RCM (None)
5334f43fa5SPieter Ghysels 
5434f43fa5SPieter Ghysels    Level: beginner
5534f43fa5SPieter Ghysels 
5634f43fa5SPieter Ghysels    References:
57606c0280SSatish Balay .  * - STRUMPACK manual
5834f43fa5SPieter Ghysels 
59db781477SPatrick Sanan .seealso: `MatGetFactor()`
60542aee0fSPieter Ghysels @*/
61d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetReordering(Mat F, MatSTRUMPACKReordering reordering)
62d71ae5a4SJacob Faibussowitsch {
6334f43fa5SPieter Ghysels   PetscFunctionBegin;
6434f43fa5SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
6534f43fa5SPieter Ghysels   PetscValidLogicalCollectiveEnum(F, reordering, 2);
66cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetReordering_C", (Mat, MatSTRUMPACKReordering), (F, reordering));
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
68575704cbSPieter Ghysels }
69575704cbSPieter Ghysels 
70d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetColPerm_STRUMPACK(Mat F, PetscBool cperm)
71d71ae5a4SJacob Faibussowitsch {
72*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
7334f43fa5SPieter Ghysels 
7434f43fa5SPieter Ghysels   PetscFunctionBegin;
75e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_mc64job", STRUMPACK_set_mc64job(*S, cperm ? 5 : 0));
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7734f43fa5SPieter Ghysels }
78e5a36eccSStefano Zampini 
79575704cbSPieter Ghysels /*@
8034f43fa5SPieter Ghysels   MatSTRUMPACKSetColPerm - Set whether STRUMPACK should try to permute the columns of the matrix in order to get a nonzero diagonal
81147403d9SBarry Smith 
82c3339decSBarry Smith    Logically Collective
83575704cbSPieter Ghysels 
84575704cbSPieter Ghysels    Input Parameters:
8511a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
8611a5261eSBarry Smith -  cperm - `PETSC_TRUE` to permute (internally) the columns of the matrix
87575704cbSPieter Ghysels 
8811a5261eSBarry Smith   Options Database Key:
89147403d9SBarry Smith .   -mat_strumpack_colperm <cperm> - true to use the permutation
90575704cbSPieter Ghysels 
91575704cbSPieter Ghysels    Level: beginner
92575704cbSPieter Ghysels 
93575704cbSPieter Ghysels    References:
94606c0280SSatish Balay .  * - STRUMPACK manual
95575704cbSPieter Ghysels 
96db781477SPatrick Sanan .seealso: `MatGetFactor()`
97575704cbSPieter Ghysels @*/
98d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetColPerm(Mat F, PetscBool cperm)
99d71ae5a4SJacob Faibussowitsch {
100575704cbSPieter Ghysels   PetscFunctionBegin;
101575704cbSPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
10234f43fa5SPieter Ghysels   PetscValidLogicalCollectiveBool(F, cperm, 2);
103cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetColPerm_C", (Mat, PetscBool), (F, cperm));
1043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
105575704cbSPieter Ghysels }
106575704cbSPieter Ghysels 
107d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetHSSRelTol_STRUMPACK(Mat F, PetscReal rtol)
108d71ae5a4SJacob Faibussowitsch {
109*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
11034f43fa5SPieter Ghysels 
11134f43fa5SPieter Ghysels   PetscFunctionBegin;
112e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_HSS_rel_tol", STRUMPACK_set_HSS_rel_tol(*S, rtol));
1133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11434f43fa5SPieter Ghysels }
115e5a36eccSStefano Zampini 
11634f43fa5SPieter Ghysels /*@
11734f43fa5SPieter Ghysels   MatSTRUMPACKSetHSSRelTol - Set STRUMPACK relative tolerance for HSS compression
118147403d9SBarry Smith 
119c3339decSBarry Smith   Logically Collective
12034f43fa5SPieter Ghysels 
12134f43fa5SPieter Ghysels    Input Parameters:
12211a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
12334f43fa5SPieter Ghysels -  rtol - relative compression tolerance
12434f43fa5SPieter Ghysels 
12511a5261eSBarry Smith   Options Database Key:
12634f43fa5SPieter Ghysels .   -mat_strumpack_hss_rel_tol <1e-2>         - Relative compression tolerance (None)
12734f43fa5SPieter Ghysels 
12834f43fa5SPieter Ghysels    Level: beginner
12934f43fa5SPieter Ghysels 
13034f43fa5SPieter Ghysels    References:
131606c0280SSatish Balay .  * - STRUMPACK manual
13234f43fa5SPieter Ghysels 
133db781477SPatrick Sanan .seealso: `MatGetFactor()`
13434f43fa5SPieter Ghysels @*/
135d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetHSSRelTol(Mat F, PetscReal rtol)
136d71ae5a4SJacob Faibussowitsch {
13734f43fa5SPieter Ghysels   PetscFunctionBegin;
13834f43fa5SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
13934f43fa5SPieter Ghysels   PetscValidLogicalCollectiveReal(F, rtol, 2);
140cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetHSSRelTol_C", (Mat, PetscReal), (F, rtol));
1413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14234f43fa5SPieter Ghysels }
14334f43fa5SPieter Ghysels 
144d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetHSSAbsTol_STRUMPACK(Mat F, PetscReal atol)
145d71ae5a4SJacob Faibussowitsch {
146*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
14734f43fa5SPieter Ghysels 
14834f43fa5SPieter Ghysels   PetscFunctionBegin;
149e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_HSS_abs_tol", STRUMPACK_set_HSS_abs_tol(*S, atol));
1503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15134f43fa5SPieter Ghysels }
152e5a36eccSStefano Zampini 
15334f43fa5SPieter Ghysels /*@
15434f43fa5SPieter Ghysels   MatSTRUMPACKSetHSSAbsTol - Set STRUMPACK absolute tolerance for HSS compression
155147403d9SBarry Smith 
156c3339decSBarry Smith    Logically Collective
15734f43fa5SPieter Ghysels 
15834f43fa5SPieter Ghysels    Input Parameters:
15911a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
16034f43fa5SPieter Ghysels -  atol - absolute compression tolerance
16134f43fa5SPieter Ghysels 
16211a5261eSBarry Smith   Options Database Key:
16334f43fa5SPieter Ghysels .   -mat_strumpack_hss_abs_tol <1e-8>         - Absolute compression tolerance (None)
16434f43fa5SPieter Ghysels 
16534f43fa5SPieter Ghysels    Level: beginner
16634f43fa5SPieter Ghysels 
16734f43fa5SPieter Ghysels    References:
168606c0280SSatish Balay .  * - STRUMPACK manual
16934f43fa5SPieter Ghysels 
170db781477SPatrick Sanan .seealso: `MatGetFactor()`
17134f43fa5SPieter Ghysels @*/
172d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetHSSAbsTol(Mat F, PetscReal atol)
173d71ae5a4SJacob Faibussowitsch {
17434f43fa5SPieter Ghysels   PetscFunctionBegin;
17534f43fa5SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
17634f43fa5SPieter Ghysels   PetscValidLogicalCollectiveReal(F, atol, 2);
177cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetHSSAbsTol_C", (Mat, PetscReal), (F, atol));
1783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17934f43fa5SPieter Ghysels }
18034f43fa5SPieter Ghysels 
181d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetHSSMaxRank_STRUMPACK(Mat F, PetscInt hssmaxrank)
182d71ae5a4SJacob Faibussowitsch {
183*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
18434f43fa5SPieter Ghysels 
18534f43fa5SPieter Ghysels   PetscFunctionBegin;
186e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_HSS_max_rank", STRUMPACK_set_HSS_max_rank(*S, hssmaxrank));
1873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18834f43fa5SPieter Ghysels }
189e5a36eccSStefano Zampini 
19034f43fa5SPieter Ghysels /*@
19134f43fa5SPieter Ghysels   MatSTRUMPACKSetHSSMaxRank - Set STRUMPACK maximum HSS rank
192147403d9SBarry Smith 
193c3339decSBarry Smith    Logically Collective
19434f43fa5SPieter Ghysels 
19534f43fa5SPieter Ghysels    Input Parameters:
19611a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
19734f43fa5SPieter Ghysels -  hssmaxrank - maximum rank used in low-rank approximation
19834f43fa5SPieter Ghysels 
19911a5261eSBarry Smith   Options Database Key:
20034f43fa5SPieter Ghysels .   -mat_strumpack_max_rank - Maximum rank in HSS compression, when using pctype ilu (None)
20134f43fa5SPieter Ghysels 
20234f43fa5SPieter Ghysels    Level: beginner
20334f43fa5SPieter Ghysels 
20434f43fa5SPieter Ghysels    References:
205606c0280SSatish Balay .  * - STRUMPACK manual
20634f43fa5SPieter Ghysels 
207db781477SPatrick Sanan .seealso: `MatGetFactor()`
20834f43fa5SPieter Ghysels @*/
209d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetHSSMaxRank(Mat F, PetscInt hssmaxrank)
210d71ae5a4SJacob Faibussowitsch {
21134f43fa5SPieter Ghysels   PetscFunctionBegin;
21234f43fa5SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
21334f43fa5SPieter Ghysels   PetscValidLogicalCollectiveInt(F, hssmaxrank, 2);
214cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetHSSMaxRank_C", (Mat, PetscInt), (F, hssmaxrank));
2153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21634f43fa5SPieter Ghysels }
21734f43fa5SPieter Ghysels 
218d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetHSSLeafSize_STRUMPACK(Mat F, PetscInt leaf_size)
219d71ae5a4SJacob Faibussowitsch {
220*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
221a36bf211SPieter Ghysels 
222a36bf211SPieter Ghysels   PetscFunctionBegin;
223e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_HSS_leaf_size", STRUMPACK_set_HSS_leaf_size(*S, leaf_size));
2243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
225a36bf211SPieter Ghysels }
226e5a36eccSStefano Zampini 
227a36bf211SPieter Ghysels /*@
228a36bf211SPieter Ghysels   MatSTRUMPACKSetHSSLeafSize - Set STRUMPACK HSS leaf size
229147403d9SBarry Smith 
230c3339decSBarry Smith    Logically Collective
231a36bf211SPieter Ghysels 
232a36bf211SPieter Ghysels    Input Parameters:
23311a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
234a36bf211SPieter Ghysels -  leaf_size - Size of diagonal blocks in HSS approximation
235a36bf211SPieter Ghysels 
23611a5261eSBarry Smith   Options Database Key:
237a36bf211SPieter Ghysels .   -mat_strumpack_leaf_size - Size of diagonal blocks in HSS approximation, when using pctype ilu (None)
238a36bf211SPieter Ghysels 
239a36bf211SPieter Ghysels    Level: beginner
240a36bf211SPieter Ghysels 
241a36bf211SPieter Ghysels    References:
242606c0280SSatish Balay .  * - STRUMPACK manual
243a36bf211SPieter Ghysels 
244db781477SPatrick Sanan .seealso: `MatGetFactor()`
245a36bf211SPieter Ghysels @*/
246d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetHSSLeafSize(Mat F, PetscInt leaf_size)
247d71ae5a4SJacob Faibussowitsch {
248a36bf211SPieter Ghysels   PetscFunctionBegin;
249a36bf211SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
250a36bf211SPieter Ghysels   PetscValidLogicalCollectiveInt(F, leaf_size, 2);
251cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetHSSLeafSize_C", (Mat, PetscInt), (F, leaf_size));
2523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
253a36bf211SPieter Ghysels }
254a36bf211SPieter Ghysels 
255d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSTRUMPACKSetHSSMinSepSize_STRUMPACK(Mat F, PetscInt hssminsize)
256d71ae5a4SJacob Faibussowitsch {
257*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
25834f43fa5SPieter Ghysels 
25934f43fa5SPieter Ghysels   PetscFunctionBegin;
260e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_HSS_min_sep_size", STRUMPACK_set_HSS_min_sep_size(*S, hssminsize));
2613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26234f43fa5SPieter Ghysels }
263e5a36eccSStefano Zampini 
264291d0ed5SPieter Ghysels /*@
265291d0ed5SPieter Ghysels   MatSTRUMPACKSetHSSMinSepSize - Set STRUMPACK minimum separator size for low-rank approximation
266147403d9SBarry Smith 
267c3339decSBarry Smith    Logically Collective
268291d0ed5SPieter Ghysels 
269291d0ed5SPieter Ghysels    Input Parameters:
27011a5261eSBarry Smith +  F - the factored matrix obtained by calling `MatGetFactor()` from PETSc-STRUMPACK interface
271291d0ed5SPieter Ghysels -  hssminsize - minimum dense matrix size for low-rank approximation
272291d0ed5SPieter Ghysels 
27311a5261eSBarry Smith   Options Database Key:
274147403d9SBarry Smith .   -mat_strumpack_hss_min_sep_size <hssminsize> - set the minimum separator size
275291d0ed5SPieter Ghysels 
276291d0ed5SPieter Ghysels    Level: beginner
277291d0ed5SPieter Ghysels 
278291d0ed5SPieter Ghysels    References:
279606c0280SSatish Balay .  * - STRUMPACK manual
280291d0ed5SPieter Ghysels 
281db781477SPatrick Sanan .seealso: `MatGetFactor()`
282291d0ed5SPieter Ghysels @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSTRUMPACKSetHSSMinSepSize(Mat F, PetscInt hssminsize)
284d71ae5a4SJacob Faibussowitsch {
285291d0ed5SPieter Ghysels   PetscFunctionBegin;
286291d0ed5SPieter Ghysels   PetscValidHeaderSpecific(F, MAT_CLASSID, 1);
287291d0ed5SPieter Ghysels   PetscValidLogicalCollectiveInt(F, hssminsize, 2);
288cac4c232SBarry Smith   PetscTryMethod(F, "MatSTRUMPACKSetHSSMinSepSize_C", (Mat, PetscInt), (F, hssminsize));
2893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
290291d0ed5SPieter Ghysels }
291291d0ed5SPieter Ghysels 
292d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_STRUMPACK(Mat A, Vec b_mpi, Vec x)
293d71ae5a4SJacob Faibussowitsch {
294*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)A->data;
2957d6ea485SPieter Ghysels   STRUMPACK_RETURN_CODE   sp_err;
2967d6ea485SPieter Ghysels   const PetscScalar      *bptr;
2977d6ea485SPieter Ghysels   PetscScalar            *xptr;
2987d6ea485SPieter Ghysels 
2997d6ea485SPieter Ghysels   PetscFunctionBegin;
3009566063dSJacob Faibussowitsch   PetscCall(VecGetArray(x, &xptr));
3019566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(b_mpi, &bptr));
3020d08a34dSPieter Ghysels 
303e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_solve", sp_err = STRUMPACK_solve(*S, (PetscScalar *)bptr, xptr, 0));
3040d08a34dSPieter Ghysels   switch (sp_err) {
305d71ae5a4SJacob Faibussowitsch   case STRUMPACK_SUCCESS:
306d71ae5a4SJacob Faibussowitsch     break;
3079371c9d4SSatish Balay   case STRUMPACK_MATRIX_NOT_SET: {
3089371c9d4SSatish Balay     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: matrix was not set");
3099371c9d4SSatish Balay     break;
3109371c9d4SSatish Balay   }
3119371c9d4SSatish Balay   case STRUMPACK_REORDERING_ERROR: {
3129371c9d4SSatish Balay     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: matrix reordering failed");
3139371c9d4SSatish Balay     break;
3149371c9d4SSatish Balay   }
315d71ae5a4SJacob Faibussowitsch   default:
316d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: solve failed");
3177d6ea485SPieter Ghysels   }
3189566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(x, &xptr));
3199566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(b_mpi, &bptr));
3203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3217d6ea485SPieter Ghysels }
3227d6ea485SPieter Ghysels 
323d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_STRUMPACK(Mat A, Mat B_mpi, Mat X)
324d71ae5a4SJacob Faibussowitsch {
3257d6ea485SPieter Ghysels   PetscBool flg;
3267d6ea485SPieter Ghysels 
3277d6ea485SPieter Ghysels   PetscFunctionBegin;
3289566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)B_mpi, &flg, MATSEQDENSE, MATMPIDENSE, NULL));
3295f80ce2aSJacob Faibussowitsch   PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Matrix B must be MATDENSE matrix");
3309566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &flg, MATSEQDENSE, MATMPIDENSE, NULL));
3315f80ce2aSJacob Faibussowitsch   PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Matrix X must be MATDENSE matrix");
3327d6ea485SPieter Ghysels   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "MatMatSolve_STRUMPACK() is not implemented yet");
3333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3347d6ea485SPieter Ghysels }
3357d6ea485SPieter Ghysels 
336d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_Info_STRUMPACK(Mat A, PetscViewer viewer)
337d71ae5a4SJacob Faibussowitsch {
338ad0c5e61SPieter Ghysels   PetscFunctionBegin;
339ad0c5e61SPieter Ghysels   /* check if matrix is strumpack type */
3403ba16761SJacob Faibussowitsch   if (A->ops->solve != MatSolve_STRUMPACK) PetscFunctionReturn(PETSC_SUCCESS);
3419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "STRUMPACK sparse solver!\n"));
3423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
343ad0c5e61SPieter Ghysels }
344ad0c5e61SPieter Ghysels 
345d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_STRUMPACK(Mat A, PetscViewer viewer)
346d71ae5a4SJacob Faibussowitsch {
347ad0c5e61SPieter Ghysels   PetscBool         iascii;
348ad0c5e61SPieter Ghysels   PetscViewerFormat format;
349ad0c5e61SPieter Ghysels 
350ad0c5e61SPieter Ghysels   PetscFunctionBegin;
3519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
352ad0c5e61SPieter Ghysels   if (iascii) {
3539566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(viewer, &format));
3549566063dSJacob Faibussowitsch     if (format == PETSC_VIEWER_ASCII_INFO) PetscCall(MatView_Info_STRUMPACK(A, viewer));
355ad0c5e61SPieter Ghysels   }
3563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
357ad0c5e61SPieter Ghysels }
3587d6ea485SPieter Ghysels 
359d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_STRUMPACK(Mat F, Mat A, const MatFactorInfo *info)
360d71ae5a4SJacob Faibussowitsch {
361*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver *S = (STRUMPACK_SparseSolver *)F->data;
3627d6ea485SPieter Ghysels   STRUMPACK_RETURN_CODE   sp_err;
3637d6ea485SPieter Ghysels   Mat_SeqAIJ             *A_d, *A_o;
3647d6ea485SPieter Ghysels   Mat_MPIAIJ             *mat;
3650d08a34dSPieter Ghysels   PetscInt                M = A->rmap->N, m = A->rmap->n;
3667d6ea485SPieter Ghysels   PetscBool               flg;
367*35e8bcc9SJunchao Zhang   const PetscScalar      *A_d_a, *A_o_a;
3687d6ea485SPieter Ghysels 
3697d6ea485SPieter Ghysels   PetscFunctionBegin;
370*35e8bcc9SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &flg));
371*35e8bcc9SJunchao Zhang   if (flg) { /* A might be MATMPIAIJCUSPARSE etc */
3727d6ea485SPieter Ghysels     mat = (Mat_MPIAIJ *)A->data;
373*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJGetArrayRead(mat->A, &A_d_a)); /* Make sure mat is sync'ed to host */
374*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJGetArrayRead(mat->B, &A_o_a));
3757d6ea485SPieter Ghysels     A_d = (Mat_SeqAIJ *)(mat->A)->data;
3767d6ea485SPieter Ghysels     A_o = (Mat_SeqAIJ *)(mat->B)->data;
377*35e8bcc9SJunchao Zhang     PetscStackCallExternalVoid("STRUMPACK_set_MPIAIJ_matrix", STRUMPACK_set_MPIAIJ_matrix(*S, &m, A_d->i, A_d->j, A_d_a, A_o->i, A_o->j, A_o_a, mat->garray));
378*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJRestoreArrayRead(mat->A, &A_d_a));
379*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJRestoreArrayRead(mat->B, &A_o_a));
380*35e8bcc9SJunchao Zhang   } else { /* A might be MATSEQAIJCUSPARSE etc */
381*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJGetArrayRead(A, &A_d_a));
3827d6ea485SPieter Ghysels     A_d = (Mat_SeqAIJ *)A->data;
383*35e8bcc9SJunchao Zhang     PetscStackCallExternalVoid("STRUMPACK_set_csr_matrix", STRUMPACK_set_csr_matrix(*S, &M, A_d->i, A_d->j, A_d_a, 0));
384*35e8bcc9SJunchao Zhang     PetscCall(MatSeqAIJRestoreArrayRead(A, &A_d_a));
3857d6ea485SPieter Ghysels   }
3867d6ea485SPieter Ghysels 
3877d6ea485SPieter Ghysels   /* Reorder and Factor the matrix. */
3887d6ea485SPieter Ghysels   /* TODO figure out how to avoid reorder if the matrix values changed, but the pattern remains the same. */
389e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_reorder", sp_err = STRUMPACK_reorder(*S));
390e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_factor", sp_err = STRUMPACK_factor(*S));
3910d08a34dSPieter Ghysels   switch (sp_err) {
392d71ae5a4SJacob Faibussowitsch   case STRUMPACK_SUCCESS:
393d71ae5a4SJacob Faibussowitsch     break;
3949371c9d4SSatish Balay   case STRUMPACK_MATRIX_NOT_SET: {
3959371c9d4SSatish Balay     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: matrix was not set");
3969371c9d4SSatish Balay     break;
3979371c9d4SSatish Balay   }
3989371c9d4SSatish Balay   case STRUMPACK_REORDERING_ERROR: {
3999371c9d4SSatish Balay     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: matrix reordering failed");
4009371c9d4SSatish Balay     break;
4019371c9d4SSatish Balay   }
402d71ae5a4SJacob Faibussowitsch   default:
403d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "STRUMPACK error: factorization failed");
4047d6ea485SPieter Ghysels   }
405cb250fa3SPieter Ghysels   F->assembled    = PETSC_TRUE;
406cb250fa3SPieter Ghysels   F->preallocated = PETSC_TRUE;
4073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4087d6ea485SPieter Ghysels }
4097d6ea485SPieter Ghysels 
410d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorSymbolic_STRUMPACK(Mat F, Mat A, IS r, IS c, const MatFactorInfo *info)
411d71ae5a4SJacob Faibussowitsch {
412*35e8bcc9SJunchao Zhang   STRUMPACK_SparseSolver       *S = (STRUMPACK_SparseSolver *)F->data;
41326cc229bSBarry Smith   PetscBool                     flg, set;
41426cc229bSBarry Smith   PetscReal                     ctol;
41526cc229bSBarry Smith   PetscInt                      hssminsize, max_rank, leaf_size;
41626cc229bSBarry Smith   STRUMPACK_REORDERING_STRATEGY ndcurrent, ndvalue;
41726cc229bSBarry Smith   STRUMPACK_KRYLOV_SOLVER       itcurrent, itsolver;
41826cc229bSBarry Smith   const char *const             STRUMPACKNDTypes[] = {"NATURAL", "METIS", "PARMETIS", "SCOTCH", "PTSCOTCH", "RCM", "STRUMPACKNDTypes", "", 0};
41926cc229bSBarry Smith   const char *const             SolverTypes[]      = {"AUTO", "NONE", "REFINE", "PREC_GMRES", "GMRES", "PREC_BICGSTAB", "BICGSTAB", "SolverTypes", "", 0};
42026cc229bSBarry Smith 
4217d6ea485SPieter Ghysels   PetscFunctionBegin;
42226cc229bSBarry Smith   /* Set options to F */
42326cc229bSBarry Smith   PetscOptionsBegin(PetscObjectComm((PetscObject)F), ((PetscObject)F)->prefix, "STRUMPACK Options", "Mat");
424e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_HSS_rel_tol", ctol = (PetscReal)STRUMPACK_HSS_rel_tol(*S));
42526cc229bSBarry Smith   PetscCall(PetscOptionsReal("-mat_strumpack_hss_rel_tol", "Relative compression tolerance", "None", ctol, &ctol, &set));
426e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_HSS_rel_tol", STRUMPACK_set_HSS_rel_tol(*S, (double)ctol));
42726cc229bSBarry Smith 
428e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_HSS_abs_tol", ctol = (PetscReal)STRUMPACK_HSS_abs_tol(*S));
42926cc229bSBarry Smith   PetscCall(PetscOptionsReal("-mat_strumpack_hss_abs_tol", "Absolute compression tolerance", "None", ctol, &ctol, &set));
430e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_HSS_abs_tol", STRUMPACK_set_HSS_abs_tol(*S, (double)ctol));
43126cc229bSBarry Smith 
432e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_mc64job", flg = (STRUMPACK_mc64job(*S) == 0) ? PETSC_FALSE : PETSC_TRUE);
43326cc229bSBarry Smith   PetscCall(PetscOptionsBool("-mat_strumpack_colperm", "Find a col perm to get nonzero diagonal", "None", flg, &flg, &set));
434e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_mc64job", STRUMPACK_set_mc64job(*S, flg ? 5 : 0));
43526cc229bSBarry Smith 
436e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_HSS_min_sep_size", hssminsize = (PetscInt)STRUMPACK_HSS_min_sep_size(*S));
43726cc229bSBarry Smith   PetscCall(PetscOptionsInt("-mat_strumpack_hss_min_sep_size", "Minimum size of separator for HSS compression", "None", hssminsize, &hssminsize, &set));
438e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_HSS_min_sep_size", STRUMPACK_set_HSS_min_sep_size(*S, (int)hssminsize));
43926cc229bSBarry Smith 
440e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_HSS_max_rank", max_rank = (PetscInt)STRUMPACK_HSS_max_rank(*S));
44126cc229bSBarry Smith   PetscCall(PetscOptionsInt("-mat_strumpack_max_rank", "Maximum rank in HSS approximation", "None", max_rank, &max_rank, &set));
442e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_HSS_max_rank", STRUMPACK_set_HSS_max_rank(*S, (int)max_rank));
44326cc229bSBarry Smith 
444e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_HSS_leaf_size", leaf_size = (PetscInt)STRUMPACK_HSS_leaf_size(*S));
44526cc229bSBarry Smith   PetscCall(PetscOptionsInt("-mat_strumpack_leaf_size", "Size of diagonal blocks in HSS approximation", "None", leaf_size, &leaf_size, &set));
446e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_HSS_leaf_size", STRUMPACK_set_HSS_leaf_size(*S, (int)leaf_size));
44726cc229bSBarry Smith 
448e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_reordering_method", ndcurrent = STRUMPACK_reordering_method(*S));
44926cc229bSBarry Smith   PetscCall(PetscOptionsEnum("-mat_strumpack_reordering", "Sparsity reducing matrix reordering", "None", STRUMPACKNDTypes, (PetscEnum)ndcurrent, (PetscEnum *)&ndvalue, &set));
450e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_reordering_method", STRUMPACK_set_reordering_method(*S, ndvalue));
45126cc229bSBarry Smith 
45226cc229bSBarry Smith   /* Disable the outer iterative solver from STRUMPACK.                                       */
45326cc229bSBarry Smith   /* When STRUMPACK is used as a direct solver, it will by default do iterative refinement.   */
45426cc229bSBarry Smith   /* When STRUMPACK is used as an approximate factorization preconditioner (by enabling       */
45526cc229bSBarry Smith   /* low-rank compression), it will use it's own preconditioned GMRES. Here we can disable    */
45626cc229bSBarry Smith   /* the outer iterative solver, as PETSc uses STRUMPACK from within a KSP.                   */
457e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_set_Krylov_solver", STRUMPACK_set_Krylov_solver(*S, STRUMPACK_DIRECT));
45826cc229bSBarry Smith 
459e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_Krylov_solver", itcurrent = STRUMPACK_Krylov_solver(*S));
46026cc229bSBarry Smith   PetscCall(PetscOptionsEnum("-mat_strumpack_iterative_solver", "Select iterative solver from STRUMPACK", "None", SolverTypes, (PetscEnum)itcurrent, (PetscEnum *)&itsolver, &set));
461e77caa6dSBarry Smith   if (set) PetscStackCallExternalVoid("STRUMPACK_set_Krylov_solver", STRUMPACK_set_Krylov_solver(*S, itsolver));
46226cc229bSBarry Smith   PetscOptionsEnd();
46326cc229bSBarry Smith 
4647d6ea485SPieter Ghysels   F->ops->lufactornumeric = MatLUFactorNumeric_STRUMPACK;
4657d6ea485SPieter Ghysels   F->ops->solve           = MatSolve_STRUMPACK;
4667d6ea485SPieter Ghysels   F->ops->matsolve        = MatMatSolve_STRUMPACK;
4673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4687d6ea485SPieter Ghysels }
4697d6ea485SPieter Ghysels 
470d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatFactorGetSolverType_aij_strumpack(Mat A, MatSolverType *type)
471d71ae5a4SJacob Faibussowitsch {
4727d6ea485SPieter Ghysels   PetscFunctionBegin;
4737d6ea485SPieter Ghysels   *type = MATSOLVERSTRUMPACK;
4743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4757d6ea485SPieter Ghysels }
4767d6ea485SPieter Ghysels 
477575704cbSPieter Ghysels /*MC
478575704cbSPieter Ghysels   MATSOLVERSSTRUMPACK = "strumpack" - A solver package providing a direct sparse solver (PCLU)
479575704cbSPieter Ghysels   and a preconditioner (PCILU) using low-rank compression via the external package STRUMPACK.
480575704cbSPieter Ghysels 
481575704cbSPieter Ghysels   Consult the STRUMPACK-sparse manual for more info.
482575704cbSPieter Ghysels 
483575704cbSPieter Ghysels   Use
484575704cbSPieter Ghysels      ./configure --download-strumpack
485575704cbSPieter Ghysels   to have PETSc installed with STRUMPACK
486575704cbSPieter Ghysels 
487575704cbSPieter Ghysels   Use
4883ca39a21SBarry Smith     -pc_type lu -pc_factor_mat_solver_type strumpack
489575704cbSPieter Ghysels   to use this as an exact (direct) solver, use
4903ca39a21SBarry Smith     -pc_type ilu -pc_factor_mat_solver_type strumpack
491575704cbSPieter Ghysels   to enable low-rank compression (i.e, use as a preconditioner).
492575704cbSPieter Ghysels 
493575704cbSPieter Ghysels   Works with AIJ matrices
494575704cbSPieter Ghysels 
495575704cbSPieter Ghysels   Options Database Keys:
49667b8a455SSatish Balay + -mat_strumpack_verbose                    - verbose info
49734f43fa5SPieter Ghysels . -mat_strumpack_hss_rel_tol <1e-2>         - Relative compression tolerance (None)
49834f43fa5SPieter Ghysels . -mat_strumpack_hss_abs_tol <1e-8>         - Absolute compression tolerance (None)
499575704cbSPieter Ghysels . -mat_strumpack_colperm <TRUE>             - Permute matrix to make diagonal nonzeros (None)
50034f43fa5SPieter Ghysels . -mat_strumpack_hss_min_sep_size <256>     - Minimum size of separator for HSS compression (None)
50134f43fa5SPieter Ghysels . -mat_strumpack_max_rank                   - Maximum rank in HSS compression, when using pctype ilu (None)
502a36bf211SPieter Ghysels . -mat_strumpack_leaf_size                  - Size of diagonal blocks in HSS approximation, when using pctype ilu (None)
50334f43fa5SPieter Ghysels . -mat_strumpack_reordering <METIS>         - Sparsity reducing matrix reordering (choose one of) NATURAL METIS PARMETIS SCOTCH PTSCOTCH RCM (None)
504a2b725a8SWilliam Gropp - -mat_strumpack_iterative_solver <DIRECT>  - Select iterative solver from STRUMPACK (choose one of) AUTO DIRECT REFINE PREC_GMRES GMRES PREC_BICGSTAB BICGSTAB (None)
505575704cbSPieter Ghysels 
506575704cbSPieter Ghysels  Level: beginner
507575704cbSPieter Ghysels 
50811a5261eSBarry Smith .seealso: `PCLU`, `PCILU`, `MATSOLVERSUPERLU_DIST`, `MATSOLVERMUMPS`, `PCFactorSetMatSolverType()`, `MatSolverType`, `MatGetFactor()`
509575704cbSPieter Ghysels M*/
510d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetFactor_aij_strumpack(Mat A, MatFactorType ftype, Mat *F)
511d71ae5a4SJacob Faibussowitsch {
5127d6ea485SPieter Ghysels   Mat                       B;
5137d6ea485SPieter Ghysels   PetscInt                  M = A->rmap->N, N = A->cmap->N;
51426cc229bSBarry Smith   PetscBool                 verb, flg;
51534f43fa5SPieter Ghysels   STRUMPACK_SparseSolver   *S;
51634f43fa5SPieter Ghysels   STRUMPACK_INTERFACE       iface;
5179371c9d4SSatish Balay   const STRUMPACK_PRECISION table[2][2][2] = {
5189371c9d4SSatish Balay     {{STRUMPACK_FLOATCOMPLEX_64, STRUMPACK_DOUBLECOMPLEX_64}, {STRUMPACK_FLOAT_64, STRUMPACK_DOUBLE_64}},
5199371c9d4SSatish Balay     {{STRUMPACK_FLOATCOMPLEX, STRUMPACK_DOUBLECOMPLEX},       {STRUMPACK_FLOAT, STRUMPACK_DOUBLE}      }
5209371c9d4SSatish Balay   };
5214ac6704cSBarry Smith   const STRUMPACK_PRECISION prec = table[(sizeof(PetscInt) == 8) ? 0 : 1][(PETSC_SCALAR == PETSC_COMPLEX) ? 0 : 1][(PETSC_REAL == PETSC_FLOAT) ? 0 : 1];
5227d6ea485SPieter Ghysels 
5237d6ea485SPieter Ghysels   PetscFunctionBegin;
5247d6ea485SPieter Ghysels   /* Create the factorization matrix */
5259566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
5269566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, M, N));
527*35e8bcc9SJunchao Zhang   PetscCall(PetscStrallocpy("strumpack", &((PetscObject)B)->type_name));
528*35e8bcc9SJunchao Zhang   PetscCall(MatSetUp(B));
52966e17bc3SBarry Smith   B->trivialsymbolic = PETSC_TRUE;
530575704cbSPieter Ghysels   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
5317d6ea485SPieter Ghysels     B->ops->lufactorsymbolic  = MatLUFactorSymbolic_STRUMPACK;
532575704cbSPieter Ghysels     B->ops->ilufactorsymbolic = MatLUFactorSymbolic_STRUMPACK;
533575704cbSPieter Ghysels   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Factor type not supported");
534*35e8bcc9SJunchao Zhang   B->ops->getinfo     = MatGetInfo_External;
5357d6ea485SPieter Ghysels   B->ops->view        = MatView_STRUMPACK;
5367d6ea485SPieter Ghysels   B->ops->destroy     = MatDestroy_STRUMPACK;
5377d6ea485SPieter Ghysels   B->ops->getdiagonal = MatGetDiagonal_STRUMPACK;
5389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_aij_strumpack));
5399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetReordering_C", MatSTRUMPACKSetReordering_STRUMPACK));
5409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetColPerm_C", MatSTRUMPACKSetColPerm_STRUMPACK));
5419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetHSSRelTol_C", MatSTRUMPACKSetHSSRelTol_STRUMPACK));
5429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetHSSAbsTol_C", MatSTRUMPACKSetHSSAbsTol_STRUMPACK));
5439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetHSSMaxRank_C", MatSTRUMPACKSetHSSMaxRank_STRUMPACK));
5449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetHSSLeafSize_C", MatSTRUMPACKSetHSSLeafSize_STRUMPACK));
5459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSTRUMPACKSetHSSMinSepSize_C", MatSTRUMPACKSetHSSMinSepSize_STRUMPACK));
546575704cbSPieter Ghysels   B->factortype = ftype;
5474dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&S));
548*35e8bcc9SJunchao Zhang   B->data = S;
5490d08a34dSPieter Ghysels 
550*35e8bcc9SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &flg)); /* A might be MATSEQAIJCUSPARSE */
5510d08a34dSPieter Ghysels   iface = flg ? STRUMPACK_MT : STRUMPACK_MPI_DIST;
5527d6ea485SPieter Ghysels 
55326cc229bSBarry Smith   PetscOptionsBegin(PetscObjectComm((PetscObject)B), ((PetscObject)B)->prefix, "STRUMPACK Options", "Mat");
554575704cbSPieter Ghysels   verb = PetscLogPrintInfo ? PETSC_TRUE : PETSC_FALSE;
5559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-mat_strumpack_verbose", "Print STRUMPACK information", "None", verb, &verb, NULL));
5567d6ea485SPieter Ghysels 
557e77caa6dSBarry Smith   PetscStackCallExternalVoid("STRUMPACK_init", STRUMPACK_init(S, PetscObjectComm((PetscObject)A), prec, iface, 0, NULL, verb));
55855c022e5SPieter Ghysels 
55988382b05SPieter Ghysels   if (ftype == MAT_FACTOR_ILU) {
56088382b05SPieter Ghysels     /* When enabling HSS compression, the STRUMPACK solver becomes an incomplete              */
56188382b05SPieter Ghysels     /* (or approximate) LU factorization.                                                     */
562e77caa6dSBarry Smith     PetscStackCallExternalVoid("STRUMPACK_enable_HSS", STRUMPACK_enable_HSS(*S));
56388382b05SPieter Ghysels   }
564d0609cedSBarry Smith   PetscOptionsEnd();
56555c022e5SPieter Ghysels 
56626cc229bSBarry Smith   /* set solvertype */
56726cc229bSBarry Smith   PetscCall(PetscFree(B->solvertype));
56826cc229bSBarry Smith   PetscCall(PetscStrallocpy(MATSOLVERSTRUMPACK, &B->solvertype));
56926cc229bSBarry Smith 
5707d6ea485SPieter Ghysels   *F = B;
5713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5727d6ea485SPieter Ghysels }
5737d6ea485SPieter Ghysels 
574d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_STRUMPACK(void)
575d71ae5a4SJacob Faibussowitsch {
5767d6ea485SPieter Ghysels   PetscFunctionBegin;
5779566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERSTRUMPACK, MATMPIAIJ, MAT_FACTOR_LU, MatGetFactor_aij_strumpack));
5789566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERSTRUMPACK, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_aij_strumpack));
5799566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERSTRUMPACK, MATMPIAIJ, MAT_FACTOR_ILU, MatGetFactor_aij_strumpack));
5809566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERSTRUMPACK, MATSEQAIJ, MAT_FACTOR_ILU, MatGetFactor_aij_strumpack));
5813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5827d6ea485SPieter Ghysels }
583