FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
hypre.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
10#include <kernel/solver/adp_solver_base.hpp>
11
12#if defined(FEAT_HAVE_HYPRE) || defined(DOXYGEN)
13
14// includes, system
15#include <vector>
16
17namespace FEAT
18{
19 namespace Solver
20 {
22 namespace Hypre
23 {
25 typedef double HypreDataType;
26
28#ifdef FEAT_TPL_HYPRE_INT64
29 typedef long long HypreIndexType;
30#else
31 typedef int HypreIndexType;
32#endif
33
57 void* create_core(const void* comm, Index dof_offset, Index num_owned_dofs, Index num_nonzeros);
58
59 void destroy_core(void* core);
60
61 HypreIndexType* get_row_ptr(void* core);
62 HypreIndexType* get_col_idx(void* core);
63 HypreDataType* get_mat_val(void* core);
64
65 HypreDataType* get_vec_def(void* core);
66 HypreDataType* get_vec_cor(void* core);
67
68 void upload_symbolic(void* core);
69 void upload_mat_val(void* core);
70 void upload_vec_def(void* core);
71 void download_vec_cor(void* core);
72 void format_vec_cor(void* core);
73
74 // ParaSails Wrappers
75 void* create_parasails(void* core, int* iparam, double* dparam);
76 void destroy_parasails(void* solver);
77 void solve_parasails(void* core, void* solver);
78
79 // Euclid Wrappers
80 void* create_euclid(void* core, int* iparam, double* dparam);
81 void destroy_euclid(void* solver);
82 void solve_euclid(void* core, void* solver);
83
84 // BoomerAMG Wrappers
85 void* create_boomeramg(void* core, int* iparam, double* dparam);
86 void destroy_boomeramg(void* solver);
87 void solve_boomeramg(void* core, void* solver);
88 } // namespace Hypre
90
104 template<typename Matrix_, typename Filter_, typename SolverBase_ = Solver::SolverBase<typename Matrix_::VectorTypeL>>
106 public ADPSolverBase<Matrix_, Filter_, SolverBase_>
107 {
108 public:
111 // the vector type
112 typedef typename BaseClass::VectorType VectorType;
113
114 protected:
116 void* _core;
117
118 explicit HypreSolverBase(const Matrix_& matrix, const Filter_& filter) :
119 BaseClass(matrix, filter),
120 _core(nullptr)
121 {
122 }
123
133 void _upload_def(const VectorType& vec_def)
134 {
135 this->_upload_vector(Hypre::get_vec_def(this->_core), vec_def.local());
136 Hypre::upload_vec_def(this->_core);
137 }
138
148 void _download_cor(VectorType& vec_cor)
149 {
150 Hypre::download_vec_cor(this->_core);
151 this->_download_vector(vec_cor.local(), Hypre::get_vec_cor(this->_core));
152
153 // apply correction filter
154 this->_system_filter.filter_cor(vec_cor);
155 }
156
159 {
160 Hypre::format_vec_cor(this->_core);
161 }
162
163 public:
173 virtual void init_symbolic() override
174 {
176
177 XASSERT(this->_core == nullptr);
178
179 // create our HYPRE core wrapper object
180 this->_core = Hypre::create_core(
181#ifdef FEAT_HAVE_MPI
182 &this->_get_comm()->mpi_comm(),
183#else
184 nullptr, // no communicator for non-MPI builds
185#endif
187
188
189 // upload matrix structure
190 BaseClass::_upload_symbolic(Hypre::get_row_ptr(this->_core), Hypre::get_col_idx(this->_core));
191
192 // assemble system
193 Hypre::upload_symbolic(this->_core);
194 }
195
202 virtual void init_numeric() override
203 {
205
206 XASSERT(this->_core != nullptr);
207
208 // upload matrix values
209 this->_upload_numeric(Hypre::get_mat_val(this->_core),
210 Hypre::get_row_ptr(this->_core), Hypre::get_col_idx(this->_core));
211
212 Hypre::upload_mat_val(this->_core);
213 }
214
221 virtual void done_symbolic() override
222 {
223 XASSERT(this->_core != nullptr);
224
225 Hypre::destroy_core(this->_core);
226 this->_core = nullptr;
227
229 }
230 }; // class HypreSolverBase<...>
231
243 template<typename Matrix_, typename Filter_>
245 public HypreSolverBase<Matrix_, Filter_>
246 {
247 public:
251 typedef typename BaseClass::VectorType VectorType;
252
253 protected:
255 void* _solver;
256
258 // 0: num levels, third argument for HYPRE_ParaSailsSetParams, default: 1
259 // 1: symmetry, second argument for HYPRE_ParaSailsSetSym, default: 2
260 int _iparam[2];
261
263 // 0: threshold, second argument for HYPRE_ParaSailsSetParams, default: 0.1
264 // 1: filter, second argument for HYPRE_ParaSailsSetFilter, default: 0.05
265 double _dparam[2];
266
267 public:
268 explicit ParaSailsPrecond(const Matrix_& matrix, const Filter_& filter) :
269 BaseClass(matrix, filter),
270 _solver(nullptr)
271 {
272 _iparam[0] = 1;
273 _iparam[1] = 2;
274
275 _dparam[0] = 0.1;
276 _dparam[1] = 0.05;
277 }
278
279 explicit ParaSailsPrecond(const String& section_name, const PropertyMap* section,
280 const Matrix_& matrix, const Filter_& filter)
281 :
282 ParaSailsPrecond(matrix, filter)
283 {
284 auto level_p = section->query("level");
285 if(level_p.second && !level_p.first.parse(_iparam[0]))
286 throw ParseError(section_name + ".level", level_p.first, "a non-negative integer");
287
288 auto sym_p = section->query("sym");
289 if(sym_p.second && !sym_p.first.parse(_iparam[1]))
290 throw ParseError(section_name + ".sym", sym_p.first, "a non-negative integer");
291
292 auto thresh_p = section->query("thresh");
293 if(thresh_p.second && !thresh_p.first.parse(_dparam[0]))
294 throw ParseError(section_name + ".thresh", thresh_p.first, "a positive float");
295
296 auto filter_p = section->query("filter");
297 if(filter_p.second && !filter_p.first.parse(_dparam[1]))
298 throw ParseError(section_name + ".filter", filter_p.first, "a positive float");
299 }
300
301 virtual String name() const override
302 {
303 return "ParaSailsPrecond";
304 }
305
306 virtual void init_numeric() override
307 {
309
310 // create ParaSails preconditioner
311 this->_solver = Hypre::create_parasails(this->_core, this->_iparam, this->_dparam);
312 }
313
314 virtual void done_numeric() override
315 {
316 if(_solver != nullptr)
317 {
318 Hypre::destroy_parasails(_solver);
319 _solver = nullptr;
320 }
321
323 }
324
325 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
326 {
327 // upload defect vector and format correction
328 this->_upload_def(vec_def);
329 this->_format_cor();
330
331 // apply ParaSails preconditioner
332 Hypre::solve_parasails(this->_core, this->_solver);
333
334 // download correction
335 this->_download_cor(vec_cor);
336
337 // okay
338 return Status::success;
339 }
340 }; // class ParaSailsPrecond
341
354 template<typename Matrix_, typename Filter_>
355 inline std::shared_ptr<ParaSailsPrecond<Matrix_, Filter_>> new_parasails_precond(
356 const Matrix_& matrix, const Filter_& filter)
357 {
358 return std::make_shared<ParaSailsPrecond<Matrix_, Filter_>>(matrix, filter);
359 }
360
379 template<typename Matrix_, typename Filter_>
380 inline std::shared_ptr<ParaSailsPrecond<Matrix_, Filter_>> new_parasails_precond(
381 const String& section_name, const PropertyMap* section,
382 const Matrix_& matrix, const Filter_& filter)
383 {
384 return std::make_shared<ParaSailsPrecond<Matrix_, Filter_>>(section_name, section, matrix, filter);
385 }
386
398 template<typename Matrix_, typename Filter_>
400 public HypreSolverBase<Matrix_, Filter_>
401 {
402 public:
406 typedef typename BaseClass::VectorType VectorType;
407
408 protected:
410 void* _solver;
411
413 // 0: factorization level for ILU(k), default: 1
414 int _iparam[1];
415
417 // 0: drop tolerance for ILU(k), default: 0.0
418 double _dparam[1];
419
420 public:
421 explicit EuclidPrecond(const Matrix_& matrix, const Filter_& filter) :
422 BaseClass(matrix, filter),
423 _solver(nullptr)
424 {
425 _iparam[0] = 1;
426 _dparam[0] = 0.0;
427 }
428
429 explicit EuclidPrecond(const String& section_name, const PropertyMap* section,
430 const Matrix_& matrix, const Filter_& filter)
431 :
432 EuclidPrecond(matrix, filter)
433 {
434 auto level_p = section->query("level");
435 if(level_p.second && !level_p.first.parse(_iparam[0]))
436 throw ParseError(section_name + ".level", level_p.first, "a non-negative integer");
437
438 auto drop_p = section->query("drop");
439 if(drop_p.second && !drop_p.first.parse(_dparam[0]))
440 throw ParseError(section_name + ".drop", drop_p.first, "a non-negative float");
441 }
442
443 virtual String name() const override
444 {
445 return "EuclidPrecond";
446 }
447
448 virtual void init_numeric() override
449 {
451
452 // create Euclid preconditioner
453 this->_solver = Hypre::create_euclid(this->_core, this->_iparam, this->_dparam);
454 }
455
456 virtual void done_numeric() override
457 {
458 if(_solver != nullptr)
459 {
460 Hypre::destroy_euclid(_solver);
461 _solver = nullptr;
462 }
463 }
464
465 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
466 {
467 // upload defect vector and format correction
468 this->_upload_def(vec_def);
469 this->_format_cor();
470
471 // apply Euclid preconditioner
472 Hypre::solve_euclid(this->_core, this->_solver);
473
474 // download correction
475 this->_download_cor(vec_cor);
476
477 // okay
478 return Status::success;
479 }
480 }; // class EuclidPrecond
481
494 template<typename Matrix_, typename Filter_>
495 inline std::shared_ptr<EuclidPrecond<Matrix_, Filter_>> new_euclid_precond(
496 const Matrix_& matrix, const Filter_& filter)
497 {
498 return std::make_shared<EuclidPrecond<Matrix_, Filter_>>(matrix, filter);
499 }
500
519 template<typename Matrix_, typename Filter_>
520 inline std::shared_ptr<EuclidPrecond<Matrix_, Filter_>> new_euclid_precond(
521 const String& section_name, const PropertyMap* section,
522 const Matrix_& matrix, const Filter_& filter)
523 {
524 return std::make_shared<EuclidPrecond<Matrix_, Filter_>>(section_name, section, matrix, filter);
525 }
526
536 template<typename Matrix_, typename Filter_>
537 class BoomerAMG :
538 public HypreSolverBase<Matrix_, Filter_>
539 {
540 public:
544 typedef typename BaseClass::VectorType VectorType;
545
546 protected:
548 void* _solver;
549
552 int _iparam[1];
553
556 double _dparam[1];
557
558 public:
559 explicit BoomerAMG(const Matrix_& matrix, const Filter_& filter) :
560 BaseClass(matrix, filter),
561 _solver(nullptr)
562 {
563 // set tolerance to 0 and maximum iterations to 1, so that BoomerAMG
564 // acts as a preconditioner rather than a real iterative solver
565 _iparam[0] = 1;
566 _dparam[0] = 0.0;
567 }
568
569 explicit BoomerAMG(const String& DOXY(section_name), const PropertyMap* DOXY(section),
570 const Matrix_& matrix, const Filter_& filter)
571 :
572 BoomerAMG(matrix, filter)
573 {
575 }
576
577 virtual String name() const override
578 {
579 return "BoomerAMG";
580 }
581
582 virtual void init_numeric() override
583 {
585
586 // create BoomerAMG preconditioner
587 this->_solver = Hypre::create_boomeramg(this->_core, this->_iparam, this->_dparam);
588 }
589
590 virtual void done_numeric() override
591 {
592 if(_solver != nullptr)
593 {
594 Hypre::destroy_boomeramg(_solver);
595 _solver = nullptr;
596 }
597 }
598
599 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
600 {
601 // upload defect vector and format correction
602 this->_upload_def(vec_def);
603 this->_format_cor();
604
605 // apply BoomerAMG preconditioner
606 Hypre::solve_boomeramg(this->_core, this->_solver);
607
608 // download correction
609 this->_download_cor(vec_cor);
610
611 // okay
612 return Status::success;
613 }
614 }; // class BoomerAMG
615
628 template<typename Matrix_, typename Filter_>
629 inline std::shared_ptr<BoomerAMG<Matrix_, Filter_>> new_boomeramg(
630 const Matrix_& matrix, const Filter_& filter)
631 {
632 return std::make_shared<BoomerAMG<Matrix_, Filter_>>(matrix, filter);
633 }
634
653 template<typename Matrix_, typename Filter_>
654 inline std::shared_ptr<BoomerAMG<Matrix_, Filter_>> new_boomeramg(
655 const String& section_name, const PropertyMap* section,
656 const Matrix_& matrix, const Filter_& filter)
657 {
658 return std::make_shared<BoomerAMG<Matrix_, Filter_>>(section_name, section, matrix, filter);
659 }
660 } // namespace Solver
661} // namespace FEAT
662
663#endif // defined(FEAT_HAVE_HYPRE) || defined(DOXYGEN)
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
FEAT Kernel base header.
Class for parser related errors.
Definition: exception.hpp:132
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Base-Class for solvers based on Algebraic-DOF-Partitioning.
const Dist::Comm * _get_comm() const
const FilterType & _system_filter
the system filter
void _upload_symbolic(RPT_ *row_ptr, CIT_ *col_idx)
Uploads the ADP matrix structure to the given arrays.
Index _get_num_owned_dofs() const
Index _get_global_dof_offset() const
void _download_vector(LocalVectorType &vector, const DTV_ *val)
Downloads the ADP vector values from the given array.
void _upload_vector(DTV_ *val, const LocalVectorType &vector)
Uploads the ADP vector values to the given array.
MatrixType::VectorTypeL VectorType
the (local) vector type
Index _get_adp_matrix_num_nzes() const
void _upload_numeric(DTV_ *val, const RPT_ *row_ptr, const CIT_ *col_idx)
Uploads the (filtered) ADP matrix values to the given array.
HYPRE BoomerAMGWrapper class template.
Definition: hypre.hpp:539
BoomerAMG(const String &section_name, const PropertyMap *section, const Matrix_ &matrix, const Filter_ &filter)
Definition: hypre.hpp:569
virtual void init_numeric() override
Numeric Initialization.
Definition: hypre.hpp:582
void * _solver
the HYPRE solver object
Definition: hypre.hpp:548
virtual void done_numeric() override
Numeric finalization method.
Definition: hypre.hpp:590
virtual String name() const override
Returns a descriptive string.
Definition: hypre.hpp:577
BaseClass::VectorType VectorType
the vector type
Definition: hypre.hpp:544
HypreSolverBase< Matrix_, Filter_ > BaseClass
our base-class
Definition: hypre.hpp:542
HYPRE Euclid Preconditioner Wrapper class template.
Definition: hypre.hpp:401
void * _solver
the HYPRE solver object
Definition: hypre.hpp:410
virtual void done_numeric() override
Numeric finalization method.
Definition: hypre.hpp:456
BaseClass::VectorType VectorType
the vector type
Definition: hypre.hpp:406
int _iparam[1]
integer parameters:
Definition: hypre.hpp:414
double _dparam[1]
double parameters:
Definition: hypre.hpp:418
virtual void init_numeric() override
Numeric Initialization.
Definition: hypre.hpp:448
virtual String name() const override
Returns a descriptive string.
Definition: hypre.hpp:443
HypreSolverBase< Matrix_, Filter_ > BaseClass
our base-class
Definition: hypre.hpp:404
Base-Class for solvers/preconditioners borrowed from HYPRE library.
Definition: hypre.hpp:107
ADPSolverBase< Matrix_, Filter_, SolverBase_ > BaseClass
our base-class
Definition: hypre.hpp:110
virtual void init_numeric() override
Numeric Initialization.
Definition: hypre.hpp:202
void _download_cor(VectorType &vec_cor)
Downloads the HYPRE correction vector.
Definition: hypre.hpp:148
virtual void done_symbolic() override
Symbolic Finalization.
Definition: hypre.hpp:221
void * _core
a pointer to our opaque core wrapper object
Definition: hypre.hpp:116
virtual void init_symbolic() override
Symbolic Initialization.
Definition: hypre.hpp:173
void _upload_def(const VectorType &vec_def)
Uploads the HYPRE defect vector.
Definition: hypre.hpp:133
void _format_cor()
Formats the HYPRE correction vector to zero.
Definition: hypre.hpp:158
HYPRE ParaSails Preconditioner Wrapper class template.
Definition: hypre.hpp:246
int _iparam[2]
integer parameters:
Definition: hypre.hpp:260
void * _solver
the HYPRE solver object
Definition: hypre.hpp:255
virtual void done_numeric() override
Numeric finalization method.
Definition: hypre.hpp:314
double _dparam[2]
double parameters:
Definition: hypre.hpp:265
BaseClass::VectorType VectorType
the vector type
Definition: hypre.hpp:251
HypreSolverBase< Matrix_, Filter_ > BaseClass
our base-class
Definition: hypre.hpp:249
virtual String name() const override
Returns a descriptive string.
Definition: hypre.hpp:301
virtual void init_numeric() override
Numeric Initialization.
Definition: hypre.hpp:306
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void init_numeric()
Numeric initialization method.
Definition: base.hpp:237
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
virtual void done_numeric()
Numeric finalization method.
Definition: base.hpp:246
String class implementation.
Definition: string.hpp:47
std::shared_ptr< EuclidPrecond< Matrix_, Filter_ > > new_euclid_precond(const Matrix_ &matrix, const Filter_ &filter)
Creates a new EuclidPrecond solver object.
Definition: hypre.hpp:495
std::shared_ptr< BoomerAMG< Matrix_, Filter_ > > new_boomeramg(const Matrix_ &matrix, const Filter_ &filter)
Creates a new BoomerAMG solver object.
Definition: hypre.hpp:629
std::shared_ptr< ParaSailsPrecond< Matrix_, Filter_ > > new_parasails_precond(const Matrix_ &matrix, const Filter_ &filter)
Creates a new ParaSailsPrecond solver object.
Definition: hypre.hpp:355
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
FEAT namespace.
Definition: adjactor.hpp:12