13#  ifdef HYPRE_SEQUENTIAL 
   14#    error FEAT_HAVE_MPI and HYPRE_SEQUENTIAL are both defined 
   16#  ifndef HYPRE_HAVE_MPI 
   17#    define HYPRE_HAVE_MPI 1 
   21#    error FEAT_HAVE_MPI is not defined, but HYPRE_HAVE_MPI is defined 
   23#  ifndef HYPRE_SEQUENTIAL 
   24#    define HYPRE_SEQUENTIAL 1 
   30#include <HYPRE_parcsr_ls.h> 
   50        std::vector<HYPRE_Int> _hypre_dof_idx;
 
   52        std::vector<HYPRE_Int> _hypre_num_nze;
 
   54        std::vector<HYPRE_Int> _hypre_col_idx;
 
   58        HYPRE_IJMatrix _hypre_matrix;
 
   60        HYPRE_IJVector _hypre_vec_def, _hypre_vec_cor;
 
   62        HYPRE_ParCSRMatrix _hypre_parcsr;
 
   64        HYPRE_ParVector _hypre_par_def, _hypre_par_cor;
 
   67        template<
typename IT_>
 
   68        explicit Core(
const void* comm, Index my_dof_offset, Index num_owned_dofs, 
const IT_* row_ptr, 
const IT_* col_idx) :
 
   70          _comm(*reinterpret_cast<const MPI_Comm*>(comm)),
 
   75          _hypre_matrix(nullptr),
 
   76          _hypre_vec_def(nullptr),
 
   77          _hypre_vec_cor(nullptr),
 
   78          _hypre_parcsr(nullptr),
 
   79          _hypre_par_def(nullptr),
 
   80          _hypre_par_cor(nullptr)
 
   86          const HYPRE_Int dof_offset = HYPRE_Int(my_dof_offset);
 
   87          const HYPRE_Int num_owned  = HYPRE_Int(num_owned_dofs);
 
   90          _hypre_dof_idx.resize((std::size_t)num_owned);
 
   91          for(HYPRE_Int i(0); i < num_owned; ++i)
 
   92            _hypre_dof_idx[std::size_t(i)] = dof_offset + i;
 
   95          const HYPRE_Int ilower = _hypre_dof_idx.front();
 
   96          const HYPRE_Int iupper = _hypre_dof_idx.back();
 
   99          HYPRE_IJMatrixCreate(_comm, ilower, iupper, ilower, iupper, &_hypre_matrix);
 
  100          HYPRE_IJMatrixSetObjectType(_hypre_matrix, HYPRE_PARCSR);
 
  101          HYPRE_IJMatrixInitialize(_hypre_matrix);
 
  104          HYPRE_IJVectorCreate(_comm, ilower, iupper, &_hypre_vec_def);
 
  105          HYPRE_IJVectorCreate(_comm, ilower, iupper, &_hypre_vec_cor);
 
  106          HYPRE_IJVectorSetObjectType(_hypre_vec_def, HYPRE_PARCSR);
 
  107          HYPRE_IJVectorSetObjectType(_hypre_vec_cor, HYPRE_PARCSR);
 
  108          HYPRE_IJVectorInitialize(_hypre_vec_def);
 
  109          HYPRE_IJVectorInitialize(_hypre_vec_cor);
 
  112          const HYPRE_Int num_nze = HYPRE_Int(row_ptr[num_owned_dofs]);
 
  115          _hypre_num_nze.resize((std::size_t)num_owned);
 
  116          _hypre_col_idx.resize((std::size_t)num_nze);
 
  119          for(HYPRE_Int i(0); i < num_owned; ++i)
 
  121            _hypre_num_nze[std::size_t(i)] = HYPRE_Int(row_ptr[i+1] - row_ptr[i]);
 
  123          for(HYPRE_Int i(0); i < num_nze; ++i)
 
  125            _hypre_col_idx[std::size_t(i)] = HYPRE_Int(col_idx[i]);
 
  129          std::vector<HYPRE_Real> va((std::size_t)num_nze, 0.0);
 
  130          std::vector<HYPRE_Real> vx((std::size_t)num_owned, 0.0);
 
  133          HYPRE_IJMatrixSetValues(_hypre_matrix, num_owned, _hypre_num_nze.data(), _hypre_dof_idx.data(),
 
  134            _hypre_col_idx.data(), va.data());
 
  137          HYPRE_IJVectorSetValues(_hypre_vec_def, num_owned, _hypre_dof_idx.data(), vx.data());
 
  138          HYPRE_IJVectorSetValues(_hypre_vec_cor, num_owned, _hypre_dof_idx.data(), vx.data());
 
  141          HYPRE_IJMatrixAssemble(_hypre_matrix);
 
  142          HYPRE_IJMatrixGetObject(_hypre_matrix, (
void**) &_hypre_parcsr);
 
  145          HYPRE_IJVectorAssemble(_hypre_vec_def);
 
  146          HYPRE_IJVectorAssemble(_hypre_vec_cor);
 
  147          HYPRE_IJVectorGetObject(_hypre_vec_def, (
void **) &_hypre_par_def);
 
  148          HYPRE_IJVectorGetObject(_hypre_vec_cor, (
void **) &_hypre_par_cor);
 
  153          HYPRE_IJVectorDestroy(_hypre_vec_cor);
 
  154          HYPRE_IJVectorDestroy(_hypre_vec_def);
 
  155          HYPRE_IJMatrixDestroy(_hypre_matrix);
 
  158        void set_matrix_values(
const double* vals)
 
  160          HYPRE_IJMatrixSetValues(_hypre_matrix, HYPRE_Int(_hypre_dof_idx.size()), _hypre_num_nze.data(),
 
  161            _hypre_dof_idx.data(), _hypre_col_idx.data(), vals);
 
  164        void set_vec_cor_values(
const double* vals)
 
  167            HYPRE_IJVectorSetValues(_hypre_vec_cor, HYPRE_Int(_hypre_dof_idx.size()), _hypre_dof_idx.data(), vals);
 
  169            HYPRE_ParVectorSetConstantValues(_hypre_par_cor, HYPRE_Real(0));
 
  172        void set_vec_def_values(
const double* vals)
 
  175            HYPRE_IJVectorSetValues(_hypre_vec_def, HYPRE_Int(_hypre_dof_idx.size()), _hypre_dof_idx.data(), vals);
 
  177            HYPRE_ParVectorSetConstantValues(_hypre_par_def, HYPRE_Real(0));
 
  180        void get_vec_cor_values(
double* vals)
 const 
  182          HYPRE_IJVectorGetValues(_hypre_vec_cor, HYPRE_Int(_hypre_dof_idx.size()), _hypre_dof_idx.data(), vals);
 
  185        void get_vec_def_values(
double* vals)
 const 
  187          HYPRE_IJVectorGetValues(_hypre_vec_cor, HYPRE_Int(_hypre_dof_idx.size()), _hypre_dof_idx.data(), vals);
 
  191      void* create_core(
const void* comm, Index dof_offset, Index num_owned_dofs,
 
  192        const unsigned int* row_ptr, 
const unsigned int* col_idx)
 
  194        return new Core(comm, dof_offset, num_owned_dofs, row_ptr, col_idx);
 
  197      void* create_core(
const void* comm, Index dof_offset, Index num_owned_dofs,
 
  198        const unsigned long* row_ptr, 
const unsigned long* col_idx)
 
  200        return new Core(comm, dof_offset, num_owned_dofs, row_ptr, col_idx);
 
  203      void* create_core(
const void* comm, Index dof_offset, Index num_owned_dofs,
 
  204        const unsigned long long* row_ptr, 
const unsigned long long* col_idx)
 
  206        return new Core(comm, dof_offset, num_owned_dofs, row_ptr, col_idx);
 
  209      void destroy_core(
void* core)
 
  211        delete reinterpret_cast<Core*
