8#ifdef FEAT_HAVE_UMFPACK 
    9#include <kernel/solver/umfpack.hpp> 
   51    template<
typename Idx_, 
int s
idx_ = sizeof(Idx_), 
bool eq_ = (sizeof(
int) == sizeof(SuiteSparse_
long))>
 
   52    struct UmfpackWrapper;
 
   55    template<
typename Idx_, 
bool eq_>
 
   56    struct UmfpackWrapper<Idx_, sizeof(int), eq_>
 
   58      static void init_defaults(
double* control)
 
   60        ::umfpack_di_defaults(control);
 
   63      static int init_symbolic(Idx_ nrows, Idx_ ncols, 
const Idx_* row_ptr, 
const Idx_* col_idx,
 
   64        const double* data, 
void** symb, 
const double* ctrl, 
double* info)
 
   66        static_assert(
sizeof(Idx_) == 
sizeof(
int), 
"invalid index size");
 
   67        return int(::umfpack_di_symbolic(
static_cast<int>(nrows), 
static_cast<int>(ncols),
 
   68          reinterpret_cast<const int*
>(row_ptr), 
reinterpret_cast<const int*
>(col_idx),
 
   69          data, symb, ctrl, info));
 
   72      static int init_numeric(
const Idx_* row_ptr, 
const Idx_* col_idx,
 
   73        const double* data, 
void* symb, 
void** nume, 
const double* ctrl, 
double* info)
 
   75        static_assert(
sizeof(Idx_) == 
sizeof(
int), 
"invalid index size");
 
   76        return int(::umfpack_di_numeric(
 
   77          reinterpret_cast<const int*
>(row_ptr), 
reinterpret_cast<const int*
>(col_idx),
 
   78          data, symb, nume, ctrl, info));
 
   81      static void free_symbolic(
void** symb)
 
   83        ::umfpack_di_free_symbolic(symb);
 
   86      static void free_numeric(
void** nume)
 
   88        ::umfpack_di_free_numeric(nume);
 
   91      static int solve(
int sys, 
const Idx_* row_ptr, 
const Idx_* col_idx, 
const double* data,
 
   92        double* x, 
const double* b, 
void* nume, 
const double* control, 
double* info)
 
   94        static_assert(
sizeof(Idx_) == 
sizeof(
int), 
"invalid index size");
 
   95        return int(::umfpack_di_solve(
static_cast<int>(sys),
 
   96          reinterpret_cast<const int*
>(row_ptr), 
reinterpret_cast<const int*
>(col_idx),
 
   97          data, x, b, nume, control, info));
 
  102    template<
