8#include <kernel/backend.hpp>
9#include <kernel/solver/direct_sparse_solver.hpp>
11#ifdef FEAT_HAVE_UMFPACK
18#define FEAT_DSS_UMFPACK_I32
26#ifdef FEAT_DSS_UMFPACK_I64
27 static_assert(
sizeof(UMFPACK_IT) == 8,
"DirectSparseSolver: UMFPACK: index type size mismatch!");
29 static_assert(
sizeof(UMFPACK_IT) == 4,
"DirectSparseSolver: UMFPACK: index type size mismatch!");
41 double control[UMFPACK_CONTROL];
43 double info[UMFPACK_INFO];
49 UMFPACK_IT num_global_dofs, dof_offset, num_owned_dofs, num_owned_nzes;
50 std::vector<UMFPACK_IT> row_ptr, col_idx;
51 std::vector<UMFPACK_DT> mat_val, rhs_val, sol_val;
53 explicit UMFPACK_Core(
const Dist::Comm& comm, Index num_global_dofs_, Index dof_offset_,
54 Index num_owned_dofs_, Index num_owned_nzes_, Index DOXY(num_global_nzes_)) :
57 num_global_dofs(UMFPACK_IT(num_global_dofs_)),
58 dof_offset(UMFPACK_IT(dof_offset_)),
59 num_owned_dofs(UMFPACK_IT(num_owned_dofs_)),
60 num_owned_nzes(UMFPACK_IT(num_owned_nzes_))
63 XASSERTM(comm.size() == 1,
"DirectSparseSolver UMFPACK core can only be used on 1 MPI process!");
70 row_ptr.resize(std::size_t(num_owned_dofs+1), 0u);
71 col_idx.resize(std::size_t(num_owned_nzes), 0u);
72 mat_val.resize(std::size_t(num_owned_nzes), 0.0);
73 rhs_val.resize(std::size_t(num_owned_dofs), 0.0);
74 sol_val.resize(std::size_t(num_owned_dofs), 0.0);
76#ifdef FEAT_DSS_UMFPACK_I64
77 ::umfpack_dl_defaults(control);
79 ::umfpack_di_defaults(control);
81 control[UMFPACK_PRL] = 1;
86 if(numeric !=
nullptr)
88#ifdef FEAT_DSS_UMFPACK_I64
89 ::umfpack_dl_free_numeric(&numeric);
91 ::umfpack_di_free_numeric(&numeric);
94 if(symbolic !=
nullptr)
96#ifdef FEAT_DSS_UMFPACK_I64
97 ::umfpack_dl_free_symbolic(&symbolic);
99 ::umfpack_di_free_symbolic(&symbolic);
109#ifdef FEAT_DSS_UMFPACK_I64
110 ::umfpack_dl_symbolic
112 ::umfpack_di_symbolic
114 (num_owned_dofs, num_owned_dofs, row_ptr.data(), col_idx.data(), mat_val.data(), &symbolic, control, info);
121 case UMFPACK_ERROR_out_of_memory:
122 throw DirectSparseSolverException(
"UMFPACK",
"out of memory");
123 case UMFPACK_ERROR_invalid_matrix:
124 throw DirectSparseSolverException(
"UMFPACK",
"invalid matrix structure");
125 case UMFPACK_ERROR_internal_error:
126 throw DirectSparseSolverException(
"UMFPACK",
"internal error");
128 throw DirectSparseSolverException(
"UMFPACK",
"unknown error");
138#ifdef FEAT_DSS_UMFPACK_I64
143 (row_ptr.data(), col_idx.data(), mat_val.data(), symbolic, &numeric, control, info);
150 case UMFPACK_ERROR_out_of_memory:
151 throw DirectSparseSolverException(
"UMFPACK",
"out of memory");
152 case UMFPACK_ERROR_invalid_matrix:
153 throw DirectSparseSolverException(
"UMFPACK",
"invalid matrix structure");
154 case UMFPACK_WARNING_singular_matrix:
155 throw DirectSparseSolverException(
"UMFPACK",
"singular matrix");
156 case UMFPACK_ERROR_different_pattern:
157 throw DirectSparseSolverException(
"UMFPACK",
"different pattern");
158 case UMFPACK_ERROR_internal_error:
159 throw DirectSparseSolverException(
"UMFPACK",
"internal error");
161 throw DirectSparseSolverException(
"UMFPACK",
"unknown error");
168#ifdef FEAT_DSS_UMFPACK_I64
169 ::umfpack_dl_free_numeric(&numeric);
171 ::umfpack_di_free_numeric(&numeric);
179#ifdef FEAT_DSS_UMFPACK_I64
184 (UMFPACK_At, row_ptr.data(), col_idx.data(), mat_val.data(), sol_val.data(), rhs_val.data(), numeric, control, info);
191 case UMFPACK_ERROR_out_of_memory:
192 throw DirectSparseSolverException(
"UMFPACK",
"out of memory");
193 case UMFPACK_WARNING_singular_matrix:
194 throw DirectSparseSolverException(
"UMFPACK",
"singular matrix");
195 case UMFPACK_ERROR_internal_error:
196 throw DirectSparseSolverException(
"UMFPACK",
"internal error");
198 throw DirectSparseSolverException(
"UMFPACK",
"unknown error");
203 void* create_umfpack_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
204 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes)
206 return new UMFPACK_Core(*comm, num_global_dofs, dof_offset, num_owned_dofs, num_owned_nzes, num_global_nzes);
209 void destroy_umfpack_core(
void* core)
212 delete reinterpret_cast<UMFPACK_Core*
>(core);
215 UMFPACK_IT* get_umfpack_row_ptr(
void* core)
218 return reinterpret_cast<UMFPACK_Core*
>(core)->row_ptr.data();
221 UMFPACK_IT* get_umfpack_col_idx(
void* core)
224 return reinterpret_cast<UMFPACK_Core*
>(core)->col_idx.data();
227 UMFPACK_DT* get_umfpack_mat_val(
void* core)
230 return reinterpret_cast<UMFPACK_Core*
>(core)->mat_val.data();
233 UMFPACK_DT* get_umfpack_rhs_val(
void* core)
236 return reinterpret_cast<UMFPACK_Core*
>(core)->rhs_val.data();
239 UMFPACK_DT* get_umfpack_sol_val(
void* core)
242 return reinterpret_cast<UMFPACK_Core*
>(core)->sol_val.data();
245 void init_umfpack_symbolic(
void* core)
248 reinterpret_cast<UMFPACK_Core*
>(core)->init_symbolic();
251 void init_umfpack_numeric(
void* core)
254 reinterpret_cast<UMFPACK_Core*
>(core)->init_numeric();
257 void done_umfpack_numeric(
void* core)
260 reinterpret_cast<UMFPACK_Core*
>(core)->done_numeric();
263 void solve_umfpack(
void* core)
266 reinterpret_cast<UMFPACK_Core*
>(core)->
solve();
274void feat_direct_sparse_solver_umfpack_dummy()
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Status solve(SolverBase< Vector_ > &solver, Vector_ &vec_sol, const Vector_ &vec_rhs, const Matrix_ &matrix, const Filter_ &filter)
Solve linear system with initial solution guess.