>(core);
 
  214      void set_matrix_values(
void* core, 
const double* vals)
 
  216        reinterpret_cast<Core*
>(core)->set_matrix_values(vals);
 
  219      void set_vec_cor_values(
void* core, 
const double* vals)
 
  221        reinterpret_cast<Core*
>(core)->set_vec_cor_values(vals);
 
  224      void set_vec_def_values(
void* core, 
const double* vals)
 
  226        reinterpret_cast<Core*
>(core)->set_vec_def_values(vals);
 
  229      void get_vec_cor_values(
const void* core, 
double* vals)
 
  231        reinterpret_cast<const Core*
>(core)->get_vec_cor_values(vals);
 
  234      void get_vec_def_values(
const void* core, 
double* vals)
 
  236        reinterpret_cast<const Core*
>(core)->get_vec_def_values(vals);
 
  243      void* create_parasails(
void* cr, 
int* iparam, 
double* dparam)
 
  245        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  246        HYPRE_Solver* solver = 
new HYPRE_Solver();
 
  249        HYPRE_ParaSailsCreate(core->_comm, solver);
 
  252        HYPRE_ParaSailsSetParams(*solver, dparam[0], iparam[0]);
 
  253        HYPRE_ParaSailsSetFilter(*solver, dparam[1]);
 
  254        HYPRE_ParaSailsSetSym(*solver, iparam[1]);
 
  258        HYPRE_ParaSailsSetup(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  263      void destroy_parasails(
void* slv)
 
  265        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  266        HYPRE_ParaSailsDestroy(*solver);
 
  270      void solve_parasails(
void* cr, 
void* slv)
 
  272        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  273        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  275        HYPRE_ParaSailsSolve(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  282      void* create_euclid(
void* cr, 
int* iparam, 
double* dparam)
 
  284        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  285        HYPRE_Solver* solver = 
new HYPRE_Solver();
 
  288        HYPRE_EuclidCreate(core->_comm, solver);
 
  291        HYPRE_EuclidSetLevel(*solver, iparam[0]);
 
  292        HYPRE_EuclidSetSparseA(*solver, dparam[0]);
 
  296        HYPRE_EuclidSetup(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  301      void destroy_euclid(
void* slv)
 
  303        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  304        HYPRE_EuclidDestroy(*solver);
 
  308      void solve_euclid(
void* cr, 
void* slv)
 
  310        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  311        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  313        HYPRE_EuclidSolve(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  320      void* create_boomeramg(
void* cr, 
int* iparam, 
double* dparam)
 
  322        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  323        HYPRE_Solver* solver = 
new HYPRE_Solver();
 
  326        HYPRE_BoomerAMGCreate(solver);
 
  329        HYPRE_BoomerAMGSetMaxIter(*solver, iparam[0]);
 
  330        HYPRE_BoomerAMGSetTol(*solver, dparam[0]);
 
  334        HYPRE_BoomerAMGSetup(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  339      void destroy_boomeramg(
void* slv)
 
  341        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  342        HYPRE_BoomerAMGDestroy(*solver);
 
  346      void solve_boomeramg(
void* cr, 
void* slv)
 
  348        Core* core = 
reinterpret_cast<Core*
>(cr);
 
  349        HYPRE_Solver* solver = 
reinterpret_cast<HYPRE_Solver*
>(slv);
 
  351        HYPRE_BoomerAMGSolve(*solver, core->_hypre_parcsr, core->_hypre_par_def, core->_hypre_par_cor);
 
  358void dummy_hypre_function() {}