typename Idx_>
 
  103    struct UmfpackWrapper<Idx_, sizeof(SuiteSparse_long), false>
 
  105      static void init_defaults(
double* control)
 
  107        ::umfpack_dl_defaults(control);
 
  110      static int init_symbolic(Idx_ nrows, Idx_ ncols, 
const Idx_* row_ptr, 
const Idx_* col_idx,
 
  111        const double* data, 
void** symb, 
const double* ctrl, 
double* info)
 
  113        static_assert(
sizeof(Idx_) == 
sizeof(SuiteSparse_long), 
"invalid index size");
 
  114        return int(::umfpack_dl_symbolic(
static_cast<SuiteSparse_long
>(nrows), 
static_cast<SuiteSparse_long
>(ncols),
 
  115          reinterpret_cast<const SuiteSparse_long*
>(row_ptr), 
reinterpret_cast<const SuiteSparse_long*
>(col_idx),
 
  116          data, symb, ctrl, info));
 
  119      static int init_numeric(
const Idx_* row_ptr, 
const Idx_* col_idx,
 
  120        const double* data, 
void* symb, 
void** nume, 
const double* ctrl, 
double* info)
 
  122        static_assert(
sizeof(Idx_) == 
sizeof(SuiteSparse_long), 
"invalid index size");
 
  123        return int(::umfpack_dl_numeric(
 
  124          reinterpret_cast<const SuiteSparse_long*
>(row_ptr), 
reinterpret_cast<const SuiteSparse_long*
>(col_idx),
 
  125          data, symb, nume, ctrl, info));
 
  128      static void free_symbolic(
void** symb)
 
  130        ::umfpack_dl_free_symbolic(symb);
 
  133      static void free_numeric(
void** nume)
 
  135        ::umfpack_dl_free_numeric(nume);
 
  138      static int solve(
int sys, 
const Idx_* row_ptr, 
const Idx_* col_idx, 
const double* data,
 
  139        double* x, 
const double* b, 
void* nume, 
const double* control, 
double* info)
 
  141        static_assert(
sizeof(Idx_) == 
sizeof(SuiteSparse_long), 
"invalid index size");
 
  142        return int(::umfpack_dl_solve(sys, 
reinterpret_cast<const SuiteSparse_long*
>(row_ptr),
 
  143          reinterpret_cast<const SuiteSparse_long*
>(col_idx), data, x, b, nume, control, info));
 
  152      _system_matrix(system_matrix),
 
  153      _umf_control(new double[UMFPACK_CONTROL]),
 
  154      _umf_symbolic(nullptr),
 
  155      _umf_numeric(nullptr),
 
  162      UmfpackWrapper<Index>::init_defaults(_umf_control);
 
  169      if(_umf_control != 
nullptr)
 
  170        delete [] _umf_control;
 
  173    void Umfpack::init_symbolic()
 
  175      BaseClass::init_symbolic();
 
  178      if(_umf_symbolic != 
nullptr)
 
  179        throw SolverException(
"UMFPACK: already have symbolic factorization");
 
  182      double info[UMFPACK_INFO];
 
  185      int status = UmfpackWrapper<Index>::init_symbolic(
 
  186        _system_matrix.rows(),
 
  187        _system_matrix.columns(),
 
  188        _system_matrix.row_ptr(),
 
  189        _system_matrix.col_ind(),
 
  201      case UMFPACK_ERROR_out_of_memory:
 
  202        throw SolverException(
"UMFPACK: out of memory");
 
  203      case UMFPACK_ERROR_invalid_matrix:
 
  204        throw InvalidMatrixStructureException(
"UMFPACK: invalid matrix structure");
 
  205      case UMFPACK_ERROR_internal_error:
 
  206        throw SolverException(
"UMFPACK: internal error");
 
  208        throw SolverException(
"UMFPACK: unknown error");
 
  212      _sym_peak_size = std::size_t(info[UMFPACK_SIZE_OF_UNIT] * info[UMFPACK_SYMBOLIC_PEAK_MEMORY]);
 
  213      _sym_mem_size = std::size_t(info[UMFPACK_SIZE_OF_UNIT] * info[UMFPACK_SYMBOLIC_SIZE]);
 
  216    void Umfpack::done_symbolic()
 
  218      if(_umf_symbolic == 
nullptr)
 
  221      UmfpackWrapper<Index>::free_symbolic(&_umf_symbolic);
 
  223      _umf_symbolic = 
nullptr;
 
  225      BaseClass::done_symbolic();
 
  228    void Umfpack::init_numeric()
 
  230      BaseClass::init_numeric();
 
  232      if(_umf_symbolic == 
nullptr)
 
  233        throw SolverException(
"UFMPACK: symbolic factorization missing");
 
  236      double info[UMFPACK_INFO];
 
  239      int status = UmfpackWrapper<Index>::init_numeric(
 
  240        _system_matrix.row_ptr(),
 
  241        _system_matrix.col_ind(),
 
  242        _system_matrix.val(),
 
  254      case UMFPACK_ERROR_out_of_memory:
 
  255        throw SolverException(
"UMFPACK: out of memory");
 
  256      case UMFPACK_ERROR_invalid_matrix:
 
  257        throw InvalidMatrixStructureException(
"UMFPACK: invalid matrix structure");
 
  258      case UMFPACK_WARNING_singular_matrix:
 
  259        throw SingularMatrixException(
"UMFPACK: singular matrix");
 
  260      case UMFPACK_ERROR_different_pattern:
 
  261        throw SolverException(
"UMFPACK: different pattern");
 
  262      case UMFPACK_ERROR_internal_error:
 
  263        throw SolverException(
"UMFPACK: internal error");
 
  265        throw SolverException(
"UMFPACK: unknown error");
 
  269      _umf_peak_size = std::size_t(info[UMFPACK_SIZE_OF_UNIT] * info[UMFPACK_PEAK_MEMORY]);
 
  270      _num_mem_size = std::size_t(info[UMFPACK_SIZE_OF_UNIT] * info[UMFPACK_NUMERIC_SIZE]);
 
  273    void Umfpack::done_numeric()
 
  275      if(_umf_numeric == 
nullptr)
 
  278      UmfpackWrapper<Index>::free_numeric(&_umf_numeric);
 
  280      _umf_numeric = 
nullptr;
 
  281      BaseClass::done_numeric();
 
  284    Status Umfpack::apply(VectorType& x, 
const VectorType& b)
 
  287      double info[UMFPACK_INFO];
 
  290      int status = UmfpackWrapper<Index>::solve(
 
  292        _system_matrix.row_ptr(),
 
  293        _system_matrix.col_ind(),
 
  294        _system_matrix.val(),
 
  302      return (status == UMFPACK_OK) ? Status::success :  Status::aborted;
 
  309    UmfpackMean::UmfpackMean(
const MatrixType& system_matrix, 
const VectorType& weight_vector) :
 
  311      _system_matrix(system_matrix),
 
  312      _weight_vector(weight_vector),
 
  313      _umfpack(_solver_matrix)
 
  317    void UmfpackMean::init_symbolic()
 
  319      BaseClass::init_symbolic();
 
  322      const Index n = _weight_vector.size();
 
  323      if((n != _system_matrix.rows()) || (n != _system_matrix.columns()))
 
  324        throw InvalidMatrixStructureException(
"system matrix/weight vector dimension mismatch");
 
  327      const Index nnze = _system_matrix.used_elements();
 
  330      _solver_matrix = MatrixType(n+1, n+1, nnze + 2*n);
 
  333      const Index* irow_ptr = _system_matrix.row_ptr();
 
  334      const Index* icol_idx = _system_matrix.col_ind();
 
  337      Index* orow_ptr = _solver_matrix.row_ptr();
 
  338      Index* ocol_idx = _solver_matrix.col_ind();
 
  341      orow_ptr[0] = 
Index(0);
 
  342      for(Index i(0); i < n; ++i)
 
  344        Index op = orow_ptr[i];
 
  346        for(Index ip(irow_ptr[i]); ip < irow_ptr[i+1]; ++ip, ++op)
 
  348          ocol_idx[op] = icol_idx[ip];
 
  353        orow_ptr[i+1] = ++op;
 
  357      Index op(orow_ptr[n]);
 
  358      for(Index j(0); j < n; ++j, ++op)
 
  368      _vec_x = _solver_matrix.create_vector_r();
 
  369      _vec_b = _solver_matrix.create_vector_r();
 
  372      _umfpack.init_symbolic();
 
  375    void UmfpackMean::done_symbolic()
 
  377      _umfpack.done_symbolic();
 
  380      _solver_matrix.clear();
 
  382      BaseClass::done_symbolic();
 
  385    void UmfpackMean::init_numeric()
 
  387      BaseClass::init_numeric();
 
  389      const Index n = _system_matrix.rows();
 
  392      const Index* irow_ptr = _system_matrix.row_ptr();
 
  393      const double* idata = _system_matrix.val();
 
  396      const double* weight = _weight_vector.elements();
 
  399      const Index* orow_ptr = _solver_matrix.row_ptr();
 
  400      double* odata = _solver_matrix.val();
 
  403      for(Index i(0); i < n; ++i)
 
  405        Index op(orow_ptr[i]);
 
  407        for(Index ip(irow_ptr[i]); ip < irow_ptr[i+1]; ++ip, ++op)
 
  409          odata[op] = idata[ip];
 
  412        odata[op] = weight[i];
 
  416      Index op(orow_ptr[n]);
 
  417      for(Index j(0); j < n; ++j, ++op)
 
  419        odata[op] = weight[j];
 
  425      _umfpack.init_numeric();
 
  428    void UmfpackMean::done_numeric()
 
  430      _umfpack.done_numeric();
 
  432      BaseClass::done_numeric();
 
  435    Status UmfpackMean::apply(VectorType& vec_sol, 
const VectorType& vec_rhs)
 
  437      const Index n = vec_sol.size();
 
  440      const double* vr = vec_rhs.elements();
 
  441      double* vb = _vec_b.elements();
 
  442      for(Index i(0); i < n; ++i)
 
  449      Status status = _umfpack.apply(_vec_x, _vec_b);
 
  452      const double* vx = _vec_x.elements();
 
  453      double* vs = vec_sol.elements();
 
  454      for(Index i(0); i < n; ++i)
 
  467void dummy_function_umfpack() {}
 
LAFEM::SparseMatrixCSR< double, Index > MatrixType
compatible matrix type
Umfpack(const MatrixType &system_matrix)
Constructor.
Status
Solver status return codes enumeration.
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.
std::uint64_t Index
Index data type.